Skip to content

Commit

Permalink
Merge pull request #96 from DEPthes/fix/#86-member-comment
Browse files Browse the repository at this point in the history
[FIX]: 회원 - 댓글 연결
  • Loading branch information
phonil authored Aug 17, 2024
2 parents d0bab19 + 8fe2acf commit d948fa9
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,40 @@
import mvp.deplog.domain.comment.domain.Comment;
import mvp.deplog.domain.comment.domain.repository.CommentRepository;
import mvp.deplog.domain.comment.dto.request.CreateCommentReq;
import mvp.deplog.domain.member.domain.Member;
import mvp.deplog.domain.member.domain.Role;
import mvp.deplog.domain.post.domain.Post;
import mvp.deplog.domain.post.domain.repository.PostRepository;
import mvp.deplog.global.common.Message;
import mvp.deplog.global.common.SuccessResponse;
import mvp.deplog.global.security.UserDetailsImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Transactional(readOnly = true)
@Service
public class CreateCommentServiceImpl implements CreateCommentService {
public class CreateAnonymousCommentServiceImpl implements CreateCommentService {

private final PostRepository postRepository;
private final CommentRepository commentRepository;

@Override
public boolean supports(Long parentCommentId) {
return parentCommentId == null;
public boolean supports(UserDetailsImpl userDetails, Long parentCommentId) {
return (userDetails == null || userDetails.getMember().getRole().equals(Role.APPLICANT)) && parentCommentId == null;
}

@Override
@Transactional
public SuccessResponse<Message> createComment(CreateCommentReq createCommentReq) {
public SuccessResponse<Message> createComment(UserDetailsImpl userDetails, CreateCommentReq createCommentReq) {
Long postId = createCommentReq.getPostId();
Post post = postRepository.findById(postId)
.orElseThrow(() -> new IllegalArgumentException("해당 아이디의 게시글을 찾을 수 없습니다: " + postId));

Comment comment = Comment.commentBuilder()
Comment comment = Comment.anonymousCommentBuilder()
.post(post)
.content(createCommentReq.getContent())
.nickname(createCommentReq.getNickname())
.avatarImage(createCommentReq.getAvatarImage())
.build();

commentRepository.save(comment);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,45 @@
import mvp.deplog.domain.comment.domain.Comment;
import mvp.deplog.domain.comment.domain.repository.CommentRepository;
import mvp.deplog.domain.comment.dto.request.CreateCommentReq;
import mvp.deplog.domain.member.domain.Member;
import mvp.deplog.domain.member.domain.Role;
import mvp.deplog.domain.member.domain.repository.MemberRepository;
import mvp.deplog.domain.post.domain.Post;
import mvp.deplog.domain.post.domain.repository.PostRepository;
import mvp.deplog.global.common.Message;
import mvp.deplog.global.common.SuccessResponse;
import mvp.deplog.global.security.UserDetailsImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Transactional(readOnly = true)
@Service
public class CreateReplyServiceImpl implements CreateCommentService {
public class CreateAnonymousReplyServiceImpl implements CreateCommentService {

private final PostRepository postRepository;
private final CommentRepository commentRepository;

@Override
public boolean supports(Long parentCommentId) {
return parentCommentId != null;
public boolean supports(UserDetailsImpl userDetails, Long parentCommentId) {
return (userDetails == null || userDetails.getMember().getRole().equals(Role.APPLICANT)) && parentCommentId != null;
}

@Override
@Transactional
public SuccessResponse<Message> createComment(CreateCommentReq createCommentReq) {
public SuccessResponse<Message> createComment(UserDetailsImpl userDetails, CreateCommentReq createCommentReq) {
Long postId = createCommentReq.getPostId();
Post post = postRepository.findById(postId)
.orElseThrow(() -> new IllegalArgumentException("해당 아이디의 게시글을 찾을 수 없습니다: " + postId));

Comment parentComment = commentRepository.findById(createCommentReq.getParentCommentId())
.orElseThrow(() -> new IllegalArgumentException("해당 아이디의 댓글을 찾을 수 없습니다: " + createCommentReq.getParentCommentId()));

Comment reply = Comment.replyBuilder()
.post(post)
Comment reply = Comment.anonymousReplyBuilder()
.parentComment(parentComment)
.post(post)
.content(createCommentReq.getContent())
.nickname(createCommentReq.getNickname())
.avatarImage(createCommentReq.getAvatarImage())
.build();

commentRepository.save(reply);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
import mvp.deplog.domain.comment.dto.request.CreateCommentReq;
import mvp.deplog.global.common.Message;
import mvp.deplog.global.common.SuccessResponse;
import mvp.deplog.global.security.UserDetailsImpl;

public interface CreateCommentService {

boolean supports(Long parentCommentId);
boolean supports(UserDetailsImpl userDetails, Long parentCommentId);

SuccessResponse<Message> createComment(CreateCommentReq createCommentReq);
SuccessResponse<Message> createComment(UserDetailsImpl userDetails, CreateCommentReq createCommentReq);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mvp.deplog.domain.comment.application;

import lombok.RequiredArgsConstructor;
import mvp.deplog.global.security.UserDetailsImpl;
import org.springframework.stereotype.Component;

import java.util.List;
Expand All @@ -11,9 +12,9 @@ public class CreateCommentServiceFactory {

private final List<CreateCommentService> createCommentServiceList;

public CreateCommentService find(Long parentCommentId) {
public CreateCommentService find(UserDetailsImpl userDetails, Long parentCommentId) {
return createCommentServiceList.stream()
.filter(v -> v.supports(parentCommentId))
.filter(v -> v.supports(userDetails, parentCommentId))
.findFirst()
.orElseThrow();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package mvp.deplog.domain.comment.application;

import lombok.RequiredArgsConstructor;
import mvp.deplog.domain.comment.domain.Comment;
import mvp.deplog.domain.comment.domain.repository.CommentRepository;
import mvp.deplog.domain.comment.dto.request.CreateCommentReq;
import mvp.deplog.domain.member.domain.Member;
import mvp.deplog.domain.member.domain.Role;
import mvp.deplog.domain.member.domain.repository.MemberRepository;
import mvp.deplog.domain.post.domain.Post;
import mvp.deplog.domain.post.domain.repository.PostRepository;
import mvp.deplog.global.common.Message;
import mvp.deplog.global.common.SuccessResponse;
import mvp.deplog.global.security.UserDetailsImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Transactional(readOnly = true)
@Service
public class CreateMemberCommentServiceImpl implements CreateCommentService {

private final PostRepository postRepository;
private final CommentRepository commentRepository;
private final MemberRepository memberRepository;

@Override
public boolean supports(UserDetailsImpl userDetails, Long parentCommentId) {
return (userDetails != null && !userDetails.getMember().getRole().equals(Role.APPLICANT)) && parentCommentId == null;
}


@Override
@Transactional
public SuccessResponse<Message> createComment(UserDetailsImpl userDetails, CreateCommentReq createCommentReq) {
Long postId = createCommentReq.getPostId();
Post post = postRepository.findById(postId)
.orElseThrow(() -> new IllegalArgumentException("해당 아이디의 게시글을 찾을 수 없습니다: " + postId));

Member member = memberRepository.findById(userDetails.getMember().getId())
.orElseThrow(() -> new IllegalArgumentException("해당되는 아이디의 회원이 존재하지 않습니다."));

Comment comment = Comment.memberCommentBuilder()
.post(post)
.member(member)
.content(createCommentReq.getContent())
.nickname(createCommentReq.getNickname())
.avatarImage(createCommentReq.getAvatarImage())
.build();

commentRepository.save(comment);

Message message = Message.builder()
.message("댓글 작성이 완료되었습니다.")
.build();

return SuccessResponse.of(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package mvp.deplog.domain.comment.application;

import lombok.RequiredArgsConstructor;
import mvp.deplog.domain.comment.domain.Comment;
import mvp.deplog.domain.comment.domain.repository.CommentRepository;
import mvp.deplog.domain.comment.dto.request.CreateCommentReq;
import mvp.deplog.domain.member.domain.Member;
import mvp.deplog.domain.member.domain.Role;
import mvp.deplog.domain.member.domain.repository.MemberRepository;
import mvp.deplog.domain.post.domain.Post;
import mvp.deplog.domain.post.domain.repository.PostRepository;
import mvp.deplog.global.common.Message;
import mvp.deplog.global.common.SuccessResponse;
import mvp.deplog.global.security.UserDetailsImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Transactional(readOnly = true)
@Service
public class CreateMemberReplyServiceImpl implements CreateCommentService {

private final PostRepository postRepository;
private final CommentRepository commentRepository;
private final MemberRepository memberRepository;

@Override
public boolean supports(UserDetailsImpl userDetails, Long parentCommentId) {
return (userDetails != null && !userDetails.getMember().getRole().equals(Role.APPLICANT)) && parentCommentId != null;
}

@Override
@Transactional
public SuccessResponse<Message> createComment(UserDetailsImpl userDetails, CreateCommentReq createCommentReq) {
Long postId = createCommentReq.getPostId();
Post post = postRepository.findById(postId)
.orElseThrow(() -> new IllegalArgumentException("해당 아이디의 게시글을 찾을 수 없습니다: " + postId));

Comment parentComment = commentRepository.findById(createCommentReq.getParentCommentId())
.orElseThrow(() -> new IllegalArgumentException("해당 아이디의 댓글을 찾을 수 없습니다: " + createCommentReq.getParentCommentId()));

Member member = memberRepository.findById(userDetails.getMember().getId())
.orElseThrow(() -> new IllegalArgumentException("해당되는 아이디의 회원이 존재하지 않습니다."));

Comment reply = Comment.memberReplyBuilder()
.parentComment(parentComment)
.post(post)
.member(member)
.content(createCommentReq.getContent())
.nickname(createCommentReq.getNickname())
.avatarImage(createCommentReq.getAvatarImage())
.build();

commentRepository.save(reply);

Message message = Message.builder()
.message("대댓글 작성이 완료되었습니다.")
.build();

return SuccessResponse.of(message);
}
}
38 changes: 34 additions & 4 deletions src/main/java/mvp/deplog/domain/comment/domain/Comment.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import mvp.deplog.domain.common.BaseEntity;
import mvp.deplog.domain.member.domain.Member;
import mvp.deplog.domain.post.domain.Post;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand All @@ -27,6 +28,10 @@ public class Comment extends BaseEntity {
@JoinColumn(name = "post_id", nullable = false)
private Post post;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;

@Column(name = "content", columnDefinition = "TEXT", nullable = false)
private String content;

Expand All @@ -40,23 +45,48 @@ public class Comment extends BaseEntity {
@Min(value = 1)
private int depth;

@Builder(builderMethodName = "commentBuilder", builderClassName = "CommentBuilder")
public Comment(Post post, String content, String nickname, String avatarImage) {
@Builder(builderMethodName = "memberCommentBuilder", builderClassName = "MemberCommentBuilder")
public Comment(Post post, Member member, String content, String nickname, String avatarImage) {
this.parentComment = null;
this.post = post;
this.member = member;
this.content = content;
this.nickname = nickname;
this.avatarImage = avatarImage;
this.depth = 1;
}

@Builder(builderMethodName = "replyBuilder", builderClassName = "ReplyBuilder")
public Comment(Comment parentComment, Post post, String content, String nickname, String avatarImage) {
@Builder(builderMethodName = "anonymousCommentBuilder", builderClassName = "AnonymousCommentBuilder")
public Comment(Post post, String content, String nickname) {
this.parentComment = null;
this.post = post;
this.member = null;
this.content = content;
this.nickname = nickname;
this.avatarImage = null;
this.depth = 1;
}

@Builder(builderMethodName = "memberReplyBuilder", builderClassName = "MemberReplyBuilder")
public Comment(Comment parentComment, Post post, Member member, String content, String nickname, String avatarImage) {
this.parentComment = parentComment;
this.post = post;
this.member = member;
this.content = content;
this.nickname = nickname;
this.avatarImage = avatarImage;
this.depth = parentComment.getDepth() + 1;
}

@Builder(builderMethodName = "anonymousReplyBuilder", builderClassName = "AnonymousReplyBuilder")
public Comment(Comment parentComment, Post post, String content, String nickname) {
this.parentComment = parentComment;
this.post = post;
this.member = null;
this.content = content;
this.nickname = nickname;
this.avatarImage = null;
this.depth = parentComment.getDepth() + 1;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
import mvp.deplog.global.common.Message;
import mvp.deplog.global.common.SuccessResponse;
import mvp.deplog.global.exception.ErrorResponse;
import mvp.deplog.global.security.UserDetailsImpl;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
Expand All @@ -37,7 +39,9 @@ public interface CommentApi {
})
@PostMapping
ResponseEntity<SuccessResponse<Message>> createComment(
@Parameter(description = "Schemas의 CommentReq를 참고해주세요.", required = true) @RequestBody CreateCommentReq createCommentReq);
@Parameter(description = "Access Token을 입력해주세요.", required = true) @AuthenticationPrincipal UserDetailsImpl userDetails,
@Parameter(description = "Schemas의 CommentReq를 참고해주세요.", required = true) @RequestBody CreateCommentReq createCommentReq
);

@Operation(summary = "댓글 목록 조회 API", description = "해당 게시글을 댓글 목록을 조회합니다.")
@ApiResponses(value = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
import mvp.deplog.domain.comment.dto.response.CommentListRes;
import mvp.deplog.global.common.Message;
import mvp.deplog.global.common.SuccessResponse;
import mvp.deplog.global.security.UserDetailsImpl;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.List;
Expand All @@ -24,11 +26,11 @@ public class CommentController implements CommentApi {

@Override
@PostMapping
public ResponseEntity<SuccessResponse<Message>> createComment(@RequestBody CreateCommentReq createCommentReq) {
CreateCommentService createCommentService = createCommentServiceFactory.find(createCommentReq.getParentCommentId());
public ResponseEntity<SuccessResponse<Message>> createComment(@AuthenticationPrincipal UserDetailsImpl userDetails, @RequestBody CreateCommentReq createCommentReq) {
CreateCommentService createCommentService = createCommentServiceFactory.find(userDetails, createCommentReq.getParentCommentId());
return ResponseEntity
.status(HttpStatus.CREATED)
.body(createCommentService.createComment(createCommentReq));
.body(createCommentService.createComment(userDetails, createCommentReq));
}

@Override
Expand Down
7 changes: 7 additions & 0 deletions src/main/resources/db/migration/V7__add_fk_comment_member.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ALTER TABLE comment
ADD COLUMN member_id BIGINT NULL;

ALTER TABLE comment
ADD CONSTRAINT fk_comment_to_member
FOREIGN KEY (member_id)
REFERENCES member (id);

0 comments on commit d948fa9

Please sign in to comment.