From 67c18808df17c8a027c1f0608f90a91cd1c8348b Mon Sep 17 00:00:00 2001 From: johnniang Date: Mon, 1 Apr 2019 00:48:44 +0800 Subject: [PATCH] Complete comment list view api --- .../halo/model/vo/CommentWithParentVO.java | 34 +++++++++ ...mentListVO.java => CommentWithPostVO.java} | 4 +- .../cc/ryanc/halo/service/CommentService.java | 19 +++-- .../halo/service/impl/CommentServiceImpl.java | 70 ++++++++++++++++--- .../admin/api/CommentController.java | 8 +-- .../controller/admin/api/PostController.java | 18 +++-- 6 files changed, 130 insertions(+), 23 deletions(-) create mode 100644 src/main/java/cc/ryanc/halo/model/vo/CommentWithParentVO.java rename src/main/java/cc/ryanc/halo/model/vo/{CommentListVO.java => CommentWithPostVO.java} (79%) diff --git a/src/main/java/cc/ryanc/halo/model/vo/CommentWithParentVO.java b/src/main/java/cc/ryanc/halo/model/vo/CommentWithParentVO.java new file mode 100644 index 000000000..4f6ec2fe4 --- /dev/null +++ b/src/main/java/cc/ryanc/halo/model/vo/CommentWithParentVO.java @@ -0,0 +1,34 @@ +package cc.ryanc.halo.model.vo; + +import cc.ryanc.halo.model.dto.CommentOutputDTO; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +/** + * Comment list with parent comment vo. + * + * @author johnniang + * @date 3/31/19 + */ +@Data +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = true) +@Slf4j +public class CommentWithParentVO extends CommentOutputDTO implements Cloneable { + + /** + * Parent comment. + */ + private CommentWithParentVO parent; + + public CommentWithParentVO clone() { + try { + return (CommentWithParentVO) super.clone(); + } catch (CloneNotSupportedException e) { + log.error("Clone not support exception", e); + return null; + } + } +} diff --git a/src/main/java/cc/ryanc/halo/model/vo/CommentListVO.java b/src/main/java/cc/ryanc/halo/model/vo/CommentWithPostVO.java similarity index 79% rename from src/main/java/cc/ryanc/halo/model/vo/CommentListVO.java rename to src/main/java/cc/ryanc/halo/model/vo/CommentWithPostVO.java index 96ceeb1c7..b6364d478 100644 --- a/src/main/java/cc/ryanc/halo/model/vo/CommentListVO.java +++ b/src/main/java/cc/ryanc/halo/model/vo/CommentWithPostVO.java @@ -7,14 +7,14 @@ import lombok.EqualsAndHashCode; import lombok.ToString; /** - * Comment vo. + * Comment list with post vo. * * @author johnniang */ @Data @ToString @EqualsAndHashCode(callSuper = true) -public class CommentListVO extends CommentOutputDTO { +public class CommentWithPostVO extends CommentOutputDTO { private PostMinimalOutputDTO post; } diff --git a/src/main/java/cc/ryanc/halo/service/CommentService.java b/src/main/java/cc/ryanc/halo/service/CommentService.java index e7f92f2f3..c3d6f6364 100644 --- a/src/main/java/cc/ryanc/halo/service/CommentService.java +++ b/src/main/java/cc/ryanc/halo/service/CommentService.java @@ -2,7 +2,8 @@ package cc.ryanc.halo.service; import cc.ryanc.halo.model.entity.Comment; import cc.ryanc.halo.model.enums.CommentStatus; -import cc.ryanc.halo.model.vo.CommentListVO; +import cc.ryanc.halo.model.vo.CommentWithParentVO; +import cc.ryanc.halo.model.vo.CommentWithPostVO; import cc.ryanc.halo.model.vo.CommentVO; import cc.ryanc.halo.service.base.CrudService; import org.springframework.data.domain.Page; @@ -36,7 +37,7 @@ public interface CommentService extends CrudService { * @return a page of comments */ @NonNull - Page pageLatest(int top); + Page pageLatest(int top); /** * Pages comments. @@ -46,7 +47,7 @@ public interface CommentService extends CrudService { * @return a page of comment */ @NonNull - Page pageBy(@NonNull CommentStatus status, @NonNull Pageable pageable); + Page pageBy(@NonNull CommentStatus status, @NonNull Pageable pageable); /** * Lists comments by post id. @@ -86,6 +87,16 @@ public interface CommentService extends CrudService { @NonNull Page pageVosBy(@NonNull Integer postId, @NonNull Pageable pageable); + /** + * Lists comment with parent vo. + * + * @param postId post id must not be null + * @param pageable page info must not be null + * @return a page of comment with parent vo. + */ + @NonNull + Page pageWithParentVoBy(@NonNull Integer postId, @NonNull Pageable pageable); + /** * Updates comment status. * @@ -94,5 +105,5 @@ public interface CommentService extends CrudService { * @return updated comment */ @NonNull - Comment updateStatus(Long commentId, CommentStatus status); + Comment updateStatus(@NonNull Long commentId, @NonNull CommentStatus status); } diff --git a/src/main/java/cc/ryanc/halo/service/impl/CommentServiceImpl.java b/src/main/java/cc/ryanc/halo/service/impl/CommentServiceImpl.java index d3d92ebc2..9d28eea46 100644 --- a/src/main/java/cc/ryanc/halo/service/impl/CommentServiceImpl.java +++ b/src/main/java/cc/ryanc/halo/service/impl/CommentServiceImpl.java @@ -7,8 +7,9 @@ import cc.ryanc.halo.model.enums.BlogProperties; import cc.ryanc.halo.model.enums.CommentStatus; import cc.ryanc.halo.model.projection.CommentCountProjection; import cc.ryanc.halo.model.support.CommentPage; -import cc.ryanc.halo.model.vo.CommentListVO; import cc.ryanc.halo.model.vo.CommentVO; +import cc.ryanc.halo.model.vo.CommentWithParentVO; +import cc.ryanc.halo.model.vo.CommentWithPostVO; import cc.ryanc.halo.repository.CommentRepository; import cc.ryanc.halo.repository.PostRepository; import cc.ryanc.halo.security.authentication.Authentication; @@ -63,7 +64,7 @@ public class CommentServiceImpl extends AbstractCrudService imple } @Override - public Page pageLatest(int top) { + public Page pageLatest(int top) { Assert.isTrue(top > 0, "Top number must not be less than 0"); // Build page request @@ -73,7 +74,7 @@ public class CommentServiceImpl extends AbstractCrudService imple } @Override - public Page pageBy(CommentStatus status, Pageable pageable) { + public Page pageBy(CommentStatus status, Pageable pageable) { Assert.notNull(status, "Comment status must not be null"); Assert.notNull(pageable, "Page info must not be null"); @@ -149,7 +150,7 @@ public class CommentServiceImpl extends AbstractCrudService imple Assert.notNull(postId, "Post id must not be null"); Assert.notNull(pageable, "Page info must not be null"); - log.debug("Getting comment of post: [{}], page info: [{}]", postId, pageable); + log.debug("Getting comment tree view of post: [{}], page info: [{}]", postId, pageable); // List all the top comments (Caution: This list will be cleared) List comments = commentRepository.findAllByPostIdAndStatus(postId, CommentStatus.PUBLISHED); @@ -186,6 +187,57 @@ public class CommentServiceImpl extends AbstractCrudService imple return new CommentPage<>(pageContent, pageable, topComments.size(), comments.size()); } + @Override + public Page pageWithParentVoBy(Integer postId, Pageable pageable) { + Assert.notNull(postId, "Post id must not be null"); + Assert.notNull(pageable, "Page info must not be null"); + + log.debug("Getting comment list view of post: [{}], page info: [{}]", postId, pageable); + + // List all the top comments (Caution: This list will be cleared) + Page commentPage = commentRepository.findAllByPostIdAndStatus(postId, CommentStatus.PUBLISHED, pageable); + + // Get all comments + List comments = commentPage.getContent(); + + // Get all comment parent ids + Set parentIds = ServiceUtils.fetchProperty(comments, Comment::getParentId); + + // Get all parent comments + List parentComments = commentRepository.findAllByIdIn(parentIds, pageable.getSort()); + + // Convert to comment map (Key: comment id, value: comment) + Map parentCommentMap = ServiceUtils.convertToMap(parentComments, Comment::getId); + + Map parentCommentVoMap = new HashMap<>(parentCommentMap.size()); + + // Convert to comment page + return commentPage.map(comment -> { + // Convert to with parent vo + CommentWithParentVO commentWithParentVO = new CommentWithParentVO().convertFrom(comment); + + // Get parent comment vo from cache + CommentWithParentVO parentCommentVo = parentCommentVoMap.get(comment.getParentId()); + + if (parentCommentVo == null) { + // Get parent comment + Comment parentComment = parentCommentMap.get(comment.getParentId()); + + if (parentComment != null) { + // Convert to parent comment vo + parentCommentVo = new CommentWithParentVO().convertFrom(parentComment); + // Cache the parent comment vo + parentCommentVoMap.put(parentComment.getId(), parentCommentVo); + } + } + + // Set parent + commentWithParentVO.setParent(parentCommentVo == null ? null : parentCommentVo.clone()); + + return commentWithParentVO; + }); + } + @Override public Comment updateStatus(Long commentId, CommentStatus status) { Assert.notNull(commentId, "Comment id must not be null"); @@ -284,7 +336,7 @@ public class CommentServiceImpl extends AbstractCrudService imple * @return a page of comment vo */ @NonNull - private Page convertBy(@NonNull Page commentPage) { + private Page convertBy(@NonNull Page commentPage) { Assert.notNull(commentPage, "Comment page must not be null"); return new PageImpl<>(convertBy(commentPage.getContent()), commentPage.getPageable(), commentPage.getTotalElements()); @@ -297,7 +349,7 @@ public class CommentServiceImpl extends AbstractCrudService imple * @return a list of comment vo */ @NonNull - private List convertBy(@Nullable List comments) { + private List convertBy(@Nullable List comments) { if (CollectionUtils.isEmpty(comments)) { return Collections.emptyList(); } @@ -310,12 +362,12 @@ public class CommentServiceImpl extends AbstractCrudService imple return comments.stream().map(comment -> { // Convert to vo - CommentListVO commentListVO = new CommentListVO().convertFrom(comment); + CommentWithPostVO commentWithPostVO = new CommentWithPostVO().convertFrom(comment); // Get post and set to the vo - commentListVO.setPost(new PostMinimalOutputDTO().convertFrom(postMap.get(comment.getPostId()))); + commentWithPostVO.setPost(new PostMinimalOutputDTO().convertFrom(postMap.get(comment.getPostId()))); - return commentListVO; + return commentWithPostVO; }).collect(Collectors.toList()); } diff --git a/src/main/java/cc/ryanc/halo/web/controller/admin/api/CommentController.java b/src/main/java/cc/ryanc/halo/web/controller/admin/api/CommentController.java index 3b96b8298..55a27b81a 100644 --- a/src/main/java/cc/ryanc/halo/web/controller/admin/api/CommentController.java +++ b/src/main/java/cc/ryanc/halo/web/controller/admin/api/CommentController.java @@ -6,7 +6,7 @@ import cc.ryanc.halo.model.entity.User; import cc.ryanc.halo.model.enums.BlogProperties; import cc.ryanc.halo.model.enums.CommentStatus; import cc.ryanc.halo.model.params.CommentParam; -import cc.ryanc.halo.model.vo.CommentListVO; +import cc.ryanc.halo.model.vo.CommentWithPostVO; import cc.ryanc.halo.security.authentication.Authentication; import cc.ryanc.halo.security.context.SecurityContextHolder; import cc.ryanc.halo.service.CommentService; @@ -51,13 +51,13 @@ public class CommentController { @GetMapping("latest") @ApiOperation("Pages latest comments") - public List pageLatest(@RequestParam(name = "top", defaultValue = "10") int top) { + public List pageLatest(@RequestParam(name = "top", defaultValue = "10") int top) { return commentService.pageLatest(top).getContent(); } @GetMapping("status/{status}") - public Page pageBy(@PageableDefault(sort = "updateTime", direction = DESC) Pageable pageable, - @PathVariable("status") CommentStatus status) { + public Page pageBy(@PageableDefault(sort = "updateTime", direction = DESC) Pageable pageable, + @PathVariable("status") CommentStatus status) { return commentService.pageBy(status, pageable); } diff --git a/src/main/java/cc/ryanc/halo/web/controller/admin/api/PostController.java b/src/main/java/cc/ryanc/halo/web/controller/admin/api/PostController.java index 7f621aff1..ded606264 100644 --- a/src/main/java/cc/ryanc/halo/web/controller/admin/api/PostController.java +++ b/src/main/java/cc/ryanc/halo/web/controller/admin/api/PostController.java @@ -5,6 +5,7 @@ import cc.ryanc.halo.model.dto.post.PostSimpleOutputDTO; import cc.ryanc.halo.model.entity.Post; import cc.ryanc.halo.model.enums.PostStatus; import cc.ryanc.halo.model.params.PostParam; +import cc.ryanc.halo.model.vo.CommentWithParentVO; import cc.ryanc.halo.model.vo.CommentVO; import cc.ryanc.halo.model.vo.PostDetailVO; import cc.ryanc.halo.service.*; @@ -103,10 +104,19 @@ public class PostController { postTagService.removeByPostId(postId); } - @GetMapping("{postId:\\d+}/comments") - public Page listComments(@PathVariable("postId") Integer postId, - @RequestParam(name = "page", required = false, defaultValue = "0") int page, - @SortDefault Sort sort) { + @GetMapping("{postId:\\d+}/comments/tree_view") + @ApiOperation("Lists comments with tree view") + public Page listCommentsTree(@PathVariable("postId") Integer postId, + @RequestParam(name = "page", required = false, defaultValue = "0") int page, + @SortDefault(sort = "createTime", direction = DESC) Sort sort) { return commentService.pageVosBy(postId, PageRequest.of(page, optionService.getCommentPageSize(), sort)); } + + @GetMapping("{postId:\\d+}/comments/list_view") + @ApiOperation("Lists comment with list view") + public Page listComments(@PathVariable("postId") Integer postId, + @RequestParam(name = "page", required = false, defaultValue = "0") int page, + @SortDefault(sort = "createTime", direction = DESC) Sort sort) { + return commentService.pageWithParentVoBy(postId, PageRequest.of(page, optionService.getCommentPageSize(), sort)); + } }