From 2ce18f84d962fe012321e18c5389fdd62178b06d Mon Sep 17 00:00:00 2001 From: "BOOK-U3FJG82JE7\\USER" Date: Mon, 4 Nov 2024 09:23:29 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=ED=8F=AC=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../post/controller/PostController.java | 8 +++++++ .../post/repository/PostRepository.java | 2 ++ .../domains/post/service/PostService.java | 22 ++++++++++++++++++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java b/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java index 1886497..75b3194 100644 --- a/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java +++ b/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java @@ -3,6 +3,7 @@ import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +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; @@ -60,4 +61,11 @@ public ResponseEntity> findPostAnd return ResponseEntity.ok(DataResponse.from(response)); } + + @DeleteMapping("/{postId}") + public ResponseEntity> deletePost(@PathVariable Long postId) { + postService.deletePost(memberLoader.getMemberId(), postId); + + return ResponseEntity.ok(DataResponse.noContent()); + } } diff --git a/backend/src/main/java/aimo/backend/domains/post/repository/PostRepository.java b/backend/src/main/java/aimo/backend/domains/post/repository/PostRepository.java index d4f4d77..3fd07be 100644 --- a/backend/src/main/java/aimo/backend/domains/post/repository/PostRepository.java +++ b/backend/src/main/java/aimo/backend/domains/post/repository/PostRepository.java @@ -15,4 +15,6 @@ public interface PostRepository extends JpaRepository { @Query("SELECT p From Post p LEFT JOIN p.postViews pv GROUP BY p ORDER BY COUNT(pv) DESC") Page findByViewsCount(Pageable pageable); + + Boolean existsByIdAndMember_Id(Long postId, Long memberId); } diff --git a/backend/src/main/java/aimo/backend/domains/post/service/PostService.java b/backend/src/main/java/aimo/backend/domains/post/service/PostService.java index 13379f8..c27b9f1 100644 --- a/backend/src/main/java/aimo/backend/domains/post/service/PostService.java +++ b/backend/src/main/java/aimo/backend/domains/post/service/PostService.java @@ -57,7 +57,12 @@ public FindPostAndCommentsByIdResponse findPostAndCommentsDtoById(Member member, } // PostType으로 글 조회 - public Page findPostDtosByPostType(Member member, PostType postType, Integer page, Integer size) { + public Page findPostDtosByPostType( + Member member, + PostType postType, + Integer page, + Integer size + ) { Page posts; if (postType == PostType.MY) { posts = findMyPosts(member.getId(), PageRequest.of(page, size)); @@ -115,4 +120,19 @@ private Page findCommentedPosts(Long memberId, Pageable pageable) { return new PageImpl<>(pagedPosts, pageable, posts.size()); } + // 글 삭제 + public void deletePost(Long memberId, Long postId) { + validateDeletePost(memberId, postId); + + postRepository.deleteById(postId); + } + + // 글 삭제 권한 확인 + public void validateDeletePost(Long memberId, Long postId) { + Boolean exists = postRepository.existsByIdAndMember_Id(postId, memberId); + + if (!exists) { + throw ApiException.from(POST_DELETE_UNAUTHORIZED); + } + } } From 3c6122099aff60c33609186dca5e65e1999f0ab0 Mon Sep 17 00:00:00 2001 From: "BOOK-U3FJG82JE7\\USER" Date: Mon, 4 Nov 2024 10:05:23 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20Vote=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/common/mapper/PostMapper.java | 15 +-------- .../post/controller/PostController.java | 5 +-- .../post/controller/VoteController.java | 33 +++++++++++++++++++ .../domains/post/dto/GetPostResponse.java | 4 --- .../domains/post/dto/PostListResponse.java | 6 ---- .../domains/post/dto/PostPreviewResponse.java | 24 -------------- .../domains/post/dto/SinglePostResponse.java | 30 ----------------- .../dto/{ => requset}/SavePostRequest.java | 2 +- .../backend/domains/post/entity/Vote.java | 11 +++++++ .../post/repository/VoteRepository.java | 12 +++++++ .../post/repository/VoteRepsoitory.java | 9 ----- .../domains/post/service/PostService.java | 2 +- .../domains/post/service/VoteService.java | 33 +++++++++++++++++++ 13 files changed, 95 insertions(+), 91 deletions(-) create mode 100644 backend/src/main/java/aimo/backend/domains/post/controller/VoteController.java delete mode 100644 backend/src/main/java/aimo/backend/domains/post/dto/GetPostResponse.java delete mode 100644 backend/src/main/java/aimo/backend/domains/post/dto/PostListResponse.java delete mode 100644 backend/src/main/java/aimo/backend/domains/post/dto/PostPreviewResponse.java delete mode 100644 backend/src/main/java/aimo/backend/domains/post/dto/SinglePostResponse.java rename backend/src/main/java/aimo/backend/domains/post/dto/{ => requset}/SavePostRequest.java (96%) create mode 100644 backend/src/main/java/aimo/backend/domains/post/repository/VoteRepository.java delete mode 100644 backend/src/main/java/aimo/backend/domains/post/repository/VoteRepsoitory.java create mode 100644 backend/src/main/java/aimo/backend/domains/post/service/VoteService.java diff --git a/backend/src/main/java/aimo/backend/common/mapper/PostMapper.java b/backend/src/main/java/aimo/backend/common/mapper/PostMapper.java index 23784ae..26c6568 100644 --- a/backend/src/main/java/aimo/backend/common/mapper/PostMapper.java +++ b/backend/src/main/java/aimo/backend/common/mapper/PostMapper.java @@ -4,8 +4,7 @@ import aimo.backend.domains.comment.entity.ParentComment; import aimo.backend.domains.member.entity.Member; -import aimo.backend.domains.post.dto.PostPreviewResponse; -import aimo.backend.domains.post.dto.SavePostRequest; +import aimo.backend.domains.post.dto.requset.SavePostRequest; import aimo.backend.domains.post.dto.response.FindPostAndCommentsByIdResponse; import aimo.backend.domains.post.dto.response.FindPostAndCommentsByIdResponse.ParentCommentDto; import aimo.backend.domains.post.dto.response.FindPostsByPostTypeResponse; @@ -30,18 +29,6 @@ public static Post toEntity(SavePostRequest request, Member member) { .build(); } - public static PostPreviewResponse toPreviewResponse(Post post) { - return new PostPreviewResponse( - post.getId(), - post.getTitle(), - getPreview(post.getSummaryAi()), - post.getPostLikes().size(), - post.getPostViews().size(), - post.getCommentsCount(), - post.getCreatedAt() - ); - } - private static String getPreview(String summaryAi) { return summaryAi.length() > PREVIEW_CONTENT_LENGTH ? summaryAi.substring(0, PREVIEW_CONTENT_LENGTH) + "..." : summaryAi; diff --git a/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java b/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java index 75b3194..1160ea5 100644 --- a/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java +++ b/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java @@ -14,7 +14,7 @@ import aimo.backend.common.dto.DataResponse; import aimo.backend.domains.member.entity.Member; -import aimo.backend.domains.post.dto.SavePostRequest; +import aimo.backend.domains.post.dto.requset.SavePostRequest; import aimo.backend.domains.post.dto.response.FindPostAndCommentsByIdResponse; import aimo.backend.domains.post.dto.response.FindPostsByPostTypeResponse; import aimo.backend.domains.post.model.PostType; @@ -54,7 +54,8 @@ public ResponseEntity>> findPosts } @GetMapping("/{postId}") - public ResponseEntity> findPostAndComments(@PathVariable Long postId) { + public ResponseEntity> findPostAndComments( + @PathVariable Long postId) { Member member = memberLoader.getMember(); FindPostAndCommentsByIdResponse response = postService.findPostAndCommentsDtoById(member, postId); diff --git a/backend/src/main/java/aimo/backend/domains/post/controller/VoteController.java b/backend/src/main/java/aimo/backend/domains/post/controller/VoteController.java new file mode 100644 index 0000000..22e6242 --- /dev/null +++ b/backend/src/main/java/aimo/backend/domains/post/controller/VoteController.java @@ -0,0 +1,33 @@ +package aimo.backend.domains.post.controller; + +import org.springframework.http.ResponseEntity; +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import aimo.backend.common.dto.DataResponse; +import aimo.backend.domains.post.model.Side; +import aimo.backend.domains.post.service.VoteService; +import aimo.backend.util.memberLoader.MemberLoader; +import lombok.RequiredArgsConstructor; + +@RestController +@RequestMapping("/api/v1/posts") +@RequiredArgsConstructor +public class VoteController { + + private final VoteService voteService; + private final MemberLoader memberLoader; + + @PostMapping("/{postId}/votes") + public ResponseEntity> votePost( + @PathVariable Long postId, + @RequestParam("side") Side side + ) { + voteService.votePost(memberLoader.getMember(), postId, side); + + return ResponseEntity.ok(DataResponse.noContent()); + } +} diff --git a/backend/src/main/java/aimo/backend/domains/post/dto/GetPostResponse.java b/backend/src/main/java/aimo/backend/domains/post/dto/GetPostResponse.java deleted file mode 100644 index 6a838e0..0000000 --- a/backend/src/main/java/aimo/backend/domains/post/dto/GetPostResponse.java +++ /dev/null @@ -1,4 +0,0 @@ -package aimo.backend.domains.post.dto; - -public record GetPostResponse() { -} diff --git a/backend/src/main/java/aimo/backend/domains/post/dto/PostListResponse.java b/backend/src/main/java/aimo/backend/domains/post/dto/PostListResponse.java deleted file mode 100644 index 76edbb2..0000000 --- a/backend/src/main/java/aimo/backend/domains/post/dto/PostListResponse.java +++ /dev/null @@ -1,6 +0,0 @@ -package aimo.backend.domains.post.dto; - -import java.util.List; - -public record PostListResponse(List postPreviews) { -} diff --git a/backend/src/main/java/aimo/backend/domains/post/dto/PostPreviewResponse.java b/backend/src/main/java/aimo/backend/domains/post/dto/PostPreviewResponse.java deleted file mode 100644 index 23ea505..0000000 --- a/backend/src/main/java/aimo/backend/domains/post/dto/PostPreviewResponse.java +++ /dev/null @@ -1,24 +0,0 @@ -package aimo.backend.domains.post.dto; - -import java.time.LocalDateTime; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; - -public record PostPreviewResponse( - @JsonProperty("post_id") - Long postId, - @JsonProperty("title") - String title, - @JsonProperty("content_preview") - String contentPreview, - @JsonProperty("likes_count") - Integer likesCount, - @JsonProperty("views_count") - Integer viewsCount, - @JsonProperty("comments_count") - Integer commentsCount, - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - LocalDateTime createdAt -) { -} diff --git a/backend/src/main/java/aimo/backend/domains/post/dto/SinglePostResponse.java b/backend/src/main/java/aimo/backend/domains/post/dto/SinglePostResponse.java deleted file mode 100644 index 59625b7..0000000 --- a/backend/src/main/java/aimo/backend/domains/post/dto/SinglePostResponse.java +++ /dev/null @@ -1,30 +0,0 @@ -package aimo.backend.domains.post.dto; - -import java.time.LocalDateTime; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; - -import aimo.backend.domains.comment.dto.response.CommentResponse; - -public record SinglePostResponse( - String title, - String username, - String content, - @JsonProperty("votes_plaintiff") - Long votesPlaintiff, - @JsonProperty("votes_defendant") - Long votesDefendant, - Long likes, - @JsonProperty("views_count") - Long viewsCount, - @JsonProperty("votes_count") - Long votesCount, - @JsonProperty("comments_count") - Long commentsCount, - @JsonProperty("comments") - List comments, - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - LocalDateTime createdAt) { -} diff --git a/backend/src/main/java/aimo/backend/domains/post/dto/SavePostRequest.java b/backend/src/main/java/aimo/backend/domains/post/dto/requset/SavePostRequest.java similarity index 96% rename from backend/src/main/java/aimo/backend/domains/post/dto/SavePostRequest.java rename to backend/src/main/java/aimo/backend/domains/post/dto/requset/SavePostRequest.java index 4e4e6a4..1ab5bd3 100644 --- a/backend/src/main/java/aimo/backend/domains/post/dto/SavePostRequest.java +++ b/backend/src/main/java/aimo/backend/domains/post/dto/requset/SavePostRequest.java @@ -1,4 +1,4 @@ -package aimo.backend.domains.post.dto; +package aimo.backend.domains.post.dto.requset; import com.fasterxml.jackson.annotation.JsonSetter; import com.fasterxml.jackson.annotation.Nulls; diff --git a/backend/src/main/java/aimo/backend/domains/post/entity/Vote.java b/backend/src/main/java/aimo/backend/domains/post/entity/Vote.java index 7e8b563..34a504b 100644 --- a/backend/src/main/java/aimo/backend/domains/post/entity/Vote.java +++ b/backend/src/main/java/aimo/backend/domains/post/entity/Vote.java @@ -15,6 +15,7 @@ import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import jakarta.persistence.UniqueConstraint; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -43,4 +44,14 @@ public class Vote extends BaseEntity { @Column(nullable = false) private Side side; + + public Vote(Post post, Member member, Side side) { + this.post = post; + this.member = member; + this.side = side; + } + + public void changeSide(Side side) { + this.side = side; + } } diff --git a/backend/src/main/java/aimo/backend/domains/post/repository/VoteRepository.java b/backend/src/main/java/aimo/backend/domains/post/repository/VoteRepository.java new file mode 100644 index 0000000..ec795d5 --- /dev/null +++ b/backend/src/main/java/aimo/backend/domains/post/repository/VoteRepository.java @@ -0,0 +1,12 @@ +package aimo.backend.domains.post.repository; + +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; + +import aimo.backend.domains.post.entity.Vote; + +public interface VoteRepository extends JpaRepository { + + Optional findByPost_IdAndMember_Id(Long postId, Long memberId); +} diff --git a/backend/src/main/java/aimo/backend/domains/post/repository/VoteRepsoitory.java b/backend/src/main/java/aimo/backend/domains/post/repository/VoteRepsoitory.java deleted file mode 100644 index 8807371..0000000 --- a/backend/src/main/java/aimo/backend/domains/post/repository/VoteRepsoitory.java +++ /dev/null @@ -1,9 +0,0 @@ -package aimo.backend.domains.post.repository; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import aimo.backend.domains.post.entity.Vote; - -public interface VoteRepsoitory extends JpaRepository { -} diff --git a/backend/src/main/java/aimo/backend/domains/post/service/PostService.java b/backend/src/main/java/aimo/backend/domains/post/service/PostService.java index c27b9f1..5b80cf0 100644 --- a/backend/src/main/java/aimo/backend/domains/post/service/PostService.java +++ b/backend/src/main/java/aimo/backend/domains/post/service/PostService.java @@ -17,7 +17,7 @@ import aimo.backend.domains.comment.entity.ChildComment; import aimo.backend.domains.comment.entity.ParentComment; import aimo.backend.domains.member.entity.Member; -import aimo.backend.domains.post.dto.SavePostRequest; +import aimo.backend.domains.post.dto.requset.SavePostRequest; import aimo.backend.domains.post.dto.response.FindPostAndCommentsByIdResponse; import aimo.backend.domains.post.dto.response.FindPostsByPostTypeResponse; import aimo.backend.domains.post.entity.Post; diff --git a/backend/src/main/java/aimo/backend/domains/post/service/VoteService.java b/backend/src/main/java/aimo/backend/domains/post/service/VoteService.java new file mode 100644 index 0000000..1d97bfe --- /dev/null +++ b/backend/src/main/java/aimo/backend/domains/post/service/VoteService.java @@ -0,0 +1,33 @@ +package aimo.backend.domains.post.service; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import aimo.backend.common.exception.ApiException; +import aimo.backend.domains.member.entity.Member; +import aimo.backend.domains.post.entity.Post; +import aimo.backend.domains.post.entity.Vote; +import aimo.backend.domains.post.model.Side; +import aimo.backend.domains.post.repository.VoteRepository; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class VoteService { + + private final VoteRepository voteRepository; + private final PostService postService; + + // 투표하기 + @Transactional(rollbackFor = ApiException.class) + public void votePost(Member member, Long postId, Side side) { + Post post = postService.findById(postId); + + voteRepository.findByPost_IdAndMember_Id(postId, member.getId()) + .ifPresentOrElse( + (vote) -> vote.changeSide(side), + () -> voteRepository.save(new Vote(post, member, side)) + ); + } +} From 8584cfeb84e9cc2122ba52890423f03bdc8ef3c4 Mon Sep 17 00:00:00 2001 From: "BOOK-U3FJG82JE7\\USER" Date: Mon, 4 Nov 2024 10:38:46 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=EC=A1=B0=ED=9A=8C=EC=88=98=20?= =?UTF-8?q?=EC=A6=9D=EA=B0=80=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../post/controller/PostViewController.java | 24 ++++++++++++++ .../backend/domains/post/entity/Post.java | 4 +++ .../backend/domains/post/entity/PostView.java | 2 +- .../post/repository/PostViewRepository.java | 4 +++ .../domains/post/service/PostViewService.java | 31 +++++++++++++++++++ 5 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/aimo/backend/domains/post/controller/PostViewController.java create mode 100644 backend/src/main/java/aimo/backend/domains/post/service/PostViewService.java diff --git a/backend/src/main/java/aimo/backend/domains/post/controller/PostViewController.java b/backend/src/main/java/aimo/backend/domains/post/controller/PostViewController.java new file mode 100644 index 0000000..1c4b92e --- /dev/null +++ b/backend/src/main/java/aimo/backend/domains/post/controller/PostViewController.java @@ -0,0 +1,24 @@ +package aimo.backend.domains.post.controller; + +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 aimo.backend.domains.post.service.PostViewService; +import aimo.backend.util.memberLoader.MemberLoader; +import lombok.RequiredArgsConstructor; + +@RestController +@RequestMapping("/api/v1/posts") +@RequiredArgsConstructor +public class PostViewController { + + private final PostViewService postViewService; + private final MemberLoader memberLoader; + + @PostMapping("/{postId}/views") + public void increaseView(@PathVariable Long postId) { + postViewService.increaseView(memberLoader.getMember(), postId); + } +} diff --git a/backend/src/main/java/aimo/backend/domains/post/entity/Post.java b/backend/src/main/java/aimo/backend/domains/post/entity/Post.java index 1f4366c..e9f950c 100644 --- a/backend/src/main/java/aimo/backend/domains/post/entity/Post.java +++ b/backend/src/main/java/aimo/backend/domains/post/entity/Post.java @@ -160,4 +160,8 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hashCode(id); } + + public void increaseViewsCount(PostView postView) { + this.postViews.add(postView); + } } diff --git a/backend/src/main/java/aimo/backend/domains/post/entity/PostView.java b/backend/src/main/java/aimo/backend/domains/post/entity/PostView.java index a11dcde..ab83827 100644 --- a/backend/src/main/java/aimo/backend/domains/post/entity/PostView.java +++ b/backend/src/main/java/aimo/backend/domains/post/entity/PostView.java @@ -41,7 +41,7 @@ public class PostView extends BaseEntity { private Member member; @Builder - private PostView(Post post, Member member) { + public PostView(Post post, Member member) { this.post = post; this.member = member; } diff --git a/backend/src/main/java/aimo/backend/domains/post/repository/PostViewRepository.java b/backend/src/main/java/aimo/backend/domains/post/repository/PostViewRepository.java index 27cc9d5..c627707 100644 --- a/backend/src/main/java/aimo/backend/domains/post/repository/PostViewRepository.java +++ b/backend/src/main/java/aimo/backend/domains/post/repository/PostViewRepository.java @@ -1,9 +1,13 @@ package aimo.backend.domains.post.repository; +import java.util.Optional; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import aimo.backend.domains.post.entity.PostView; public interface PostViewRepository extends JpaRepository { + + Optional findByMember_IdAndPost_Id(Long memberId, Long postId); } diff --git a/backend/src/main/java/aimo/backend/domains/post/service/PostViewService.java b/backend/src/main/java/aimo/backend/domains/post/service/PostViewService.java new file mode 100644 index 0000000..5a6b9d4 --- /dev/null +++ b/backend/src/main/java/aimo/backend/domains/post/service/PostViewService.java @@ -0,0 +1,31 @@ +package aimo.backend.domains.post.service; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import aimo.backend.domains.member.entity.Member; +import aimo.backend.domains.post.entity.Post; +import aimo.backend.domains.post.entity.PostView; +import aimo.backend.domains.post.repository.PostViewRepository; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class PostViewService { + + private final PostViewRepository postViewRepository; + private final PostService postService; + + // 조회수 증가 + @Transactional(rollbackFor = Exception.class) + public void increaseView(Member member, Long postId) { + Post post = postService.findById(postId); + + postViewRepository.findByMember_IdAndPost_Id(member.getId(), postId) + .ifPresentOrElse( + (postView) -> {}, + () -> postViewRepository.save(new PostView(post, member)) + ); + } +} From ba0f92937db99c2cd58076839a5bde8c6129a330 Mon Sep 17 00:00:00 2001 From: "BOOK-U3FJG82JE7\\USER" Date: Mon, 4 Nov 2024 10:52:01 +0900 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20=EC=A2=8B=EC=95=84=EC=9A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/aimo/backend/common/entity/Like.java | 4 +++ .../post/controller/PostController.java | 16 ++++++++++ .../post/controller/PostViewController.java | 24 --------------- .../backend/domains/post/entity/PostLike.java | 6 ++++ .../post/repository/PostLikeRepository.java | 2 ++ .../domains/post/service/PostLikeService.java | 30 +++++++++++++++++++ .../domains/post/service/PostService.java | 1 + 7 files changed, 59 insertions(+), 24 deletions(-) delete mode 100644 backend/src/main/java/aimo/backend/domains/post/controller/PostViewController.java create mode 100644 backend/src/main/java/aimo/backend/domains/post/service/PostLikeService.java diff --git a/backend/src/main/java/aimo/backend/common/entity/Like.java b/backend/src/main/java/aimo/backend/common/entity/Like.java index 30ed315..6bf9939 100644 --- a/backend/src/main/java/aimo/backend/common/entity/Like.java +++ b/backend/src/main/java/aimo/backend/common/entity/Like.java @@ -30,4 +30,8 @@ public abstract class Like extends BaseEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id", nullable = false) private Member member; + + public Like(Member member) { + this.member = member; + } } diff --git a/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java b/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java index 1160ea5..ee2e481 100644 --- a/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java +++ b/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java @@ -18,7 +18,9 @@ import aimo.backend.domains.post.dto.response.FindPostAndCommentsByIdResponse; import aimo.backend.domains.post.dto.response.FindPostsByPostTypeResponse; import aimo.backend.domains.post.model.PostType; +import aimo.backend.domains.post.service.PostLikeService; import aimo.backend.domains.post.service.PostService; +import aimo.backend.domains.post.service.PostViewService; import aimo.backend.util.memberLoader.MemberLoader; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -30,6 +32,8 @@ public class PostController { private final PostService postService; + private final PostViewService postViewService; + private final PostLikeService postLikeService; private final MemberLoader memberLoader; @PostMapping @@ -69,4 +73,16 @@ public ResponseEntity> deletePost(@PathVariable Long postId) return ResponseEntity.ok(DataResponse.noContent()); } + + @PostMapping("/{postId}/likes") + public ResponseEntity> likePost(@PathVariable Long postId) { + postLikeService.like(memberLoader.getMember(), postId); + + return ResponseEntity.ok(DataResponse.noContent()); + } + + @PostMapping("/{postId}/views") + public void increaseView(@PathVariable Long postId) { + postViewService.increaseView(memberLoader.getMember(), postId); + } } diff --git a/backend/src/main/java/aimo/backend/domains/post/controller/PostViewController.java b/backend/src/main/java/aimo/backend/domains/post/controller/PostViewController.java deleted file mode 100644 index 1c4b92e..0000000 --- a/backend/src/main/java/aimo/backend/domains/post/controller/PostViewController.java +++ /dev/null @@ -1,24 +0,0 @@ -package aimo.backend.domains.post.controller; - -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 aimo.backend.domains.post.service.PostViewService; -import aimo.backend.util.memberLoader.MemberLoader; -import lombok.RequiredArgsConstructor; - -@RestController -@RequestMapping("/api/v1/posts") -@RequiredArgsConstructor -public class PostViewController { - - private final PostViewService postViewService; - private final MemberLoader memberLoader; - - @PostMapping("/{postId}/views") - public void increaseView(@PathVariable Long postId) { - postViewService.increaseView(memberLoader.getMember(), postId); - } -} diff --git a/backend/src/main/java/aimo/backend/domains/post/entity/PostLike.java b/backend/src/main/java/aimo/backend/domains/post/entity/PostLike.java index 1dd4084..f85fa0c 100644 --- a/backend/src/main/java/aimo/backend/domains/post/entity/PostLike.java +++ b/backend/src/main/java/aimo/backend/domains/post/entity/PostLike.java @@ -3,6 +3,7 @@ import static lombok.AccessLevel.*; import aimo.backend.common.entity.Like; +import aimo.backend.domains.member.entity.Member; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; @@ -25,4 +26,9 @@ public class PostLike extends Like { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "post_id") private Post post; + + public PostLike(Post post, Member member) { + super(member); + this.post = post; + } } diff --git a/backend/src/main/java/aimo/backend/domains/post/repository/PostLikeRepository.java b/backend/src/main/java/aimo/backend/domains/post/repository/PostLikeRepository.java index 0e3d4f4..7d31e4a 100644 --- a/backend/src/main/java/aimo/backend/domains/post/repository/PostLikeRepository.java +++ b/backend/src/main/java/aimo/backend/domains/post/repository/PostLikeRepository.java @@ -1,6 +1,7 @@ package aimo.backend.domains.post.repository; import java.beans.JavaBean; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -8,4 +9,5 @@ import aimo.backend.domains.post.entity.PostLike; public interface PostLikeRepository extends JpaRepository { + Optional findByMember_IdAndPost_Id(Long memberId, Long postId); } diff --git a/backend/src/main/java/aimo/backend/domains/post/service/PostLikeService.java b/backend/src/main/java/aimo/backend/domains/post/service/PostLikeService.java new file mode 100644 index 0000000..f9ad145 --- /dev/null +++ b/backend/src/main/java/aimo/backend/domains/post/service/PostLikeService.java @@ -0,0 +1,30 @@ +package aimo.backend.domains.post.service; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import aimo.backend.domains.member.entity.Member; +import aimo.backend.domains.post.entity.Post; +import aimo.backend.domains.post.entity.PostLike; +import aimo.backend.domains.post.repository.PostLikeRepository; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class PostLikeService { + + private final PostLikeRepository postLikeRepository; + private final PostService postService; + + @Transactional(rollbackFor = Exception.class) + public void like(Member member, Long postId) { + Post post = postService.findById(postId); + + postLikeRepository.findByMember_IdAndPost_Id(member.getId(), postId) + .ifPresentOrElse( + postLikeRepository::delete, + () -> postLikeRepository.save(new PostLike(post, member)) + ); + } +} diff --git a/backend/src/main/java/aimo/backend/domains/post/service/PostService.java b/backend/src/main/java/aimo/backend/domains/post/service/PostService.java index 5b80cf0..100ec81 100644 --- a/backend/src/main/java/aimo/backend/domains/post/service/PostService.java +++ b/backend/src/main/java/aimo/backend/domains/post/service/PostService.java @@ -121,6 +121,7 @@ private Page findCommentedPosts(Long memberId, Pageable pageable) { } // 글 삭제 + @Transactional public void deletePost(Long memberId, Long postId) { validateDeletePost(memberId, postId); From b1bba736705ed771a556e552a7b15a22190afde9 Mon Sep 17 00:00:00 2001 From: "BOOK-U3FJG82JE7\\USER" Date: Mon, 4 Nov 2024 11:28:39 +0900 Subject: [PATCH 5/5] =?UTF-8?q?feat:=20=EC=9E=90=EC=8B=9D,=20=EB=B6=80?= =?UTF-8?q?=EB=AA=A8=20=EB=8C=93=EA=B8=80=20=EC=A2=8B=EC=95=84=EC=9A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ChildCommentController.java | 2 + .../domains/comment/entity/ChildComment.java | 1 + .../domains/comment/entity/ParentComment.java | 1 + .../comment/service/ChildCommentService.java | 8 ++- .../like/controller/LikeController.java | 61 +++++++++++++++++++ .../entity/ChildCommentLike.java | 13 +++- .../{common => domains/like}/entity/Like.java | 3 +- .../entity/ParentCommentLike.java | 13 +++- .../{post => like}/entity/PostLike.java | 8 ++- .../backend/domains/like/model/LikeType.java | 12 ++++ .../ChildCommentLikeRepository.java | 12 ++++ .../ParentCommentLikeRepository.java | 12 ++++ .../like/repository/PostLikeRepository.java | 12 ++++ .../like/service/ChildCommentLikeService.java | 39 ++++++++++++ .../service/ParentCommentLikeService.java | 39 ++++++++++++ .../domains/like/service/PostLikeService.java | 40 ++++++++++++ .../post/controller/PostController.java | 9 +-- .../backend/domains/post/entity/Post.java | 1 + .../post/repository/PostLikeRepository.java | 13 ---- .../domains/post/service/PostLikeService.java | 30 --------- 20 files changed, 266 insertions(+), 63 deletions(-) create mode 100644 backend/src/main/java/aimo/backend/domains/like/controller/LikeController.java rename backend/src/main/java/aimo/backend/domains/{comment => like}/entity/ChildCommentLike.java (68%) rename backend/src/main/java/aimo/backend/{common => domains/like}/entity/Like.java (91%) rename backend/src/main/java/aimo/backend/domains/{comment => like}/entity/ParentCommentLike.java (68%) rename backend/src/main/java/aimo/backend/domains/{post => like}/entity/PostLike.java (81%) create mode 100644 backend/src/main/java/aimo/backend/domains/like/model/LikeType.java create mode 100644 backend/src/main/java/aimo/backend/domains/like/repository/ChildCommentLikeRepository.java create mode 100644 backend/src/main/java/aimo/backend/domains/like/repository/ParentCommentLikeRepository.java create mode 100644 backend/src/main/java/aimo/backend/domains/like/repository/PostLikeRepository.java create mode 100644 backend/src/main/java/aimo/backend/domains/like/service/ChildCommentLikeService.java create mode 100644 backend/src/main/java/aimo/backend/domains/like/service/ParentCommentLikeService.java create mode 100644 backend/src/main/java/aimo/backend/domains/like/service/PostLikeService.java delete mode 100644 backend/src/main/java/aimo/backend/domains/post/repository/PostLikeRepository.java delete mode 100644 backend/src/main/java/aimo/backend/domains/post/service/PostLikeService.java diff --git a/backend/src/main/java/aimo/backend/domains/comment/controller/ChildCommentController.java b/backend/src/main/java/aimo/backend/domains/comment/controller/ChildCommentController.java index f862392..35988ef 100644 --- a/backend/src/main/java/aimo/backend/domains/comment/controller/ChildCommentController.java +++ b/backend/src/main/java/aimo/backend/domains/comment/controller/ChildCommentController.java @@ -11,6 +11,7 @@ import aimo.backend.common.dto.DataResponse; import aimo.backend.domains.comment.dto.request.SaveChildCommentRequest; +import aimo.backend.domains.like.service.ChildCommentLikeService; import aimo.backend.domains.comment.service.ChildCommentService; import aimo.backend.domains.member.entity.Member; import aimo.backend.util.memberLoader.MemberLoader; @@ -24,6 +25,7 @@ public class ChildCommentController { private final ChildCommentService childCommentService; private final MemberLoader memberLoader; + private final ChildCommentLikeService childCommentLikeService; @PostMapping("/{postId}/comments/{parentCommentId}/child") public ResponseEntity> saveChildComment( diff --git a/backend/src/main/java/aimo/backend/domains/comment/entity/ChildComment.java b/backend/src/main/java/aimo/backend/domains/comment/entity/ChildComment.java index 482526c..beaa54a 100644 --- a/backend/src/main/java/aimo/backend/domains/comment/entity/ChildComment.java +++ b/backend/src/main/java/aimo/backend/domains/comment/entity/ChildComment.java @@ -7,6 +7,7 @@ import aimo.backend.common.entity.BaseEntity; import aimo.backend.domains.comment.costants.CommentConstants; +import aimo.backend.domains.like.entity.ChildCommentLike; import aimo.backend.domains.member.entity.Member; import aimo.backend.domains.post.entity.Post; import jakarta.persistence.Column; diff --git a/backend/src/main/java/aimo/backend/domains/comment/entity/ParentComment.java b/backend/src/main/java/aimo/backend/domains/comment/entity/ParentComment.java index 321ba9b..01ae5a2 100644 --- a/backend/src/main/java/aimo/backend/domains/comment/entity/ParentComment.java +++ b/backend/src/main/java/aimo/backend/domains/comment/entity/ParentComment.java @@ -6,6 +6,7 @@ import aimo.backend.common.entity.BaseEntity; import aimo.backend.domains.comment.costants.CommentConstants; +import aimo.backend.domains.like.entity.ParentCommentLike; import aimo.backend.domains.member.entity.Member; import aimo.backend.domains.post.entity.Post; import jakarta.persistence.*; diff --git a/backend/src/main/java/aimo/backend/domains/comment/service/ChildCommentService.java b/backend/src/main/java/aimo/backend/domains/comment/service/ChildCommentService.java index 7e7d600..17c418e 100644 --- a/backend/src/main/java/aimo/backend/domains/comment/service/ChildCommentService.java +++ b/backend/src/main/java/aimo/backend/domains/comment/service/ChildCommentService.java @@ -2,8 +2,6 @@ import static aimo.backend.common.exception.ErrorCode.*; -import java.util.List; - import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -67,4 +65,10 @@ public void validateAndDeleteChildComment(Member member, Long childCommentId) { childCommentRepository.findById(childCommentId) .ifPresent(ChildComment::deleteChildCommentSoftly); } + + // id로 자식 댓글 조회 + public ChildComment findById(Long childCommentId) { + return childCommentRepository.findById(childCommentId) + .orElseThrow(() -> ApiException.from(CHILD_COMMENT_NOT_FOUND)); + } } diff --git a/backend/src/main/java/aimo/backend/domains/like/controller/LikeController.java b/backend/src/main/java/aimo/backend/domains/like/controller/LikeController.java new file mode 100644 index 0000000..014ce53 --- /dev/null +++ b/backend/src/main/java/aimo/backend/domains/like/controller/LikeController.java @@ -0,0 +1,61 @@ +package aimo.backend.domains.like.controller; + +import org.springframework.http.ResponseEntity; +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import aimo.backend.common.dto.DataResponse; +import aimo.backend.domains.like.model.LikeType; +import aimo.backend.domains.like.service.ChildCommentLikeService; +import aimo.backend.domains.like.service.ParentCommentLikeService; +import aimo.backend.domains.like.service.PostLikeService; +import aimo.backend.domains.member.entity.Member; +import aimo.backend.util.memberLoader.MemberLoader; +import lombok.RequiredArgsConstructor; + +@RestController +@RequestMapping("/api/v1/") +@RequiredArgsConstructor +public class LikeController { + + private final PostLikeService postLikeService; + private final MemberLoader memberLoader; + private final ChildCommentLikeService childCommentLikeService; + private final ParentCommentLikeService parentCommentLikeService; + + @PostMapping("/{postId}/likes") + public ResponseEntity> likePost( + @PathVariable Long postId, + @RequestParam("likeType") LikeType likeType + ) { + Member member = memberLoader.getMember(); + postLikeService.likePost(member, postId, likeType); + + return ResponseEntity.ok(DataResponse.noContent()); + } + + @PostMapping("/comments/child/{childCommentId}/like") + public ResponseEntity> likeChildComment( + @PathVariable Long childCommentId, + @RequestParam("likeType") LikeType likeType + ) { + Member member = memberLoader.getMember(); + childCommentLikeService.likeChildComment(member, childCommentId, likeType); + + return ResponseEntity.ok(DataResponse.ok()); + } + + @PostMapping("/comments/{parentCommentId}/like") + public ResponseEntity> likeParentComment( + @PathVariable Long parentCommentId, + @RequestParam("likeType") LikeType likeType + ) { + Member member = memberLoader.getMember(); + parentCommentLikeService.likeParentComment(member, parentCommentId, likeType); + + return ResponseEntity.ok(DataResponse.ok()); + } +} diff --git a/backend/src/main/java/aimo/backend/domains/comment/entity/ChildCommentLike.java b/backend/src/main/java/aimo/backend/domains/like/entity/ChildCommentLike.java similarity index 68% rename from backend/src/main/java/aimo/backend/domains/comment/entity/ChildCommentLike.java rename to backend/src/main/java/aimo/backend/domains/like/entity/ChildCommentLike.java index bca7197..bc7f621 100644 --- a/backend/src/main/java/aimo/backend/domains/comment/entity/ChildCommentLike.java +++ b/backend/src/main/java/aimo/backend/domains/like/entity/ChildCommentLike.java @@ -1,15 +1,16 @@ -package aimo.backend.domains.comment.entity; +package aimo.backend.domains.like.entity; import static lombok.AccessLevel.*; -import aimo.backend.common.entity.Like; -import aimo.backend.domains.post.entity.Post; +import aimo.backend.domains.comment.entity.ChildComment; +import aimo.backend.domains.member.entity.Member; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import jakarta.persistence.UniqueConstraint; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -26,4 +27,10 @@ public class ChildCommentLike extends Like { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "child_comment_id") private ChildComment childComment; + + @Builder + private ChildCommentLike(Member member, ChildComment childComment) { + super(member); + this.childComment = childComment; + } } diff --git a/backend/src/main/java/aimo/backend/common/entity/Like.java b/backend/src/main/java/aimo/backend/domains/like/entity/Like.java similarity index 91% rename from backend/src/main/java/aimo/backend/common/entity/Like.java rename to backend/src/main/java/aimo/backend/domains/like/entity/Like.java index 6bf9939..bfdcc1c 100644 --- a/backend/src/main/java/aimo/backend/common/entity/Like.java +++ b/backend/src/main/java/aimo/backend/domains/like/entity/Like.java @@ -1,9 +1,10 @@ -package aimo.backend.common.entity; +package aimo.backend.domains.like.entity; import static jakarta.persistence.GenerationType.*; import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import aimo.backend.common.entity.BaseEntity; import aimo.backend.domains.member.entity.Member; import jakarta.persistence.Column; import jakarta.persistence.EntityListeners; diff --git a/backend/src/main/java/aimo/backend/domains/comment/entity/ParentCommentLike.java b/backend/src/main/java/aimo/backend/domains/like/entity/ParentCommentLike.java similarity index 68% rename from backend/src/main/java/aimo/backend/domains/comment/entity/ParentCommentLike.java rename to backend/src/main/java/aimo/backend/domains/like/entity/ParentCommentLike.java index 52d3ece..1326f64 100644 --- a/backend/src/main/java/aimo/backend/domains/comment/entity/ParentCommentLike.java +++ b/backend/src/main/java/aimo/backend/domains/like/entity/ParentCommentLike.java @@ -1,15 +1,16 @@ -package aimo.backend.domains.comment.entity; +package aimo.backend.domains.like.entity; import static lombok.AccessLevel.*; -import aimo.backend.common.entity.Like; -import aimo.backend.domains.post.entity.Post; +import aimo.backend.domains.comment.entity.ParentComment; +import aimo.backend.domains.member.entity.Member; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import jakarta.persistence.UniqueConstraint; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -26,4 +27,10 @@ public class ParentCommentLike extends Like { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_comment_id") private ParentComment parentComment; + + @Builder + private ParentCommentLike(Member member, ParentComment parentComment) { + super(member); + this.parentComment = parentComment; + } } diff --git a/backend/src/main/java/aimo/backend/domains/post/entity/PostLike.java b/backend/src/main/java/aimo/backend/domains/like/entity/PostLike.java similarity index 81% rename from backend/src/main/java/aimo/backend/domains/post/entity/PostLike.java rename to backend/src/main/java/aimo/backend/domains/like/entity/PostLike.java index f85fa0c..68e8187 100644 --- a/backend/src/main/java/aimo/backend/domains/post/entity/PostLike.java +++ b/backend/src/main/java/aimo/backend/domains/like/entity/PostLike.java @@ -1,15 +1,16 @@ -package aimo.backend.domains.post.entity; +package aimo.backend.domains.like.entity; import static lombok.AccessLevel.*; -import aimo.backend.common.entity.Like; import aimo.backend.domains.member.entity.Member; +import aimo.backend.domains.post.entity.Post; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import jakarta.persistence.UniqueConstraint; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -27,7 +28,8 @@ public class PostLike extends Like { @JoinColumn(name = "post_id") private Post post; - public PostLike(Post post, Member member) { + @Builder + private PostLike(Post post, Member member) { super(member); this.post = post; } diff --git a/backend/src/main/java/aimo/backend/domains/like/model/LikeType.java b/backend/src/main/java/aimo/backend/domains/like/model/LikeType.java new file mode 100644 index 0000000..40cc486 --- /dev/null +++ b/backend/src/main/java/aimo/backend/domains/like/model/LikeType.java @@ -0,0 +1,12 @@ +package aimo.backend.domains.like.model; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum LikeType { + LIKE("좋아요"), + CANCEL_LIKE("좋아요 취소") + ; + + private final String value; +} diff --git a/backend/src/main/java/aimo/backend/domains/like/repository/ChildCommentLikeRepository.java b/backend/src/main/java/aimo/backend/domains/like/repository/ChildCommentLikeRepository.java new file mode 100644 index 0000000..a0806c9 --- /dev/null +++ b/backend/src/main/java/aimo/backend/domains/like/repository/ChildCommentLikeRepository.java @@ -0,0 +1,12 @@ +package aimo.backend.domains.like.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import aimo.backend.domains.like.entity.ChildCommentLike; + +public interface ChildCommentLikeRepository extends JpaRepository { + + void deleteByMember_IdAndChildComment_Id(Long id, Long childCommentId); + + boolean existsByChildComment_IdAndMember_Id(Long childCommentId, Long id); +} diff --git a/backend/src/main/java/aimo/backend/domains/like/repository/ParentCommentLikeRepository.java b/backend/src/main/java/aimo/backend/domains/like/repository/ParentCommentLikeRepository.java new file mode 100644 index 0000000..aba67c4 --- /dev/null +++ b/backend/src/main/java/aimo/backend/domains/like/repository/ParentCommentLikeRepository.java @@ -0,0 +1,12 @@ +package aimo.backend.domains.like.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import aimo.backend.domains.like.entity.ParentCommentLike; + +public interface ParentCommentLikeRepository extends JpaRepository { + + void deleteByParentComment_Id(Long id, Long parentCommentId); + + Boolean existsByParentComment_IdAndMember_Id(Long parentCommentId, Long memberId); +} diff --git a/backend/src/main/java/aimo/backend/domains/like/repository/PostLikeRepository.java b/backend/src/main/java/aimo/backend/domains/like/repository/PostLikeRepository.java new file mode 100644 index 0000000..836a5f1 --- /dev/null +++ b/backend/src/main/java/aimo/backend/domains/like/repository/PostLikeRepository.java @@ -0,0 +1,12 @@ +package aimo.backend.domains.like.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import aimo.backend.domains.like.entity.PostLike; + +public interface PostLikeRepository extends JpaRepository { + + void deleteByMember_IdAndPost_Id(Long id, Long postId); + + boolean existsByPost_IdAndMember_Id(Long postId, Long memberId); +} diff --git a/backend/src/main/java/aimo/backend/domains/like/service/ChildCommentLikeService.java b/backend/src/main/java/aimo/backend/domains/like/service/ChildCommentLikeService.java new file mode 100644 index 0000000..7202611 --- /dev/null +++ b/backend/src/main/java/aimo/backend/domains/like/service/ChildCommentLikeService.java @@ -0,0 +1,39 @@ +package aimo.backend.domains.like.service; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import aimo.backend.domains.comment.entity.ChildComment; +import aimo.backend.domains.comment.service.ChildCommentService; +import aimo.backend.domains.like.entity.ChildCommentLike; +import aimo.backend.domains.like.model.LikeType; +import aimo.backend.domains.like.repository.ChildCommentLikeRepository; +import aimo.backend.domains.member.entity.Member; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class ChildCommentLikeService { + + private final ChildCommentLikeRepository childCommentLikeRepository; + private final ChildCommentService childCommentService; + + public void likeChildComment(Member member, Long childCommentId, LikeType likeType) { + ChildComment childComment = childCommentService.findById(childCommentId); + + if (likeType == LikeType.LIKE) { + // 라이크가 이미 존재하면 무시 + if (childCommentLikeRepository.existsByChildComment_IdAndMember_Id(childCommentId, member.getId())) { + return; + } + + childCommentLikeRepository.save(ChildCommentLike.builder() + .childComment(childComment) + .member(member) + .build()); + } else { + childCommentLikeRepository.deleteByMember_IdAndChildComment_Id(member.getId(), childCommentId); + } + } +} diff --git a/backend/src/main/java/aimo/backend/domains/like/service/ParentCommentLikeService.java b/backend/src/main/java/aimo/backend/domains/like/service/ParentCommentLikeService.java new file mode 100644 index 0000000..812d73c --- /dev/null +++ b/backend/src/main/java/aimo/backend/domains/like/service/ParentCommentLikeService.java @@ -0,0 +1,39 @@ +package aimo.backend.domains.like.service; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import aimo.backend.domains.comment.entity.ParentComment; +import aimo.backend.domains.comment.service.ParentCommentService; +import aimo.backend.domains.like.entity.ParentCommentLike; +import aimo.backend.domains.like.model.LikeType; +import aimo.backend.domains.like.repository.ParentCommentLikeRepository; +import aimo.backend.domains.member.entity.Member; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class ParentCommentLikeService { + + private final ParentCommentLikeRepository parentCommentLikeRepository; + private final ParentCommentService parentCommentService; + + public void likeParentComment(Member member, Long parentCommentId, LikeType likeType) { + ParentComment parentComment = parentCommentService.findById(parentCommentId); + + if (likeType == LikeType.LIKE) { + // 라이크가 이미 존재하면 무시 + if (parentCommentLikeRepository.existsByParentComment_IdAndMember_Id(parentCommentId, member.getId())) { + return; + } + + parentCommentLikeRepository.save(ParentCommentLike.builder() + .parentComment(parentComment) + .member(member) + .build()); + } else { + parentCommentLikeRepository.deleteByParentComment_Id(member.getId(), parentCommentId); + } + } +} diff --git a/backend/src/main/java/aimo/backend/domains/like/service/PostLikeService.java b/backend/src/main/java/aimo/backend/domains/like/service/PostLikeService.java new file mode 100644 index 0000000..72c4b16 --- /dev/null +++ b/backend/src/main/java/aimo/backend/domains/like/service/PostLikeService.java @@ -0,0 +1,40 @@ +package aimo.backend.domains.like.service; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import aimo.backend.domains.like.model.LikeType; +import aimo.backend.domains.member.entity.Member; +import aimo.backend.domains.post.entity.Post; +import aimo.backend.domains.like.entity.PostLike; +import aimo.backend.domains.like.repository.PostLikeRepository; +import aimo.backend.domains.post.service.PostService; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class PostLikeService { + + private final PostLikeRepository postLikeRepository; + private final PostService postService; + + @Transactional(rollbackFor = Exception.class) + public void likePost(Member member, Long postId, LikeType likeType) { + Post post = postService.findById(postId); + + if (likeType == LikeType.LIKE) { + // 라이크가 이미 존재하면 무시 + if (postLikeRepository.existsByPost_IdAndMember_Id(postId, member.getId())) { + return; + } + + postLikeRepository.save(PostLike.builder() + .post(post) + .member(member) + .build()); + } else { + postLikeRepository.deleteByMember_IdAndPost_Id(member.getId(), postId); + } + } +} diff --git a/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java b/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java index ee2e481..cc7d99a 100644 --- a/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java +++ b/backend/src/main/java/aimo/backend/domains/post/controller/PostController.java @@ -13,12 +13,12 @@ import org.springframework.web.bind.annotation.RestController; import aimo.backend.common.dto.DataResponse; +import aimo.backend.domains.like.service.PostLikeService; import aimo.backend.domains.member.entity.Member; import aimo.backend.domains.post.dto.requset.SavePostRequest; import aimo.backend.domains.post.dto.response.FindPostAndCommentsByIdResponse; import aimo.backend.domains.post.dto.response.FindPostsByPostTypeResponse; import aimo.backend.domains.post.model.PostType; -import aimo.backend.domains.post.service.PostLikeService; import aimo.backend.domains.post.service.PostService; import aimo.backend.domains.post.service.PostViewService; import aimo.backend.util.memberLoader.MemberLoader; @@ -74,13 +74,6 @@ public ResponseEntity> deletePost(@PathVariable Long postId) return ResponseEntity.ok(DataResponse.noContent()); } - @PostMapping("/{postId}/likes") - public ResponseEntity> likePost(@PathVariable Long postId) { - postLikeService.like(memberLoader.getMember(), postId); - - return ResponseEntity.ok(DataResponse.noContent()); - } - @PostMapping("/{postId}/views") public void increaseView(@PathVariable Long postId) { postViewService.increaseView(memberLoader.getMember(), postId); diff --git a/backend/src/main/java/aimo/backend/domains/post/entity/Post.java b/backend/src/main/java/aimo/backend/domains/post/entity/Post.java index e9f950c..962ff77 100644 --- a/backend/src/main/java/aimo/backend/domains/post/entity/Post.java +++ b/backend/src/main/java/aimo/backend/domains/post/entity/Post.java @@ -9,6 +9,7 @@ import aimo.backend.common.entity.BaseEntity; import aimo.backend.domains.comment.entity.ParentComment; +import aimo.backend.domains.like.entity.PostLike; import aimo.backend.domains.member.entity.Member; import aimo.backend.domains.post.model.Category; import aimo.backend.domains.post.model.Side; diff --git a/backend/src/main/java/aimo/backend/domains/post/repository/PostLikeRepository.java b/backend/src/main/java/aimo/backend/domains/post/repository/PostLikeRepository.java deleted file mode 100644 index 7d31e4a..0000000 --- a/backend/src/main/java/aimo/backend/domains/post/repository/PostLikeRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package aimo.backend.domains.post.repository; - -import java.beans.JavaBean; -import java.util.Optional; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import aimo.backend.domains.post.entity.PostLike; - -public interface PostLikeRepository extends JpaRepository { - Optional findByMember_IdAndPost_Id(Long memberId, Long postId); -} diff --git a/backend/src/main/java/aimo/backend/domains/post/service/PostLikeService.java b/backend/src/main/java/aimo/backend/domains/post/service/PostLikeService.java deleted file mode 100644 index f9ad145..0000000 --- a/backend/src/main/java/aimo/backend/domains/post/service/PostLikeService.java +++ /dev/null @@ -1,30 +0,0 @@ -package aimo.backend.domains.post.service; - -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import aimo.backend.domains.member.entity.Member; -import aimo.backend.domains.post.entity.Post; -import aimo.backend.domains.post.entity.PostLike; -import aimo.backend.domains.post.repository.PostLikeRepository; -import lombok.RequiredArgsConstructor; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class PostLikeService { - - private final PostLikeRepository postLikeRepository; - private final PostService postService; - - @Transactional(rollbackFor = Exception.class) - public void like(Member member, Long postId) { - Post post = postService.findById(postId); - - postLikeRepository.findByMember_IdAndPost_Id(member.getId(), postId) - .ifPresentOrElse( - postLikeRepository::delete, - () -> postLikeRepository.save(new PostLike(post, member)) - ); - } -}