fix: 设定集编辑文字回退(乐观更新+embedding防抖)
This commit is contained in:
1 parent
171bf4704f
commit
35bab53251
2 files changed
+31
-8
No files matched your search
@@ -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
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user