From 3d6e1b5bc30d2dbe39b49c6165136092743d5074 Mon Sep 17 00:00:00 2001 From: Keon Date: Fri, 22 Nov 2024 01:59:46 +0900 Subject: [PATCH 1/7] feat: add like dto --- .../gummy_dang/like/domain/LikeCount.java | 14 ++++++++++++++ .../gummy_dang/like/domain/LikeResponse.java | 15 +++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/main/java/com/develop_mouse/gummy_dang/like/domain/LikeCount.java create mode 100644 src/main/java/com/develop_mouse/gummy_dang/like/domain/LikeResponse.java diff --git a/src/main/java/com/develop_mouse/gummy_dang/like/domain/LikeCount.java b/src/main/java/com/develop_mouse/gummy_dang/like/domain/LikeCount.java new file mode 100644 index 0000000..8db249e --- /dev/null +++ b/src/main/java/com/develop_mouse/gummy_dang/like/domain/LikeCount.java @@ -0,0 +1,14 @@ +package com.develop_mouse.gummy_dang.like.domain; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class LikeCount { + + private Integer likeCount; + +} diff --git a/src/main/java/com/develop_mouse/gummy_dang/like/domain/LikeResponse.java b/src/main/java/com/develop_mouse/gummy_dang/like/domain/LikeResponse.java new file mode 100644 index 0000000..25b4053 --- /dev/null +++ b/src/main/java/com/develop_mouse/gummy_dang/like/domain/LikeResponse.java @@ -0,0 +1,15 @@ +package com.develop_mouse.gummy_dang.like.domain; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class LikeResponse { + + private Long likeId; + private Long postId; + +} From 5bb12c943ab9c874daab5e47ff9d4f9132deb7d8 Mon Sep 17 00:00:00 2001 From: Keon Date: Fri, 22 Nov 2024 02:00:42 +0900 Subject: [PATCH 2/7] feat: add LikeRepository --- .../gummy_dang/like/repository/LikeRepository.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/com/develop_mouse/gummy_dang/like/repository/LikeRepository.java diff --git a/src/main/java/com/develop_mouse/gummy_dang/like/repository/LikeRepository.java b/src/main/java/com/develop_mouse/gummy_dang/like/repository/LikeRepository.java new file mode 100644 index 0000000..e41c618 --- /dev/null +++ b/src/main/java/com/develop_mouse/gummy_dang/like/repository/LikeRepository.java @@ -0,0 +1,14 @@ +package com.develop_mouse.gummy_dang.like.repository; + +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.develop_mouse.gummy_dang.like.domain.entity.Like; +import com.develop_mouse.gummy_dang.member.domain.entity.Member; +import com.develop_mouse.gummy_dang.post.domain.entity.Post; + +public interface LikeRepository extends JpaRepository { + + Optional findByMemberAndPost(Member member, Post post); +} From 05c725cd01386c56f5da3cdf644bb2631e8e8a39 Mon Sep 17 00:00:00 2001 From: Keon Date: Fri, 22 Nov 2024 02:01:35 +0900 Subject: [PATCH 3/7] feat: add post method --- .../gummy_dang/post/repository/PostRepository.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/com/develop_mouse/gummy_dang/post/repository/PostRepository.java b/src/main/java/com/develop_mouse/gummy_dang/post/repository/PostRepository.java index 209a4e4..48b6cca 100644 --- a/src/main/java/com/develop_mouse/gummy_dang/post/repository/PostRepository.java +++ b/src/main/java/com/develop_mouse/gummy_dang/post/repository/PostRepository.java @@ -1,10 +1,20 @@ package com.develop_mouse.gummy_dang.post.repository; +import java.util.List; +import java.util.Optional; + import com.develop_mouse.gummy_dang.post.domain.entity.Post; + +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; public interface PostRepository extends JpaRepository{ + @EntityGraph(attributePaths = {"like"}) + Optional findByIdIs(Long postId); + + @EntityGraph(attributePaths = {"member"}) + List findAll(); } From 676b20ada73699738550e1b83014eeae66c7ae80 Mon Sep 17 00:00:00 2001 From: Keon Date: Fri, 22 Nov 2024 02:01:53 +0900 Subject: [PATCH 4/7] feat: add like service V2 --- .../like/service/LikeServiceV2.java | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/main/java/com/develop_mouse/gummy_dang/like/service/LikeServiceV2.java diff --git a/src/main/java/com/develop_mouse/gummy_dang/like/service/LikeServiceV2.java b/src/main/java/com/develop_mouse/gummy_dang/like/service/LikeServiceV2.java new file mode 100644 index 0000000..c7f5597 --- /dev/null +++ b/src/main/java/com/develop_mouse/gummy_dang/like/service/LikeServiceV2.java @@ -0,0 +1,90 @@ +package com.develop_mouse.gummy_dang.like.service; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.develop_mouse.gummy_dang.authentication.util.SecurityContextUtil; +import com.develop_mouse.gummy_dang.common.Exception.BusinessException; +import com.develop_mouse.gummy_dang.common.domain.ResponseCode; +import com.develop_mouse.gummy_dang.common.domain.response.Response; +import com.develop_mouse.gummy_dang.like.domain.LikeCount; +import com.develop_mouse.gummy_dang.like.domain.LikeResponse; +import com.develop_mouse.gummy_dang.like.domain.entity.Like; +import com.develop_mouse.gummy_dang.like.repository.LikeRepository; +import com.develop_mouse.gummy_dang.member.domain.entity.Member; +import com.develop_mouse.gummy_dang.member.repository.MemberRepository; +import com.develop_mouse.gummy_dang.post.domain.entity.Post; +import com.develop_mouse.gummy_dang.post.repository.PostRepository; + +import lombok.RequiredArgsConstructor; + +@Service +@Transactional +@RequiredArgsConstructor +public class LikeServiceV2 { + + private final LikeRepository likeRepository; + private final PostRepository postRepository; + private final SecurityContextUtil securityContextUtil; + private final MemberRepository memberRepository; + + public Response createLike(Long postId) { + // Member 정보 조회 + Member member = memberRepository.findById(securityContextUtil.getContextMemberInfo().getMemberId()) + .stream() + .findAny() + .orElseThrow(() -> new BusinessException(ResponseCode.MEMBER_NOT_FOUND)); + + // Post 정보 조회 + Post post = postRepository.findById(postId).stream() + .findAny() + .orElseThrow(() -> new BusinessException(ResponseCode.POST_NOT_FOUND)); + + likeRepository.findByMemberAndPost(member, post).ifPresent(like -> { + throw new BusinessException(ResponseCode.LIKE_DUPLICATE); + }); + + Like like = Like.builder() + .member(member) + .post(post) + .build(); + + Like savedLike = likeRepository.save(like); + + return Response.ok(new LikeResponse(savedLike.getId(), post.getId())); + } + + public Response deleteLike(Long postId) { + // Member 정보 조회 + Member member = memberRepository.findById(securityContextUtil.getContextMemberInfo().getMemberId()) + .stream() + .findAny() + .orElseThrow(() -> new BusinessException(ResponseCode.MEMBER_NOT_FOUND)); + + // Post 정보 조회 + Post post = postRepository.findById(postId).stream() + .findAny() + .orElseThrow(() -> new BusinessException(ResponseCode.POST_NOT_FOUND)); + + Like like = likeRepository.findByMemberAndPost(member, post).stream() + .findAny() + .orElseThrow(() -> new BusinessException(ResponseCode.LIKE_NOT_FOUND)); + + if (like.getMember() != member) { + throw new BusinessException(ResponseCode.MEMBER_UNAUTHORIZED); + } + + likeRepository.delete(like); + + return Response.ok(); + } + + public Response getLikeCount(Long postId) { + Post post = postRepository.findByIdIs(postId).stream() + .findAny() + .orElseThrow(() -> new BusinessException(ResponseCode.POST_NOT_FOUND)); + + return Response.ok(new LikeCount(post.getLike().size())); + } + +} From 2e49d4aea802133ea261223e226058b20db6348b Mon Sep 17 00:00:00 2001 From: Keon Date: Fri, 22 Nov 2024 02:02:22 +0900 Subject: [PATCH 5/7] feat: add Like controller V2 --- .../like/controller/LikeControllerV2.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/main/java/com/develop_mouse/gummy_dang/like/controller/LikeControllerV2.java diff --git a/src/main/java/com/develop_mouse/gummy_dang/like/controller/LikeControllerV2.java b/src/main/java/com/develop_mouse/gummy_dang/like/controller/LikeControllerV2.java new file mode 100644 index 0000000..e82d560 --- /dev/null +++ b/src/main/java/com/develop_mouse/gummy_dang/like/controller/LikeControllerV2.java @@ -0,0 +1,51 @@ +package com.develop_mouse.gummy_dang.like.controller; + +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.develop_mouse.gummy_dang.common.domain.response.Response; +import com.develop_mouse.gummy_dang.like.domain.LikeCount; +import com.develop_mouse.gummy_dang.like.domain.LikeResponse; +import com.develop_mouse.gummy_dang.like.service.LikeServiceV2; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequestMapping("/api") +@RequiredArgsConstructor +public class LikeControllerV2 { + + private final LikeServiceV2 likeService; + + /** + * 좋아요 누르기 + * @param postId : 누르고자 하는 게시글 id + */ + @PostMapping("/post/{postId}/like") + public Response createLike(@PathVariable Long postId) { + return likeService.createLike(postId); + } + + /** + * 좋아요 취소 + * @param postId : 취소하고자 하는 게시글 id + */ + @DeleteMapping("/post/{postId}/like") + public Response deleteLike(@PathVariable Long postId) { + return likeService.deleteLike(postId); + } + + /** + * 게시글의 총 좋아요 수 가져오기 + * @param postId : 조회하고자 하는 게시글 id + */ + @GetMapping("/post/{postId}/like-count") + public Response getLikeCount(@PathVariable Long postId) { + return likeService.getLikeCount(postId); + } + +} From 5958f2c01118538eb459c4f310b76c18cc5d0035 Mon Sep 17 00:00:00 2001 From: Keon Date: Fri, 22 Nov 2024 02:02:52 +0900 Subject: [PATCH 6/7] feat: add post like count --- .../gummy_dang/common/domain/ResponseCode.java | 2 ++ .../gummy_dang/post/domain/response/PostResponse.java | 2 ++ .../gummy_dang/post/service/PostServiceImpl.java | 7 ++++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/develop_mouse/gummy_dang/common/domain/ResponseCode.java b/src/main/java/com/develop_mouse/gummy_dang/common/domain/ResponseCode.java index a3d3b1f..7a2ac8b 100644 --- a/src/main/java/com/develop_mouse/gummy_dang/common/domain/ResponseCode.java +++ b/src/main/java/com/develop_mouse/gummy_dang/common/domain/ResponseCode.java @@ -24,6 +24,8 @@ public enum ResponseCode { IMAGE_NOT_FOUND("IMG-001", "There's no image onb request."), COMMENT_NOT_FOUND("CMT-001", "No such comment exist."), COMMENT_WRITER_DIFFERENCE("CMT-002", "User and author are different"), + LIKE_NOT_FOUND("LKE-001", "Like count not found."), + LIKE_DUPLICATE("LKE-002", "Like is duplicate.") ; private final String responseCode; diff --git a/src/main/java/com/develop_mouse/gummy_dang/post/domain/response/PostResponse.java b/src/main/java/com/develop_mouse/gummy_dang/post/domain/response/PostResponse.java index b768b8a..ab229b3 100644 --- a/src/main/java/com/develop_mouse/gummy_dang/post/domain/response/PostResponse.java +++ b/src/main/java/com/develop_mouse/gummy_dang/post/domain/response/PostResponse.java @@ -23,6 +23,8 @@ public class PostResponse { private String description; private String imageUrl; private LocalDate createdAt; + @Builder.Default + private Boolean liked = false; private List postCoordinates; diff --git a/src/main/java/com/develop_mouse/gummy_dang/post/service/PostServiceImpl.java b/src/main/java/com/develop_mouse/gummy_dang/post/service/PostServiceImpl.java index b99d1b8..1326d8b 100644 --- a/src/main/java/com/develop_mouse/gummy_dang/post/service/PostServiceImpl.java +++ b/src/main/java/com/develop_mouse/gummy_dang/post/service/PostServiceImpl.java @@ -4,10 +4,10 @@ import com.develop_mouse.gummy_dang.common.Exception.BusinessException; import com.develop_mouse.gummy_dang.common.domain.ResponseCode; import com.develop_mouse.gummy_dang.common.domain.response.Response; +import com.develop_mouse.gummy_dang.like.repository.LikeRepository; import com.develop_mouse.gummy_dang.member.domain.entity.Member; import com.develop_mouse.gummy_dang.member.repository.MemberRepository; import com.develop_mouse.gummy_dang.post.DTO.PostCoordinateDTO; -import com.develop_mouse.gummy_dang.post.DTO.PostDTO; import com.develop_mouse.gummy_dang.post.domain.entity.Post; import com.develop_mouse.gummy_dang.post.domain.entity.PostCoordinate; import com.develop_mouse.gummy_dang.post.domain.request.PostRequest; @@ -43,6 +43,7 @@ public class PostServiceImpl implements PostService{ private final MemberRepository memberRepository; private final SecurityContextUtil securityContextUtil; // 현 사용자 불러오기 위해 주입 private final PostCoordinateRepository postCoordinateRepository; + private final LikeRepository likeRepository; // +) 이미지에서 사용 private ServletContext servletContext; // ServletContext 주입 @@ -189,6 +190,7 @@ public Response deletePost(Long id) { // 글 하나 보기 @Override public Response detailPost(Long id) { + Optional member = memberRepository.findById(securityContextUtil.getContextMemberInfo().getMemberId()); Post post = postRepository.findById(id).stream() .findAny() .orElseThrow(() -> new BusinessException(ResponseCode.POST_NOT_FOUND)); @@ -198,6 +200,7 @@ public Response detailPost(Long id) { .title(post.getTitle()) .description(post.getDescription()) .imageUrl(post.getImageUrl()) + .liked(member.isPresent() && likeRepository.findByMemberAndPost(member.get(), post).isPresent()) .postCoordinates(post.getPostCoordinates().stream() .map(PostCoordinateDTO::fromEntity) .toList()) @@ -210,6 +213,7 @@ public Response detailPost(Long id) { // 글 목록 @Override public Response> postList() { + Optional member = memberRepository.findById(securityContextUtil.getContextMemberInfo().getMemberId()); List posts = postRepository.findAll(); List postResponses = posts.stream() @@ -218,6 +222,7 @@ public Response> postList() { .title(post.getTitle()) .description(post.getDescription()) .imageUrl(post.getImageUrl()) + .liked(member.isPresent() && likeRepository.findByMemberAndPost(member.get(), post).isPresent()) .postCoordinates(post.getPostCoordinates().stream() .map(PostCoordinateDTO::fromEntity) .toList()) From 387e94392d2bec8542e36c60480b124467ca0e12 Mon Sep 17 00:00:00 2001 From: Keon Date: Fri, 22 Nov 2024 02:14:19 +0900 Subject: [PATCH 7/7] feat: add created time field on post list --- .../develop_mouse/gummy_dang/post/service/PostServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/develop_mouse/gummy_dang/post/service/PostServiceImpl.java b/src/main/java/com/develop_mouse/gummy_dang/post/service/PostServiceImpl.java index 1326d8b..1551003 100644 --- a/src/main/java/com/develop_mouse/gummy_dang/post/service/PostServiceImpl.java +++ b/src/main/java/com/develop_mouse/gummy_dang/post/service/PostServiceImpl.java @@ -226,6 +226,7 @@ public Response> postList() { .postCoordinates(post.getPostCoordinates().stream() .map(PostCoordinateDTO::fromEntity) .toList()) + .createdAt(post.getCreatedAt().toLocalDate()) .build()) .toList();