Complete comment list view api

pull/137/head
johnniang 2019-04-01 00:48:44 +08:00
parent 6f9aac5aad
commit 67c18808df
6 changed files with 130 additions and 23 deletions

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -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<Comment, Long> {
* @return a page of comments
*/
@NonNull
Page<CommentListVO> pageLatest(int top);
Page<CommentWithPostVO> pageLatest(int top);
/**
* Pages comments.
@ -46,7 +47,7 @@ public interface CommentService extends CrudService<Comment, Long> {
* @return a page of comment
*/
@NonNull
Page<CommentListVO> pageBy(@NonNull CommentStatus status, @NonNull Pageable pageable);
Page<CommentWithPostVO> pageBy(@NonNull CommentStatus status, @NonNull Pageable pageable);
/**
* Lists comments by post id.
@ -86,6 +87,16 @@ public interface CommentService extends CrudService<Comment, Long> {
@NonNull
Page<CommentVO> 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<CommentWithParentVO> pageWithParentVoBy(@NonNull Integer postId, @NonNull Pageable pageable);
/**
* Updates comment status.
*
@ -94,5 +105,5 @@ public interface CommentService extends CrudService<Comment, Long> {
* @return updated comment
*/
@NonNull
Comment updateStatus(Long commentId, CommentStatus status);
Comment updateStatus(@NonNull Long commentId, @NonNull CommentStatus status);
}

View File

@ -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<Comment, Long> imple
}
@Override
public Page<CommentListVO> pageLatest(int top) {
public Page<CommentWithPostVO> 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<Comment, Long> imple
}
@Override
public Page<CommentListVO> pageBy(CommentStatus status, Pageable pageable) {
public Page<CommentWithPostVO> 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<Comment, Long> 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<Comment> comments = commentRepository.findAllByPostIdAndStatus(postId, CommentStatus.PUBLISHED);
@ -186,6 +187,57 @@ public class CommentServiceImpl extends AbstractCrudService<Comment, Long> imple
return new CommentPage<>(pageContent, pageable, topComments.size(), comments.size());
}
@Override
public Page<CommentWithParentVO> 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<Comment> commentPage = commentRepository.findAllByPostIdAndStatus(postId, CommentStatus.PUBLISHED, pageable);
// Get all comments
List<Comment> comments = commentPage.getContent();
// Get all comment parent ids
Set<Long> parentIds = ServiceUtils.fetchProperty(comments, Comment::getParentId);
// Get all parent comments
List<Comment> parentComments = commentRepository.findAllByIdIn(parentIds, pageable.getSort());
// Convert to comment map (Key: comment id, value: comment)
Map<Long, Comment> parentCommentMap = ServiceUtils.convertToMap(parentComments, Comment::getId);
Map<Long, CommentWithParentVO> 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<Comment, Long> imple
* @return a page of comment vo
*/
@NonNull
private Page<CommentListVO> convertBy(@NonNull Page<Comment> commentPage) {
private Page<CommentWithPostVO> convertBy(@NonNull Page<Comment> 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<Comment, Long> imple
* @return a list of comment vo
*/
@NonNull
private List<CommentListVO> convertBy(@Nullable List<Comment> comments) {
private List<CommentWithPostVO> convertBy(@Nullable List<Comment> comments) {
if (CollectionUtils.isEmpty(comments)) {
return Collections.emptyList();
}
@ -310,12 +362,12 @@ public class CommentServiceImpl extends AbstractCrudService<Comment, Long> 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());
}

View File

@ -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<CommentListVO> pageLatest(@RequestParam(name = "top", defaultValue = "10") int top) {
public List<CommentWithPostVO> pageLatest(@RequestParam(name = "top", defaultValue = "10") int top) {
return commentService.pageLatest(top).getContent();
}
@GetMapping("status/{status}")
public Page<CommentListVO> pageBy(@PageableDefault(sort = "updateTime", direction = DESC) Pageable pageable,
@PathVariable("status") CommentStatus status) {
public Page<CommentWithPostVO> pageBy(@PageableDefault(sort = "updateTime", direction = DESC) Pageable pageable,
@PathVariable("status") CommentStatus status) {
return commentService.pageBy(status, pageable);
}

View File

@ -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<CommentVO> 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<CommentVO> 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<CommentWithParentVO> 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));
}
}