diff --git a/src/main/java/melting_pot/ewha_sinmungo/post/controller/PostController.java b/src/main/java/melting_pot/ewha_sinmungo/post/controller/PostController.java index 571bdd8..9e7fe49 100644 --- a/src/main/java/melting_pot/ewha_sinmungo/post/controller/PostController.java +++ b/src/main/java/melting_pot/ewha_sinmungo/post/controller/PostController.java @@ -7,8 +7,10 @@ import melting_pot.ewha_sinmungo.post.entity.Category; import melting_pot.ewha_sinmungo.post.entity.Status; import melting_pot.ewha_sinmungo.post.service.PostService; +import melting_pot.ewha_sinmungo.vote.service.VoteService; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -17,6 +19,7 @@ @RequiredArgsConstructor public class PostController { private final PostService postService; + private final VoteService voteService; @PostMapping("/article") public String postPost (@RequestBody @Valid PostRequestDTO.PostSaveDto request) { @@ -60,16 +63,20 @@ public ApiResponse> getPostPreviewHot(@Path return ApiResponse.onSuccess(previews); } - @PutMapping("/article/{postId}/vote/enable") - public ApiResponse enablePostLike(@PathVariable Long postId){ - postService.enablePostLike(postId); - return ApiResponse.onSuccess(Boolean.TRUE); + //투표 생성 + @PostMapping("/article/{postId}/vote") + @ResponseStatus(value = HttpStatus.OK) + public String createVote(@PathVariable final Long postId){ + voteService.createVote(postId); + return "투표했습니다."; } - @PutMapping("/article/{postId}/vote/disable") - public ApiResponse disablePostLike(@PathVariable Long postId){ - postService.disablePostLike(postId); - return ApiResponse.onSuccess(Boolean.TRUE); + //투표 삭제 + @DeleteMapping("/article/{postId}/vote") + @ResponseStatus(value = HttpStatus.OK) + public String deleteVote(@PathVariable final Long postId){ + voteService.deleteVote(postId); + return "투표를 취소했습니다."; } } diff --git a/src/main/java/melting_pot/ewha_sinmungo/post/domain/PostMemberReaction.java b/src/main/java/melting_pot/ewha_sinmungo/post/domain/PostMemberReaction.java deleted file mode 100644 index 69a3fef..0000000 --- a/src/main/java/melting_pot/ewha_sinmungo/post/domain/PostMemberReaction.java +++ /dev/null @@ -1,42 +0,0 @@ -package melting_pot.ewha_sinmungo.post.domain; - -import lombok.*; -import melting_pot.ewha_sinmungo.member.entity.Member; -import melting_pot.ewha_sinmungo.post.entity.Post; - - -import javax.persistence.*; - -@Entity -@Builder -@Getter -@IdClass(PostMemberReactionId.class) -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@AllArgsConstructor -public class PostMemberReaction { - - @Id - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "postId") - private Post post; - - @Id - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "memberId") - private Member member; - - private boolean isLiked = false; - - public void enableLike() { - if(!isLiked){ - post.increaseVoteCount(); - } - this.isLiked = true; - } - public void disableLike(){ - if(isLiked){ - post.decreaseVoteCount(); - } - this.isLiked = false; - } -} diff --git a/src/main/java/melting_pot/ewha_sinmungo/post/domain/PostMemberReactionId.java b/src/main/java/melting_pot/ewha_sinmungo/post/domain/PostMemberReactionId.java deleted file mode 100644 index ea7a91d..0000000 --- a/src/main/java/melting_pot/ewha_sinmungo/post/domain/PostMemberReactionId.java +++ /dev/null @@ -1,16 +0,0 @@ -package melting_pot.ewha_sinmungo.post.domain; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import melting_pot.ewha_sinmungo.member.entity.Member; -import melting_pot.ewha_sinmungo.post.entity.Post; - -import java.io.Serializable; -@Getter -@AllArgsConstructor -@NoArgsConstructor -public class PostMemberReactionId implements Serializable { - private Post post; - private Member member; -} diff --git a/src/main/java/melting_pot/ewha_sinmungo/post/entity/Post.java b/src/main/java/melting_pot/ewha_sinmungo/post/entity/Post.java index f9fa14d..2e99a88 100644 --- a/src/main/java/melting_pot/ewha_sinmungo/post/entity/Post.java +++ b/src/main/java/melting_pot/ewha_sinmungo/post/entity/Post.java @@ -37,6 +37,7 @@ public class Post extends BaseTimeEntity { @Column(nullable = false) private Category category; + @Setter @Builder.Default @Column(nullable = false, columnDefinition = "integer default 0") private int voteCount = 0; @@ -63,10 +64,6 @@ public class Post extends BaseTimeEntity { @JoinColumn(name = "memberId",nullable = false) private Member member; -// @ManyToOne -// @JoinColumn(name = "noticeId",nullable = false) -// private Notice notice; - @OneToMany (mappedBy = "post", cascade = CascadeType.ALL) private List postUrlList = new ArrayList<>(); diff --git a/src/main/java/melting_pot/ewha_sinmungo/post/repository/PostMemberReactionRepository.java b/src/main/java/melting_pot/ewha_sinmungo/post/repository/PostMemberReactionRepository.java deleted file mode 100644 index 0cee329..0000000 --- a/src/main/java/melting_pot/ewha_sinmungo/post/repository/PostMemberReactionRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package melting_pot.ewha_sinmungo.post.repository; - -import melting_pot.ewha_sinmungo.post.domain.PostMemberReaction; -import melting_pot.ewha_sinmungo.post.domain.PostMemberReactionId; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface PostMemberReactionRepository extends JpaRepository { -} diff --git a/src/main/java/melting_pot/ewha_sinmungo/post/service/PostService.java b/src/main/java/melting_pot/ewha_sinmungo/post/service/PostService.java index fb283ad..4c81956 100644 --- a/src/main/java/melting_pot/ewha_sinmungo/post/service/PostService.java +++ b/src/main/java/melting_pot/ewha_sinmungo/post/service/PostService.java @@ -1,28 +1,20 @@ package melting_pot.ewha_sinmungo.post.service; import lombok.RequiredArgsConstructor; -import melting_pot.ewha_sinmungo.global.apiResponse.code.status.ErrorStatus; import melting_pot.ewha_sinmungo.global.apiResponse.exception.GeneralException; -import melting_pot.ewha_sinmungo.member.entity.Member; import melting_pot.ewha_sinmungo.member.service.MemberService; import melting_pot.ewha_sinmungo.post.converter.PostConverter; -import melting_pot.ewha_sinmungo.post.domain.PostMemberReaction; -import melting_pot.ewha_sinmungo.post.domain.PostMemberReactionId; import melting_pot.ewha_sinmungo.post.dto.requestDto.PostRequestDTO; import melting_pot.ewha_sinmungo.post.dto.responseDto.PostResponseDTO; import melting_pot.ewha_sinmungo.post.entity.Category; import melting_pot.ewha_sinmungo.post.entity.Post; import melting_pot.ewha_sinmungo.post.entity.Status; -import melting_pot.ewha_sinmungo.post.repository.PostMemberReactionRepository; import melting_pot.ewha_sinmungo.post.repository.PostRepository; 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.List; -import java.util.Optional; - import static melting_pot.ewha_sinmungo.global.apiResponse.code.status.ErrorStatus.ARTICLE_NOT_FOUND; @Service @@ -30,8 +22,6 @@ public class PostService { private final PostRepository postRepository; private final PostConverter postConverter; - private final MemberService memberService; - private final PostMemberReactionRepository postMemberReactionRepository; @Transactional public void createPost(PostRequestDTO.PostSaveDto request){ @@ -75,35 +65,6 @@ public Page getHotPostPreview(Pageable pageable) Page hotPosts = postRepository.findByIsHotTrueOrderByCreatedDateDesc(pageable); return postConverter.toPreviewListDto(hotPosts); } - @Transactional - public void enablePostLike(Long postId) { - Post post = findById(postId); - Member member = memberService.getCurrentMember(); - PostMemberReaction reaction = getPostMemberReaction(post, member); - reaction.enableLike(); - } - - @Transactional - public void disablePostLike(Long postId) { - Post post = findById(postId); - Member member = memberService.getCurrentMember(); - PostMemberReaction reaction = getPostMemberReaction(post, member); - reaction.disableLike(); - } - - private PostMemberReaction getPostMemberReaction(Post post, Member member) { - PostMemberReactionId reactionId = new PostMemberReactionId(post, member); - Optional reactionOptional = postMemberReactionRepository.findById(reactionId); - if (reactionOptional.isPresent()) { - return reactionOptional.get(); - } else { - PostMemberReaction reaction = PostMemberReaction.builder() - .post(reactionId.getPost()) - .member(reactionId.getMember()) - .build(); - return postMemberReactionRepository.save(reaction); - } - } public Post findById(Long postId) { diff --git a/src/main/java/melting_pot/ewha_sinmungo/vote/controller/VoteController b/src/main/java/melting_pot/ewha_sinmungo/vote/controller/VoteController new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/melting_pot/ewha_sinmungo/vote/entity/Vote.java b/src/main/java/melting_pot/ewha_sinmungo/vote/entity/Vote.java index 3c3eee4..f781025 100644 --- a/src/main/java/melting_pot/ewha_sinmungo/vote/entity/Vote.java +++ b/src/main/java/melting_pot/ewha_sinmungo/vote/entity/Vote.java @@ -1,6 +1,8 @@ package melting_pot.ewha_sinmungo.vote.entity; import javax.persistence.*; + +import lombok.Builder; import lombok.NoArgsConstructor; import melting_pot.ewha_sinmungo.member.entity.Member; import melting_pot.ewha_sinmungo.post.entity.Post; @@ -14,7 +16,17 @@ public class Vote { @Column(name = "vote_id") private Long id; + @ManyToOne + @JoinColumn(name = "member_id",nullable = false) + private Member member; + @ManyToOne @JoinColumn(name = "post_id",nullable = false) private Post post; + + @Builder + public Vote(Post post, Member member){ + this.post = post; + this.member = member; + } } diff --git a/src/main/java/melting_pot/ewha_sinmungo/vote/reporitory/VoteRepository.java b/src/main/java/melting_pot/ewha_sinmungo/vote/reporitory/VoteRepository.java new file mode 100644 index 0000000..81e1d71 --- /dev/null +++ b/src/main/java/melting_pot/ewha_sinmungo/vote/reporitory/VoteRepository.java @@ -0,0 +1,14 @@ +package melting_pot.ewha_sinmungo.vote.reporitory; + +import melting_pot.ewha_sinmungo.member.entity.Member; +import melting_pot.ewha_sinmungo.post.entity.Post; +import melting_pot.ewha_sinmungo.vote.entity.Vote; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface VoteRepository extends JpaRepository { + boolean existsByMemberAndPost(Member member, Post post); + + Optional findByMemberAndPost(Member member, Post post); +} diff --git a/src/main/java/melting_pot/ewha_sinmungo/vote/service/VoteService.java b/src/main/java/melting_pot/ewha_sinmungo/vote/service/VoteService.java new file mode 100644 index 0000000..91af7bd --- /dev/null +++ b/src/main/java/melting_pot/ewha_sinmungo/vote/service/VoteService.java @@ -0,0 +1,67 @@ +package melting_pot.ewha_sinmungo.vote.service; + + +import lombok.RequiredArgsConstructor; +import melting_pot.ewha_sinmungo.member.entity.Member; +import melting_pot.ewha_sinmungo.member.service.MemberService; +import melting_pot.ewha_sinmungo.post.entity.Post; +import melting_pot.ewha_sinmungo.post.repository.PostRepository; +import melting_pot.ewha_sinmungo.post.service.PostService; +import melting_pot.ewha_sinmungo.vote.entity.Vote; +import melting_pot.ewha_sinmungo.vote.reporitory.VoteRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@Service +@RequiredArgsConstructor +public class VoteService { + + private final MemberService memberService; + private final PostService postService; + private final VoteRepository voteRepository; + + //투표 생성 + public void createVote(Long postId){ + Member member = memberService.getCurrentMember(); + Post post = postService.findById(postId); + + if(isExistsByMemberAndPost(member,post)){ + throw new RuntimeException("이미 투표한 게시물입니다."); + } + + Vote vote = Vote.builder() + .post(post) + .member(member) + .build(); + + voteRepository.save(vote); + increaseVoteCount(post); + } + + //투표 삭제 + public void deleteVote(Long postId){ + Post post = postService.findById(postId); + Member member = memberService.getCurrentMember(); + + Vote vote = voteRepository.findByMemberAndPost(member, post) + .orElseThrow(()->new RuntimeException("투표가 존재하지 않습니다.")); + voteRepository.delete(vote); + decreaseVoteCount(post); + } + + @Transactional(readOnly = true) + public boolean isExistsByMemberAndPost(Member member, Post post){ + return voteRepository.existsByMemberAndPost(member,post); + } + + private void increaseVoteCount(Post post){ + post.setVoteCount(post.getVoteCount()+1); + } + + private void decreaseVoteCount(Post post){ + post.setVoteCount(post.getVoteCount()-1); + } +}