From 312c80ca2a22004e42f8dc9630f670ec4818ff86 Mon Sep 17 00:00:00 2001 From: tianfeng <769204422@qq.com> Date: Thu, 5 Feb 2026 12:16:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=AF=84=E8=AE=BA=E9=87=87?= =?UTF-8?q?=E7=94=A8=E9=80=92=E5=BD=92=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../delete/DynamicCommentDelCmdExe.java | 64 +++++++++++++++++-- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/dynamic/delete/DynamicCommentDelCmdExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/dynamic/delete/DynamicCommentDelCmdExe.java index da13325f..d3ef7485 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/dynamic/delete/DynamicCommentDelCmdExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/dynamic/delete/DynamicCommentDelCmdExe.java @@ -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 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 collectCommentTreeSafe(Long commentId) { + Set allIds = new HashSet<>(); + Queue 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 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());