refactor: move graph import flow into ui actions controller

This commit is contained in:
Youzini-afk
2026-03-29 17:18:42 +08:00
parent 18897dc6bf
commit 6695f68f11
2 changed files with 108 additions and 76 deletions

View File

@@ -79,6 +79,7 @@ import {
onFetchEmbeddingModelsController, onFetchEmbeddingModelsController,
onFetchMemoryLLMModelsController, onFetchMemoryLLMModelsController,
onExportGraphController, onExportGraphController,
onImportGraphController,
onManualCompressController, onManualCompressController,
onRebuildController, onRebuildController,
onTestEmbeddingController, onTestEmbeddingController,
@@ -4545,82 +4546,28 @@ async function onExportGraph() {
} }
async function onImportGraph() { async function onImportGraph() {
if (!ensureGraphMutationReady("导入图谱")) { return await onImportGraphController({
return { cancelled: true }; clearInjectionState,
} clearTimeout,
const input = document.createElement("input"); document,
input.type = "file"; ensureGraphMutationReady,
input.accept = ".json"; getCurrentChatId,
return await new Promise((resolve, reject) => { importGraph,
let settled = false; markVectorStateDirty,
let focusTimer = null; normalizeGraphRuntimeState,
saveGraphToChat,
const cleanup = () => { setCurrentGraph: (graph) => {
if (focusTimer) { currentGraph = graph;
clearTimeout(focusTimer); },
focusTimer = null; setExtractionCount: (value) => {
} extractionCount = value;
input.onchange = null; },
window.removeEventListener("focus", onWindowFocus, true); setLastExtractedItems: (items) => {
}; lastExtractedItems = items;
},
const finish = (value, isError = false) => { toastr,
if (settled) return; updateLastRecalledItems,
settled = true; window,
cleanup();
if (isError) {
reject(value);
} else {
resolve(value);
}
};
const onWindowFocus = () => {
focusTimer = setTimeout(() => {
if (!settled) {
finish({ cancelled: true });
}
}, 180);
};
window.addEventListener("focus", onWindowFocus, true);
input.addEventListener(
"cancel",
() => {
finish({ cancelled: true });
},
{ once: true },
);
input.onchange = async (e) => {
const file = e.target.files?.[0];
if (!file) {
finish({ cancelled: true });
return;
}
try {
const text = await file.text();
currentGraph = normalizeGraphRuntimeState(
importGraph(text),
getCurrentChatId(),
);
markVectorStateDirty("导入图谱后需要重建向量索引");
extractionCount = 0;
lastExtractedItems = [];
updateLastRecalledItems(currentGraph.lastRecallResult || []);
clearInjectionState();
saveGraphToChat({ reason: "graph-import-complete" });
toastr.success("图谱已导入");
finish({ imported: true, handledToast: true });
} catch (err) {
const error =
err instanceof Error ? err : new Error(String(err || "导入失败"));
toastr.error(`导入失败: ${error.message}`);
error._stBmeToastHandled = true;
finish(error, true);
}
};
input.click();
}); });
} }

View File

@@ -245,3 +245,88 @@ export async function onRebuildController(runtime) {
runtime.refreshPanelLiveState(); runtime.refreshPanelLiveState();
} }
} }
export async function onImportGraphController(runtime) {
if (!runtime.ensureGraphMutationReady("导入图谱")) {
return { cancelled: true };
}
const input = runtime.document.createElement("input");
input.type = "file";
input.accept = ".json";
return await new Promise((resolve, reject) => {
let settled = false;
let focusTimer = null;
const cleanup = () => {
if (focusTimer) {
runtime.clearTimeout(focusTimer);
focusTimer = null;
}
input.onchange = null;
runtime.window.removeEventListener("focus", onWindowFocus, true);
};
const finish = (value, isError = false) => {
if (settled) return;
settled = true;
cleanup();
if (isError) {
reject(value);
} else {
resolve(value);
}
};
const onWindowFocus = () => {
focusTimer = setTimeout(() => {
if (!settled) {
finish({ cancelled: true });
}
}, 180);
};
runtime.window.addEventListener("focus", onWindowFocus, true);
input.addEventListener(
"cancel",
() => {
finish({ cancelled: true });
},
{ once: true },
);
input.onchange = async (event) => {
const file = event.target.files?.[0];
if (!file) {
finish({ cancelled: true });
return;
}
try {
const text = await file.text();
const importedGraph = runtime.normalizeGraphRuntimeState(
runtime.importGraph(text),
runtime.getCurrentChatId(),
);
runtime.setCurrentGraph(importedGraph);
runtime.markVectorStateDirty("导入图谱后需要重建向量索引");
runtime.setExtractionCount(0);
runtime.setLastExtractedItems([]);
runtime.updateLastRecalledItems(importedGraph.lastRecallResult || []);
runtime.clearInjectionState();
runtime.saveGraphToChat({ reason: "graph-import-complete" });
runtime.toastr.success("图谱已导入");
finish({ imported: true, handledToast: true });
} catch (err) {
const error =
err instanceof Error ? err : new Error(String(err || "导入失败"));
runtime.toastr.error(`导入失败: ${error.message}`);
error._stBmeToastHandled = true;
finish(error, true);
}
};
input.click();
});
}