diff --git a/server/src/main/java/com/main36/pikcha/domain/comment/controller/CommentController.java b/server/src/main/java/com/main36/pikcha/domain/comment/controller/CommentController.java index ae25187e..9b1c4b72 100644 --- a/server/src/main/java/com/main36/pikcha/domain/comment/controller/CommentController.java +++ b/server/src/main/java/com/main36/pikcha/domain/comment/controller/CommentController.java @@ -1,11 +1,13 @@ package com.main36.pikcha.domain.comment.controller; +import com.main36.pikcha.domain.comment.dto.CommentDetailResponseDto; import com.main36.pikcha.domain.comment.dto.CommentDto; import com.main36.pikcha.domain.comment.dto.CommentResponseDto; import com.main36.pikcha.domain.comment.entity.Comment; import com.main36.pikcha.domain.comment.mapper.CommentMapper; import com.main36.pikcha.domain.comment.service.CommentService; import com.main36.pikcha.domain.member.entity.Member; +import com.main36.pikcha.domain.post.entity.Post; import com.main36.pikcha.domain.post.service.PostService; import com.main36.pikcha.global.aop.LoginUser; import com.main36.pikcha.global.response.DataResponseDto; @@ -20,7 +22,10 @@ import javax.validation.Valid; import javax.validation.constraints.Positive; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; @RestController @Slf4j @@ -44,9 +49,9 @@ public ResponseEntity> postComment(Member loginUser, commentBuilder .commentContent(commentPostDto.getCommentContent()) .member(loginUser) - .post(postService.findPost(postId)) + .post(postService.findPostNoneSetView(postId)) .build() - ); + ,commentPostDto.getParentId()); CommentResponseDto commentResponseDto = mapper.commentToCommentResponseDto(comment); @@ -72,15 +77,41 @@ public ResponseEntity> getComment(@PathVariable("comment-id") mapper.commentToCommentResponseDto(commentService.findComment(commentId)); return ResponseEntity.ok(new DataResponseDto<>(response)); } - @GetMapping() - public ResponseEntity> getComment(@Positive @RequestParam(required = false, defaultValue = "1") int page, + + @GetMapping("/listof/{post-id}") + public ResponseEntity> getComment(@PathVariable("post-id") @Positive long postId, + @Positive @RequestParam(required = false, defaultValue = "1") int page, @Positive @RequestParam(required = false, defaultValue = "10") int size) { - Page commentPage = commentService.findComments(page - 1, size); - List comments = commentPage.getContent(); + Post findPost = postService.findPostNoneSetView(postId); + Page commentPage = commentService.findComments(page - 1, size, findPost); + List commentList = commentPage.getContent(); + for(Comment c : commentList) { + log.info(c.getCommentContent()); + } + List result = new ArrayList<>(); + Map map = new HashMap<>(); - List commentResponseDtos = mapper.commentsToCommentResponseDtos(comments); + commentList.stream().forEach(c-> { + CommentDetailResponseDto rDto = CommentDetailResponseDto.convertCommentToDto(c); + // map <댓글Id, responseDto> + map.put(c.getCommentId(), rDto); + // 댓글이 부모가 있다면 + if(c.getParent() != null) { + // 부모 댓글의 id의 responseDto를 조회한다음 + map.get(c.getParent().getCommentId()) + // 부모 댓글 responseDto의 자식으로 + .getChildren() + // rDto를 추가한다. + .add(rDto); + } + // 댓글이 최상위 댓글이라면 + else{ + // 그냥 result에 추가한다. + result.add(rDto); + } + }); - return ResponseEntity.ok(new MultiResponseDto<>(commentResponseDtos, commentPage)); + return ResponseEntity.ok(new MultiResponseDto<>(result, commentPage)); } @LoginUser diff --git a/server/src/main/java/com/main36/pikcha/domain/comment/dto/CommentDetailResponseDto.java b/server/src/main/java/com/main36/pikcha/domain/comment/dto/CommentDetailResponseDto.java new file mode 100644 index 00000000..77fb73f8 --- /dev/null +++ b/server/src/main/java/com/main36/pikcha/domain/comment/dto/CommentDetailResponseDto.java @@ -0,0 +1,39 @@ +package com.main36.pikcha.domain.comment.dto; + +import com.main36.pikcha.domain.comment.entity.Comment; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Getter +@Setter +@Builder +public class CommentDetailResponseDto { + private Long commentId; + private Long parentId; + private Long memberId; + private String username; + private String memberPicture; + private String commentContent; + private LocalDateTime createdAt; + private LocalDateTime modifiedAt; + private List children; + + public static CommentDetailResponseDto convertCommentToDto(Comment comment){ + return CommentDetailResponseDto.builder() + .commentId(comment.getCommentId()) + .parentId(comment.getParent() == null ? null : comment.getParent().getCommentId()) + .memberId(comment.getMember().getMemberId()) + .username(comment.getMember().getUsername()) + .memberPicture(comment.getMember().getPicture()) + .commentContent(comment.getCommentContent()) + .createdAt(comment.getCreatedAt()) + .modifiedAt(comment.getModifiedAt()) + .children(new ArrayList<>()) + .build(); + } +} diff --git a/server/src/main/java/com/main36/pikcha/domain/comment/dto/CommentDto.java b/server/src/main/java/com/main36/pikcha/domain/comment/dto/CommentDto.java index baf41b04..329810ce 100644 --- a/server/src/main/java/com/main36/pikcha/domain/comment/dto/CommentDto.java +++ b/server/src/main/java/com/main36/pikcha/domain/comment/dto/CommentDto.java @@ -11,6 +11,7 @@ public class CommentDto { @Getter public static class Post { + private Long parentId; @NotBlank(message = "댓글 내용을 입력해주세요.") private String commentContent; } diff --git a/server/src/main/java/com/main36/pikcha/domain/comment/dto/CommentResponseDto.java b/server/src/main/java/com/main36/pikcha/domain/comment/dto/CommentResponseDto.java index b10daf7e..28fb1612 100644 --- a/server/src/main/java/com/main36/pikcha/domain/comment/dto/CommentResponseDto.java +++ b/server/src/main/java/com/main36/pikcha/domain/comment/dto/CommentResponseDto.java @@ -9,6 +9,7 @@ @Builder public class CommentResponseDto { private Long commentId; + private Long parentId; private Long memberId; private String username; private String memberPicture; diff --git a/server/src/main/java/com/main36/pikcha/domain/comment/entity/Comment.java b/server/src/main/java/com/main36/pikcha/domain/comment/entity/Comment.java index 4aea7e61..acd5600f 100644 --- a/server/src/main/java/com/main36/pikcha/domain/comment/entity/Comment.java +++ b/server/src/main/java/com/main36/pikcha/domain/comment/entity/Comment.java @@ -34,9 +34,17 @@ public class Comment extends Auditable { private Post post; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "comment_id") + @JoinColumn(name = "parent") private Comment parent; - @OneToMany(fetch = FetchType.LAZY, mappedBy = "parent") + public void updateParent(Comment parent){ + this.parent = parent; + } + + @OneToMany(fetch = FetchType.LAZY, mappedBy = "parent", orphanRemoval = true) private List children = new ArrayList<>(); + + public List getChildren(){ + return this.children; + } } diff --git a/server/src/main/java/com/main36/pikcha/domain/comment/mapper/CommentMapper.java b/server/src/main/java/com/main36/pikcha/domain/comment/mapper/CommentMapper.java index 3a7b3e58..cc80b550 100644 --- a/server/src/main/java/com/main36/pikcha/domain/comment/mapper/CommentMapper.java +++ b/server/src/main/java/com/main36/pikcha/domain/comment/mapper/CommentMapper.java @@ -1,5 +1,6 @@ package com.main36.pikcha.domain.comment.mapper; +import com.main36.pikcha.domain.comment.dto.CommentDetailResponseDto; import com.main36.pikcha.domain.comment.dto.CommentDto; import com.main36.pikcha.domain.comment.dto.CommentResponseDto; import com.main36.pikcha.domain.comment.entity.Comment; @@ -16,7 +17,15 @@ public interface CommentMapper { @Mapping(target = "username", source = "member.username") @Mapping(target = "memberId", source = "member.memberId") @Mapping(target = "memberPicture", source = "member.picture") + @Mapping(target = "parentId", source = "parent.commentId") CommentResponseDto commentToCommentResponseDto(Comment comment); + @Mapping(target = "username", source = "member.username") + @Mapping(target = "memberId", source = "member.memberId") + @Mapping(target = "memberPicture", source = "member.picture") + @Mapping(target = "parentId", source = "parent.commentId") + CommentDetailResponseDto commentToCommentDetailResponseDto(Comment comment); + List commentsToCommentResponseDtos(List comments); + List commentsToCommentDetailResponseDtos(List comments); } diff --git a/server/src/main/java/com/main36/pikcha/domain/comment/repository/CommentCustomRepository.java b/server/src/main/java/com/main36/pikcha/domain/comment/repository/CommentCustomRepository.java index 9993d75c..36b40af8 100644 --- a/server/src/main/java/com/main36/pikcha/domain/comment/repository/CommentCustomRepository.java +++ b/server/src/main/java/com/main36/pikcha/domain/comment/repository/CommentCustomRepository.java @@ -2,26 +2,9 @@ import com.main36.pikcha.domain.comment.entity.Comment; import com.main36.pikcha.domain.post.entity.Post; -import com.querydsl.jpa.impl.JPAQueryFactory; -import org.springframework.stereotype.Repository; -import java.util.List; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; -import static com.main36.pikcha.domain.comment.entity.QComment.comment; - -@Repository -public class CommentCustomRepository { - private JPAQueryFactory jpaQueryFactory; - - public CommentCustomRepository(JPAQueryFactory jpaQueryFactory) { - this.jpaQueryFactory = jpaQueryFactory; - } - - public List findCommentByPost(Post post){ - return jpaQueryFactory.selectFrom(comment) - .leftJoin(comment.parent) - .fetchJoin() - .where(comment.post.postId.eq(post.getPostId())) - .orderBy(comment.parent.commentId.asc().nullsFirst(), comment.createdAt.asc()) - .fetch(); - } +public interface CommentCustomRepository { + Page findCommentByPost(Post post, Pageable pageable); } diff --git a/server/src/main/java/com/main36/pikcha/domain/comment/repository/CommentCustomRepositoryImpl.java b/server/src/main/java/com/main36/pikcha/domain/comment/repository/CommentCustomRepositoryImpl.java new file mode 100644 index 00000000..cfccae7d --- /dev/null +++ b/server/src/main/java/com/main36/pikcha/domain/comment/repository/CommentCustomRepositoryImpl.java @@ -0,0 +1,53 @@ +package com.main36.pikcha.domain.comment.repository; + +import com.main36.pikcha.domain.comment.entity.Comment; +import com.main36.pikcha.domain.post.entity.Post; +import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.impl.JPAQueryFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.data.support.PageableExecutionUtils; +import org.springframework.stereotype.Repository; + +import java.util.List; + +import static com.main36.pikcha.domain.comment.entity.QComment.comment; + +@Repository +public class CommentCustomRepositoryImpl implements CommentCustomRepository{ + private JPAQueryFactory jpaQueryFactory; + + public CommentCustomRepositoryImpl(JPAQueryFactory jpaQueryFactory) { + this.jpaQueryFactory = jpaQueryFactory; + } + + @Override + public Page findCommentByPost(Post post, Pageable pageable) { + List commentList = findCommnetList(post, pageable); + + JPAQuery countQuery = getCount(post); + + return PageableExecutionUtils.getPage(commentList, pageable, ()-> countQuery.fetchOne()); + } + + private JPAQuery getCount(Post post) { + JPAQuery countQuery = jpaQueryFactory + .select(comment.count()) + .from(comment) + .where(comment.post.postId.eq(post.getPostId())); + + return countQuery; + } + + private List findCommnetList(Post post, Pageable pageable){ + return jpaQueryFactory.selectFrom(comment) + .leftJoin(comment.parent) + .fetchJoin() + .where(comment.post.postId.eq(post.getPostId())) + .orderBy(comment.parent.commentId.asc().nullsFirst(), comment.createdAt.asc()) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + } +} diff --git a/server/src/main/java/com/main36/pikcha/domain/comment/service/CommentService.java b/server/src/main/java/com/main36/pikcha/domain/comment/service/CommentService.java index 52e42363..a4c00626 100644 --- a/server/src/main/java/com/main36/pikcha/domain/comment/service/CommentService.java +++ b/server/src/main/java/com/main36/pikcha/domain/comment/service/CommentService.java @@ -1,7 +1,10 @@ package com.main36.pikcha.domain.comment.service; +import com.main36.pikcha.domain.comment.dto.CommentDto; import com.main36.pikcha.domain.comment.entity.Comment; +import com.main36.pikcha.domain.comment.repository.CommentCustomRepositoryImpl; import com.main36.pikcha.domain.comment.repository.CommentRepository; +import com.main36.pikcha.domain.post.entity.Post; import com.main36.pikcha.global.exception.BusinessLogicException; import com.main36.pikcha.global.exception.ExceptionCode; import lombok.RequiredArgsConstructor; @@ -19,8 +22,16 @@ public class CommentService { private final CommentRepository commentRepository; + private final CommentCustomRepositoryImpl customRepository; - public Comment createComment(Comment comment) { + public Comment createComment(Comment comment, Long parentId) { + // 부모가 있는 댓글이라면 + if(parentId != null) { + // 부모댓글의 유효성 검증 + Comment parent = findVerifiedComment(parentId); + // 부모 아래에 추가 + comment.updateParent(parent); + } return commentRepository.save(comment); } @@ -37,6 +48,11 @@ public Page findComments(int page, int size) { page, size, Sort.by("commentId").ascending() )); } + + @Transactional(readOnly = true) + public Page findComments(int page, int size, Post post){ + return customRepository.findCommentByPost(post, PageRequest.of(page, size)); + } public void deleteComment(Comment comment) { commentRepository.delete(comment); } diff --git a/server/src/main/java/com/main36/pikcha/domain/post/mapper/PostMapper.java b/server/src/main/java/com/main36/pikcha/domain/post/mapper/PostMapper.java index 6b71111d..9d808928 100644 --- a/server/src/main/java/com/main36/pikcha/domain/post/mapper/PostMapper.java +++ b/server/src/main/java/com/main36/pikcha/domain/post/mapper/PostMapper.java @@ -43,6 +43,7 @@ default PostResponseDto.Detail postToPostDetailResponseDto(Post post) { .map(comment -> { return CommentResponseDto.builder() .commentId(comment.getCommentId()) + .parentId(comment.getParent().getCommentId()) .memberId(comment.getMember().getMemberId()) .username(comment.getMember().getUsername()) .memberPicture(comment.getMember().getPicture()) diff --git a/server/src/main/resources/application-local.yml b/server/src/main/resources/application-local.yml index edd80f14..c7630990 100644 --- a/server/src/main/resources/application-local.yml +++ b/server/src/main/resources/application-local.yml @@ -24,7 +24,7 @@ spring: jpa: hibernate: - ddl-auto: none + ddl-auto: create show-sql: true properties: hibernate: @@ -72,11 +72,11 @@ server: servlet: encoding: force-response: true - ssl: - key-store: classpath:keystore.p12 - key-store-type: PKCS12 - key-store-password: ${SSL_PASSWORD} - port: 8080 +# ssl: +# key-store: classpath:keystore.p12 +# key-store-type: PKCS12 +# key-store-password: ${SSL_PASSWORD} +# port: 8080 mail: address: diff --git a/server/src/main/resources/application.yml b/server/src/main/resources/application.yml index 2a564937..d74c444c 100644 --- a/server/src/main/resources/application.yml +++ b/server/src/main/resources/application.yml @@ -1,3 +1,3 @@ spring: profiles: - active: server + active: local