fix: 修复节点点击无响应 + 支持对比后返回完整导图重新选择复习范围

- MindMapViewer: mind-elixir v5 的 selectNode(el) 不传第二参数导致 selectNewNode 永不触发,改为 monkey-patch selectNode 捕获节点点击
- MindMapViewer: 根节点加入 nodePathMap,子节点路径补全根标题前缀
- ReviewRecall: 新增 resetComparison(),对比完成后可点击「返回完整导图」清空结果,重新选择节点开始新一轮复习

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
cat-win
2026-07-08 22:43:13 +08:00
co-authored by Claude Fable 5
parent e66bdb79dc
commit 1ea15db504
2 changed files with 55 additions and 9 deletions
+36 -8
View File
@@ -99,11 +99,26 @@ const toElixirNode = (node: MindMapTreeNode, ancestors: string[] = []): any => {
const toElixirData = (tree: MindMapTreeNode): MindElixirData => {
nodeCounter = 0;
const rootTitle = tree.title || "思维导图";
// register root node in path map so clicking it also works
if (props.selectable) {
nodePathMap["root"] = {
title: rootTitle,
path: rootTitle,
childCount: (tree.children || []).reduce(
(sum, c) => sum + 1 + countAllDescendants(c),
0,
),
};
}
return {
nodeData: {
id: "root",
topic: tree.title || "思维导图",
children: (tree.children || []).map(c => toElixirNode(c)),
topic: rootTitle,
// pass root title as ancestor so child paths include it (e.g. "根 / 子节点")
children: (tree.children || []).map((c) =>
toElixirNode(c, [rootTitle]),
),
},
} as MindElixirData;
};
@@ -147,18 +162,31 @@ const render = () => {
});
}
instance.bus.addListener("selectNewNode", (node: any) => {
if (props.selectable && node?.id) {
const info = nodePathMap[node.id];
// mind-elixir v5: selectNode(el) is called on every node click, but the
// selectNewNode event is never fired (it requires selectNode(el, true),
// which the default click handler never passes). Monkey-patch selectNode
// to hook into node clicks for both selectable and source-navigation modes.
const origSelectNode = instance.selectNode.bind(instance);
instance.selectNode = function (el: any, fireEvent?: boolean) {
origSelectNode(el, fireEvent);
if (!el?.nodeObj) return;
const nodeData = el.nodeObj;
// selectable mode → emit node-select with title/path/childCount
if (props.selectable && nodeData?.id) {
const info = nodePathMap[nodeData.id];
if (info) {
emit("node-select", info);
return;
}
}
if (node?.sourceType && node?.sourceId != null) {
emit("node-click", { sourceType: String(node.sourceType), sourceId: Number(node.sourceId) });
// source navigation → emit node-click with sourceType/sourceId
if (nodeData?.sourceType && nodeData?.sourceId != null) {
emit("node-click", {
sourceType: String(nodeData.sourceType),
sourceId: Number(nodeData.sourceId),
});
}
});
};
};
watch(