fix: 根治保存必弹磁盘冲突——编辑不再污染乐观锁基准
- editorStore 新增 baseUpdatedAt(磁盘基准版本),仅 loadFlow/syncSavedFlow 更新 - 保存 expectedUpdatedAt 改用 baseUpdatedAt;此前用每次编辑都会拨快的 flow.meta.updatedAt 做比对,导致任何编辑后首次保存必然误判冲突 - 移除 flows:save/get 诊断日志(保留内容一致放行逻辑)
This commit is contained in:
parent
778f69e14d
commit
b40fcbdd35
@ -127,7 +127,9 @@ function registerIpc(): void {
|
||||
for (const flow of createExampleFlows(url)) saveFlow(flow);
|
||||
return listFlows();
|
||||
});
|
||||
ipcMain.handle("flows:get", (_event, id: string) => getFlow(id));
|
||||
ipcMain.handle("flows:get", (_event, id: string) => {
|
||||
return getFlow(id);
|
||||
});
|
||||
ipcMain.handle("flows:save", (_event, flow: FlowDefinition, opts?: FlowSaveOptions): FlowSaveResult => {
|
||||
if (!opts?.force && opts?.expectedUpdatedAt) {
|
||||
let disk: FlowDefinition | null = null;
|
||||
|
||||
@ -65,7 +65,9 @@ export function EditorPage({ catalog, onToast, onBack }: EditorPageProps) {
|
||||
setSaving(true);
|
||||
try {
|
||||
const result = await window.rpa.flows.save(current, {
|
||||
expectedUpdatedAt: current.meta?.updatedAt || undefined
|
||||
// 用「磁盘基准版本」做乐观锁,不能用 current.meta.updatedAt——
|
||||
// 每次本地编辑都会拨快它,会导致每次保存都误判磁盘冲突
|
||||
expectedUpdatedAt: useEditorStore.getState().baseUpdatedAt || undefined
|
||||
});
|
||||
if (result.conflict) {
|
||||
if (opts?.interactive) {
|
||||
|
||||
@ -57,6 +57,10 @@ function uniqueOutputVar(base: string, nodes: FlowNode[]): string {
|
||||
|
||||
interface EditorState {
|
||||
flow: FlowDefinition | null;
|
||||
/** 乐观锁基准:最近一次从磁盘加载/保存成功返回的 meta.updatedAt。
|
||||
* 保存时以此为 expectedUpdatedAt;不能直接用 flow.meta.updatedAt,
|
||||
* 因为 commit() 每次编辑都会拨快它,会导致每次保存都误判磁盘冲突。 */
|
||||
baseUpdatedAt: string | null;
|
||||
catalog: Catalog | null;
|
||||
selectedNodeId: string | null;
|
||||
dirty: boolean;
|
||||
@ -104,6 +108,7 @@ export const useEditorStore = create<EditorState>((set, get) => {
|
||||
|
||||
return {
|
||||
flow: null,
|
||||
baseUpdatedAt: null,
|
||||
catalog: null,
|
||||
selectedNodeId: null,
|
||||
dirty: false,
|
||||
@ -116,7 +121,14 @@ export const useEditorStore = create<EditorState>((set, get) => {
|
||||
// 切换流程时清掉上一次的运行面板状态,避免显示旧流程的运行结果
|
||||
const runState = useRunStore.getState();
|
||||
if (!runState.running) runState.clear();
|
||||
set({ flow, selectedNodeId: null, dirty: false, past: [], future: [] });
|
||||
set({
|
||||
flow,
|
||||
selectedNodeId: null,
|
||||
dirty: false,
|
||||
past: [],
|
||||
future: [],
|
||||
baseUpdatedAt: flow.meta?.updatedAt ?? null
|
||||
});
|
||||
},
|
||||
|
||||
selectNode: (id) => set({ selectedNodeId: id }),
|
||||
@ -340,9 +352,11 @@ export const useEditorStore = create<EditorState>((set, get) => {
|
||||
},
|
||||
|
||||
markSaved: () => set({ dirty: false }),
|
||||
syncSavedFlow: (flow) => set({ flow, dirty: false }),
|
||||
syncSavedFlow: (flow) =>
|
||||
set({ flow, dirty: false, baseUpdatedAt: flow.meta?.updatedAt ?? null }),
|
||||
|
||||
reset: () => set({ flow: null, selectedNodeId: null, dirty: false, past: [], future: [] })
|
||||
reset: () =>
|
||||
set({ flow: null, baseUpdatedAt: null, selectedNodeId: null, dirty: false, past: [], future: [] })
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user