From 1df1fc7922a4b97d4fbc1a4c862b86749349e7d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=85=E5=BF=B5?= Date: Wed, 14 Oct 2026 21:40:29 +0800 Subject: [PATCH] =?UTF-8?q?fix(admin):=20=E9=87=8D=E5=BB=BA=20watch=20?= =?UTF-8?q?=E8=A1=A5=20slug=20=E6=BA=90=EF=BC=88=E9=98=B2=E7=BC=BA?= =?UTF-8?q?=E7=BB=84=E7=A7=9F=E6=88=B7=E5=88=87=E6=8D=A2=E8=8D=89=E7=A8=BF?= =?UTF-8?q?=E6=B3=84=E6=BC=8F=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit c6bd542 拆分后的分组 watch 只盯组 props 引用——seed 租户快照可能缺组 (如无 ai/contact/misc 组),两家租户都缺时切租户该组 prop 走 undefined→undefined 引用不变、watch 不触发,上一家租户的草稿留在当前 租户界面(dirty 也残留)。旧的全量耦合顺带防住了它,拆分后暴露。 修复:六个 pane 的重建 watch 源统一加 () => props.slug 兜底——slug 变化 即强制重建(缺组时空槽归位、dirty 归 false);单卡保存路径不受影响 (组引用照常换新触发)。覆盖 CredsPane 三卡 + WallPane / PromptsPane / ContactFormPane / EngineFormPane / MiscFormPane(均已声明 slug prop, index.vue 挂载处均已传 activeSlug,零接线改动)。 顺手:CredsPane 测试态注释仍提已删除的 resetAll → 改提三卡 watch; 计划文档 Task 15 段落末补 Batch 1 遗留打磨项处置注记(色列宽度/头像 提示样式经 Task 16 走查目检后定夺)。 Co-Authored-By: Claude Code --- .../views/config/center/ContactFormPane.vue | 4 ++-- admin/src/views/config/center/CredsPane.vue | 24 +++++++++++++++---- .../views/config/center/EngineFormPane.vue | 4 ++-- .../src/views/config/center/MiscFormPane.vue | 4 ++-- admin/src/views/config/center/PromptsPane.vue | 4 ++-- admin/src/views/config/center/WallPane.vue | 4 ++-- .../2026-10-14-config-center-ux-visual.md | 2 ++ 7 files changed, 31 insertions(+), 15 deletions(-) diff --git a/admin/src/views/config/center/ContactFormPane.vue b/admin/src/views/config/center/ContactFormPane.vue index 4f9a228..2ee020d 100644 --- a/admin/src/views/config/center/ContactFormPane.vue +++ b/admin/src/views/config/center/ContactFormPane.vue @@ -114,8 +114,8 @@ const baseline = ref(JSON.stringify(contactToForm(undefined))) watch( - () => props.group, - (group) => { + [() => props.slug, () => props.group], + ([, group]) => { const next = contactToForm(group) Object.assign(form, next) baseline.value = JSON.stringify(next) diff --git a/admin/src/views/config/center/CredsPane.vue b/admin/src/views/config/center/CredsPane.vue index 31deb99..84cb7a0 100644 --- a/admin/src/views/config/center/CredsPane.vue +++ b/admin/src/views/config/center/CredsPane.vue @@ -442,7 +442,7 @@ const pushBaseline = ref(JSON.stringify(normalizePushCredsGroup(undefined).form)) const aiBaseline = ref(JSON.stringify(normalizeAiCredsGroup(undefined).form)) - // 测试态(声明先于下方 immediate watch 的 resetAll——避免 TDZ 引用) + // 测试态(声明先于下方 immediate 的三卡 watch——避免 TDZ 引用) const emailTestTo = ref('') const emailTesting = ref(false) const emailTestResult = ref<{ @@ -494,10 +494,24 @@ // 分组 watch(替代旧 array-source 全量 resetAll):父层 onPaneSaved 对快照做 // {...snapshot, [group]: config} 展开——只有被保存组引用换新,兄弟组引用不动 // → 只重建该卡;切租户/回滚时快照先置 null 再整份换新,三组引用齐变 → 三卡 - // 全量重置(保持既有行为) - watch(() => props.emailGroup, resetEmailCard, { immediate: true }) - watch(() => props.pushGroup, resetPushCard, { immediate: true }) - watch(() => props.aiGroup, resetAiCard, { immediate: true }) + // 全量重置(保持既有行为)。watch 源额外带 slug:seed 租户快照可能缺组(如 + // 无 ai 组),两家都缺时组 prop undefined→undefined 引用不变、watch 不触发, + // 上一家租户的草稿会留在当前租户界面——slug 变化兜底强制三卡重建 + watch( + [() => props.slug, () => props.emailGroup], + ([, group]) => resetEmailCard(group), + { immediate: true } + ) + watch( + [() => props.slug, () => props.pushGroup], + ([, group]) => resetPushCard(group), + { immediate: true } + ) + watch( + [() => props.slug, () => props.aiGroup], + ([, group]) => resetAiCard(group), + { immediate: true } + ) /** 未保存判定:三表单任一偏离基线,或密钥三态(输入非空 = 覆盖新值 / * cleared = 显式清除)——密钥输入框基线恒空串,只能独立判定 */ diff --git a/admin/src/views/config/center/EngineFormPane.vue b/admin/src/views/config/center/EngineFormPane.vue index 274a10a..01b67c0 100644 --- a/admin/src/views/config/center/EngineFormPane.vue +++ b/admin/src/views/config/center/EngineFormPane.vue @@ -133,8 +133,8 @@ const baseline = ref(JSON.stringify(engineToForm(undefined))) watch( - () => props.group, - (group) => { + [() => props.slug, () => props.group], + ([, group]) => { const next = engineToForm(group) Object.assign(form, next) baseline.value = JSON.stringify(next) diff --git a/admin/src/views/config/center/MiscFormPane.vue b/admin/src/views/config/center/MiscFormPane.vue index 57f5943..6505636 100644 --- a/admin/src/views/config/center/MiscFormPane.vue +++ b/admin/src/views/config/center/MiscFormPane.vue @@ -103,8 +103,8 @@ const baseline = ref(JSON.stringify(miscToForm(undefined))) watch( - () => props.group, - (group) => { + [() => props.slug, () => props.group], + ([, group]) => { const next = miscToForm(group) Object.assign(form, next) baseline.value = JSON.stringify(next) diff --git a/admin/src/views/config/center/PromptsPane.vue b/admin/src/views/config/center/PromptsPane.vue index c58e4c8..fc9414c 100644 --- a/admin/src/views/config/center/PromptsPane.vue +++ b/admin/src/views/config/center/PromptsPane.vue @@ -198,8 +198,8 @@ const baseline = ref(JSON.stringify(normalizePromptsGroup(undefined))) watch( - () => props.group, - (group) => { + [() => props.slug, () => props.group], + ([, group]) => { const next = normalizePromptsGroup(group) Object.assign(draft, next) baseline.value = JSON.stringify(next) diff --git a/admin/src/views/config/center/WallPane.vue b/admin/src/views/config/center/WallPane.vue index e62913c..a66cdb8 100644 --- a/admin/src/views/config/center/WallPane.vue +++ b/admin/src/views/config/center/WallPane.vue @@ -244,8 +244,8 @@ const baseline = ref(null) watch( - () => props.group, - (group) => { + [() => props.slug, () => props.group], + ([, group]) => { model.value = initWallEdit(group) baseline.value = model.value ? (JSON.parse(JSON.stringify(model.value)) as WallEditModel) diff --git a/docs/superpowers/plans/2026-10-14-config-center-ux-visual.md b/docs/superpowers/plans/2026-10-14-config-center-ux-visual.md index e09e065..843b2ed 100644 --- a/docs/superpowers/plans/2026-10-14-config-center-ux-visual.md +++ b/docs/superpowers/plans/2026-10-14-config-center-ux-visual.md @@ -1195,6 +1195,8 @@ watch(activeSlug, async () => { - [ ] **Step 2: 逐页轻改**——原则(spec §7):空态从「暂无数据」改具体动作指引(会话页「暂无会话——客户开始聊天后会出现在这里」/统计页「暂无数据——产生会话后展示分析」/平台设置存储表空「暂无设置项——从上方推荐键开始」);提示文案去术语(「线索」统一、错误 toast 主语明确)。**只改文案与空态,不动布局/逻辑**;每页改完 dev 目检 - [ ] **Step 3: Commit**——`git commit -m "polish(admin): 各页文案与空态轻量打磨"` +> 处置注记(Task 15 收尾):色列宽度与头像提示样式打磨经 Task 16 走查目检后定夺(视觉可接受则结项,否则列入后续)。 + ### Task 16: 全局回归 + 验收 - [ ] **Step 1: 前端全量测试**——`cd admin && pnpm test`,预期全绿且总数 ≥ 改造前(既有用例随退役迁移、新增只增不减;当前基线 164)