| 项目 | 结论 |
|---|---|
| 变更规模 | 4 个文件,约 +160 / −7 行(3 处产品代码 + 1 个新增测试) |
| 新增缺陷 | 1 个 Medium 确认缺陷(状态未复位)+ 2 个 Medium/需确认的口径回归风险,其余为 Low |
| 安全面 | 无新增网络请求、无鉴权/注入面变化、无 dangerouslySetInnerHTML;无 Critical/High 安全类问题 |
| 工具报告“修复 2 条” | 均为伪修复(同一问题因上方插入 33 行而位移,代码本体一字未改,已逐行比对确认) |
| 工具报告“新增 3 条” | 1 条真实(行过长 @142)、1 条伪新增(重复代码块 @472,系位移)、1 条真实但琐碎(测试内重复块) |
| 发布建议 | 可发布,但建议先修 §3.1(1 行改动);§3.2 需产品或服务端确认后再定 |
src/pages/pos/workbench/model.ts(−7/+2)— ✅ 改善defaultAllocRows 由「round2(1/n) + 末位补尾差」简化为一句话调用 evenAllocRatios(n),消除了 0.3333 型浮点尾差特判,与 salesAllocRows 共用同一口径(整数百分比)。这是本次唯一真实的可维护性改善(工具未计入“修复”)。
⚠ 业务口径变化(不是纯展示变化):3 人分摊由 0.3333/0.3333/0.3334 变为 0.34/0.33/0.33,分摊金额随 ratio 由服务端计算 → 首位恒多 1%(每单约 0.67% 相对偏差,随单量累积)。与销售单既有口径一致,可接受,但建议在版本说明中标注。
src/pages/pos/workbench/AllocPanel.tsx(+6)新增 resizeLineRows,把服务单行内「添加分摊人 / 移除」改为按人数重新平分(原先新增行 ratio: null 留白待手填)。逻辑正确(setRows 为闭包内当前渲染值,事件回调内调用无 TDZ/陈旧值问题)。
src/pages/pos/workbench/SettleOrderModal.tsx(+33)— ⚠ 见 §3新增「有建单意向即预填成可编辑行」的 useEffect(131–154),走 详情 → draftAllocs → AllocRow[] 映射:
order_item_index 全缺失才按整单多人预填(判断正确);lines.forEach((line, ix) 的 ix 与 detail.items 下标严格 1:1(detailToLines 对 items 是 map,不放缩、不展开),索引映射正确;划卡行显式跳过,正确。src/pages/pos/workbench/__tests__/allocAutoFill.test.tsx(+126,新增)3 个用例覆盖:整数百分比默认值、服务单加人 1→2→3 人平分、销售单加人平分(含受控组件 Harness 写法,正确)。与既有 allocMulti.test.tsx(已断言 34/33/33)口径一致,不会打破既有断言(已确认无测试依赖 0.3333 浮点值)。
seededRef 未随 reset() 复位 → 关闭后重开同一张单,预填消失SettleOrderModal.tsx:131(const seededRef = useRef(''))、:135(if (seededRef.current === sig) return)、:209-219(reset() 清 allocs 但不清 seededRef)src/pages/pos/pending/index.tsx:142-147 是常驻无 koşul渲染 <SettleOrderModal orderId={settleRow?.order_id ?? null} .../>,关闭只 setSettleRow(null),组件不卸载,<Modal> 无 destroyOnClose。
close() → reset() 把 allocs 清空,seededRef.current 仍为 "601:销售单";useQuery(['pos-pending-order', 601]) 命中缓存立即有 detail → effect 命中 seededRef 守卫直接 return → allocs 保持 [],预填行消失。SettleOrderModal.tsx:139-152(预填不做 Σ 校验)、:167-180(salesPending / servicePending 只看 rows.length > 0)、:378(disabled={!detail || allocBlocked})allocs 为空 → intentFallback 豁免 → 提交放行、服务端回落 draft_allocs;改造后只要意向非空就一定预填,一旦意向数据本身不平,salesAllocPending/lineAllocPending 即判「待分摊」→ 提交按钮被禁用。触发数据包括:
draft_allocs 中 ratio 非数值 → parseDraftAllocs 兜底 ratio: 0(src/api/order.ts:343-347)→ 预填 ratio:0 → 命中 (a.ratio ?? 0) <= 0 → pending;Math.abs(Σratio − 1) <= 0.01 且所有人 ratio > 0,不满足则不预填(退回空=fallback 的旧行为),并保留横幅告知“下单意向不平,留空将沿用服务端处理”;evenAllocRatios),把纠正成本降到 1 次点击。:144-151(只为有意向的行生成行)+ 提交分支 allocs.length > 0(约 :299-312)allocs.length > 0 → 提交带 [{order_item_index:0,...}],不再进入“空分摊=整单回落”分支。若服务端 settle.rs 对“传了 allocs”按整单以传入为准处理,其余行的意向归属将丢失。:154 依赖数组含未被使用的 me(effect 体内引用的 isSalesKind/vals 均来自模块或 detail),会触发 react-hooks/exhaustive-deps 的 “unnecessary dependency” 警告,且让人误以为预填与当前用户相关(注释恰恰强调“不预填当前收银员”)。useEffect 写“初始值派生”导致首帧先渲染空分摊、再跳成预填(一次多余渲染 + 视觉跳动);建议改为 useState(() => ...) 不行(detail 异步),可用 useMemo 派生 seededAllocs + 一次 useEffect 仅在 !allocs.length 时接管。AllocPanel.resizeLineRows 会无提示覆盖手工比例AllocPanel.tsx:101-105,用于 :362(移除)与 :374(添加)。message.info('已按人数重新平分') 提示。新增测试覆盖了“面板平分”,但没有覆盖本次真正新增的 SettleOrderModal 预填逻辑:draftIntent.test.tsx 只断言了顶部横幅文案与“不出现待分摊”,未断言预填行出现(例如 getAllByRole('spinbutton') 值 ['50','50']),也未覆盖 §3.1 的“关闭重开”路径。建议补 2 个断言/用例。
| 工具结论 | 复核结果 |
|---|---|
行过长 @SettleOrderModal.tsx:291 已修复 | 未修复。base:291 = ...(p.line_key !== undefined ? { order_item_index: Math.max(0, lines.findIndex(...)) } : {}),本次 diff 未触碰该行,head 中仍存在(约 :324),只是同规则的上榜位置被新增长行(:142)顶替 |
重复代码块 @:439 已修复 | 未修复。base:441/447 与 head:470/476 为同一处「抹角/抹元」两按钮 `disabled={payMode === '按行' |
结论:本次真实修复 0 条(工具未识别 model.ts 的 defaultAllocRows 简化,属漏报的改善)。 |
| 工具结论 | 复核结果 | 定级 |
|---|---|---|
行过长 @:142(>120 字符) | 真实:next.push(...intent.map((r) => ({ key: uuid(), line_key: ORDER_ALLOC_KEY, ... })));建议抽出 toAllocRow(r, lineKey) 映射函数(同时消掉 :149 的近重复映射) | Low |
重复代码块 @:472 | 伪新增(base:439 同一处位移,见 4.1) | Info |
重复代码块 @allocAutoFill.test.tsx:51 | 真实但琐碎:两个 render/rerender(<AntdApp><AllocPanel payments={[{ key:'p1', method:'微信', amount:100 }]} .../>) 块,建议抽 renderPanel(allocs) 局部 helper | Low |
SettleOrderModal 507 行 / 圈复杂度 100 / 直接依赖 64 个函数;AllocPanel 320 行 / 复杂度 51 / 扇出 41 —— 均为既存问题,本次 +33 行与 +6 行使其更差。建议后续把「分摊预填 + 分摊校验」抽为 useAllocSeed(detail) hook,可同时解决 §3.1/§3.4 并显著降低两处复杂度。
draft_allocs 比例不全的单(或 ratio 缺失)→ 观察「收款完成」按钮是否被禁用(本应可留空走服务端回落)。settle.rs 等服务端回落粒度、draft_allocs 真实数据质量无法验证,故 §3.2/§3.3 标注为“需确认”。const reset = () => {
seededRef.current = '' // ← 新增:允许下次打开重新预填
setPayments([])
...
}