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:
@@ -99,11 +99,26 @@ const toElixirNode = (node: MindMapTreeNode, ancestors: string[] = []): any => {
|
|||||||
|
|
||||||
const toElixirData = (tree: MindMapTreeNode): MindElixirData => {
|
const toElixirData = (tree: MindMapTreeNode): MindElixirData => {
|
||||||
nodeCounter = 0;
|
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 {
|
return {
|
||||||
nodeData: {
|
nodeData: {
|
||||||
id: "root",
|
id: "root",
|
||||||
topic: tree.title || "思维导图",
|
topic: rootTitle,
|
||||||
children: (tree.children || []).map(c => toElixirNode(c)),
|
// pass root title as ancestor so child paths include it (e.g. "根 / 子节点")
|
||||||
|
children: (tree.children || []).map((c) =>
|
||||||
|
toElixirNode(c, [rootTitle]),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
} as MindElixirData;
|
} as MindElixirData;
|
||||||
};
|
};
|
||||||
@@ -147,18 +162,31 @@ const render = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.bus.addListener("selectNewNode", (node: any) => {
|
// mind-elixir v5: selectNode(el) is called on every node click, but the
|
||||||
if (props.selectable && node?.id) {
|
// selectNewNode event is never fired (it requires selectNode(el, true),
|
||||||
const info = nodePathMap[node.id];
|
// 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) {
|
if (info) {
|
||||||
emit("node-select", info);
|
emit("node-select", info);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node?.sourceType && node?.sourceId != null) {
|
// source navigation → emit node-click with sourceType/sourceId
|
||||||
emit("node-click", { sourceType: String(node.sourceType), sourceId: Number(node.sourceId) });
|
if (nodeData?.sourceType && nodeData?.sourceId != null) {
|
||||||
}
|
emit("node-click", {
|
||||||
|
sourceType: String(nodeData.sourceType),
|
||||||
|
sourceId: Number(nodeData.sourceId),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
|||||||
@@ -223,6 +223,14 @@ const resetRecall = () => {
|
|||||||
recallTree.value = buildEmptyRecallTree();
|
recallTree.value = buildEmptyRecallTree();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 返回完整标准导图,重新选择复习范围
|
||||||
|
const resetComparison = () => {
|
||||||
|
lastResult.value = null;
|
||||||
|
hasCompared.value = false;
|
||||||
|
focusPath.value = "";
|
||||||
|
recallTree.value = buildEmptyRecallTree();
|
||||||
|
};
|
||||||
|
|
||||||
// 编辑标准导图
|
// 编辑标准导图
|
||||||
const startEditStandard = () => {
|
const startEditStandard = () => {
|
||||||
editOutline.value = standard.value?.outline || "";
|
editOutline.value = standard.value?.outline || "";
|
||||||
@@ -438,8 +446,18 @@ onMounted(() => {
|
|||||||
<!-- 标准导图(含对比着色) -->
|
<!-- 标准导图(含对比着色) -->
|
||||||
<article class="surface-card standard-panel">
|
<article class="surface-card standard-panel">
|
||||||
<div class="panel-header">
|
<div class="panel-header">
|
||||||
<h3>📖 标准思维导图</h3>
|
<h3>
|
||||||
|
{{ hasCompared ? '📖 标准思维导图(对比结果)' : '📖 标准思维导图' }}
|
||||||
|
</h3>
|
||||||
<div class="panel-actions">
|
<div class="panel-actions">
|
||||||
|
<el-button
|
||||||
|
v-if="hasCompared"
|
||||||
|
size="small"
|
||||||
|
type="success"
|
||||||
|
@click="resetComparison"
|
||||||
|
>
|
||||||
|
返回完整导图
|
||||||
|
</el-button>
|
||||||
<el-button size="small" @click="standardExpanded = !standardExpanded">
|
<el-button size="small" @click="standardExpanded = !standardExpanded">
|
||||||
{{ standardExpanded ? "折叠" : "展开" }}
|
{{ standardExpanded ? "折叠" : "展开" }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|||||||
Reference in New Issue
Block a user