From d0fd390bd0f017b50f699b3ee480df5221d203b6 Mon Sep 17 00:00:00 2001 From: Script Generator Date: Wed, 17 Jun 2026 11:23:39 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=88=9B=E5=BB=BA=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E5=90=8E=E8=A6=81=E5=88=B7=E6=96=B0=E6=89=8D=E5=87=BA=E7=8E=B0?= =?UTF-8?q?=20+=20=E5=88=B7=E6=96=B0=E5=90=8E=E5=B7=B2=E6=9C=89=E4=BA=A7?= =?UTF-8?q?=E5=93=81=E7=9A=84=E9=A1=B9=E7=9B=AE=E8=A2=AB=E6=B8=85=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因: 1. createProduct try 路径调 fetchOverview,但 fetchOverview 第 103 行 `if (overview.length > 0) return` 直接 early return,导致新产品没被加进 overview,需刷新才能从 localStorage 重读。 2. fetchOverview 在 cached 已有数据时仍会调 api.get 拉远端,远端 mock 返回简化数据(无 projects)覆盖整个 overview,导致已有产品下的项目消失。 修复(mock 模式核心数据完全本地化): - createProduct:直接本地新增 + saveLocal,异步尝试远端但不依赖(不再调 fetchOverview) - fetchOverview:cached 有数据时直接用,不再调远端覆盖;空时才走远端/MOCK 路径 Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/web/stores/useProductStore.ts | 49 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/apps/web/stores/useProductStore.ts b/apps/web/stores/useProductStore.ts index 646fc58..f24757f 100644 --- a/apps/web/stores/useProductStore.ts +++ b/apps/web/stores/useProductStore.ts @@ -102,18 +102,19 @@ export const useProductStore = create((set, get) => ({ fetchOverview: async () => { if (get().overview.length > 0) return; const cached = loadLocal(); - if (cached.length > 0) set({ overview: cached, loading: false }); - else set({ loading: true, error: null }); + if (cached.length > 0) { + // 有本地缓存,直接用,不再调远端覆盖(mock 模式核心数据在本地) + set({ overview: cached, loading: false }); + return; + } + set({ loading: true, error: null }); try { const overview = await api.get('/products/overview'); set({ overview, loading: false }); saveLocal(overview); } catch { - if (cached.length === 0) { - set({ overview: MOCK_OVERVIEW, error: null, loading: false }); - } else { - set({ loading: false }); - } + set({ overview: MOCK_OVERVIEW, error: null, loading: false }); + saveLocal(MOCK_OVERVIEW); } }, @@ -133,24 +134,22 @@ export const useProductStore = create((set, get) => ({ }, createProduct: async (data) => { - try { - await api.post('/products', data); - await get().fetchOverview(); - } catch { - const newProduct: ProductOverview = { - id: `local-${Date.now()}`, - name: data.name || '', - description: data.description || '', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - projects: [], - versions: [], - _count: { requirements: 0, projects: 0, versions: 0 }, - }; - const updated = [newProduct, ...get().overview]; - set({ overview: updated }); - saveLocal(updated); - } + // 直接本地新增(mock 模式核心,保留远端兼容但不依赖) + const newProduct: ProductOverview = { + id: `local-${Date.now()}`, + name: data.name || '', + description: data.description || '', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + projects: [], + versions: [], + _count: { requirements: 0, projects: 0, versions: 0 }, + }; + const updated = [newProduct, ...get().overview]; + set({ overview: updated }); + saveLocal(updated); + // 异步尝试同步远端(失败也无所谓,本地已更新) + try { await api.post('/products', data); } catch {} }, updateProduct: async (id, data) => {