diff --git a/src/main/java/com/devin/dev/controller/post/PostController.java b/src/main/java/com/devin/dev/controller/post/PostController.java index df9a272..68a9a18 100644 --- a/src/main/java/com/devin/dev/controller/post/PostController.java +++ b/src/main/java/com/devin/dev/controller/post/PostController.java @@ -3,7 +3,6 @@ import com.devin.dev.controller.reply.ReplyOrderCondition; import com.devin.dev.dto.post.PostDetailsDto; import com.devin.dev.model.DefaultResponse; -import com.devin.dev.security.JwtAuthTokenProvider; import com.devin.dev.service.PostService; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Sort; @@ -52,6 +51,12 @@ public DefaultResponse deletePost(@PathVariable("id") Long postI @PostMapping("/post") public DefaultResponse post(@RequestBody PostForm form, HttpServletRequest request) { - return postService.post(request, form); + return postService.post(form, request); } + + @PatchMapping("/post/{id}/like") + public DefaultResponse changePostLike(@PathVariable("id") Long postId, HttpServletRequest request) { + return postService.changePostLike(postId, request); + } + } diff --git a/src/main/java/com/devin/dev/entity/post/PostLike.java b/src/main/java/com/devin/dev/entity/post/PostLike.java index bd3d1f0..89459a7 100644 --- a/src/main/java/com/devin/dev/entity/post/PostLike.java +++ b/src/main/java/com/devin/dev/entity/post/PostLike.java @@ -1,14 +1,16 @@ package com.devin.dev.entity.post; import com.devin.dev.entity.base.Created; +import com.devin.dev.entity.user.User; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; import javax.persistence.*; @Entity -@NoArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor @Getter public class PostLike extends Created { @@ -21,4 +23,17 @@ public class PostLike extends Created { @JoinColumn(name = "post_id") private Post post; + @Setter + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + public void changePost(Post post) { + if(this.post != null) { + this.post.getLikes().remove(this); + } else { + this.post = post; + post.getLikes().add(this); + } + } } diff --git a/src/main/java/com/devin/dev/repository/post/PostLikeRepository.java b/src/main/java/com/devin/dev/repository/post/PostLikeRepository.java index 7d9fcf0..203dd39 100644 --- a/src/main/java/com/devin/dev/repository/post/PostLikeRepository.java +++ b/src/main/java/com/devin/dev/repository/post/PostLikeRepository.java @@ -1,7 +1,14 @@ package com.devin.dev.repository.post; +import com.devin.dev.entity.post.Post; import com.devin.dev.entity.post.PostLike; +import com.devin.dev.entity.user.User; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; +import java.util.Optional; + public interface PostLikeRepository extends JpaRepository { + + Optional findByPostAndUser(Post post, User user); } diff --git a/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java b/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java index 2027333..8ab6408 100644 --- a/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java +++ b/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java @@ -125,9 +125,9 @@ public Optional findPostDetailsById(Long id, ReplyOrderCondition Post result = queryFactory .select(post) .from(post) - .innerJoin(post.replies, reply).fetchJoin() - .innerJoin(post.user, user).fetchJoin() - .innerJoin(reply.user, user).fetchJoin() + .leftJoin(post.replies, reply).fetchJoin() + .leftJoin(post.user, user).fetchJoin() + .leftJoin(reply.user, user).fetchJoin() .where(post.id.eq(id)) .orderBy( replyOrder(condition) diff --git a/src/main/java/com/devin/dev/service/PostService.java b/src/main/java/com/devin/dev/service/PostService.java index d92de63..5bd7484 100644 --- a/src/main/java/com/devin/dev/service/PostService.java +++ b/src/main/java/com/devin/dev/service/PostService.java @@ -210,6 +210,60 @@ public DefaultResponse deletePost(Long postId) { return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.DELETED_POST); } + + public DefaultResponse changePostLike(Long postId, HttpServletRequest request) { + String token = tokenProvider.parseToken(request); + Long userId; + if (tokenProvider.validateToken(token)) { + userId = tokenProvider.getUserId(token); + } else { + return new DefaultResponse<>(StatusCode.FAIL_AUTH, ResponseMessage.NOT_FOUND_USER); + } + Optional userOptional = userRepository.findById(userId); + if (userOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); + } + User user = userOptional.get(); + + Optional postOptional = postRepository.findById(postId); + if (postOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_POST); + } + Post post = postOptional.get(); + + Optional likeOptional = postLikeRepository.findByPostAndUser(post, user); + + PostLike postLike; + // 추천 유무에 따라 실행 + if (likeOptional.isPresent()) { + postLike = likeOptional.get(); + postLikeRepository.delete(postLike); + if (isNotSameUser(user, post.getUser())) { + // 좋아요 누른 사람 경험치 감소 + user.changeExp(User.ExpChangeType.REPLY_CANCEL_LIKE); + // 답변 작성자 경험치 감소 + post.getUser().changeExp(User.ExpChangeType.REPLY_NOT_BE_LIKED); + } + } else { + postLike = post.like(user, new PostLike()); + if (isNotSameUser(user, post.getUser())) { + // 좋아요 누른 사람 경험치 증가 + user.changeExp(User.ExpChangeType.REPLY_LIKE); + // 답변 작성자 경험치 증가 + post.getUser().changeExp(User.ExpChangeType.REPLY_BE_LIKED); + } + postLikeRepository.save(postLike); + } + + ReplyLikeDto replyLikeDto = new ReplyLikeDto(postLike.getId(), user.getName()); + + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.REPLY_LIKE_CHANGE_SUCCESS, replyLikeDto); + + } + + private boolean isNotSameUser(User firstUser, User secondUser) { + return !firstUser.getId().equals(secondUser.getId()); + } }