좌충우돌 개발공부

TIL(20240608) [뉴스피드 프로젝트 :댓글 좋아요 기능구현]


📌 Spring

💡 뉴스피드 프로젝트 : 댓글 좋아요 기능 추가구현

댓글도 게시물 좋아요와 동일해서 게시물 좋아요에서 구현했던 코드를 API URL 등 일부 수정만 했다.

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class LikesController {

    private final LikesService likesService;

    // 게시물 좋아요
    @PostMapping("/post/{postId}/likes")
    public ResponseEntity<String> postLikePost(@PathVariable Long postId, @AuthenticationPrincipal UserDetailsImpl userDetails) {
        likesService.postLikePost(postId, userDetails.getUser());
        return ResponseEntity.ok("게시물의 좋아요 등록 완료");
    }

    // 게시물 좋아요 취소
    @DeleteMapping("/post/{postId}/unlikes")
    public ResponseEntity<String> postUnlikePost(@PathVariable Long postId, @AuthenticationPrincipal UserDetailsImpl userDetails) {
        likesService.postUnlikePost(postId, userDetails.getUser());
        return ResponseEntity.ok("게시물의 좋아요 취소 완료");
    }

    // 댓글 좋아요
    @PostMapping("/comment/{commentId}/likes")
    public ResponseEntity<String> likePost(@PathVariable Long commentId, @AuthenticationPrincipal UserDetailsImpl userDetails) {
        likesService.commentLikePost(commentId, userDetails.getUser());
        return ResponseEntity.ok("댓글의 좋아요 등록 완료");
    }

    // 댓글 좋아요 취소
    @DeleteMapping("/comment/{commentId}/unlikes")
    public ResponseEntity<String> unlikePost(@PathVariable Long commentId, @AuthenticationPrincipal UserDetailsImpl userDetails) {
        likesService.commentUnlikePost(commentId, userDetails.getUser());
        return ResponseEntity.ok("댓글의 좋아요 취소 완료");
    }

}


@Service
@RequiredArgsConstructor
public class LikesService {

    private final LikesRepository likesRepository;
    private final PostRepository postRepository;
    private final CommentRepository commentRepository;

    // 게시물의 좋아요 기능
    @Transactional
    public int postLikePost(Long postId, User user) {
        Post post = findPostId(postId);

        // 사용자가 게시물의 작성자인지 확인
        if (post.getUser().getId().equals(user.getId())) {
            throw new IllegalArgumentException("자신의 게시물에 좋아요를 할 수 없습니다.");
        }
        // 사용자가 이미 좋아요를 했는지 확인
        if (likesRepository.findByPostIdAndUserId(postId, user.getId()).isPresent()) {
            throw new IllegalArgumentException("중복 좋아요는 할 수 없습니다.");
        } else {
            post.setPostLikesCount(post.getPostLikesCount() + 1);
            likesRepository.save(new Likes(post, user, ContentType.POST));
        }
        return post.getPostLikesCount();
    }

    // 게시물의 좋아요 취소 기능
    @Transactional
    public int postUnlikePost(Long postId, User user) {
        Post post = findPostId(postId);

        // 사용자가 게시물에 좋아요를 했는지 확인
        Likes like = likesRepository.findByPostIdAndUserId(postId, user.getId()).orElseThrow(() ->
                new IllegalArgumentException("해당 게시물에 좋아요를 하지 않았습니다."));

        post.setPostLikesCount(post.getPostLikesCount() - 1);
        likesRepository.delete(like);
        return post.getPostLikesCount();
    }

    private Post findPostId(Long postId) {
        return postRepository.findById(postId).orElseThrow(() ->
                new IllegalArgumentException("해당 게시물은 존재하지 않습니다."));
    }

    // 댓글의 좋아요 기능
    @Transactional
    public int commentLikePost(Long commentId, User user) {
        Comment comment = findCommentId(commentId);

        // 사용자가 게시물의 작성자인지 확인
        if (comment.getUser().getId().equals(user.getId())) {
            throw new IllegalArgumentException("자신의 댓글에 좋아요를 할 수 없습니다.");
        }
        // 사용자가 이미 좋아요를 했는지 확인
        if (likesRepository.findByCommentIdAndUserId(commentId, user.getId()).isPresent()) {
            throw new IllegalArgumentException("중복 좋아요는 할 수 없습니다.");
        } else {
            comment.setCommentLikesCount(comment.getCommentLikesCount() + 1);
            likesRepository.save(new Likes(comment, user, ContentType.COMMENT));
        }
        return comment.getCommentLikesCount();
    }

    // 댓글의 좋아요 취소 기능
    @Transactional
    public int commentUnlikePost(Long commentId, User user) {
        Comment comment = findCommentId(commentId);

        // 사용자가 게시물에 좋아요를 했는지 확인
        Likes like = likesRepository.findByCommentIdAndUserId(commentId, user.getId()).orElseThrow(() ->
                new IllegalArgumentException("해당 댓글에 좋아요를 하지 않았습니다."));

        comment.setCommentLikesCount(comment.getCommentLikesCount() - 1);
        likesRepository.delete(like);
        return comment.getCommentLikesCount();
    }

    private Comment findCommentId(Long commentId) {
        return commentRepository.findById(commentId).orElseThrow(() ->
                new IllegalArgumentException("해당 댓글은 존재하지 않습니다."));
    }

}


@Entity
@Getter
@Setter
@Table(name = "likes")
@NoArgsConstructor
public class Likes extends Timestamped {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "like_id")
    private Long id;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne
    @JoinColumn(name = "post_id")
    Post post;

    @ManyToOne
    @JoinColumn(name = "comment_id")
    Comment comment;

    @Column(name = "content_type")
    @Enumerated(EnumType.STRING)
    private ContentType contentType;

    public Likes(Post post, User user, ContentType contentType) {
        this.post = post;
        this.user = user;
        this.contentType = contentType;
    }

    public Likes(Comment comment, User user, ContentType contentType) {
        this.comment = comment;
        this.user = user;
        this.contentType = contentType;
    }

}



@Getter
public class CommentResponseDto {
    private Long id;
    private String contents;
    private LocalDateTime createdAt;
    private LocalDateTime modifiedAt;
    private int commentLikesCount;

    public CommentResponseDto(Comment comment) {
        this.id = comment.getId();
        this.contents = comment.getContents();
        this.createdAt = comment.getCreatedAt();
        this.modifiedAt = comment.getModifiedAt();
        this.commentLikesCount = comment.getCommentLikesCount();
    }

}

좋아요 부분에서는 사실 만족스럽게 구현이 된거 같아서 .. 뿌듯…(?)😂 게시물 좋아요를 복사 붙여넣기.. 변수명 수정 정도만 한 것 같다!


📌 .gitignore이 적용이 안되는 경우

  • git의 캐시가 원인이라고 한다. 그래서 git에 있는 캐시파일을 지워주고 다시 add .
git rm -r --cached .
git add .
git commit -m "remove cached"

이메일 인증 구현을 하면서 application.properties에 SMTP관련 앱 비밀번호가 있어서 보안처리를 하기 위해서 .gitignore을 사용해보았다. 처음 테스트 했을 때 적용이 되지 않아 캐시파일을 지워주고 브랜치 삭제 후 다시 push했다. 적용 완료!😁