dzs/dzs-admin(前端后台,Next.js/React + antd)v1.0.105f5da644ba4724fabf776bda1a572758f4b946a22(对应 tag v1.0.104)99e465cc94ed09e0df64d3fb93cfdee0e9e61cc8本版本是 v1.0.104 发布后的一次「发布后修正」,全部围绕一条用户裁定:
2026-10-15 用户裁定:后台「插入数据」面板中品类恒单选——不允许同时勾选多个品类。 连锁效果:① 品类下拉不再进入多选态;②「对比表」
table_compare随「多品类对比」一并不可达 → 展示形式选项里不再出现;③ 历史多品类长码(targetId=1,2)回填时收敛为「保留第一个」。
实现方式是一枚全局闸门常量,引擎与组件共读,保证单一出处、不出现口径漂移:
// src/lib/placeholder-panel.ts
export const ALLOW_MULTI_COMMODITY = false; // 恢复条件:C 端 resolve_price 支持多品类 且 需求改回多选
| 类别 | 文件 | 改动摘要 |
|---|---|---|
| 源码(核心) | src/lib/placeholder-panel.ts | 新增导出 ALLOW_MULTI_COMMODITY = false;derivePanelState 的 allowMulti 加闸门 → 多品类 targetIds 收敛为保留第一个;formatOptionsFor 的 multi 分支保留但不可达 |
| 源码(组件) | src/components/articles/MarkdownEditor.tsx | 引入该常量;allowMultiTarget 加闸门 → 品类 Select 的 mode / value 随之恒单选 |
| 脚本 | scripts/verify-placeholder-panel.ts | 断言从「多品类只剩对比表」改为「多品类输入被收敛为单选 + 对比表不出现」,并保留「单选时排列形式仍含『按品类对比』」以证明存量解析不受影响 |
| 测试(用例改写) | e2e/specs/24-article-editor-preview.spec.ts | TC-EDT-105 由「多选→对比表」改写为「品类恒单选(下拉非多选态 / 选第二个替换第一个 / 不出现对比表)」 |
| 测试(页面对象) | e2e/pages/article-editor.page.ts |
工具实测:修复 0 条。
本增量未修复任何既有质检问题(git diff 中亦无针对历史缺陷的修补)。
工具实测:新增 1 条。
| 严重度 | 类型 | 位置 | 描述 |
|---|---|---|---|
| Low | Maintainability | e2e/specs/24-article-editor-preview.spec.ts:36 | 注释代码过多(many commented-out code lines detected) |
研判(本报告结论):大概率为误报 / 可接受。该处(第 31–38 行 TC-EDT-003)是解释性注释,逐行说明「抽屉 mask={false} 的关闭语义由哪条用例守护」,并非被注释掉的死代码;本文件是团队刻意重注释的回归用例集。建议不改,若质检平台支持白名单可将其归入误报。
无 Critical / High 级别新增问题。改动未触碰鉴权、SQL、外部接口边界。
逐项核对了闸门在多品类相关路径上的覆盖情况(src/lib/placeholder-panel.ts、src/components/articles/MarkdownEditor.tsx):
引擎侧收敛 ✅
derivePanelState 中
const allowMulti = ALLOW_MULTI_COMMODITY && dataKind === 'price' && field === 'representative';
...
if (targetIds.length > 1 && !allowMulti) targetIds = [targetIds[0]];
闸门为 false 时 allowMulti 恒为 false → 任何多品类输入都会被收敛为第一个,行为符合裁定。
组件侧展示 ✅
品类 Select 的绑定与之同源:
mode={allowMultiTarget ? 'multiple' : undefined}
value={allowMultiTarget ? panelSelection.targetIds : panelSelection.targetIds[0]}
与引擎用同一个常量判定,不存在「引擎已收敛、组件仍多选」的错配。
下游「对比表」不可达 ✅
const multi = targetIds.length > 1; 因 targetIds 已被收敛,multi 恒为 false → formatOptionsFor 的 if (multi) return build(['table_compare']) 分支不可达,展示形式选项不再出现「对比表」。逻辑正确。
契约未被破坏(关键) ✅
defaultFormatFor 仍然保留「多品类 → table_compare」的返回;formatOptionsFor 的 分支也保留。二者只是,占位符第 8 段 7 个取值(含 )依旧合法,存量卡解析/短码/快照固化均不受影响。这与 「契约三条」及 `dzs-api 零改动」的结论一致。
| 风险项 | 等级 | 说明与建议 |
|---|---|---|
| 编辑存量多品类卡会静默改写正文 | 中(行为变更,已裁决) | 打开一张 targetId=1,2 的存量卡点保存时,targetIds 收敛为 1、格式由 table_compare 回落(如折线图);而保存逻辑会把正文中该长码的全部出现一并替换 → 存量多品类卡被改写为单品卡。此为「保留第一个」的既定语义,但改写了用户既有内容,建议在保存前对「原卡为多品类」给出确认/提示,或在发布说明中显式告知运营。 |
| 已发布文章的影响面未在本仓闭环 | 低 | 需求原文多品类对比面向 C 端;C 端 resolve_price 对多品类返回「暂不支持该维度」→ 表现为「数据缺失」。本仓仅关闭后台入口,存量已插入卡照旧解析;C 端渲染改动本期不动(用户另行通知),需跨仓跟踪。 |
| 闸门开合的一致性 | 低 | 常量在引擎与组件各被引用一次,e2e/断言脚本已覆盖;恢复时只需置 true 并恢复多选用例,风险可控。 |
| 测试覆盖 | 低 | TC-EDT-105 已改写为单选语义用例;selectPanelOptions 多选用法在闸门关闭期内无用例覆盖(属预期)。 |
commodity:1,2 ... :table_compare 的已发布文章,走「卡片 ✎ 编辑 → 保存」,确认:① 不报错;② 长码被改写为单品;③ 是否需要对运营弹确认(见风险①)。table_compare 长码确认短码生成、快照固化、C 端解析路径不受影响(本仓零改动即可由既有用例守住)。ALLOW_MULTI_COMMODITY = true 后,scripts/verify-placeholder-panel.ts 与 TC-EDT-105 的多选断言应能一次性恢复,验证闸门设计未破坏原逻辑。selectPanelOptions() 方法注释标注「当前不可用,保留待闸门重开」 |
| 文档/规则 | rules/frontend.md、rules/backend.md、plans/specs/2026-10-14-placeholder-insert-design.md、plans/specs/.reports/2026-10-15-placeholder-insert-impl.md | 同步为「品类恒单选」口径;明确占位符契约 7 个取值不变、table_compare 为将来保留 |
table_comparetable_comparerules/backend.md潜在死代码(非缺陷,提示性) ⚠️
formatOptionsFor 的 multi 分支、defaultFormatFor 的 table_compare 返回在闸门关闭期不可达——有意保留(恢复条件已注释说明),不建议删除。e2e/pages/article-editor.page.ts 的 selectPanelOptions() 变成未使用方法——同样有意保留,已有注释说明。