fix: MKH-BOM 配件库存增加箱表兜底,修正「配件有货却判配件不足」 #55
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "codex/mkh-component-stock-pack-fallback-0930"
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 却把引用它的成品判为「配件不足」、可组装数 0。
MKHDNZ0409260600849,瓶颈配件唯一 =DNZ040947N1440V01ZT-30,判「正常」)modularStockMonitorService.buildRealtimeStockSql):inventoryInfo→ 同仓箱表兜底 → 监控快照mkhBomService.loadComponentStock):只查rpt.jst_inventoryInfo,一级到底rpt.jst_packInventoryInfo(小时级,当日 10:30 已记bin=ZT-30 qty=200)已有货 → 两页结论相反修改的模块/文件
backend/src/services/mkhBomService.jsloadComponentStock():改为一条语句同时取两张表(UNION ALL+src标记)。库存表有正库存以它为准;为 0 / 缺行时用同仓jst_packInventoryInfo的bin非空行合计兜底。只补 0、不覆盖正库存,与配件监控页同口径。jst_packInventoryInfo当配件库存 —— 与 MKH 配件零交集」这条结论。它是 09-17 的表状态(当时该表 85,152 行、仅 3 个箱、bin全表为空),09-18 上游整表重建后已失效(09-19 目标仓 794 个 SKU 命中 727 个;09-30 配件仓 743 个 SKU 有箱记录)。backend/test/mkhBomService.test.js:新增 3 个用例。是否使用 AI 及负责开发者:AI 辅助定位与实现,开发者 yanhui 负责。
同步与兼容性
b0b618eb0b618e(建 PR 时本地领先 1 / 落后 0)a93691fgit merge-tree --write-tree origin/main <branch>预演 → 冲突文件 0 个(tree958409a6);且合并产物与我提交的 blob 完全一致(mkhBomService.js=6fe8844,测试 =ce4b006),即「本分支所测即合并后所得」。AGENTS.md/仓库提交与合并规范.md/服务器部署规范.md/README.md(git diff --stat为空)。验证
1. 单元测试(含对照组实验)
bin非空 + 限定仓)③查询失败仍降级不做判定。expected: 200/actual: 0,正是业务现象)、用例 ② 失败,用例 ③ 通过;恢复后 54/54 全通过。证明测试确实在验这条修复,而非空过。cd backend && node --test test/mkhBomService.test.js→# tests 54 / # pass 54 / # fail 02. 后端全量
cd backend && npm run check(=check-syntax+node --test test/*.test.js)Syntax check passed for 179 JavaScript files;# tests 393 / # pass 392 / # fail 1resilientSecretStore.test.js的secret backup survives outside the repository with owner-only permissions(Windows 权限断言0o666vs0o600)。既有环境差异,与本改动无关。3. 真库验证(本地直连业务库)
loadComponentStock(['DNZ040947N1440V01','DNZ040959N1440V01','DNZ040946N1440V01','DNZ039802N1410V01'])200 / 200 / 60 / 87,degraded=false,耗时 1.9s0)4. 同一数据快照下的新旧口径对照(最有说服力的验证)
getMkhBomList(scope='warning'),逐行 diff。2026-09-29):true→false2 行(MKHDNZ0409260601376、MKHDNZ0409260601298,瓶颈均为DNZ040947N1440V01:0/0→ 消失,可组装数0 → 30);反向变化 0 行;其他字段变化 0 处;预警级别变化 0 处。→ 改动只影响「配件不足」标记,不动预警级别、排序与总数。
5. 端到端(本地接口)
POST /api/mkh-bom/sync清进程内缓存(49.0s,证明真重查库)后取全部预警行:不再有任何行的瓶颈是那两个兜底配件。6. 负载与数据量边界(规范第 6 节要求)
jst_inventoryInfo837 行;jst_packInventoryInfo1163 行(bin非空 1024 行)。SET STATISTICS IO(300 编码 = 一个分片):jst_inventoryInfoscan 9 / 逻辑读 4543 页;jst_packInventoryInfoscan 9 / 逻辑读 947 页;物理读 0、Worktable 0(无落盘)。COMPONENT_STOCK_CHUNK_SIZE = 300(远低于 MSSQL 单语句 2100 参数上限)。未运行或失败的检查及原因
SET SHOWPLAN_XML返回SHOWPLAN permission denied in database 'JSReportReplica'(该库账号无 SHOWPLAN 权限)。改用STATISTICS IO+ 实测耗时 + 数据量边界 作为执行计划等价证据(上条)。rpt下两个对象均为 VIEW(sys.objects.type = 'V'),索引在前端基表上,本视图无索引可查。风险与回退
已知风险
bin为空的装箱记录 → SQL 已强制过滤NULLIF(LTRIM(RTRIM(p.bin)),N'') IS NOT NULL。本案若不过滤会读到 400(200 装箱记录 + 200 货位)而非正确的 200。rpt对象是视图、无独立索引,上游整表重建可能变慢 → 已实测数据量(837 + 1163 行)、逻辑读(4543 + 947 页)、耗时增量(+176ms/分片);分片 + 10 分钟缓存控制负载。degraded=true→ 调用方放弃配件判定(宁可少标不误标),语义未变。回退方式
git revert a93691f(无其他提交依赖)。回退后行为立即恢复为「只查库存表」,无需数据修复。/api/mkh-bom/sync立即清)。根因 - 配件监控页取实时库存是三级兜底(inventoryInfo → 同仓箱表 packInventoryInfo → 监控快照 jsStock),而 MKH-BOM 的 loadComponentStock **只查 jst_inventoryInfo**, 一级来源到底就结束。 - 上游 jst_inventoryInfo 存在滞后:2026-09-30 该行停在 09-28 14:51 的值 0, 而 jst_packInventoryInfo 当日 10:30 已记 bin=ZT-30 qty=200。 - 结果:同一个仓(15718196)、同一个配件,配件监控页显示 200(判「正常」), MKH-BOM 判「配件不足」、可组装数 0。 案例 MKHDNZ0409260600849 的配件 DNZ040947N1440V01(瓶颈唯一)。 改动 - backend/src/services/mkhBomService.js · loadComponentStock():一条语句同时取两张表(UNION ALL + src 标记), 库存表有正库存以它为准;为 0 / 缺行时用同仓 jst_packInventoryInfo 的 bin 非空行合计兜底。**只补 0、不覆盖正库存**,与配件监控页 buildRealtimeStockSql 同口径;查询失败仍整体 degraded(不做判定)。 · 文件头 ⑪:修正「不能用 jst_packInventoryInfo 当配件库存 —— 与 MKH 配件 零交集」这条结论 —— 它是 09-17 的表状态(当时该表 bin 全空), 09-18 上游整表重建后已失效。 · 文件头 ⑤:同理修正该表的关联列与数据现状结论。PR #22 的提交信息声称 已更新 ⑤,但实际 diff 未改,此处补齐(该表 wms_co_id 关联、目标仓 727/794 命中、配件仓 743 个 SKU 有箱记录)。 - backend/test/mkhBomService.test.js · 新增 3 个用例:箱表兜底生效且不覆盖正库存 / SQL 形状防腐化(两张表 + bin 非空 + 限定仓)/ 查询失败仍降级不做判定。 对照组已验证:在修复前的实现上前两个用例失败(expected 200、actual 0)。 影响与验证 - 仅影响 MKH-BOM 的「配件不足」标记与可组装数;不改预警级别、排序与预警总数。 - 同一数据快照下的新旧口径对照(监控日 2026-09-29): 配件不足 26 → 24(2 行翻盘)、预警总数 29、缺货 23 两边一致, 0 行反向变化、0 处其他字段变化、0 处级别变化。 - 真库实测:DNZ040947N1440V01 0 → 200、DNZ040959N1440V01 0 → 200; 库存表本就有正数的对照配件(60 / 87)未被箱表覆盖。 - 负载(SET STATISTICS IO,300 编码一个分片):jst_inventoryInfo 4543 逻辑读 + jst_packInventoryInfo 947 逻辑读,物理读 0、Worktable 0;实测中位耗时 215ms → 391ms(+176ms/分片,配件全集 784 个约 3 个分片,占冷查 61s 的 1% 以内, 且结果按编码缓存 10 分钟)。 说明:SHOWPLAN 权限被拒(账号无该权限),改用 STATISTICS IO + 实测耗时 + 数据量 作为执行计划等价证据。 - 数据量边界:配件仓 jst_inventoryInfo 837 行、jst_packInventoryInfo 1163 行 (bin 非空 1024 行)。 - 后端:check-syntax 179 文件通过;node --test 393 项 392 通过 (唯一失败为既有环境问题 resilientSecretStore 权限断言,与本改动无关)。