fix: 设定集编辑文字回退(乐观更新+embedding防抖)

This commit is contained in:
YuanShiJiLoong committed 2026-03-01 22:20:34 +09:00
1 parent 171bf4704f
commit 35bab53251
2 files changed
+31 -8

No files matched your search

+4 -2
View File
@@ -534,9 +534,11 @@ export default function SettingsPanel() {
setNodes(prev => prev.map(n => n.id === id ? { ...n, enabled: newEnabled } : n));
};
const handleUpdateNode = async (id, updates) => {
await updateSettingsNode(id, updates);
const handleUpdateNode = (id, updates) => {
// 乐观更新:立即同步 React 状态,防止异步操作(如 embedding API)导致文字回退
setNodes(prev => prev.map(n => n.id === id ? { ...n, ...updates, updatedAt: new Date().toISOString() } : n));
// 后台持久化(不 await,避免阻塞 UI)
updateSettingsNode(id, updates);
};
const selectedNode = visibleNodes.find(n => n.id === selectedNodeId);
+27 -6
View File
@@ -503,6 +503,9 @@ export async function addSettingsNode({ name, type, category, parentId, icon, co
}
// 更新节点 (Async)
// Embedding 防抖定时器 — 避免每次编辑都触发 embedding API 调用
const _embeddingTimers = {};
export async function updateSettingsNode(id, updates) {
const nodes = await getSettingsNodes();
const idx = nodes.findIndex(n => n.id === id);
@@ -516,17 +519,35 @@ export async function updateSettingsNode(id, updates) {
delete updates.parentId;
}
// 如果名称或内容发生改变,且是条目,且开启了嵌入功能,重新计算 embedding
// 先立即保存内容(不等 embedding),确保数据不丢失
nodes[idx] = { ...nodes[idx], ...updates, updatedAt: new Date().toISOString() };
await saveSettingsNodes(nodes);
// 如果名称或内容发生改变,且是条目,且开启了嵌入功能,延迟计算 embedding
// 使用 3 秒防抖,避免输入过程中频繁调用 embedding API
const nodeType = updates.type || nodes[idx].type;
const { apiConfig } = getProjectSettings();
if (nodeType === 'item' && apiConfig.useCustomEmbed && (updates.name !== undefined || updates.content !== undefined)) {
const tempNode = { ...nodes[idx], ...updates };
const textToEmbed = extractTextForEmbedding(tempNode);
updates.embedding = await getEmbedding(textToEmbed, apiConfig);
clearTimeout(_embeddingTimers[id]);
_embeddingTimers[id] = setTimeout(async () => {
try {
delete _embeddingTimers[id];
// 重新读取最新节点数据来计算 embedding
const freshNodes = await getSettingsNodes();
const freshIdx = freshNodes.findIndex(n => n.id === id);
if (freshIdx === -1) return;
const textToEmbed = extractTextForEmbedding(freshNodes[freshIdx]);
const embedding = await getEmbedding(textToEmbed, apiConfig);
if (embedding) {
freshNodes[freshIdx] = { ...freshNodes[freshIdx], embedding };
await saveSettingsNodes(freshNodes);
}
} catch (e) {
console.warn('[Settings] Deferred embedding failed for node', id, e);
}
}, 3000);
}
nodes[idx] = { ...nodes[idx], ...updates, updatedAt: new Date().toISOString() };
await saveSettingsNodes(nodes);
return nodes[idx];
}