feat(导图): 防并发生成 + 增量合并 + mergeTrees 工具
- MindMapTreeTool.mergeTrees() 按标准化标题合并新旧树节点 - StandardMindServiceImpl 防并发生成(ConcurrentHashMap 锁) - incrementalGenerate() 保留用户编辑节点 + 追加新节点 - regenerate 端点接受 mode 参数(full/incremental)
This commit is contained in:
@@ -211,6 +211,70 @@ public class MindMapTreeTool {
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并新旧树:保留旧树中已有节点(用户编辑),追加新树中的新节点。
|
||||
* 按标准化标题匹配同级节点,旧树匹配到的节点优先保留。
|
||||
*
|
||||
* @param oldRoot 旧树根(用户可能编辑过)
|
||||
* @param newRoot 新树根(AI/BUILTIN 最新生成)
|
||||
* @return 合并后的树
|
||||
*/
|
||||
public static MindMapNode mergeTrees(MindMapNode oldRoot, MindMapNode newRoot) {
|
||||
if (oldRoot == null) return newRoot;
|
||||
if (newRoot == null) return oldRoot;
|
||||
MindMapNode result = copyNodeShallow(oldRoot);
|
||||
result.setChildren(mergeChildren(oldRoot.getChildren(), newRoot.getChildren()));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** 递归合并子节点列表 */
|
||||
private static List<MindMapNode> mergeChildren(List<MindMapNode> oldChildren, List<MindMapNode> newChildren) {
|
||||
Map<String, MindMapNode> oldByNormalized = new LinkedHashMap<>();
|
||||
if (oldChildren != null) {
|
||||
for (MindMapNode child : oldChildren) {
|
||||
oldByNormalized.put(normalizeForMerge(child.getTitle()), child);
|
||||
}
|
||||
}
|
||||
|
||||
List<MindMapNode> merged = new ArrayList<>();
|
||||
Set<String> usedKeys = new HashSet<>();
|
||||
|
||||
if (newChildren != null) {
|
||||
for (MindMapNode newNode : newChildren) {
|
||||
String key = normalizeForMerge(newNode.getTitle());
|
||||
MindMapNode oldNode = oldByNormalized.get(key);
|
||||
if (oldNode != null) {
|
||||
// 旧节点存在:保留旧节点标题,递归合并子节点
|
||||
MindMapNode kept = copyNodeShallow(oldNode);
|
||||
kept.setChildren(mergeChildren(oldNode.getChildren(), newNode.getChildren()));
|
||||
merged.add(kept);
|
||||
usedKeys.add(key);
|
||||
} else {
|
||||
// 新节点:直接添加
|
||||
merged.add(newNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加旧树中有但新树中没有的节点(用户添加的额外节点)
|
||||
if (oldChildren != null) {
|
||||
for (MindMapNode oldNode : oldChildren) {
|
||||
if (!usedKeys.contains(normalizeForMerge(oldNode.getTitle()))) {
|
||||
merged.add(oldNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
private static String normalizeForMerge(String s) {
|
||||
if (s == null) return "";
|
||||
return s.replaceAll("[\\s 、,。!?:;()\\[\\]{},.!?:;()\\-—/\\\\|]", "")
|
||||
.toLowerCase(Locale.ROOT)
|
||||
.trim();
|
||||
}
|
||||
|
||||
/** 序列化整棵树为 JSON */
|
||||
public static String toJson(MindMapNode root, ObjectMapper mapper) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user