feat(导图): 防并发生成 + 增量合并 + mergeTrees 工具
- MindMapTreeTool.mergeTrees() 按标准化标题合并新旧树节点 - StandardMindServiceImpl 防并发生成(ConcurrentHashMap 锁) - incrementalGenerate() 保留用户编辑节点 + 追加新节点 - regenerate 端点接受 mode 参数(full/incremental)
This commit is contained in:
+57
-1
@@ -20,6 +20,8 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -44,9 +46,13 @@ public class StandardMindMapServiceImpl implements StandardMindMapService {
|
||||
|
||||
private static final String GENERATOR_BUILTIN = "BUILTIN";
|
||||
private static final String GENERATOR_USER = "USER";
|
||||
private static final String GENERATOR_USER_MERGE = "USER_MERGE";
|
||||
private static final String MATCH_STATUS_MATCHED = "MATCHED";
|
||||
private static final String MATCH_STATUS_MISSED = "MISSED";
|
||||
|
||||
/** 防并发生成:taskNum → 是否正在生成中 */
|
||||
private final ConcurrentHashMap<String, AtomicBoolean> generatingTasks = new ConcurrentHashMap<>();
|
||||
|
||||
// ============ 查询与生成 ============
|
||||
|
||||
@Override
|
||||
@@ -59,7 +65,57 @@ public class StandardMindMapServiceImpl implements StandardMindMapService {
|
||||
@Override
|
||||
public ReviewStandardMindMapEntity regenerate(String taskNum) throws NotFindEntitiesException, OperationFailedException {
|
||||
ensureTaskExists(taskNum);
|
||||
return doGenerate(taskNum);
|
||||
// 防并发生成:同一任务正在生成时直接返回当前实体
|
||||
AtomicBoolean lock = generatingTasks.computeIfAbsent(taskNum, k -> new AtomicBoolean(false));
|
||||
if (!lock.compareAndSet(false, true)) {
|
||||
ReviewStandardMindMapEntity existing = queryByTaskNum(taskNum);
|
||||
log.warn("任务[{}]正在生成中,跳过重复请求", taskNum);
|
||||
return existing;
|
||||
}
|
||||
try {
|
||||
return doGenerate(taskNum);
|
||||
} finally {
|
||||
lock.set(false);
|
||||
generatingTasks.remove(taskNum);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ReviewStandardMindMapEntity incrementalGenerate(String taskNum) throws NotFindEntitiesException, OperationFailedException {
|
||||
ensureTaskExists(taskNum);
|
||||
ReviewStandardMindMapEntity existing = queryByTaskNum(taskNum);
|
||||
if (existing == null) {
|
||||
throw new NotFindEntitiesException("标准思维导图尚不存在,无法增量更新");
|
||||
}
|
||||
// 防并发生成
|
||||
AtomicBoolean lock = generatingTasks.computeIfAbsent(taskNum, k -> new AtomicBoolean(false));
|
||||
if (!lock.compareAndSet(false, true)) {
|
||||
log.warn("任务[{}]正在生成中,跳过重复增量请求", taskNum);
|
||||
return existing;
|
||||
}
|
||||
try {
|
||||
ReviewStandardMindMapEntity fresh = doGenerate(taskNum);
|
||||
// 合并新旧树:保留用户编辑过的节点,追加新节点
|
||||
MindMapNode oldRoot = MindMapTreeTool.fromJson(existing.getContent(), objectMapper);
|
||||
MindMapNode newRoot = MindMapTreeTool.fromJson(fresh.getContent(), objectMapper);
|
||||
MindMapNode merged = MindMapTreeTool.mergeTrees(oldRoot, newRoot);
|
||||
String mergedJson = MindMapTreeTool.toJson(merged, objectMapper);
|
||||
String mergedOutline = MindMapTreeTool.toFullOutline(merged);
|
||||
|
||||
existing.setContent(mergedJson);
|
||||
existing.setOutline(mergedOutline);
|
||||
existing.setTitle(merged.getTitle() != null ? merged.getTitle() : "思维导图");
|
||||
existing.setGenerator(GENERATOR_USER_MERGE);
|
||||
existing.setGeneratorVersion(fresh.getGeneratorVersion());
|
||||
existing.setSummary("增量更新,共 " + MindMapTreeTool.countNodes(merged) + " 个节点");
|
||||
existing.setGeneratedTime(LocalDateTime.now());
|
||||
standardMindMapMapper.updateById(existing);
|
||||
return existing;
|
||||
} finally {
|
||||
lock.set(false);
|
||||
generatingTasks.remove(taskNum);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user