Complete page top comments service

pull/161/head
johnniang 2019-05-14 23:42:21 +08:00
parent 71dbdbeb75
commit 2dcdcdc080
10 changed files with 160 additions and 21 deletions

View File

@ -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<CommentWithHasChildrenVO> 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<BaseCommentDTO> 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<BaseCommentVO> listCommentsTree(@PathVariable("postId") Integer postId,

View File

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

View File

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

View File

@ -16,8 +16,8 @@ import java.util.List;
*/
public interface JournalCommentRepository extends BaseCommentRepository<JournalComment> {
@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<CommentCountProjection> countByPostIds(@NonNull Iterable<Integer> 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<CommentCountProjection> countByPostIds(@NonNull Iterable<Integer> postIds);
}

View File

@ -16,9 +16,9 @@ import java.util.List;
*/
public interface PostCommentRepository extends BaseCommentRepository<PostComment> {
@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<CommentCountProjection> countByPostIds(@NonNull Iterable<Integer> 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<CommentCountProjection> countByPostIds(@NonNull Iterable<Integer> postIds);
}

View File

@ -15,9 +15,9 @@ import java.util.List;
* @date 19-4-24
*/
public interface SheetCommentRepository extends BaseCommentRepository<SheetComment> {
@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<CommentCountProjection> countByPostIds(@NonNull Iterable<Integer> 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<CommentCountProjection> countByPostIds(@NonNull Iterable<Integer> postIds);
}

View File

@ -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<COMMENT extends BaseComment> 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<CommentCountProjection> countByPostIds(@NonNull Iterable<Integer> postIds);
@ -89,4 +93,11 @@ public interface BaseCommentRepository<COMMENT extends BaseComment> extends Base
*/
@NonNull
Page<COMMENT> 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<CommentChildrenCountProjection> findDirectChildrenCount(@NonNull Iterable<Long> commentIds);
}

View File

@ -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<String> optionalToken = optionService.getByProperty(OtherProperties.API_TOKEN, String.class);

View File

@ -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<COMMENT extends BaseComment> 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<CommentWithHasChildrenVO> 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<BaseCommentDTO> listChildrenBy(@NonNull Integer targetId, @NonNull Integer commentParentId, @NonNull CommentStatus status, @NonNull Sort sort);
}

View File

@ -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<COMMENT extends BaseComment> 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<COMMENT extends BaseComment> extend
return topVirtualComment.getChildren();
}
@Override
public Page<CommentWithHasChildrenVO> 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<COMMENT> topCommentPage = baseCommentRepository.findAllByPostIdAndStatus(targetId, status, pageable);
// Get top comment ids
Set<Long> topCommentIds = ServiceUtils.fetchProperty(topCommentPage.getContent(), BaseComment::getId);
// Get direct children count
List<CommentChildrenCountProjection> directChildrenCount = baseCommentRepository.findDirectChildrenCount(topCommentIds);
// Convert to comment - children count map
Map<Long, Long> 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<BaseCommentDTO> 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.
*