From 90f651ddfe9072483808c3d46c934727a2c63fde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Mon, 5 Oct 2026 17:26:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=B7=E6=96=B0=E6=97=B6=E5=85=88=E6=92=A4?= =?UTF-8?q?=E6=8E=89=E5=BE=85=E8=A7=A6=E5=8F=91=E7=9A=84=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=EF=BC=8C=E9=81=BF=E5=85=8D=E6=97=A7=E5=80=BC?= =?UTF-8?q?=E8=A2=AB=E5=86=99=E5=9B=9E=E6=B3=A8=E5=86=8C=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - load() 在读盘前就把 dirty 归零:原来要等读回来的那一刻才归零,若这次读得比停止输入的 600ms 还慢,等待中的自动保存会先到点,把用户手里那份旧值写回注册表,随后刷新又用读到的内容盖掉界面,两边都不一致。 - 新增一例回归用例:第二次读(点刷新那次)故意慢 1200ms,越过自动保存的延时后断言没有发出 save_xhs_minitool_export_form,且界面回到磁盘上的值。已验证去掉修复后这例失败。 --- .../export/state/useXhsMinitoolExport.ts | 3 +- .../tests/xhsMinitoolExport.test.tsx | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/apps/ai-game-creator-shell/src/view/project-development/export/state/useXhsMinitoolExport.ts b/apps/ai-game-creator-shell/src/view/project-development/export/state/useXhsMinitoolExport.ts index 53169172e..b2808f513 100644 --- a/apps/ai-game-creator-shell/src/view/project-development/export/state/useXhsMinitoolExport.ts +++ b/apps/ai-game-creator-shell/src/view/project-development/export/state/useXhsMinitoolExport.ts @@ -84,6 +84,8 @@ export function useXhsMinitoolExport({ return; } setLoading(true); + // 刷新以磁盘为准:先撤掉还在等待触发的自动保存,否则读盘期间那一次保存会把旧值写回去。 + setDirty(false); try { const state = await readXhsMinitoolExport(invoke, projectPath); setForm(state.form); @@ -92,7 +94,6 @@ export function useXhsMinitoolExport({ setFieldError(null); setConflict(null); setFailure(null); - setDirty(false); } catch (error) { const structured = asXhsMinitoolFailure(error); if (structured) setFailure(failureState(structured)); diff --git a/apps/ai-game-creator-shell/tests/xhsMinitoolExport.test.tsx b/apps/ai-game-creator-shell/tests/xhsMinitoolExport.test.tsx index ca8922891..4c7877430 100644 --- a/apps/ai-game-creator-shell/tests/xhsMinitoolExport.test.tsx +++ b/apps/ai-game-creator-shell/tests/xhsMinitoolExport.test.tsx @@ -276,6 +276,43 @@ describe('状态 hook', () => { ); }); + it('刷新期间不再把待保存的旧值写回去', async () => { + let reads = 0; + const invoke = vi.fn(async (command: string) => { + if (command !== 'read_xhs_minitool_export') return {}; + reads += 1; + // 第二次读(点刷新那次)故意慢:让停止输入后的自动保存在读盘期间到点。 + if (reads > 1) { + await new Promise((resolve) => setTimeout(resolve, 1200)); + } + return { form: FORM, hasScript: true, contentHash: CONTENT_HASH }; + }); + installTauriRuntime({ core: { invoke } }); + const { result } = renderHook(() => + useXhsMinitoolExport({ + enabled: true, + projectPath: PROJECT_PATH, + submitTurn: vi.fn(async () => true), + }), + ); + await waitFor(() => expect(result.current.form).toEqual(FORM)); + + await act(async () => { + result.current.updateField('name', '新名字'); + void result.current.load(); + }); + // 越过自动保存的 600ms:刷新以磁盘为准,这份还没保存的输入不该再落盘。 + await act(async () => { + await new Promise((resolve) => setTimeout(resolve, 1500)); + }); + + expect(invoke).not.toHaveBeenCalledWith( + 'save_xhs_minitool_export_form', + expect.anything(), + ); + expect(result.current.form).toEqual(FORM); + }); + it('导出把打包脚本的输出尾部一并报给用户', async () => { const invoke = vi.fn(async (command: string) => { if (command === 'read_xhs_minitool_export') {