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 b5ba1b8c5..6782dcbd1 100644 --- a/src/main/java/run/halo/app/repository/base/BaseCommentRepository.java +++ b/src/main/java/run/halo/app/repository/base/BaseCommentRepository.java @@ -123,7 +123,17 @@ public interface BaseCommentRepository extends Base * @return a list of comment */ @NonNull - List findAllByPostIdAndStatusAndParentId(Integer postId, CommentStatus status, Long parentId); + List findAllByPostIdAndStatusAndParentId(@NonNull Integer postId, @NonNull CommentStatus status, @NonNull Long parentId); + + /** + * Finds comments by post id and parent id. + * + * @param postId post id must not be null + * @param parentId comment parent id must not be null + * @return a list of comment + */ + @NonNull + List findAllByPostIdAndParentId(@NonNull Integer postId, @NonNull Long parentId); /** * Finds all comments by status and parent id collection. @@ -135,6 +145,14 @@ public interface BaseCommentRepository extends Base @NonNull List findAllByStatusAndParentIdIn(@NonNull CommentStatus status, @NonNull Collection parentIds); + /** + * Finds all comments by parent id collection. + * + * @param parentIds parent id collection must not be null + * @return a list of comment + */ + List findAllByParentIdIn(@NonNull Collection parentIds); + /** * Finds comments by post id, comment status and parent id. * 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 dea641a6f..a3500a77e 100644 --- a/src/main/java/run/halo/app/service/base/BaseCommentService.java +++ b/src/main/java/run/halo/app/service/base/BaseCommentService.java @@ -264,6 +264,17 @@ public interface BaseCommentService extends CrudSer @NonNull List listChildrenBy(@NonNull Integer targetId, @NonNull Long commentParentId, @NonNull CommentStatus status, @NonNull Sort sort); + /** + * Lists children comments. + * + * @param targetId target id must not be null + * @param commentParentId comment parent id 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 Long commentParentId, @NonNull Sort sort); + /** * Filters comment ip address. * 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 f2137ad24..b8a216c23 100644 --- a/src/main/java/run/halo/app/service/impl/BaseCommentServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/BaseCommentServiceImpl.java @@ -48,6 +48,8 @@ import javax.persistence.criteria.Predicate; import java.util.*; import java.util.stream.Collectors; +import static org.springframework.data.domain.Sort.Direction.DESC; + /** * Base comment service implementation. * @@ -372,10 +374,12 @@ public abstract class BaseCommentServiceImpl extend COMMENT comment = baseCommentRepository.findById(id).orElseThrow(() -> new NotFoundException("查询不到该评论的信息").setErrorData(id)); - if (comment.getParentId() == 0) { - // Remove comment children. - List comments = baseCommentRepository.deleteByParentId(id); - log.debug("Removed comment children: [{}]", comments); + List children = listChildrenBy(comment.getPostId(), id, Sort.by(DESC, "createTime")); + + if (children.size() > 0) { + children.forEach(child -> { + super.removeById(child.getId()); + }); } return super.removeById(id); @@ -537,6 +541,30 @@ public abstract class BaseCommentServiceImpl extend return childrenList; } + @Override + public List listChildrenBy(Integer targetId, Long commentParentId, 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"); + + // Get comments recursively + + // Get direct children + List directChildren = baseCommentRepository.findAllByPostIdAndParentId(targetId, commentParentId); + + // Create result container + Set children = new HashSet<>(); + + // Get children comments + getChildrenRecursively(directChildren, children); + + // Sort children + List childrenList = new ArrayList<>(children); + childrenList.sort(Comparator.comparing(BaseComment::getId)); + + return childrenList; + } + @Override public T filterIpAddress(@NonNull T comment) { Assert.notNull(comment, "Base comment dto must not be null"); @@ -612,6 +640,32 @@ public abstract class BaseCommentServiceImpl extend children.addAll(topComments); } + /** + * Get children comments recursively. + * + * @param topComments top comment list + * @param children children result must not be null + */ + private void getChildrenRecursively(@Nullable List topComments, @NonNull Set children) { + Assert.notNull(children, "Children comment set must not be null"); + + if (CollectionUtils.isEmpty(topComments)) { + return; + } + + // Convert comment id set + Set commentIds = ServiceUtils.fetchProperty(topComments, COMMENT::getId); + + // Get direct children + List directChildren = baseCommentRepository.findAllByParentIdIn(commentIds); + + // Recursively invoke + getChildrenRecursively(directChildren, children); + + // Add direct children to children result + children.addAll(topComments); + } + /** * Concretes comment tree. *