feat: MKH-BOM 补货预警(订单驱动 + 配件不足)与日销口径改近 15 天 #16
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "codex/mkh-alert-export-0917"
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?
目的与范围
backend/src/services/mkhBomService.js(在途加工单 / 待发货订单 / 配件不足 / 日销口径)backend/src/jobs/mkhReplenishAlertJob.js(通知文案与统计)backend/src/services/modularStockMonitorService.js(日均发货量口径与字段名)backend/test/mkhBomService.test.js、backend/test/mkhReplenishAlertJob.test.jsfrontend/src/pages/MkhBomData/index.jsx、style.cssfrontend/src/pages/ModularStockMonitor/index.jsx关于「近 30 天日销」
业务最初要求改「近30天日销」,但实测已接入的所有数据源都没有 30 天日销,改用已实现的最长周期
fifteenAvgSale(15 天),经与业务确认。排查结论已写入mkhBomService.js文件头 ⑦,避免重复排查:rpt.pm_stockMonitor只有threeAvgSale(3天) /sevenAvgSale(7天) /fifteenAvgSale(15天),且整表只保留 1 天快照(2026-09-16),攒不出 30 天历史rpt.dws_sn_sales_full_info_di(stat_date + skuid + goods_count,数据新鲜到 09-15)里 MKH 商品 0 个;目标仓 794 个 SKU 命中也是 0rpt.dws_order_sales_cost_detail_di停在 2025-04(历史归档)rpt.jst_salesOutboundInfo只有出库单头,无 SKU 明细;业务库无出库明细表rpt.op_BarcodeSalePrice30dDaily名字带 30d,但只有salePrice没有销量同步与兼容性
6c00977a928135(已合并进本分支,见897bbd2与06952d8;main 在本任务期间前进了 11 个提交)3e02c3epackage.json/ lock 的变动来自合并 main,不是本任务引入)backend/src/services/mkhBomService.js4 处冲突 → 逐处取本分支侧,并并入 main 收紧后的MKH_WHERE(必须是jst_skuBomItem正式 BOM 父项)与文件头 ① 的新口径说明。本分支 ⑤~⑪ 注释与loadComponentLocations是 main 那段的超集,双方都已删除buildInventoryWarehouseMap回退链,语义一致backend/test/mkhBomService.test.js1 处(hunk 边界)→ 双方各缺一个});。main 新增的「无箱记录不回退仓库」测试按语义插在仓位测试之后,再接本分支新增测试,两处闭合各自补回frontend/src/pages/MkhBomData/index.jsx2 处 → 合并双方文案。数据口径采用 main 的表述(正式 BOM 父项、仓位只取rpt.jst_packInventoryInfo),保留本分支的补货预警 / 待发货订单 / 在途加工单 / 配件不足四段说明ours/theirs批量取舍MKH_WHERE收紧、仓位来源变更、文案调整全部在位total由 4408 变为 4223,证明 main 的成品口径收紧已生效验证
3e02c3e):npm --prefix backend run check→ 语法检查 151 个文件通过;测试 334 tests / 333 pass / 1 failresilientSecretStore.test.js「secret backup survives outside the repository with owner-only permissions」chmod 600实际得到0o666,断言期望0o384,属环境固有问题,未修改node --test test/mkhBomService.test.js test/mkhReplenishAlertJob.test.js→ 52/52 通过total=4223 / warningCount=19 / outOfStockCount=10 / saleWindowDays=15 / componentShortageCount=12 / componentStockDegraded=falsenpm --prefix frontend run check未运行(受阻):本地frontend/node_modules被一次中断的npm ci损坏(eslint包内文件缺失、vite/rolldown-vite的dist为空),修复期间网络安装耗时过长未完成。不能写成通过。@babel/parser对改动的 2 个.jsx做 JSX 语法解析,均通过(MkhBomData 1108 行 / ModularStockMonitor 431 行)git diff,确认前端改动仅为:字符串文案「近7日」→「近15天」、dataIndexavgShip7d→avgShip15d、列头文案、以及一段纯文本口径说明风险与回退
预警变少是因为 15 天日销普遍低于 7 天(近期销量走低),可用天数随之变大。这是口径变化的正常结果,不是 bug。
mkhBomService.js的SALE_WINDOW_DAYS与DAILY_SALE_COLUMN两个常量(SQL 已按常量插值)。bi_processing_work_orders(在途加工单)是整表快照,会随上游刷新变化(实测同一天 1 小时内 5 单/40 件 → 20 单/185 件),因此scheduledCount等数字会波动,非 bug。jsUseDays(源系统口径),两者并非同一时间窗 —— 已在页面口径说明中如实标注。3e02c3e/f69d267/fe831c3e),无需数据恢复。3e02c3e即可,不影响订单驱动与配件不足功能。补货预警在原有「销量 + 库存」口径之外增加两条判定,均不改变已上线行为: 1. 待发订单驱动 - MKH 成品条码历史无销售量、但存在未发货订单时,同样进入补货预警。 - 建议补货量按「未发货件数 − 现有库存」计算,无订单时不参与该口径。 - 列表新增待发货订单列,展示件数、单数与最早下单时间。 2. 配件不足 - 对判定为缺货或预警的商品,按 BOM 计算可组装数: 可组装数 = 各配件 ⌊(现有库存 − 未完成加工单占用) ÷ 单台用量⌋ 取最小值。 - 可组装数为 0 时标记「配件不足,无法补货」并保留在清单中, 建议补货量显示「—」,同时给出短板配件及其库存。 - 配件库存只认「简尚-崔桥工厂半成品包装项目仓」的现有库存, 按业务确认不计采购在途。 - 配件库存查询失败时降级为空索引并标记 componentStockDegraded, 不写入缓存,避免把瞬时故障固化为错误数据。 导出与通知文案同步:导出新增「配件不足」列、补货量按同一口径输出; 缺货通知在配件不足时插入短板配件提示并把建议补货量显示为「—」。 验证:backend 相关单测全部通过(新增 9 例);语法检查通过; 前端 eslint 零错误且 vite build 通过;接口实测与页面渲染结果见 PR。业务要求「近7日日销」改「近30天日销」。实测业务库与产品资料库均无 30 天日销, 已实现的最长周期是 pm_stockMonitor.fifteenAvgSale(15 天),经与业务确认改用 15 天。 为什么没有 30 天(2026-09-17 实测,避免重复排查): - rpt.pm_stockMonitor 只有 threeAvgSale(3天)/sevenAvgSale(7天)/fifteenAvgSale(15天), 且整表只保留 1 天快照(2026-09-16),攒不出 30 天历史 - rpt.dws_sn_sales_full_info_di(stat_date+skuid+goods_count,新鲜到 09-15) 里 MKH 商品 0 个;目标仓 794 个 SKU 命中也是 0 - rpt.dws_order_sales_cost_detail_di 停在 2025-04(历史归档) - rpt.jst_salesOutboundInfo 只有出库单头,无 SKU 明细;业务库无出库明细表 - rpt.op_BarcodeSalePrice30dDaily 名字带 30d,但只有 salePrice 没有销量 改动: - backend/src/services/mkhBomService.js · SALE_WINDOW_DAYS 7 → 15,新增 DAILY_SALE_COLUMN='fifteenAvgSale', 监控快照 SQL 按该常量插值取数(以后改口径只改常量) · buildReplenishMetrics 入参 sevenAvgSale → avgSale(语义与周期解耦) · 文件头 ⑦ 补「为什么是 15 天」的完整排查结论;⑦ / ⑩ / ⑪ 实测数字按新口径更新 - backend/src/services/modularStockMonitorService.js · 取数列与 API 字段名 sevenAvgSale/avgShip7d → fifteenAvgSale/avgShip15d (字段名同步改,避免名不副实) - frontend/src/pages/MkhBomData/index.jsx · 列头与口径说明「近7日」→「近15天」;动态文案兜底 7 → 15 - frontend/src/pages/ModularStockMonitor/index.jsx · 列头「近7日日均发货量」→「近15天日均发货量」,dataIndex 同步改 · 口径说明补充:可用天数仍沿用 jsUseDays(源系统口径),与日销并非同一时间窗 影响(同一份 09-16 快照,7 天 vs 15 天): 有销商品 114 → 170 周期拉长,更多商品进得了「有销」集合 补货预警 25 → 19 反而变少:15 天日销普遍低于 7 天(近期销量走低), 可用天数 = 库存 ÷ 日销 随之变大,跌破 3 天的变少 缺货 9 → 10 已排产 11 → 13 订单驱动 14 → 8 更多商品自己有日销,不再需要靠订单兜底 配件不足 10 → 12 「预警变少」是口径变化的正常结果,不是 bug。 验证: - 后端语法检查 151 个文件通过 - mkhBomService + mkhReplenishAlertJob 单测 52/52 通过 - 后端全量 334 tests / 333 pass(唯一失败是 resilientSecretStore 的 Windows 文件权限断言,与本改动无关的环境固有问题) - 接口实测:total 4223 / warningCount 19 / outOfStockCount 10 / saleWindowDays 15 / componentShortageCount 12- backend/src/services/modularStockMonitorService.js - 「已配置MKH」判定口径切回 jst_comboProductItem 组合装引用: 该 SKU 出现在 jst_comboProductItem.src_sku_id 且 combine_sku_id 以 'MKH' 开头 即视为被 MKH 模块化成品(组合装/成品档案)引用为配件。 - 移除产品资料系统数据库覆盖清单逻辑(resolveProductCoverage / productCoveredCsv), 产品资料库仅保留作图片来源。 - 实测目标仓 794 SKU 中 29 个命中(原产品资料库口径 661 已废弃)。 - frontend/src/pages/ModularStockMonitor/index.jsx - 状态列 tooltip 文案同步为「是否被 MKH 模块化成品作为配件引用」。 注:本改动会令已配置MKH数量从 661 降至 29(数据使然,非 bug)。