diff --git a/src/components/MindMapViewer.vue b/src/components/MindMapViewer.vue index 29d17d2..3ad2bab 100644 --- a/src/components/MindMapViewer.vue +++ b/src/components/MindMapViewer.vue @@ -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( diff --git a/src/components/ReviewRecall.vue b/src/components/ReviewRecall.vue index b8490f3..7bf2305 100644 --- a/src/components/ReviewRecall.vue +++ b/src/components/ReviewRecall.vue @@ -223,6 +223,14 @@ const resetRecall = () => { recallTree.value = buildEmptyRecallTree(); }; +// 返回完整标准导图,重新选择复习范围 +const resetComparison = () => { + lastResult.value = null; + hasCompared.value = false; + focusPath.value = ""; + recallTree.value = buildEmptyRecallTree(); +}; + // 编辑标准导图 const startEditStandard = () => { editOutline.value = standard.value?.outline || ""; @@ -438,8 +446,18 @@ onMounted(() => {
-

📖 标准思维导图

+

+ {{ hasCompared ? '📖 标准思维导图(对比结果)' : '📖 标准思维导图' }} +

+ + 返回完整导图 + {{ standardExpanded ? "折叠" : "展开" }}