Skip to content

Commit

Permalink
Merge pull request #83 from aelimited/feature/#63-RefactoringClub
Browse files Browse the repository at this point in the history
Feature/#63 refactoring club(clubLike)
  • Loading branch information
aelimited authored Jun 8, 2024
2 parents 9472f5e + fbf0695 commit 7e492fc
Show file tree
Hide file tree
Showing 12 changed files with 219 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package com.core.linkup.club.club.controller;

import com.core.linkup.club.club.request.ClubApplicationRequest;
import com.core.linkup.club.club.request.ClubCreateRequest;
import com.core.linkup.club.club.request.ClubSearchRequest;
import com.core.linkup.club.club.request.ClubUpdateRequest;
import com.core.linkup.club.club.request.*;
import com.core.linkup.club.club.response.ClubApplicationResponse;
import com.core.linkup.club.club.response.ClubLikeResponse;
import com.core.linkup.club.club.response.ClubSearchResponse;
import com.core.linkup.club.club.service.ClubService;
import com.core.linkup.common.exception.BaseException;
import com.core.linkup.common.response.BaseResponse;
import com.core.linkup.common.response.BaseResponseStatus;
import com.core.linkup.security.MemberDetails;
Expand Down Expand Up @@ -109,4 +108,38 @@ public BaseResponse<List<ClubApplicationResponse>> findMyApplicationList(
List<ClubApplicationResponse> response = clubService.findMyClubApplicationList(member);
return BaseResponse.response(response);
}

//소모임 좋아요
@PostMapping("/{club_id}/like")
public BaseResponse<ClubLikeResponse> likeClub(
@AuthenticationPrincipal MemberDetails member,
@PathVariable("club_id") Long clubId
) {
Long memberId = member.getId();

ClubLikeResponse response = clubService.likeClub(memberId, clubId);
return BaseResponse.response(response);
}

// 좋아요 조회
@GetMapping("/like")
public BaseResponse<Page<ClubLikeResponse>> findClub(
@AuthenticationPrincipal MemberDetails member,
@PageableDefault(sort = "id", direction = Sort.Direction.ASC) Pageable pageable,
@ModelAttribute ClubLikeRequest request
) {
Page<ClubLikeResponse> response = clubService.findLikeClub(member, pageable, request);
return BaseResponse.response(response);
}

//삭제
@DeleteMapping("/{club_id}/like")
public BaseResponse<Void> deleteClub(
@AuthenticationPrincipal MemberDetails member,
@PathVariable("club_id") Long clubId
) {
Long memberId = member.getId();
clubService.unlikeClub(memberId, clubId);
return BaseResponse.response(BaseResponseStatus.DELETE_SUCCESS);
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
package com.core.linkup.club.club.converter;

import com.core.linkup.club.club.entity.Club;
import com.core.linkup.club.club.entity.ClubAnswer;
import com.core.linkup.club.club.entity.ClubMember;
import com.core.linkup.club.club.entity.ClubQuestion;
import com.core.linkup.club.club.entity.*;
import com.core.linkup.club.club.request.*;
import com.core.linkup.club.club.response.ClubAnswerResponse;
import com.core.linkup.club.club.response.ClubApplicationResponse;
import com.core.linkup.club.club.response.ClubMemberResponse;
import com.core.linkup.club.club.response.ClubSearchResponse;
import com.core.linkup.club.club.response.*;
import com.core.linkup.club.clubmeeting.entity.ClubMeeting;
import com.core.linkup.club.clubmeeting.response.ClubMeetingResponse;
import com.core.linkup.common.annotation.Converter;
Expand All @@ -18,6 +12,7 @@
import com.core.linkup.member.entity.Member;
import com.core.linkup.security.MemberDetails;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -160,4 +155,32 @@ private ClubAnswerResponse toClubAnswerResponse(ClubAnswer clubAnswer) {
.qorders(clubAnswer.getQorders())
.build();
}

public ClubLike toLikeEntity(Long memberId, Long clubId) {
return ClubLike.builder()
.memberId(memberId)
.clubId(clubId)
.build();
}

public ClubLikeResponse toLikeResponse(ClubLike clubLike) {
return ClubLikeResponse.builder()
.id(clubLike.getId())
.memberId(clubLike.getMemberId())
.clubId(clubLike.getClubId())
.build();
}

public ClubLikeResponse toLikeResponse(ClubLike clubLike, Club club, ClubMeeting clubMeeting) {
return ClubLikeResponse.builder()
.id(clubLike.getId())
.memberId(clubLike.getMemberId())
.clubId(clubLike.getClubId())
.clubThumbnail(club.getClubThumbnail())
.clubName(club.getTitle())
.clubIntroduction(club.getIntroduction())
.clubMemberCount(club.getRecruitCount())
.clubMeetingDate(clubMeeting != null ? LocalDate.from(clubMeeting.getDate()) : null)
.build();
}
}
19 changes: 19 additions & 0 deletions src/main/java/com/core/linkup/club/club/entity/ClubLike.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.core.linkup.club.club.entity;

import com.core.linkup.common.entity.BaseEntity;
import jakarta.persistence.Entity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

@Entity(name = "club_like")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@SuperBuilder
public class ClubLike extends BaseEntity {

private Long clubId;
private Long memberId;
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
package com.core.linkup.club.club.repository;

import com.core.linkup.club.club.entity.Club;
import com.core.linkup.club.club.entity.ClubLike;
import com.core.linkup.club.club.request.ClubSearchRequest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

public interface ClubCustomRepository {

Page<Club> findSearchClubs(ClubSearchRequest request, Pageable pageable);

boolean existsValidMembershipWithLocation(Long memberId);

Long findOfficeBuildingIdByLocation(String location);

Page<ClubLike> findClubLikes(Long memberId, Pageable pageable);

boolean existsByMemberIdAndClubId(Long memberId, Long clubId);
void deleteByMemberIdAndClubId(Long memberId, Long clubId);

}
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
package com.core.linkup.club.club.repository;

import com.core.linkup.club.club.entity.Club;
import com.core.linkup.club.club.entity.ClubLike;
import com.core.linkup.club.club.entity.QClub;
import com.core.linkup.club.club.entity.QClubLike;
import com.core.linkup.club.club.request.ClubSearchRequest;
import com.core.linkup.club.clubmeeting.entity.QClubMeeting;
import com.core.linkup.common.entity.enums.ClubType;
import com.core.linkup.office.entity.QOfficeBuilding;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPADeleteClause;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import static com.core.linkup.club.club.entity.QClubLike.clubLike;
import static com.core.linkup.office.entity.QOfficeBuilding.officeBuilding;
import static com.core.linkup.reservation.membership.company.entity.QCompanyMembership.companyMembership;
import static com.core.linkup.reservation.membership.individual.entity.QIndividualMembership.individualMembership;
Expand Down Expand Up @@ -72,7 +79,49 @@ public Long findOfficeBuildingIdByLocation(String location) {
return queryFactory.select(officeBuilding.id)
.from(officeBuilding)
.where(officeBuilding.location.eq(location))
//String.valueOf(officeBuilding.location.isNull()))
//String.valueOf(officeBuilding.location.isNull()))
.fetchFirst();
}

@Override
public Page<ClubLike> findClubLikes(Long memberId, Pageable pageable) {
QClubLike clubLike = QClubLike.clubLike;
QClub club = QClub.club;
QClubMeeting clubMeeting = QClubMeeting.clubMeeting;

List<ClubLike> results = queryFactory.select(clubLike)
.from(clubLike)
.leftJoin(club).on(clubLike.clubId.eq(club.id))
.leftJoin(clubMeeting).on(club.id.eq(clubMeeting.id))
.where(clubLike.memberId.eq(memberId))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(clubLike.id.asc())
.fetch();

long total = queryFactory.selectFrom(clubLike)
.where(clubLike.memberId.eq(memberId))
.fetchCount();

return new PageImpl<>(results, pageable, total);
}
@Override
public boolean existsByMemberIdAndClubId(Long memberId, Long clubId) {
Integer fetchOne = queryFactory
.selectOne()
.from(clubLike)
.where(clubLike.memberId.eq(memberId).and(clubLike.clubId.eq(clubId)))
.fetchFirst();

return fetchOne != null;
}

@Override
@Transactional
public void deleteByMemberIdAndClubId(Long memberId, Long clubId) {
queryFactory
.delete(clubLike)
.where(clubLike.memberId.eq(memberId).and(clubLike.clubId.eq(clubId)))
.execute();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.core.linkup.club.club.repository;

import com.core.linkup.club.club.entity.ClubLike;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ClubLikeRepository extends JpaRepository<ClubLike, Long> {

void deleteByMemberIdAndClubId(Long memberId, Long clubId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.core.linkup.club.club.request;

public record ClubLikeRequest () {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.core.linkup.club.club.response;

import lombok.Builder;

import java.time.LocalDate;

@Builder
public record ClubLikeResponse(
Long id,
Long clubId,
Long memberId,
String clubThumbnail,
String clubName,
String clubIntroduction,
Integer clubMemberCount,
LocalDate clubMeetingDate
) {
}
50 changes: 36 additions & 14 deletions src/main/java/com/core/linkup/club/club/service/ClubService.java
Original file line number Diff line number Diff line change
@@ -1,33 +1,25 @@
package com.core.linkup.club.club.service;

import com.core.linkup.club.club.converter.ClubConverter;
import com.core.linkup.club.club.entity.Club;
import com.core.linkup.club.club.entity.ClubAnswer;
import com.core.linkup.club.club.entity.ClubMember;
import com.core.linkup.club.club.entity.ClubQuestion;
import com.core.linkup.club.club.repository.ClubAnswerRepository;
import com.core.linkup.club.club.repository.ClubMemberRepository;
import com.core.linkup.club.club.repository.ClubQuestionRepository;
import com.core.linkup.club.club.repository.ClubRepository;
import com.core.linkup.club.club.request.ClubApplicationRequest;
import com.core.linkup.club.club.request.ClubCreateRequest;
import com.core.linkup.club.club.request.ClubSearchRequest;
import com.core.linkup.club.club.request.ClubUpdateRequest;
import com.core.linkup.club.club.entity.*;
import com.core.linkup.club.club.repository.*;
import com.core.linkup.club.club.request.*;
import com.core.linkup.club.club.response.ClubApplicationResponse;
import com.core.linkup.club.club.response.ClubLikeResponse;
import com.core.linkup.club.club.response.ClubSearchResponse;
import com.core.linkup.club.clubmeeting.entity.ClubMeeting;
import com.core.linkup.club.clubmeeting.repository.ClubMeetingRepository;
import com.core.linkup.common.exception.BaseException;
import com.core.linkup.common.response.BaseResponseStatus;
import com.core.linkup.member.entity.Member;
import com.core.linkup.member.repository.MemberRepository;
import com.core.linkup.office.repository.OfficeRepository;
import com.core.linkup.security.MemberDetails;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
Expand All @@ -45,7 +37,7 @@ public class ClubService {
private final ClubConverter clubConverter;
private final ClubAnswerRepository clubAnswerRepository;
private final ClubMeetingRepository clubMeetingRepository;
private final OfficeRepository officeRepository;
private final ClubLikeRepository clubLikeRepository;

//소모임 조회
public ClubSearchResponse findClub(Long clubId) {
Expand Down Expand Up @@ -220,4 +212,34 @@ private Club validateClub(Long clubId) {
.orElseThrow(() -> new BaseException(BaseResponseStatus.INVALID_CLUB_ID));
return club;
}

public ClubLikeResponse likeClub(Long memberId, Long clubId) {
boolean duplicate = clubRepository.existsByMemberIdAndClubId(memberId, clubId);

if (duplicate) {
throw new BaseException(BaseResponseStatus.DUPLICATE_CLUB_LIKE);
}

ClubLike clubLike = clubConverter.toLikeEntity(memberId, clubId);
clubLikeRepository.save(clubLike);
return clubConverter.toLikeResponse(clubLike);
}


public Page<ClubLikeResponse> findLikeClub(MemberDetails member, Pageable pageable, ClubLikeRequest request) {
Long memberId = member.getId();

Page<ClubLike> clubLikes = clubRepository.findClubLikes(memberId, pageable);

return clubLikes.map(clubLike -> {
Club club = clubRepository.findById(clubLike.getClubId()).orElseThrow((null));
ClubMeeting clubMeeting = clubMeetingRepository.findFirstByClubIdOrderByDateDesc(club.getId()).orElse(null);
return clubConverter.toLikeResponse(clubLike, club, clubMeeting);
});
}

@Transactional
public void unlikeClub(Long memberId, Long clubId) {
clubLikeRepository.deleteByMemberIdAndClubId(memberId, clubId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ public interface ClubMeetingRepository extends JpaRepository<ClubMeeting, Long>

List<ClubMeeting> findByClubId(Long clubId);
Optional<ClubMeeting> findByIdAndClubId(Long id, Long clubId);

Optional<ClubMeeting> findFirstByClubIdOrderByDateDesc(Long id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class ClubNotice extends BaseEntity { // board -> notice
private Long memberId;
private String title;
private String content;

@Enumerated(EnumType.STRING)
private NotificationType type; //게시판 or 공지
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public enum BaseResponseStatus {
INVALID_CLUB_MEETING(false, NOT_FOUND.value(), "소모임에 등록된 정기모임이 아닙니다."),
INVALID_CLUB_MEETING_OWNER(false, NOT_FOUND.value(), "소모임 공지사항 작성자가 입니다."),
INVALID_MEMBERSHIP(false, NOT_FOUND.value(),"멤버십을 먼저 구매 후에 이용해 주세요"),
DUPLICATE_CLUB_LIKE(false, BAD_REQUEST.value(), "이미 좋아요를 눌렀습니다"),

AUTHCODE_ISSUE_ERROR(false, INTERNAL_SERVER_ERROR.value(), "인증코드 발급에 실패했습니다."),

Expand Down

0 comments on commit 7e492fc

Please sign in to comment.