Files
bj_power/临时.md
T
SunYF 132c3ed6bd docs(test): 更新电表箱装配业务回归测试文档
- 将文档从代码审计任务转换为端到端业务回归测试链路
- 重新组织文档结构为链路总览、示例数据基线和详细步骤
- 添加完整的业务场景清单涵盖WMS/MES/工位终端三大系统
- 定义统一的测试数据包括产品型号、物料清单、工位派工等
- 提供详细的步骤断言和数量等式验证方法
- 建立贯穿全链路的数据流向和状态变更追踪体系
2026-09-21 10:48:53 +08:00

212 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 库存查询重构 + 来料检验修复 · 最优方案(评审稿)
> 范围:WMS 库存查询页重构、WMS↔MES 数据交换定调、MES 排产支撑视图、来料检验三问题修复。
> 原则:一次做干净,不打补丁、不留旧口径;改 schema 走 ent 重生成 + db.go applyColumnPatches 幂等 DDL;改前端必须 npm run build + go build 重编 exe。
---
## 0. 数据交换方式(架构定调,先解决"谁拉谁、看什么")
### 现状(实读代码)
- WMS 库存页 onMounted → `GET /api/stock/producible` → WMS `mesclient.FetchProducible` → MES `/api/internal/producible` → MES `ComputeProducible`(读 BOM + 反向拉 WMS `/api/internal/stock/check` 可用量)→ 算「可生产套数 + 未来5天需求」→ 回 WMS 落 `producible_snapshot` + `material_demand` 两张快照表。
- 问题:**可生产套数是 MES 视角,却显示在 WMS 库存页**;一次拉取把两种诉求混在一起;WMS 侧无分页全量展示所有成品。
### 真源与方向(定调)
| 数据 | 真源 | 谁缺 | 交换方向 |
|---|---|---|---|
| 库存可用量(合格可用) | WMS | MES 缺 | MES 拉 WMS `/api/internal/stock/check`(已有 `StockAvailable` |
| BOM 单台用量 + 日排产 | MES | WMS 缺 | WMS 拉 MES「物料排产需求量」 |
**核心:每个系统只拉自己缺的原始数据,各自算各自视角的结论,不再互相代算对方的展示指标。**
- **WMS 视角 = 缺料补货**:WMS 用「MES 排产需求量」对比「本地可用库存」→ 缺什么料、缺多少、该进什么料。
- **MES 视角 = 排产支撑**:MES 用「WMS 可用库存」对比「日排产需求速率」→ 可生产套数 + 还能支撑到哪天/多少天。
### 落地动作
1. **可生产套数从 WMS 移除**,迁到 MES 新视图(见 §A2)。
2. WMS 保留 `material_demand``ledgerState` 备料四态预警仍用 future5Qty),但**喂数改为专职拉「排产需求」**;删除 `producible_snapshot` 表 + `queryProducibleHandler` + `FetchProducible` 的 items 分支(彻底清理旧库旧代码)。
3. MES 侧 `ComputeProducible` 复用,新增 MES 用户态接口 + 前端页(见 §A2)。
---
## A. 库存查询重构
### A1. 三 Tab 维度归位(根治"质量状态被当拆行维度")
现状三 Tab:物料汇总 / 库存明细(物料×区域×质量拆行) / 区域汇总(区域×质量×类型拆行)。
问题:`aggregateStock` 分组键含 `QualityStatus``buildZoneSummary` 分组键含 `quality+type`,导致**同一物料/区域被质量、类型拆成多行**,用户误以为重复。
**方案:每个 Tab 只负责一个主维度,质量/类型降为"列"或"标签",不做拆行维度。**
| Tab(新) | 主维度(一行=一个) | 质量怎么放 | 类型怎么放 |
|---|---|---|---|
| 物料汇总 | 物料编码 | 合格/未检/不合格 **三列数量**(现状已是列,保留) | 管理粒度列(结构件/电气件/其他) |
| 库位明细(原"库存明细"改名) | 物料 × 库位(区域/货架/层/位置) × 批次/SN | 质量作**列**(每行一个质量状态标签),**不进分组键** | 管理粒度列 |
| 区域汇总 | 区域编码(一区域一行) | 合格/未检/不合格 **三列数量** | 结构件/电气件/其他 **三列数量** |
改动要点:
- `aggregateStock`[stock.go:227-258](file:///d:/hardman/bj_power/bj_power_wms/internal/handler/stock.go#L227-L258))分组键 `stockKey` **去掉 QualityStatus**,改为 `物料+区域+货架+层+位置+管理粒度`;质量分布改成聚合列(合格/未检/不合格数量)。
- `buildZoneSummary`[stock.go:685-778](file:///d:/hardman/bj_power/bj_power_wms/internal/handler/stock.go#L685-L778))**一区域一行**:数量、可用量、锁定量、质量三列、类型三列;**去掉"区域创建时间"**,保留"最近入库时间"(可改"最近变动时间")。
- 前端 [Inventory.vue](file:///d:/hardman/bj_power/bj_power_wms/frontend/src/pages/Inventory.vue) 三张表列头按上表重排。
### A2. 可生产数量 → 迁出 WMS,MES 新建「排产支撑」视图
**WMS 侧(删)**
- 删 [Inventory.vue:272-299](file:///d:/hardman/bj_power/bj_power_wms/frontend/src/pages/Inventory.vue#L272-L299) 可生产数量卡片 + `loadProducible`
-`producible.go` `queryProducibleHandler`、routes 的 `/api/stock/producible``producible_snapshot` schema + ent 文件、db.go 相关 DDL。
**MES 侧(新增"排产支撑"页)**
- 后端:新增用户态接口 `GET /api/v1/production/producible-support`,复用 `ComputeProducible`,返回每个成品:可生产套数、短板物料、**支撑天数/支撑到哪天**。
- **支撑天数算法(最优:按日排产逐日消耗)**:取 WMS 可用量 avail,按 `daily_plan` 从今天起逐日扣减当日需求(台数×单台用量),直到某物料不足 → 支撑天数 = 能满产的完整天数;并给出"最先告罄的短板物料"。简化兜底:`floor(avail / 日均需求)`
- 前端:MES 新增菜单/路由 `排产支撑`[router/index.js](file:///d:/hardman/bj_power/bj_power_mes/frontend/src/router/index.js) + MainLayout 菜单 + 新 `ProducibleSupport.vue`),成品分页展示(**分页/懒加载,解决"内存炸弹"**:只算启用成品、按需分页,不再全量无分页)。
### A3. WMS 新建「缺料补货」视图(WMS 最该知道:该进什么料)
- 数据来源:WMS 拉 MES「排产需求量」(按物料,可带日期窗口,如未来5天/逐日);对比 WMS 本地可用库存(合格可用,口径同出库门禁 `QStatusPass`)。
- 输出每物料一行:排产需求量、当前可用量、**缺口量(=需求-可用,>0 才列)**、安全库存、建议采购量、告罄日(结合逐日需求)。
- 与现有 `shortageHandler`[stock.go:1074](file:///d:/hardman/bj_power/bj_power_wms/internal/handler/stock.go#L1074) 仅按安全库存)区分:**安全库存缺货**(常规补货)vs **排产缺料**(按订单需求)两者并列,缺料补货视图以"排产缺料"为主、安全库存为辅。
- 前端:库存页新增 Tab「缺料补货」或独立菜单;复用/扩展 `material_demand` 表存拉取到的排产需求。
- 交换实现:`mesclient` 新增 `FetchMaterialDemand(ctx)` → MES `/api/internal/material-demand`(由 `computeFuture5Demand` 逻辑扩展为可传日期窗口/逐日)。
### A4. 库位明细加"库位筛选"(区域→货架→层→位置 联动)
- 现状 [Inventory.vue:319-339](file:///d:/hardman/bj_power/bj_power_wms/frontend/src/pages/Inventory.vue#L319-L339) 明细只有"区域"筛选。
- 方案:复用区域维护/入库页的四级联动下拉(`/zone/picker` 按 level+zoneCode+shelfNo 逐级取),明细查询参数增加 `shelfNo/layerNo/positionNo``aggregateStock` 增加对应 whereinventory 已有 `shelf_no/layer_no/position_no` 列,直接过滤,无需 join)。
### A5. 质量维度:独立"不合格品"视图 + 快捷筛选
- 现状找不合格品要在明细里逐列翻。
- 方案:库位明细/物料汇总提供"质量状态"快捷筛选(未检/合格/不合格);另加「不合格品」快捷入口(预设 quality=不合格 的明细视图),一屏定位"不合格在哪(物料/库位/批次/SN)"。
### A6. 细节清理
- **导出按钮统一命名"导出Excel"**(现状"导出物料汇总"/"导出"/"导出区域汇总"三种)。
- **"最近入库单"字段**:一个批次可能多次入库,"最近一单"误导 → 明细下钻里保留逐条入库单,汇总行去掉或改"首次入库时间"。
- 区域汇总去掉"区域创建时间"列(与库存无关)。
---
## B. 来料检验修复(三问题,按已确认决策)
### B1. 目标类型加"其他" + 按入库类型筛选(问题1,决策:两者都要)
**事实**`item_type=4`(辅料/工装/试验设备,即"其他入库")建档时被**强制 manage_mode=1**[material.go:96-98](file:///d:/hardman/bj_power/bj_power_wms/internal/handler/material.go#L96-L98)),现混在"批次(结构件)"里,无法单独识别/筛选。inventory 表**无 item_type 列**(在 material 表)、**无 inbound_type 列**(在 inbound_order 表)。
**方案**
- 目标类型 radio 增第三项:**批次(结构件) / SN(电气件) / 其他(辅料·工装·试验设备)**。
- 拾取器/待检清单支持两类过滤:
- **按品类=其他**:过滤 `item_type=4`。因 inventory 无该列,走 **join material**`materialCodesByItemType(4)` 取编码集,再 `MaterialCodeIn`);与现有 `materialCodesBySpec` 同套路。
- **按入库类型**:过滤 inbound_order.inbound_typepurchase/semi/finished/return/other),走 **join inbound_order by inbound_no**;待检清单接口支持 `inboundType` 参数。
- `aggregateStock`/`/stock/query` 增加 `itemType` 过滤参数(join material)。`resolveInspectionTarget` 无需改(其他类是 manage_mode=1,按 batchNo 已能命中)。
### B2. 新增"待检清单"视图(问题2,决策:新增视图)
- 来料检验页新增 Tab「待检清单」:列出 `quality_status=未检` 的库存行,可按 物料/入库类型/目标类型(结构件·电气件·其他) 筛选,分页。
- 每行带勾选 + "送检"按钮 → 勾选项带入录入表单"已选清单";检验提交后质量状态翻转,自动移出待检清单。
- 后端:新增 `GET /api/inspection/pending`(或复用 `/stock/query?qualityStatus=未检` + itemType/inboundType 过滤),返回未检库存行(含物料、库位、批次/SN、数量、入库类型)。
### B3. 逐个判定 + 不合格数(问题3,决策:逐个判定+不合格数)
**现状缺陷**
- 一次提交只能给所有选中编号**同一结论**,不能一屏内这个判合格、那个判不合格。
- `batch-flip` 多选时把**相同的 inspectQty/passQty 写进每条记录**[inspection.go:239-240](file:///d:/hardman/bj_power/bj_power_wms/internal/handler/inspection.go#L239-L240)),每对象数量失真。
- InspectionRecord **无独立"不合格数"字段**,只有 inspect_qty/pass_qty。
**数据模型**
- `InspectionRecord` 增字段 `reject_qty`(不合格数,默认0)。schema 改 + ent 重生成(WMS`go run -tags entgenerate ./tools/generate.go`+ db.go `applyColumnPatches` 幂等加列 `ALTER TABLE inspection_records ADD COLUMN IF NOT EXISTS reject_qty ...`
- 校验口径:`检验数 = 合格数 + 不合格数``reject_qty = inspect_qty - pass_qty`(提交时后端复核,不信任前端)。
**录入交互(逐个判定)**
- **电气件(SN) / 其他**:已选清单每行一个"结论"单选(合格/不合格),一屏内逐个判定;每行独立写 inspect_qty=1、pass_qty=1/0、reject_qty=0/1。
- **结构件(批次)**:每行填 检验数/合格数,不合格数自动=差;判不合格选处置(部分入库 PARTIAL 拆 合格数入库 + 差额 NG 隔离,逻辑已存在于 `disposeInspectionHandler`)。
- 后端:`batch-flip` 改造为**逐对象结果**提交 —— body `items:[{targetId,status,inspectQty,passQty,rejectQty,disposalType,returnTrackingNo,...}]`,每条按自身数量写记录、按自身处置翻状态(修复"所有记录同数量"bug)。保留一次事务原子提交。
**列表/导出**
- 检验记录列表 + xlsx 导出([inspection.go:419](file:///d:/hardman/bj_power/bj_power_wms/internal/handler/inspection.go#L419) headers)增加"不合格数"列。
- 记录页明确展示:对象(批次/SN)、结论、检验数/合格数/不合格数、处置方式,做到"哪个 SN 不合格、对应哪条记录"一目了然(每 SN 一条记录,本就可追溯;配合逐个判定后完全对齐)。
### B4. 结构件 vs 电气件不合格的口径(在帮助文档写清)
- **结构件(批次)**:一行 qty=N,判不合格=整批隔离;"N 里坏 M 个"用**部分入库**填合格数 N-M,系统拆 (N-M)合格 + M不合格(-NG 批次)。
- **电气件(SN)/其他**:逐个判定,每个 SN/件一条记录、一行库存,选中判不合格即隔离该件,无需拆分。
- 更新 `helpInspection`[help.js](file:///d:/hardman/bj_power/bj_power_wms/frontend/src/help.js))说明两者差异与不合格数口径。
---
## C. 施工顺序与构建(避免遗漏)
1. **schema 改**InspectionRecord 加 `reject_qty`;删 `producible_snapshot`。→ WMS ent 重生成(`go run -tags entgenerate ./tools/generate.go`,注意删残留 per-entity 文件含 where.go+ db.go applyColumnPatches 幂等 DDL(加 reject_qtyproducible_snapshot 旧表按需 DROP)。
2. **WMS 后端**stock.go 三 Tab 维度归位 + 库位/itemType 筛选 + 缺料补货 + 删 producibleinspection.go 逐个判定 + pending + reject_qtymesclient 加 FetchMaterialDemandroutes 增删。
3. **MES 后端**`/api/internal/material-demand`(供 WMS 拉);`/api/v1/production/producible-support`(供 MES 前端,含支撑天数)。
4. **WMS 前端**Inventory.vue 三 Tab 重构 + 缺料补货 + 库位筛选 + 不合格视图 + 导出改名;Inspection.vue 目标类型加"其他" + 待检清单 Tab + 逐个判定交互。
5. **MES 前端**:新增 ProducibleSupport.vue + 路由 + 菜单。
6. **构建**
- WMS 前端 `cd d:\hardman\bj_power\bj_power_wms\frontend; npm run build``cd d:\hardman\bj_power\bj_power_wms; go build -o bj_power_wms.exe .`
- MES 前端 `cd d:\hardman\bj_power\bj_power_mes\frontend; npm run build``cd d:\hardman\bj_power\bj_power_mes; go build -o bj_power_mes.exe .`
- PowerShell 用 `;` 不用 `&&`
## D. 口径已定案(采纳评审建议,本轮按此实现)
1. **支撑天数**:逐日排产消耗为主 —— 有排产的日期按 `daily_plan` 当日需求逐日扣减 WMS 可用量;**排产只排了 N 天、第 N+1 天起无排产时,用「最近3天平均日需求」外推兜底**,直到某物料告罄。输出"支撑天数 + 支撑到哪天 + 最先告罄短板物料"。
2. **缺料补货分两列,不合并**(合并会掩盖两种性质不同的缺料):
- 列A「安全库存补货量」= 安全库存 − 可用量(常规补货,>0 才列)
- 列B「排产缺料量」= 排产需求 − 可用量(订单驱动紧急补料,>0 才列)
- 「在途量」当前**无数据源**,列留空显示"—",不纳入计算(不臆造)。
3. **待检清单 = 独立 Tab**(量大需分页/筛选,不内嵌录入页)。
---
## E. 对 deepseek 复核意见的逐条核实(结合实际代码)
> deepseek 不看代码,以下逐条核实:采纳 / 已实现无需改 / 与你的原则冲突需纠正。
| deepseek 意见 | 核实结论 | 处理 |
|---|---|---|
| 补充1 归属字段要改造 | **已实现**Inspection.vue 归属默认"其他"、命名"工单编号/科技项目号/其他"、归属编号手动输入不联动 MES | 无需改造;但见 §E1 归属应从入库单带入 |
| 补充2 待检清单按入库单分组 | 合理,契合你"来料检验根据入库管理检查"的原意 | **采纳**:见 §E2 |
| 补充3 录入页按入库单驱动、勾选带入 | 合理,是 B2 的强化 | **采纳**:见 §E2 |
| 补充4 scan_record 孤儿表 | 属 **MES 侧报工记录**改造,不在本轮(WMS 库存+来料检验)范围 | 标注排除,见 §E4 |
| 补充5 帮助文档同步更新 | 成立,原方案只提了 helpInspection | **采纳**:见 §E5 |
| D1/D2/D3 建议 | 均合理 | 已定案,见 §D |
| 注意1 join material 性能 | 方案已是"先查 material 取 item_type=4 编码集,再 IN 查 inventory",非逐行 join | **强调落实**:见 §E6 |
| 注意2 reject_qty 历史回填 | 成立 | **采纳**:见 §E7 迁移回填 |
| 注意3 batch-flip 接口兼容、加版本号/留旧接口 | **与你"不兼容妥协、不留旧代码"原则冲突**;且实测 `/inspection/batch-flip` 全仓仅 Inspection.vue 一个调用方 | **纠正**:干净改 body 结构 + 同步改唯一前端调用方,**不加版本、不留旧接口**,见 §E8 |
### E1. 归属从入库单自动带入(补充1 的正确落点)
来料检按入库单驱动,而入库单已存 `ownership_type/ownership_no`[inbound.go:164-165](file:///d:/hardman/bj_power/bj_power_wms/internal/handler/inbound.go#L164-L165))。待检清单勾选带入录入页时,**归属类型/归属编号一并从入库单带入**(可手改),检验记录归属与入库单归属保持一致,避免二次手抄。录入页归属字段本身无需改(已符合决策)。
### E2. 待检清单:按入库单分组 + 勾选带入录入页(补充2+3)
- 待检清单 Tab **以入库单为主行**(一张入库单一行:入库单号、入库类型、物料、数量、未检批次数/SN数、归属、入库时间),**展开看该单下的批次/SN 明细**quality_status=未检 的行)。
- 勾选(整单或单条批次/SN)→「送检」带入录入页"已选清单",并自动回填 物料/归属/入库类型/检测单号等字段;**用户在录入页只需逐个判结论 + 填检验数/合格数**,实现"按入库单驱动、闭环"。
- 后端 `GET /api/inspection/pending` 返回按 inbound_no 分组的未检库存(join inbound_order 取 inbound_type/归属)。
### E3. 死接口清理(本轮新发现)
`/api/inspection/create``createInspectionHandler`)**前端无任何调用方**(录入只走 batch-flip)。按"彻底清理旧代码"原则,本轮改造 batch-flip 时**一并删除 createInspectionHandler + 其路由**,避免两个语义重叠的检验写入口并存。(实施前再全仓 grep 确认无内部/MES 调用。)
### E4. 范围排除声明(补充4)
**报工记录改造(MES 侧 scan_record 孤儿表、/scan/report、/scan/records、报工 Tab 改查 workpiece_process)不在本轮范围**,需单独一轮处理。本轮仅 WMS 库存查询重构 + WMS 来料检验修复 + 配套的 MES 排产支撑视图/物料需求接口。
### E5. 帮助文档同步(补充5)
界面改动同步更新帮助文档,避免用户看不懂:
- `helpInventory`:三 Tab 新维度解释(质量/类型降为列、库位明细四级库位、区域汇总一区域一行)。
- 新增「缺料补货」帮助:两列缺料口径、数据来源(拉 MES 排产需求 vs 本地可用)。
- 新增 MES「排产支撑」帮助:可生产套数/支撑天数算法口径。
- `helpInspection`:目标类型加"其他"、待检清单用法、逐个判定、不合格数口径、结构件 vs 电气件不合格差异(B4)。
### E6. itemType/inboundType 过滤走"子查询 IN"而非逐行 join(注意1
`item_type=4`(其他入库物料):先 `material.Query().Where(ItemTypeEQ(4))` 取编码集(量小),再 `inventory.MaterialCodeIn(codes...)`;与现有 `materialCodesBySpec` 同套路,**不做逐行 join**,避免大数据量下变慢。按入库类型同理:先由 inbound_order 取符合 inbound_type 的 inbound_no 集,再 `inventory.InboundNoIn(...)`
### E7. reject_qty 历史数据回填(注意2
db.go applyColumnPatches 加列后,**回填历史行**:`UPDATE inspection_records SET reject_qty = inspect_qty - pass_qty WHERE reject_qty = 0 AND inspect_qty > pass_qty`(幂等,只补差异>0 的旧行),保证历史记录"不合格数"列不空白、口径一致。
### E8. batch-flip 干净改造,不做兼容(注意3 纠正)
实测 `/inspection/batch-flip` 全仓仅 [Inspection.vue:145](file:///d:/hardman/bj_power/bj_power_wms/frontend/src/pages/Inspection.vue#L145) 一个调用方。body 由 `{targetIds:[],status,inspectQty,passQty,...}` 改为**逐对象结果** `{items:[{targetId,status,inspectQty,passQty,rejectQty,disposalType,returnTrackingNo,ownershipType,ownershipNo,...}]}`,**同步改唯一前端调用方**;不加版本号、不留旧接口(符合"不兼容妥协、彻底清理"原则)。
---
## F. 决策已定案(2026-09-21 用户拍板,本方案定稿)
1. **缺料补货入口** = 库存页新增 Tab「缺料补货」,与物料汇总/库位明细/区域汇总并列。
2. **拉取时机** = 打开页面实时拉一次(同现状 producible 口径),**不做定时同步**,保持 WMS/MES 两系统无定时耦合。
3. **死接口 `/api/inspection/create`createInspectionHandler= 删除**(连同其路由;实施前再全仓 grep 确认无内部/MES 调用)。
4. **待检清单分组粒度** = 按入库单为主行、展开看该单下批次/SN 明细(见 §E2)。
> 方案至此定稿,无遗留待决项。实施严格按 §C 顺序:schema→ent 重生成→db.go 幂等 DDL(含 §E7 回填)→WMS 后端→MES 后端→WMS 前端→MES 前端→帮助文档(§E5)→两侧 npm build + go build。改前端必须重编 exego:embed)。