fix: MKH-BOM 新增日销订单表兜底,修复上游快照漏算导致「库存 0 却不报缺货」 #18
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "codex/mkh-sale-fallback-0919"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
目的与范围
解决的问题:MKH-BOM 补货预警的日销盲区。上游
rpt.pm_stockMonitor.fifteenAvgSale会漏算(快照 09-18 下,窗口内有真实发货的 178 个 MKH 成品编码里 24 个被记成 0,其中 16 个订单全部来自
样品专用店铺属合理口径,剩 8 个是真实店铺);此时若待发货订单也为 0,判定会落到「无销量」分支、
hasWarning=false,商品彻底隐身,库存为 0 也不报缺货。业务实例:
MKHDNZ0409260601548近 15 天实发 2 件(09-09 / 09-19)、库存 0,页面无任何提示。修改的模块/文件
backend/src/services/mkhBomService.jsloadPendingOrderIndex重构为loadOrderIndex,一条查询同时取「待发货」与「近 15 天已发货」;PENDING_ORDER_TABLES更名ORDER_TABLESbackend/test/mkhBomService.test.jsfrontend/src/pages/MkhBomData/index.jsxfrontend/src/pages/MkhBomData/style.css.mkh-sale-fallback样式是否使用 AI 及负责开发者:使用 AI 辅助开发,负责开发者 yanhui。
同步与兼容性
d650fd0(PR #17 合并后的 main)d650fd03e64702/api/mkh-bom/list与导出接口只新增响应字段(dailySaleSource/snapshotDailySale/recentShippedQty),不删不改既有字段;ORDER_TABLES是模块内私有导出(原PENDING_ORDER_TABLES更名,两张表的口径未变),无外部调用方。
d650fd0切出。git diff --stat仅涉及上表 4 个文件;AGENTS.md/仓库提交与合并规范.md/服务器部署规范.md与 main 零差异(防回退检查通过)。验证
cd backend && node scripts/check-syntax.js→ 151 文件通过cd backend && node --test test/*.test.js→ 338 项 337 通过cd backend && node --test test/mkhBomService.test.js→ 44/44 通过cd frontend && node node_modules/eslint/bin/eslint.js src/pages/MkhBomData/index.jsx→ 0 问题cd frontend && node node_modules/vite/bin/vite.js build→ 构建成功真实数据端到端(本地接口
/api/mkh-bom/list,全量 4,223 个成品):· 21 个等级变化全部是「无销量 → 缺货 / 正常 / 已排产」,没有任何既有预警被降级
· 其中 10 个新缺货均为「库存 0 + 近 15 天真实发货 9~27 件」的真盲区
·
MKHDNZ0409260601548:日销0 → 0.1333(source=orders),不再隐身· 样品店排除按整行生效:实测某编码窗口内共 5 件(含样品店 1 件)→ 索引记为 4 件
resilientSecretStore权限断言(期望0o600、Windows 实际0o666)为平台固有失败,与本次改动无关;未在生产环境验证(部署需另行授权)。
/planning/operation/mkh-bom-data→ 搜索MKHDNZ0409260601548→ 日销列显示
0.13且带虚线下划(悬停说明该值来自订单实算、非上游快照),预警由「无销量」变为「已排产」(该成品当前有未完成加工单,按既有 ⑧ 口径不预警)。
风险与回退
shippedBySku为空 → 兜底自动失效,退化成旧口径,不会误报。分支(已有真实需求历史时用「结余库存 ÷ 日销」衡量更准),已加单测锁定该优先级。
背景 - 业务反馈 MKHDNZ0409260601548 近 15 天实发 2 件、库存 0,页面既不报缺货也不进任何预警。 - 根因是双重盲区: ① 上游 rpt.pm_stockMonitor.fifteenAvgSale 漏算 —— 快照 09-18 下,窗口内有真实发货的 178 个 MKH 成品编码里有 24 个被记成 0;其中 16 个订单全部来自样品专用店铺(上游同样 不计样品单,属合理口径),剩 8 个是真实店铺(天猫/京东/拼多多)。该列是**保留两位 小数的日均**(最小非零 0.07 = 1 件 ÷ 15 天),无法用四舍五入解释。 ② 快照日销 = 0 且待发货订单 = 0 时,判定直接落到「无销量」分支、hasWarning=false, 彻底排除在预警之外 —— 库存为 0 也救不回来。 改动 - 日销兜底(服务文件头新增 ⑦-a):**快照日销 ≤ 0 且近 15 天有真实发货**时,日销改用 订单表实算值 = 已发货件数 ÷ 15;快照 > 0 一律以上游为准,不覆盖,避免两套口径打架。 · 排除样品/测试专用店铺(shop_name 含「样品」「测试」),与上游口径对齐 · 窗口 = 含今天在内的 15 个自然日,与分母同口径 · 结果透出 dailySaleSource('snapshot'|'orders') / snapshotDailySale / recentShippedQty - 取数:loadPendingOrderIndex 重构为 loadOrderIndex,一条查询同时覆盖「待发货 (send_date IS NULL)」与「近 15 天已发货(send_date 在窗口内)」。实测合并后总耗时 约 1.25s ≈ 单查待发货,而拆成两条独立查询要在现有开销之上再加一次全表扫描 (首轮冷执行计划下 qmcust 单表可劣化到 20s+)。 - PENDING_ORDER_TABLES 更名 ORDER_TABLES:两张表的口径没变,只是不再仅服务待发货。 - 前端:日销来自兜底时加虚线下划 + 悬停说明,业务拿该数字与源系统 fifteenAvgSale 对照时不会被误判为数据错误。 验证 - 语法检查:151 文件通过。 - 后端测试:338 项 337 通过。唯一失败为 resilientSecretStore 的权限断言(期望 0o600、 Windows 实际 0o666),平台固有,与本改动无关。 - 新增回归测试:兜底生效 / 快照非零不覆盖 / 无发货不兜底 / 与订单驱动的优先级 / 订单源降级时退化成旧口径;订单索引测试补充「已发货同编码跨表累加」与「样品、测试店排除」断言。 - 真实数据端到端(本地接口 /api/mkh-bom/list,4,223 个成品): · MKHDNZ0409260601548:日销 0 → 0.1333(source=orders),不再隐身 · 日销 > 0 的商品 177 → 198;有效预警(缺货 + 预警)18 → 28 · 21 个等级变化**全部是「无销量 → 缺货/正常/已排产」**,没有任何既有预警被降级 · 其中 10 个新缺货均为「库存 0 + 近 15 天真实发货 9~27 件」的真盲区 · 样品店排除按整行生效:实测某编码窗口内 5 件(含样品店 1 件)→ 索引记为 4 件 - 前端 eslint 通过、vite build 通过。 风险与回退 - 只影响「快照日销 = 0」的商品,快照 > 0 的商品行为完全不变。 - 订单源不可用时兜底自动失效,退化成旧口径(不会误报)。 - 回退:本提交可整体 revert,无表结构变更、无数据迁移。yanhui referenced this pull request2026-09-19 14:50:18 +08:00