diff --git a/src/main/java/com/moongeul/backend/api/book/dto/ReviewItemDTO.java b/src/main/java/com/moongeul/backend/api/book/dto/ReviewItemDTO.java index 43c433b..0c11cd6 100644 --- a/src/main/java/com/moongeul/backend/api/book/dto/ReviewItemDTO.java +++ b/src/main/java/com/moongeul/backend/api/book/dto/ReviewItemDTO.java @@ -24,5 +24,5 @@ public class ReviewItemDTO { private Double rating; // 별점 private String content; // 내용 private List quotes; // 인상 깊은 구절들 - private PostDTO.LikesInfo likesInfo; // 받은 감정 상태들(공감 통계) + private PostDTO.LikesCnt likesCnt; // 받은 감정 상태들(공감 통계) } diff --git a/src/main/java/com/moongeul/backend/api/book/service/ReviewService.java b/src/main/java/com/moongeul/backend/api/book/service/ReviewService.java index 190de82..ce9cc0d 100644 --- a/src/main/java/com/moongeul/backend/api/book/service/ReviewService.java +++ b/src/main/java/com/moongeul/backend/api/book/service/ReviewService.java @@ -67,7 +67,7 @@ private ReviewItemDTO convertToReviewItemDTO(Post post) { .build()) .collect(Collectors.toList()); - PostDTO.LikesInfo likesInfo = PostDTO.LikesInfo.builder() + PostDTO.LikesCnt likesCnt = PostDTO.LikesCnt.builder() .relatableCount(post.getRelatableCount()) .sameTasteCount(post.getSameTasteCount()) .impressiveExpressionCount(post.getImpressiveExpressionCount()) @@ -84,7 +84,7 @@ private ReviewItemDTO convertToReviewItemDTO(Post post) { .rating(post.getRating()) .content(post.getContent()) .quotes(quoteDTOs) - .likesInfo(likesInfo) + .likesCnt(likesCnt) .build(); } } diff --git a/src/main/java/com/moongeul/backend/api/member/service/MemberService.java b/src/main/java/com/moongeul/backend/api/member/service/MemberService.java index c79071c..4b1c189 100644 --- a/src/main/java/com/moongeul/backend/api/member/service/MemberService.java +++ b/src/main/java/com/moongeul/backend/api/member/service/MemberService.java @@ -373,7 +373,7 @@ private PostDTO convertToPostDTO(Post post) { .build()) .collect(Collectors.toList()); - PostDTO.LikesInfo likesInfo = PostDTO.LikesInfo.builder() + PostDTO.LikesCnt likesCnt = PostDTO.LikesCnt.builder() .relatableCount(post.getRelatableCount()) .sameTasteCount(post.getSameTasteCount()) .impressiveExpressionCount(post.getImpressiveExpressionCount()) @@ -391,7 +391,7 @@ private PostDTO convertToPostDTO(Post post) { .readDate(post.getReadDate()) .quotesCnt(quoteDTOList.size()) .quotes(quoteDTOList) - .likesInfo(likesInfo) + .likesCnt(likesCnt) .build(); } diff --git a/src/main/java/com/moongeul/backend/api/post/controller/PostController.java b/src/main/java/com/moongeul/backend/api/post/controller/PostController.java index f8d5b0a..04322bc 100644 --- a/src/main/java/com/moongeul/backend/api/post/controller/PostController.java +++ b/src/main/java/com/moongeul/backend/api/post/controller/PostController.java @@ -93,9 +93,11 @@ public ResponseEntity> getAllPost( @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "해당 기록(게시글)을 찾을 수 없습니다.") }) @GetMapping("/{id}") - public ResponseEntity> getPost(@PathVariable Long id) { + public ResponseEntity> getPost(@AuthenticationPrincipal UserDetails userDetails, + @PathVariable Long id) { - PostDTO response = postService.getPostDetail(id); + String username = (userDetails != null) ? userDetails.getUsername() : "anonymousUser"; + PostDTO response = postService.getPostDetail(id, username); return ApiResponse.success(SuccessStatus.GET_POST_SUCCESS, response); } diff --git a/src/main/java/com/moongeul/backend/api/post/dto/PostDTO.java b/src/main/java/com/moongeul/backend/api/post/dto/PostDTO.java index 0689b94..bea70d8 100644 --- a/src/main/java/com/moongeul/backend/api/post/dto/PostDTO.java +++ b/src/main/java/com/moongeul/backend/api/post/dto/PostDTO.java @@ -30,7 +30,8 @@ public class PostDTO { private Integer quotesCnt; // 인용 총 개수 private List quotes; // 인상깊은구절 리스트 - private LikesInfo likesInfo; // 공감 개수 정보 + private LikesCnt likesCnt; // 공감 개수 정보 + private MyLikesStatus myLikesStatus; // 내가 누른 공감 유형 정보 @Getter @Builder @@ -63,12 +64,31 @@ public static class QuoteDTO { @Getter @Builder - public static class LikesInfo{ + public static class LikesCnt { private Integer relatableCount; // 공감돼요 private Integer sameTasteCount; // 취향이 같아요 private Integer impressiveExpressionCount; // 표현이 인상적이에요 private Integer wantToReadCount; // 읽고싶네요 private Integer helpfulCount; // 도움이 됐어요 } - + + @Getter + @Builder + public static class MyLikesStatus{ + private boolean relatableCount; // 공감돼요 + private boolean sameTasteCount; // 취향이 같아요 + private boolean impressiveExpressionCount; // 표현이 인상적이에요 + private boolean wantToReadCount; // 읽고싶네요 + private boolean helpfulCount; // 도움이 됐어요 + + public static MyLikesStatus empty() { + return MyLikesStatus.builder() + .relatableCount(false) + .sameTasteCount(false) + .impressiveExpressionCount(false) + .wantToReadCount(false) + .helpfulCount(false) + .build(); + } + } } diff --git a/src/main/java/com/moongeul/backend/api/post/repository/LikeRepository.java b/src/main/java/com/moongeul/backend/api/post/repository/LikeRepository.java index 5a8ad56..9b0467f 100644 --- a/src/main/java/com/moongeul/backend/api/post/repository/LikeRepository.java +++ b/src/main/java/com/moongeul/backend/api/post/repository/LikeRepository.java @@ -1,5 +1,6 @@ package com.moongeul.backend.api.post.repository; +import com.moongeul.backend.api.post.entity.LikeType; import com.moongeul.backend.api.post.entity.Likes; import org.springframework.data.jpa.repository.JpaRepository; @@ -8,7 +9,9 @@ public interface LikeRepository extends JpaRepository { - Optional findByPostIdAndMemberId(Long postId, Long memberId); + List findByPostIdAndMemberId(Long postId, Long memberId); + + Optional findByPostIdAndMemberIdAndLikeType(Long postId, Long memberId, LikeType likeType); // 특정 게시글의 모든 공감 조회 List findByPostId(Long postId); diff --git a/src/main/java/com/moongeul/backend/api/post/service/PostService.java b/src/main/java/com/moongeul/backend/api/post/service/PostService.java index 2748de9..1a49698 100644 --- a/src/main/java/com/moongeul/backend/api/post/service/PostService.java +++ b/src/main/java/com/moongeul/backend/api/post/service/PostService.java @@ -33,6 +33,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; @Slf4j @Service @@ -125,7 +127,7 @@ public PostAllResponseDTO getPostAll(PostAllRequestDTO postAllRequestDTO, String List postDTOList = new ArrayList<>(); if (!postPage.isEmpty()) { for(Post post : postPage.getContent()){ - postDTOList.add(getPostDetail(post.getId())); + postDTOList.add(getPostDetail(post.getId(), member.getEmail())); } } @@ -141,7 +143,7 @@ public PostAllResponseDTO getPostAll(PostAllRequestDTO postAllRequestDTO, String /* 기록(게시글) 상세 조회 */ @Transactional - public PostDTO getPostDetail(Long postId){ + public PostDTO getPostDetail(Long postId, String email){ Post post = getPost(postId); Book book = getBook(post.getBook().getIsbn()); @@ -177,7 +179,7 @@ public PostDTO getPostDetail(Long postId){ } // 공감 개수 DTO - PostDTO.LikesInfo likesInfo = PostDTO.LikesInfo.builder() + PostDTO.LikesCnt likesCnt = PostDTO.LikesCnt.builder() .relatableCount(post.getRelatableCount()) .sameTasteCount(post.getSameTasteCount()) .impressiveExpressionCount(post.getImpressiveExpressionCount()) @@ -185,6 +187,12 @@ public PostDTO getPostDetail(Long postId){ .helpfulCount(post.getHelpfulCount()) .build(); + /* 내가 누른 공감 유형 정보 DTO */ + boolean isAnonymous = (email == null || "anonymousUser".equals(email)); + PostDTO.MyLikesStatus myLikesStatus = isAnonymous + ? PostDTO.MyLikesStatus.empty() + : convertToMyLikesStatus(email, postId); + return PostDTO.builder() .postId(postId) .memberInfo(memberInfo) @@ -195,7 +203,33 @@ public PostDTO getPostDetail(Long postId){ .readDate(post.getReadDate()) .quotesCnt(quoteDTOList.size()) .quotes(quoteDTOList) - .likesInfo(likesInfo) + .likesCnt(likesCnt) + .myLikesStatus(myLikesStatus) + .build(); + } + + // 메서드: 내가 누른 공감 유형 정보 DTO 변환 + private PostDTO.MyLikesStatus convertToMyLikesStatus(String email, Long postId){ + Member member = getMemberByEmail(email); + + List myLikes = likeRepository.findByPostIdAndMemberId(postId, member.getId()); + + // 아무것도 누르지 않았을 때의 로직 + if (myLikes.isEmpty()) { + return PostDTO.MyLikesStatus.empty(); + } + + // 리스트를 돌면서 각 타입이 있는지 확인 + Set myLikesTypes = myLikes.stream() + .map(Likes::getLikeType) + .collect(Collectors.toSet()); + + return PostDTO.MyLikesStatus.builder() + .relatableCount(myLikesTypes.contains(LikeType.RELATABLE)) + .sameTasteCount(myLikesTypes.contains(LikeType.SAME_TASTE)) + .impressiveExpressionCount(myLikesTypes.contains(LikeType.IMPRESSIVE_EXPRESSION)) + .wantToReadCount(myLikesTypes.contains(LikeType.WANT_TO_READ)) + .helpfulCount(myLikesTypes.contains(LikeType.HELPFUL)) .build(); } @@ -293,34 +327,23 @@ public void likePost(Long postId, String email, LikeDTO likeDTO){ Member member = getMemberByEmail(email); Post post = getPost(postId); + LikeType requestLikeType = likeDTO.getLikeType(); - // 사용자가 해당 게시글에 누른 공감 유형이 있다면 - Optional existingLike = likeRepository.findByPostIdAndMemberId(postId, member.getId()); + // 사용자가 해당 게시글에 '해당 유형'의 공감을 눌렀는지 + Optional existingLike = likeRepository.findByPostIdAndMemberIdAndLikeType(postId, member.getId(), requestLikeType); if(existingLike.isPresent()){ - Likes currentLikes = existingLike.get(); - - // 사용자가 해당 게시글에 누른 "같은 공감 유형"이 있다면(또 누른 경우) -> 공감 삭제 - if (currentLikes.getLikeType().equals(likeDTO.getLikeType())) { - decrementLikeCount(post, currentLikes.getLikeType()); - likeRepository.delete(currentLikes); - return; - } - - // 사용자가 해당 게시글에 누른 "다른 공감 유형"이 있다면 -> 공감 유형 수정 - decrementLikeCount(post, currentLikes.getLikeType()); - currentLikes.changeLikeType(likeDTO.getLikeType()); - incrementLikeCount(post, likeDTO.getLikeType()); + // 이미 있다면 -> 취소 + decrementLikeCount(post, requestLikeType); + likeRepository.delete(existingLike.get()); + } else{ + // 없다면 새로 추가 + Likes newLike = likeDTO.toEntity(member, post); + likeRepository.save(newLike); + incrementLikeCount(post, requestLikeType); notificationTriggerService.likeNotification(post.getMember(), member, post); // 알림 발생 - return; } - - // 처음 공감을 누르는 경우 -> 새로 저장 - likeRepository.save(likeDTO.toEntity(member, post)); - incrementLikeCount(post, likeDTO.getLikeType()); - - notificationTriggerService.likeNotification(post.getMember(), member, post); // 알림 발생 } // 공감 카운트 증가 메서드