From 2dcdcdc080008c6c1ee8792e6395be473e088ca2 Mon Sep 17 00:00:00 2001 From: johnniang Date: Tue, 14 May 2019 23:42:21 +0800 Subject: [PATCH] Complete page top comments service --- .../content/api/PostController.java | 20 ++++++++++ .../CommentChildrenCountProjection.java | 21 ++++++++++ .../model/vo/CommentWithHasChildrenVO.java | 20 ++++++++++ .../repository/JournalCommentRepository.java | 8 ++-- .../app/repository/PostCommentRepository.java | 8 ++-- .../repository/SheetCommentRepository.java | 10 ++--- .../base/BaseCommentRepository.java | 13 ++++++- .../filter/ApiAuthenticationFilter.java | 17 +++++--- .../app/service/base/BaseCommentService.java | 25 ++++++++++++ .../service/impl/BaseCommentServiceImpl.java | 39 ++++++++++++++++++- 10 files changed, 160 insertions(+), 21 deletions(-) create mode 100644 src/main/java/run/halo/app/model/projection/CommentChildrenCountProjection.java create mode 100644 src/main/java/run/halo/app/model/vo/CommentWithHasChildrenVO.java diff --git a/src/main/java/run/halo/app/controller/content/api/PostController.java b/src/main/java/run/halo/app/controller/content/api/PostController.java index 2c2dbbfa6..e3f647a5f 100644 --- a/src/main/java/run/halo/app/controller/content/api/PostController.java +++ b/src/main/java/run/halo/app/controller/content/api/PostController.java @@ -13,14 +13,18 @@ import run.halo.app.model.dto.BaseCommentDTO; import run.halo.app.model.dto.post.BasePostDetailDTO; import run.halo.app.model.dto.post.BasePostSimpleDTO; import run.halo.app.model.entity.Post; +import run.halo.app.model.enums.CommentStatus; import run.halo.app.model.enums.PostStatus; import run.halo.app.model.params.PostCommentParam; import run.halo.app.model.vo.BaseCommentVO; import run.halo.app.model.vo.BaseCommentWithParentVO; +import run.halo.app.model.vo.CommentWithHasChildrenVO; import run.halo.app.service.OptionService; import run.halo.app.service.PostCommentService; import run.halo.app.service.PostService; +import java.util.List; + import static org.springframework.data.domain.Sort.Direction.DESC; /** @@ -74,6 +78,22 @@ public class PostController { return detailDTO; } + @GetMapping("{postId:\\d+}/comments/top_view") + public Page listTopComments(@PathVariable("postId") Integer postId, + @RequestParam(name = "page", required = false, defaultValue = "0") int page, + @SortDefault(sort = "createTime", direction = DESC) Sort sort) { + return postCommentService.pageTopCommentsBy(postId, CommentStatus.PUBLISHED, PageRequest.of(page, optionService.getCommentPageSize(), sort)); + } + + + @GetMapping("{postId:\\d+}/comments/{commentParentId:\\d+}/children") + public List listChildrenBy(@PathVariable("postId") Integer postId, + @PathVariable("commentParentId") Integer commentParentId, + @SortDefault(sort = "createTime", direction = DESC) Sort sort) { + return postCommentService.listChildrenBy(postId, commentParentId, CommentStatus.PUBLISHED, sort); + } + + @GetMapping("{postId:\\d+}/comments/tree_view") @ApiOperation("Lists comments with tree view") public Page listCommentsTree(@PathVariable("postId") Integer postId, diff --git a/src/main/java/run/halo/app/model/projection/CommentChildrenCountProjection.java b/src/main/java/run/halo/app/model/projection/CommentChildrenCountProjection.java new file mode 100644 index 000000000..ebd7d1571 --- /dev/null +++ b/src/main/java/run/halo/app/model/projection/CommentChildrenCountProjection.java @@ -0,0 +1,21 @@ +package run.halo.app.model.projection; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Comment children count projection. + * + * @author johnniang + * @date 19-5-14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CommentChildrenCountProjection { + + private Long directChildrenCount; + + private Long commentId; +} diff --git a/src/main/java/run/halo/app/model/vo/CommentWithHasChildrenVO.java b/src/main/java/run/halo/app/model/vo/CommentWithHasChildrenVO.java new file mode 100644 index 000000000..aef582e32 --- /dev/null +++ b/src/main/java/run/halo/app/model/vo/CommentWithHasChildrenVO.java @@ -0,0 +1,20 @@ +package run.halo.app.model.vo; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import run.halo.app.model.dto.BaseCommentDTO; + +/** + * Comment including replied count. + * + * @author johnniang + * @date 19-5-14 + */ +@Data +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = true) +public class CommentWithHasChildrenVO extends BaseCommentDTO { + + private boolean hasChildren; +} diff --git a/src/main/java/run/halo/app/repository/JournalCommentRepository.java b/src/main/java/run/halo/app/repository/JournalCommentRepository.java index cd1158dcf..e72b06b6f 100644 --- a/src/main/java/run/halo/app/repository/JournalCommentRepository.java +++ b/src/main/java/run/halo/app/repository/JournalCommentRepository.java @@ -16,8 +16,8 @@ import java.util.List; */ public interface JournalCommentRepository extends BaseCommentRepository { - @Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) from JournalComment comment where comment.postId in ?1 group by comment.postId") - @NonNull - @Override - List countByPostIds(@NonNull Iterable postIds); +// @Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) from JournalComment comment where comment.postId in ?1 group by comment.postId") +// @NonNull +// @Override +// List countByPostIds(@NonNull Iterable postIds); } diff --git a/src/main/java/run/halo/app/repository/PostCommentRepository.java b/src/main/java/run/halo/app/repository/PostCommentRepository.java index e34d9065f..a8d1fc775 100644 --- a/src/main/java/run/halo/app/repository/PostCommentRepository.java +++ b/src/main/java/run/halo/app/repository/PostCommentRepository.java @@ -16,9 +16,9 @@ import java.util.List; */ public interface PostCommentRepository extends BaseCommentRepository { - @Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) from PostComment comment where comment.postId in ?1 group by comment.postId") - @NonNull - @Override - List countByPostIds(@NonNull Iterable postIds); +// @Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) from PostComment comment where comment.postId in ?1 group by comment.postId") +// @NonNull +// @Override +// List countByPostIds(@NonNull Iterable postIds); } diff --git a/src/main/java/run/halo/app/repository/SheetCommentRepository.java b/src/main/java/run/halo/app/repository/SheetCommentRepository.java index 39a4fa52f..d4fb2679a 100644 --- a/src/main/java/run/halo/app/repository/SheetCommentRepository.java +++ b/src/main/java/run/halo/app/repository/SheetCommentRepository.java @@ -15,9 +15,9 @@ import java.util.List; * @date 19-4-24 */ public interface SheetCommentRepository extends BaseCommentRepository { - - @Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) from SheetComment comment where comment.postId in ?1 group by comment.postId") - @NonNull - @Override - List countByPostIds(@NonNull Iterable postIds); +// +// @Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) from SheetComment comment where comment.postId in ?1 group by comment.postId") +// @NonNull +// @Override +// List countByPostIds(@NonNull Iterable postIds); } diff --git a/src/main/java/run/halo/app/repository/base/BaseCommentRepository.java b/src/main/java/run/halo/app/repository/base/BaseCommentRepository.java index 09429b537..4658d8386 100644 --- a/src/main/java/run/halo/app/repository/base/BaseCommentRepository.java +++ b/src/main/java/run/halo/app/repository/base/BaseCommentRepository.java @@ -9,6 +9,7 @@ import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import run.halo.app.model.entity.BaseComment; import run.halo.app.model.enums.CommentStatus; +import run.halo.app.model.projection.CommentChildrenCountProjection; import run.halo.app.model.projection.CommentCountProjection; import java.util.List; @@ -57,7 +58,10 @@ public interface BaseCommentRepository extends Base * @param postIds post id collection must not be null * @return a list of comment count */ -// @Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) from BaseComment comment where comment.postId in ?1 group by comment.postId") + @Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) " + + "from BaseComment comment " + + "where comment.postId in ?1 " + + "group by comment.postId") @NonNull List countByPostIds(@NonNull Iterable postIds); @@ -89,4 +93,11 @@ public interface BaseCommentRepository extends Base */ @NonNull Page findAllByPostIdAndStatus(Integer postId, CommentStatus status, Pageable pageable); + + @Query("select new run.halo.app.model.projection.CommentChildrenCountProjection(count(comment.id), comment.parentId) " + + "from BaseComment comment " + + "where comment.parentId in ?1 " + + "group by comment.parentId") + @NonNull + List findDirectChildrenCount(@NonNull Iterable commentIds); } diff --git a/src/main/java/run/halo/app/security/filter/ApiAuthenticationFilter.java b/src/main/java/run/halo/app/security/filter/ApiAuthenticationFilter.java index faa8eedab..bdea4ce6b 100644 --- a/src/main/java/run/halo/app/security/filter/ApiAuthenticationFilter.java +++ b/src/main/java/run/halo/app/security/filter/ApiAuthenticationFilter.java @@ -42,12 +42,8 @@ public class ApiAuthenticationFilter extends AbstractAuthenticationFilter { @Override protected void doAuthenticate(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - // Get token - String token = getTokenFromRequest(request); - - if (StringUtils.isBlank(token)) { - // If the token is missing - getFailureHandler().onFailure(request, response, new AuthenticationException("Missing API token")); + if (!haloProperties.isAuthEnabled()) { + filterChain.doFilter(request, response); return; } @@ -59,6 +55,15 @@ public class ApiAuthenticationFilter extends AbstractAuthenticationFilter { return; } + // Get token + String token = getTokenFromRequest(request); + + if (StringUtils.isBlank(token)) { + // If the token is missing + getFailureHandler().onFailure(request, response, new AuthenticationException("Missing API token")); + return; + } + // Get token from option Optional optionalToken = optionService.getByProperty(OtherProperties.API_TOKEN, String.class); diff --git a/src/main/java/run/halo/app/service/base/BaseCommentService.java b/src/main/java/run/halo/app/service/base/BaseCommentService.java index a153bb97f..d31a1843d 100644 --- a/src/main/java/run/halo/app/service/base/BaseCommentService.java +++ b/src/main/java/run/halo/app/service/base/BaseCommentService.java @@ -2,6 +2,7 @@ package run.halo.app.service.base; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import run.halo.app.model.dto.BaseCommentDTO; @@ -11,6 +12,7 @@ import run.halo.app.model.params.BaseCommentParam; import run.halo.app.model.params.CommentQuery; import run.halo.app.model.vo.BaseCommentVO; import run.halo.app.model.vo.BaseCommentWithParentVO; +import run.halo.app.model.vo.CommentWithHasChildrenVO; import java.util.Collection; import java.util.Comparator; @@ -189,4 +191,27 @@ public interface BaseCommentService extends CrudSer * @param targetId target id must not be null (post id, sheet id or journal id) */ void targetMustExist(@NonNull Integer targetId); + + /** + * Lists a page of top comment. + * + * @param targetId target id must not be null + * @param status comment status must not be null + * @param pageable page info must not be null + * @return a page of top comment + */ + @NonNull + Page pageTopCommentsBy(@NonNull Integer targetId, @NonNull CommentStatus status, @NonNull Pageable pageable); + + /** + * Lists children comments. + * + * @param targetId target id must not be null + * @param commentParentId comment parent id must not be null + * @param status comment status must not be null + * @param sort sort info must not be null + * @return a list of children comment + */ + @NonNull + List listChildrenBy(@NonNull Integer targetId, @NonNull Integer commentParentId, @NonNull CommentStatus status, @NonNull Sort sort); } diff --git a/src/main/java/run/halo/app/service/impl/BaseCommentServiceImpl.java b/src/main/java/run/halo/app/service/impl/BaseCommentServiceImpl.java index 4208c4ea9..1ce99e536 100644 --- a/src/main/java/run/halo/app/service/impl/BaseCommentServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/BaseCommentServiceImpl.java @@ -23,12 +23,14 @@ import run.halo.app.model.entity.User; import run.halo.app.model.enums.CommentStatus; import run.halo.app.model.params.BaseCommentParam; import run.halo.app.model.params.CommentQuery; +import run.halo.app.model.projection.CommentChildrenCountProjection; import run.halo.app.model.projection.CommentCountProjection; import run.halo.app.model.properties.BlogProperties; import run.halo.app.model.properties.CommentProperties; import run.halo.app.model.support.CommentPage; import run.halo.app.model.vo.BaseCommentVO; import run.halo.app.model.vo.BaseCommentWithParentVO; +import run.halo.app.model.vo.CommentWithHasChildrenVO; import run.halo.app.repository.base.BaseCommentRepository; import run.halo.app.security.authentication.Authentication; import run.halo.app.security.context.SecurityContextHolder; @@ -294,7 +296,7 @@ public abstract class BaseCommentServiceImpl extend // Anonymous comment // Check email if (userService.getByEmail(commentParam.getEmail()).isPresent()) { - throw new BadRequestException("不能使用博主的邮件,如果您是博主,请登录管理端进行回复。"); + throw new BadRequestException("不能使用博主的邮箱,如果您是博主,请登录管理端进行回复。"); } } @@ -416,6 +418,41 @@ public abstract class BaseCommentServiceImpl extend return topVirtualComment.getChildren(); } + @Override + public Page pageTopCommentsBy(Integer targetId, CommentStatus status, Pageable pageable) { + Assert.notNull(targetId, "Target id must not be null"); + Assert.notNull(status, "Comment status must not be null"); + Assert.notNull(pageable, "Page info must not be null"); + + // Get all comments + Page topCommentPage = baseCommentRepository.findAllByPostIdAndStatus(targetId, status, pageable); + + // Get top comment ids + Set topCommentIds = ServiceUtils.fetchProperty(topCommentPage.getContent(), BaseComment::getId); + + // Get direct children count + List directChildrenCount = baseCommentRepository.findDirectChildrenCount(topCommentIds); + + // Convert to comment - children count map + Map commentChildrenCountMap = ServiceUtils.convertToMap(directChildrenCount, CommentChildrenCountProjection::getCommentId, CommentChildrenCountProjection::getDirectChildrenCount); + + // Convert to comment with has children vo + return topCommentPage.map(topComment -> { + CommentWithHasChildrenVO comment = new CommentWithHasChildrenVO().convertFrom(topComment); + comment.setHasChildren(commentChildrenCountMap.getOrDefault(topComment.getId(), 0L) > 0); + return comment; + }); + } + + @Override + public List listChildrenBy(Integer targetId, Integer commentParentId, CommentStatus status, Sort sort) { + Assert.notNull(targetId, "Target id must not be null"); + Assert.notNull(commentParentId, "Comment parent id must not be null"); + Assert.notNull(sort, "Sort info must not be null"); + + return null; + } + /** * Concretes comment tree. *