From 6b963fd918a24c523dcda82e0f91b3a8cc53cb53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=91=A3=E5=AE=8F=E5=87=AF?= Date: Sun, 21 Jun 2026 20:21:49 +0800 Subject: [PATCH] =?UTF-8?q?fix(roundtable):=20=E4=BF=AE=E5=A4=8D=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=91=98=E8=BF=9E=E7=BB=AD=E7=BC=96=E8=BE=91=E7=AC=AC?= =?UTF-8?q?=E4=BA=8C=E6=9D=A1=E4=BB=96=E4=BA=BA=E4=B8=9A=E5=8A=A1=E9=93=BE?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=20404=E3=80=8C=E5=B7=B2=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 编辑器 chainId 闸门由「整组件生命周期只加载一次」改为「按已应用的 chainId 追踪、变化即重载」。 此编辑器实例在多次导航间可能不卸载(从业务链弹窗进来时尤甚),旧闸门导致第二次打开另一条链条 时根本不加载,currentChainId 停在上一条 → 保存打到错误 id → 后端 404,必须重新登录才恢复。 同一 chainId 不重复加载、也不覆盖编辑器内的手动切换;getChain 取不到时给出明确提示。 Co-Authored-By: Claude Opus 4.8 (1M context) --- .../pages/BusinessChainEditorPage.tsx | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/frontend-web/src/roundtable-planning/pages/BusinessChainEditorPage.tsx b/frontend-web/src/roundtable-planning/pages/BusinessChainEditorPage.tsx index 737f4586..fabac967 100644 --- a/frontend-web/src/roundtable-planning/pages/BusinessChainEditorPage.tsx +++ b/frontend-web/src/roundtable-planning/pages/BusinessChainEditorPage.tsx @@ -327,17 +327,21 @@ export default function BusinessChainEditorPage() { setStep(1); }, []); - // ─── URL 参数 chainId:从「业务链条」弹窗点「设置」进来时自动切到该链条 ────── - // 只在链条列表加载完后应用一次(用 ref 闸门避免覆盖用户后续的手动切换)。 - const appliedChainParamRef = useRef(false); + // ─── URL 参数 chainId:从「业务链条」弹窗 / 列表点「设置」进来时自动切到该链条 ────── + // 按「已应用的 chainId」做闸门(而非「只应用一次」):当 URL 的 chainId 变化时重新加载。 + // 关键修复:此编辑器实例在多次导航间可能不卸载(从弹窗进来时尤甚),用「只应用一次」的 + // 旧闸门会导致第二次打开另一条链条时根本不加载,currentChainId 停在上一条 → 保存打到错误 + // 的 id → 后端 404「已删除」,必须重新登录(整页刷新重建组件)才恢复。改为追踪已应用的 id + // 后,chainId 变了就重载;同一 chainId 不重复加载,也不覆盖用户在编辑器内的手动切换。 + const appliedChainIdRef = useRef(null); useEffect(() => { - if (appliedChainParamRef.current) return; const chainId = searchParams.get("chainId"); if (!chainId) return; - appliedChainParamRef.current = true; // 只应用一次,之后不覆盖用户手动切换 + if (appliedChainIdRef.current === chainId) return; // 这条已加载过,别覆盖用户后续操作 + appliedChainIdRef.current = chainId; // 优先用「我的链条」列表里已拉到的对象(省一次请求);不在列表里(管理员从「全部链条」 // 点设置 / 公共链条 / 自己没有任何链条)则直接按 id 拉取。后端对管理员放开任意链条、 - // 对所有人放开已发布公共链条;拉不到则静默保持空白新建态。 + // 对所有人放开已发布公共链条;拉不到给出提示并保持空白新建态。 const local = chains.find((c) => c.id === chainId); if (local) { loadChain(local); @@ -347,6 +351,7 @@ export default function BusinessChainEditorPage() { try { const chain = await getChain(chainId); if (chain) loadChain(chain); + else toast.error("该业务链条不存在或无权访问"); } catch { // 静默:取不到就保持当前(空白)状态。 }