删除评论采用递归删除

This commit is contained in:
tianfeng 2026-02-05 12:16:31 +08:00
parent c2be8d1e43
commit 312c80ca2a

View File

@ -7,6 +7,7 @@ import com.red.circle.other.app.enums.violation.ViolationTypeEnum;
import com.red.circle.other.infra.database.cache.service.other.DynamicCacheService;
import com.red.circle.other.infra.database.mongo.service.dynamic.DynamicPopularService;
import com.red.circle.other.infra.database.rds.entity.dynamic.DynamicComment;
import com.red.circle.other.infra.database.rds.entity.dynamic.DynamicCommentLike;
import com.red.circle.other.infra.database.rds.entity.dynamic.DynamicContent;
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicCommentLikeService;
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicCommentService;
@ -15,8 +16,11 @@ import com.red.circle.other.infra.database.rds.service.sys.AdministratorAuthServ
import com.red.circle.other.infra.database.rds.service.sys.AdministratorService;
import com.red.circle.other.inner.asserts.DynamicErrorCode;
import com.red.circle.tool.core.num.NumUtils;
import java.util.Objects;
import java.util.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
@ -29,6 +33,7 @@ import org.springframework.stereotype.Component;
*/
@Component
@RequiredArgsConstructor
@Slf4j
public class DynamicCommentDelCmdExe {
private final DynamicCacheService dynamicCacheService;
@ -95,15 +100,66 @@ public class DynamicCommentDelCmdExe {
private Long deleteComment(AppIdLongCmd cmd, DynamicComment comment) {
dynamicCommentService.deleteById(cmd.getId());
dynamicCommentService.deleteByReplyCommentId(cmd.getId());
// 收集所有需要删除的评论id包括子孙评论
Set<Long> idsToDelete = collectCommentTreeSafe(cmd.getId());
// 批量删除评论
if (!idsToDelete.isEmpty()) {
dynamicCommentService.delete()
.in(DynamicComment::getId, idsToDelete)
.execute();
// 批量删除点赞记录
dynamicCommentLikeService.delete()
.in(DynamicCommentLike::getDynamicCommentId, idsToDelete)
.execute();
}
// 重新统计评论数
Integer dynamicCommentCount = dynamicCommentService
.getNumberByDynamicId(comment.getDynamicContentId());
.getNumberByDynamicId(comment.getDynamicContentId());
return dynamicCacheService.initCommentQuantity(comment.getDynamicContentId(), dynamicCommentCount).longValue();
}
/**
* 安全收集评论树广度优先 + 防环检测
*/
private Set<Long> collectCommentTreeSafe(Long commentId) {
Set<Long> allIds = new HashSet<>();
Queue<Long> queue = new LinkedList<>();
queue.offer(commentId);
int safetyCounter = 0;
final int MAX_NODES = 10000; // 防止无限循环
while (!queue.isEmpty() && safetyCounter++ < MAX_NODES) {
Long currentId = queue.poll();
// 防止重复处理
if (allIds.contains(currentId)) {
continue;
}
allIds.add(currentId);
// 查找所有直接回复
List<DynamicComment> replies = dynamicCommentService.query()
.eq(DynamicComment::getReplyCommentId, currentId)
.select(DynamicComment::getId)
.list();
replies.forEach(r -> queue.offer(r.getId()));
}
if (safetyCounter >= MAX_NODES) {
log.error("评论树节点数超过限制可能存在循环引用rootId={}, collected={}",
commentId, allIds.size());
}
return allIds;
}
private Long getCommentLikeQuantity(DynamicComment comment) {
return dynamicCacheService
.getCommentLikeQuantity(comment.getDynamicContentId(), comment.getId());