Files
bj_power/案例.md
T
SunYF 8e6e8e1d20 docs(business): 生成业务契约文档并重构MES客户端代码
- 创建案例.md文档,包含业务场景清单、业务流程、案例和回归测试三份完整文档
- WMS库房管理系统涵盖入库、出库、库存、检验、盘点等24个业务场景
- MES产线控制系统包含工单、排产、BOM、备料、质检、追溯等23个业务场景
- 工位终端系统支持上线、报工、下线、领料、巡检等15个现场作业场景
- 主链路从合同到成品入库,异常链路处理不合格、数量不符、退料等情况
- 删除MES客户端中的ScanRecord相关代码,精简客户端结构
- 更新客户端初始化逻辑,移除扫描记录相关的依赖注入配置
2026-09-20 18:25:44 +08:00

30 KiB
Raw Blame History

任务:通读 bj_power 代码,生成业务契约文档

【你要读的代码】

  • bj_power_mes、bj_power_wms、bj_power_workstation 三个 Go 项目的 handler、logic、schema
  • 各项目 frontend/src/pages/*.vue
  • 根目录所有 .md 文档(只作背景,代码是唯一事实)

【文档定位】 这是给业务方和开发看的业务场景流水账,不是代码审计报告。 用业务语言写,人能看懂。不要贴代码,不要标行号,不要贴函数名。

【铁律】

  1. 读代码,但用业务语言描述,不暴露代码细节。
  2. 业务逻辑如果跑不通,记录下来,停止后续操作。
  3. 如何判断逻辑跑不通? 每一步,都有 前置条件、执行过程、产生的数据。如果 本步骤需要的数据条件, 前面步骤无法提供,就是业务流程不通。
  4. 不写"应该怎样"、"建议改成"、"后续优化"。
  5. 不合并场景,不擅自拆分。
  6. 英文枚举名转中文。

【第一步:列场景清单】 通读代码后,列出系统实际支持的全部业务场景。 每个场景写:场景名、从哪个菜单进入、干什么事。 清单只写代码里真实存在的。列完清单后,直接进入第二步,不要停下来等确认。

【第二步:在此文档 写三份 大标题】

文档1:业务流程 顶层地图。主链路 + 异常链路,每个节点指向“案例”的场景编号。 一个节点一句话。不重复场景内容。

文档2:案例 场景流水,禁止写分支,从头到尾只有一条路径,禁止写 "如果...就..."、"否则..."、"另一种情况"。每个场景独立成章,格式:

场景N:场景名

前置条件

操作步骤(角色 + 系统 + 菜单 + 填什么字段(关键字段即可) + 点什么按钮)

系统反应(业务语言,如"库存扣减204颗,锁定量清零")

数据变化(哪个表、哪个字段、变成什么值)

验证点(页面能看到什么、数据库断言什么、数量等式是否成立)

对不上的地方(标红,只标真正对不上的,不标"代码在哪")

文档3:回归测试 可断言用例。按场景分组,格式:

测试场景N:场景名

前置数据准备(SQL 或 API

执行步骤(API 路径 + body

预期结果(表名 + 字段 + 期望值)

数量等式断言

清理步骤

断言必须是具体数值/状态/条数,不能写"页面正常"。

【执行顺序】

  1. 列场景清单
  2. 写业务流程
  3. 写案例(一次一个场景,写完继续下一个,不要停)
  4. 写回归测试

【禁止】

  1. 禁止凭想象写业务逻辑
  2. 禁止把设计文档当事实
  3. 禁止贴代码、标行号、贴函数名
  4. 禁止写"应该"、"建议"、"后续优化"
  5. 禁止模糊断言
  6. 禁止英文枚举直接写文档
  7. 禁止在案例里写代码细节

下面是执行结果输出文本:

第一步:业务场景清单

清单只列代码里真实存在的菜单与功能。分三套系统:WMS 库房管理(端口 8890)、MES 产线控制(端口 8888)、工位终端(端口 8892)。

一、WMS 库房管理

编号 场景名 入口菜单 干什么事
W1 登录 登录页 库管员/管理员用账号密码登录,取得访问令牌
W2 工作台 工作台 查看库存总览、预警等首页概览
W3 入库登记 入库管理 结构件按批次、电气件按序列号登记入库,支持 Excel 批量导入,入库后库存增加
W4 入库作废 入库管理 对已登记入库单填原因作废,库存按批次/序列号精确回滚
W5 备料出库 出库管理 按工单备料出库,装箱、指定目标工位,库存扣减
W6 通用出库 出库管理 非工单的一般出库,库存扣减
W7 退库确认 退库确认 工位退回物料,库管确认收货后库存加回
W8 库存查询 库存查询 按物料汇总/区域汇总/明细三种口径查库存
W9 来料检验 来料检验 登记来料检验结论,合格/不合格翻转与处置
W10 过程检验 过程检验 登记生产过程检验结论与处置
W11 完工检验 完工检验 登记完工检验结论与处置
W12 库存盘点 库存盘点 发起盘点、扫码录入实盘、完成写回差异、取消、导出明细
W13 半成品入库/出库 半成品管理 半成品入库存/出库存与查询
W14 工单备料台账 工单备料台账 查看某工单各物料的锁定量/在途量/线边量/已接料量四段台账
W15 AGV 配送 AGV配送 向海康调度系统下发搬运任务、查看任务与接驳台状态、取消
W16 区域维护 区域维护 维护区域/货架/层/位置号四级库位结构,支持批量生成
W17 物料档案维护 物料档案 新增/修改/查询物料档案,支持导入导出
W18 接驳台维护 接驳台维护 查看系统预置的接驳台只读主数据
W19 账号管理 账号管理 增删改查登录账号、分配角色
W20 角色管理 角色管理 增删改查角色、配置权限
W21 操作日志 操作日志 查询系统操作留痕
W22 附件中心 附件中心 集中查看/归档/清理各业务上传的附件
W23 修改密码 修改密码 当前用户修改自己的登录密码
W24 库存大屏 库存大屏(免登录) 全屏展示库存概览

二、MES 产线控制

编号 场景名 入口菜单 干什么事
M1 工单管理 工单管理 新增/修改/查询工单、切换工单状态、自动排产
M2 日排产 日排产 为工单编排每日生产计划、推荐接驳台
M3 产品物料清单 产品物料清单 维护产品型号的 BOM,支持导入、删除条目
M4 备料单 备料单 按 BOM 生成备料单、领料、触发 WMS 自动出库、查看配送进度
M5 数量不符处理 数量不符处理 处理工位上报的物料数量不符,查看统计
M6 工位组合下发 工位组合下发 把工艺下发到 PLC,查看下发日志
M7 拧紧查询 拧紧查询 查询拧紧记录、按组统计、审计修改
M8 工艺流程 工艺流程 维护产品型号的工艺流程与工序步骤、上传工艺文件
M9 关联工位 关联工位 维护工位、配置工位与工序的派工关系
M10 绩效报表 绩效报表 按人/按工位/明细三口径统计工作量并导出
M11 巡检终端 巡检终端 登记巡检记录、上传照片、一键生成工序间检验记录
M12 质量检验 质量检验 查 BOM 物料、登记检验处置、生成不合格单
M13 在制品 在制品 查看线上在制工件
M14 手动报工 手动报工 工件上线、工序报工、完工
M15 工件追溯 工件追溯 按工件追溯全流程、面板绑定/解绑
M16 生产流程卡 生产流程卡 打印工单流程卡、查看型号全景流程卡
M17 物料档案 物料档案 维护产品型号/物料档案
M18 预警中心 预警中心 配置预警规则、查看预警、标记已读、应急呼叫
M19 附件中心 附件中心 查看/下载/归档/删除附件
M20 操作日志 操作日志 查询操作留痕
M21 账号管理 账号管理 增删改查账号、分配角色
M22 角色管理 角色管理 增删改查角色与权限
M23 修改密码 修改密码 当前用户修改密码

三、工位终端(产线现场触摸屏)

编号 场景名 入口 干什么事
S1 工位登录/登出 主界面 工位操作员登录、登出
S2 当前任务 主界面 显示本工位当前应生产的任务
S3 工件上线 上线面板 扫码工件上线建档
S4 报工/拧紧 工作面板 按工序采集数据、记录拧紧、工序完工报工、暂存
S5 工件下线/完工 下线面板 工件末道完工下线
S6 面板绑定 工作面板 工件与面板绑定/解绑
S7 移料/叫料 移动面板 产线点位移料、叫料、占用点位
S8 领料 物料面板 查看备料单、确认接料
S9 巡检 巡检面板 现场提交巡检、上传照片
S10 数量不符上报 物料面板 上报物料数量不符
S11 退料 物料面板 工位退回物料,生成 WMS 退库单
S12 应急呼叫 主界面 现场发起应急呼叫
S13 工艺文件查看 主界面 查看工序对应的工艺文件(PDF
S14 工作量查询 主界面 查看本工位工作量
S15 离线同步 主界面 断网时本地暂存、恢复后回传,查看同步状态

场景清单完毕。以下进入第二步:写三份文档(业务流程 / 案例 / 回归测试)。

文档1:业务流程

顶层地图。一个节点一句话,括号内指向「文档2:案例」的场景编号。

主链路(从合同到成品入库)

  1. 建产品型号与 BOM,定义一台产品由哪些物料、多少数量构成(M17、M3)。
  2. 维护工艺流程与工位派工,定义型号要过哪些工序、每道工序在哪个工位干(M8、M9)。
  3. 按合同建工单,一个合同对应一个工单,定下产品型号与数量(M1)。
  4. 对工单做日排产,把工单排到具体生产日并推荐接驳台(M2)。
  5. 按排产生成备料单,算出每个工位、每道工序需要哪些物料、多少量(M4)。
  6. WMS 备料出库,按备料单从库存扣料、装箱、指定目标工位,台账记「已发出」(W5)。
  7. AGV 把料从库房搬到接驳台(W15)。
  8. 工位扫码接料,备料单记「已接料」,在途量清零(S8)。
  9. 工件上线建档,一件产品进入产线(S3、M14)。
  10. 逐道工序报工,采集过程数据、记录拧紧、推进工件工序状态(S4、M14)。
  11. 过程巡检与质检,记录工序间检验结论(S9、M11、M12)。
  12. 末道完工下线,成品经内部接口自动回流 WMS 入库为成品,并按整份 BOM 反冲核销台账「已消耗」(S5)。
  13. 工件追溯与绩效统计,回看全流程、按人/工位汇总工作量(M15、M10)。

异常链路

  • 来料不合格:来料检验判不合格后做退货/让步处置(W9)。
  • 数量不符:工位上报物料数量不符(S10)→ MES 处理并生成补发备料单(M5、M4)。
  • 退料:工位退回物料(S11)→ WMS 退库确认收货、库存加回、台账记「已退回」(W7)。
  • 入库作废:入库单填原因作废,库存按批次/序列号回滚(W4)。
  • 质检不合格:质量检验判不合格并生成不合格单(M12)。
  • 盘点差异:盘点扫码录入实盘,完成时写回盘盈盘亏(W12)。
  • 拧紧超差:拧紧记录超差被审计修改并留痕(M7)。
  • 应急呼叫:工位现场发起应急呼叫,进预警中心(S12、M18)。
  • 断网离线:工位断网本地暂存,恢复后回传(S15)。

支撑域(不在主链路上,但全局依赖)

  • 主数据:区域库位四级结构(W16)、物料档案(W17/M17)、接驳台(W18)。
  • 库存查询与台账:库存三口径查询(W8)、工单备料四段量台账(W14)。
  • 权限与留痕:账号(W19/M21)、角色(W20/M22)、操作日志(W21/M20)、修改密码(W23/M23)。
  • 附件与展示:附件中心(W22/M19)、库存大屏(W24)、生产流程卡(M16)、在制品看板(M13)、预警中心(M18)。
  • 下发:工位组合下发到 PLCM6)。

文档2:案例

每个场景独立成章,从头到尾只一条路径。数据变化写到表/字段/值。本批为生产主链路(工单→排产→派工→备料→接料→上线→报工→完工→追溯)。

场景 M1:建工单

前置条件

  • 已存在产品型号(物料档案 M17),型号编码记为 CP001。

操作步骤

  • 计划员登录 MES,进「工单管理」,点「新增工单」,填:工单号 WO20260920、产品型号 CP001、数量 10、合同编号 HT001、工程编号 GC001、产品序号 01、完成日期 2026-09-30,点「保存」。

系统反应

  • 工单创建成功,状态为「已创建」,完成数量 0、NG 数量 0,创建人记为当前登录用户。

数据变化

  • work_order 表新增一行:workOrderNo=WO20260920、productCode=CP001、quantity=10、finishedNum=0、failNum=0、contractNo=HT001、projectNo=GC001、productSerial=01、status=CREATED。

验证点

  • 工单管理列表出现 WO20260920,状态「已创建」,数量 10,完成 0。
  • 数据库断言:work_order 中 workOrderNo=WO20260920 的行 status='CREATED' 且 quantity=10。

对不上的地方

  • 无,链路打通。

场景 M2:日排产

前置条件

  • 工单 WO20260920 存在(M1)。

操作步骤

  • 计划员在 MES「日排产」,选工单 WO20260920、排产日期 2026-09-20、计划数量 10,点「保存」。

系统反应

  • 生成当日排产计划,状态「待生产」,系统给出推荐接驳台。

数据变化

  • daily_plan 表新增一行:orderNo=WO20260920、planDate=2026-09-20、planQty=10、completedQty=0、status=PENDING。

验证点

  • 日排产列表出现 2026-09-20 / WO20260920 / 计划 10。
  • 数据库断言:daily_plan 中 (planDate=2026-09-20, orderNo=WO20260920) 唯一一行,planQty=10。

对不上的地方

  • 无。

场景 M9:工位派工

前置条件

  • 型号 CP001 的工艺流程含工序 1、工序 2(M8);工位 1、工位 2 已维护(M9 关联工位)。

操作步骤

  • 工艺员在 MES「关联工位」,选生效日期 2026-09-20,把工位 1 派给工序 1、工位 2 派给工序 2,点「保存」。

系统反应

  • 当日派工生效,同工位同天同班次覆盖式写入。

数据变化

  • station_process 写入行:(stationNo=1, processCode=1, effectDate=2026-09-20)、(stationNo=2, processCode=2, effectDate=2026-09-20)。

验证点

  • 数据库断言:station_process 中 effectDate=2026-09-20 存在工位1→工序1、工位2→工序2(stationNo,effectDate,shift) 唯一。

对不上的地方

  • 无。

场景 M4:生成备料单并自动出库

前置条件

  • 工单 WO20260920 已排产到 2026-09-20(M2);今日已配工位派工(M9)。
  • 型号 CP001 已配 BOM(M3):物料 M-A(结构件、单台用量 2、损耗率 0、装配工序 1)、物料 M-B(电气件、单台用量 4、装配工序 2)。
  • WMS 物料档案存在 M-A、M-BW17);WMS 有 M-A、M-B 的合格在库库存。

操作步骤

  • 计划员在 MES「备料单」,选排产日期 2026-09-20,点「生成备料单」。

系统反应

  • 系统把 BOM 展开到叶子,按工位拆料:工位 1 需 M-A = 10×2 = 20,工位 2 需 M-B = 10×4 = 40。
  • 生成前校验 M-A、M-B 在 WMS 物料档案存在(缺失则不生成并回缺料清单)。
  • 生成后把工单需求总量同步到 WMS 台账:M-A total_qty=20、M-B total_qty=40。
  • 随即自动出库:按 FIFO 从合格在库库存扣料,补足未发数量;缺料则记「备料未齐套」预警。

数据变化

  • material_request 新增行:(orderNo=WO20260920, planDate=2026-09-20, materialCode=M-A, stationNo=1, processCode=1, reqQty=20, sentQty=20, status=LOCKED)M-B 同理 reqQty=40、stationNo=2、sentQty=40。
  • WMS order_material_ledgerM-A total_qty=20、out_qty=20M-B total_qty=40、out_qty=40。
  • WMS outbound_order:新增出库单 outbound_type=workorder、status=已出库、order_no=WO20260920outbound_detail 记批次/SN 与数量。
  • WMS inventoryM-A 对应批次 quantity 减 20M-B 对应 40 个 SN status 由「在库」→「出库」。

验证点

  • 备料单列表出现 M-A(工位1,需20)、M-B(工位2,需40),已发出=需求。
  • 数量等式:material_request.sentQty ≤ reqQty;台账 net_out = out_qty returned_qty ≤ total_qty;库存可用 = quantity locked_qty ≥ 0。
  • WMS 工单备料台账(W14)显示 M-A 已发出 20 / 需求 20。

对不上的地方

  • 无。

场景 S8:工位扫码接料

前置条件

  • 备料单 M-A(工位1) 已发出 sentQty=20(M4),料已送到工位。

操作步骤

  • 工位 1 操作员在工位终端「物料面板」,扫备料单/物料码,点「接料」。

系统反应

  • 系统登记已接料,接料量不超过已发出量;接满且已发齐需求时备料单完结。

数据变化

  • material_request(M-A,工位1)receivedQty 0→20、receivedAt=当前时间、receiveBy=操作员、status LOCKED→DONE。

验证点

  • 备料单状态「已完成」,已接料 20。
  • 数量等式:在途 = sentQty receivedQty = 0receivedQty ≤ sentQty。

对不上的地方

  • 无。

场景 S3:工件上线

前置条件

  • 工单 WO20260920 存在。

操作步骤

  • 上线位操作员在工位终端「上线面板」,扫工件 SN0001、选工单 WO20260920,点「上线」。

系统反应

  • 工件建档进线,状态「已进线」,记进线时间。

数据变化

  • workpiece 新增行:sn=SN0001、orderNo=WO20260920、workOrderId=工单ID、status=ONLINE、currentProcess=0、onlineAt=当前时间。

验证点

  • 在制品(M13)出现 SN0001,状态在制,当前工位=上线位。
  • 数据库断言:workpiece sn=SN0001 status='ONLINE' currentProcess=0。

对不上的地方

  • 无。

场景 S4:工序报工

前置条件

  • 工件 SN0001 已上线(S3),currentProcess=0。
  • 工位 1 今日派工为工序 1(M9)并绑定工艺流程;本工序 BOM 物料 M-A 已在工位接料(S8)。

操作步骤

  • 工位 1 操作员在「工作面板」,上料时系统记开始时间,装配后录入各步骤实测值、勾选需检测确认的步骤、绑定本工序装配物料(M-A 批次号),点「报工」。

系统反应

  • 系统强校验:工件在制、本工位是下一道工序(工序号=已完成工序+1)、装配物料齐套、需检测确认的步骤已勾选。
  • 校验通过后写报工实绩与步骤考核,按考核标准判定 OK/NG,推进工件工序状态。

数据变化

  • workpiece_process 新增行:sn=SN0001、processCode=1、stationNo=1、status=DONE、result=OK(全部步骤合格)或 NG、operator、startedAt/endedAt/durationSec。
  • step_data 新增各步骤实测行:value、is_ok 按考核标准判定。
  • workpiece_bind:本工序绑定的 M-A 批次落库。
  • workpiece(SN0001)currentProcess 0→1status ONLINE→PROCESSING。

验证点

  • 报工记录(M14)出现 SN0001 工序1 记录,结果 OK。
  • 数量等式:workpiece.currentProcess = 已报工工序数;durationSec = endedAt startedAt(≥0)。
  • 数据库断言:workpiece_process(sn=SN0001,processCode=1) 存在且 status='DONE'。

对不上的地方

  • 无。(跳站/漏站/工件非在制/物料未绑齐/需检测步骤未勾选时,报工被拒——属前置校验,非链路断裂。)

场景 S5:完工下线并成品回流入库

前置条件

  • 工件 SN0001 已报完全部工序(S4),当前工序=末道工序;全部工序装配物料已绑齐。

操作步骤

  • 下线位操作员在「下线面板」,扫工件 SN0001,录入结构件批次清单/电气件 SN 清单,点「完工」。

系统反应

  • 系统兜底校验全部工序物料齐套,登记完工,生成成品关联追溯。
  • 成品经内部接口自动回流 WMS,入库为成品;并按整份 BOM 反冲核销工单台账「已消耗」。
  • 工单完成数量 +1,日排产完成数量 +1。

数据变化

  • workpiece(SN0001)status PROCESSING→DONEdoneAt=当前时间。
  • association_trace 新增/更新:finishedSn=SN0001、orderNo=WO20260920、batchItems=[结构件批次]、serialItems=[电气件SN]、operator。
  • work_order(WO20260920)finishedNum +1daily_plancompletedQty +1。
  • WMS inventory:新增成品行 category=3、material_code=CP001、sn_code=SN0001、manage_mode=2、quantity=1、order_no=WO20260920、status=在库。
  • WMS order_material_ledgerM-A、M-B 的 consumed_qty 按整份 BOM 单件消耗累加(核销上限=net_out−已消耗)。

验证点

  • 在制品不再显示 SN0001;工件追溯(M15)可查到全流程。
  • WMS 库存查询(W8)成品口径出现 CP001/SN0001。
  • 数量等式:consumed_qty ≤ net_out_qty = out_qty returned_qty;工单 finishedNum ≤ quantity。

对不上的地方

  • 反冲只核销台账 consumed_qty,不扣库存、不生成出库单(WMS 实际行为);但 MES 侧完工反冲的实现注释写「生成 backflush 出库单」,与 WMS 实际行为对不上。业务链路本身打通(库存已在备料出库时扣过,不重复扣),仅注释误导。

场景 M15:工件追溯

前置条件

  • 工件 SN0001 已完工(S5)。

操作步骤

  • 质量员在 MES「工件追溯」,输入 SN0001,点「查询」。

系统反应

  • 系统按 SN 汇总工序时间线、操作人、步骤数据、装配物料批次/SN、拧紧数据、成品关联追溯。

数据变化

  • 只读,无写入。

验证点

  • 页面显示 SN0001 全部工序记录、绑定的结构件批次与电气件 SN、拧紧记录。
  • 数据库断言:association_trace finishedSn=SN0001 的 batchItems/serialItems 与页面一致。

对不上的地方

  • 无。

文档3:回归测试

可断言用例,按场景分组。断言为具体数值/状态/条数。MES 接口前缀 /api/v1(需 JWT);WMS 接口前缀 /api(需 JWT);内部接口带 X-API-TOKEN。 公共前置:用管理员账号 POST /api/v1/login 取 token,后续 MES 请求带 Authorization: Bearer WMS 同理 POST /api/auth/login。

测试场景 M1:建工单

前置数据准备(SQL

  • 确保产品型号存在:INSERT INTO product_type(code,name) VALUES('CP001','测试产品') ON CONFLICT DO NOTHING;(取回其 id 记为 :ptId

执行步骤(API

  • POST /api/v1/work-ordersbody{"workOrderNo":"WO20260920","productTypeId":,"productCode":"CP001","productName":"测试产品","quantity":10,"contractNo":"HT001","projectNo":"GC001","productSerial":"01","dueDate":"2026-09-30T00:00:00Z"}

预期结果

  • work_orderworkOrderNo='WO20260920' 新增一行,status='CREATED'、quantity=10、finishedNum=0、failNum=0、contractNo='HT001'。

数量等式断言

  • SELECT count(*) FROM work_order WHERE workOrderNo='WO20260920' → 1finishedNum=0 且 finishedNum ≤ quantity。

清理步骤

  • DELETE FROM work_order WHERE workOrderNo='WO20260920';

测试场景 M2:日排产

前置数据准备

  • 工单 WO20260920 存在(M1)。

执行步骤(API

  • POST /api/v1/daily-plansbody{"orderNo":"WO20260920","planDate":"2026-09-20","planQty":10}

预期结果

  • daily_plan(orderNo='WO20260920',planDate='2026-09-20') 新增一行,planQty=10、completedQty=0、status='PENDING'。

数量等式断言

  • SELECT count(*) FROM daily_plan WHERE orderNo='WO20260920' AND planDate='2026-09-20' → 1planDate+orderNo 唯一)。

清理步骤

  • DELETE FROM daily_plan WHERE orderNo='WO20260920' AND planDate='2026-09-20';

测试场景 M9:工位派工

前置数据准备

  • 工位 1、2 存在(station 表)。

执行步骤(API

  • POST /api/v1/station-process/savebody{"effectDate":"2026-09-20","items":[{"stationNo":1,"processCode":1},{"stationNo":2,"processCode":2}]}

预期结果

  • station_processeffectDate='2026-09-20' 存在 (stationNo=1,processCode=1) 与 (stationNo=2,processCode=2)。

数量等式断言

  • SELECT count(*) FROM station_process WHERE effectDate='2026-09-20' AND stationNo IN(1,2) → 2(stationNo,effectDate,shift) 无重复。

清理步骤

  • DELETE FROM station_process WHERE effectDate='2026-09-20';

测试场景 M4:生成备料单并自动出库

前置数据准备(SQL/API

  • BOMMES work_order_bom):INSERT 两行:(productCode='CP001',bomName='默认',materialCode='M-A',manageMode='1',processCode=1,unitQty=2,lossRate=0)、(productCode='CP001',bomName='默认',materialCode='M-B',manageMode='2',processCode=2,unitQty=4,lossRate=0)。
  • WMS 物料档案:POST /api/material/create 建 M-A(结构件)、M-B(电气件)。
  • WMS 合格在库库存:
    • INSERT INTO inventories(manage_mode,category,material_code,batch_no,quantity,locked_qty,quality_status,status) VALUES(1,1,'M-A','B001',100,0,'合格','在库');
    • 电气件 M-B 插 40 行 SNINSERT INTO inventories(manage_mode,category,material_code,sn_code,quantity,locked_qty,quality_status,status) VALUES(2,1,'M-B','SNB0001',1,0,'合格','在库'); … 至 'SNB0040'。
  • 已存在 M1/M2/M9 的前置数据。

执行步骤(API

  • POST /api/v1/material-requests/generatebody{"planDate":"2026-09-20"}

预期结果

  • material_request:新增 (orderNo='WO20260920',materialCode='M-A',stationNo=1,processCode=1,reqQty=20,sentQty=20,status='LOCKED') 与 (materialCode='M-B',stationNo=2,reqQty=40,sentQty=40,status='LOCKED')。
  • WMS order_material_ledger(WO20260920,'M-A') total_qty=20、out_qty=20(WO20260920,'M-B') total_qty=40、out_qty=40。
  • WMS outbound_order:新增 outbound_type='workorder'、status='已出库'、order_no='WO20260920' 的出库单。
  • WMS inventoriesM-A 批次 B001 quantity 100→80M-B 的 40 个 SN status '在库'→'出库'。

数量等式断言

  • material_request.sentQty ≤ reqQtyM-A:20≤20M-B:40≤40)。
  • ledger net_out = out_qty returned_qty ≤ total_qty20≤2040≤40)。
  • SELECT quantity FROM inventories WHERE batch_no='B001' → 80SELECT count(*) FROM inventories WHERE material_code='M-B' AND status='出库' → 40。

清理步骤

  • DELETE FROM material_request WHERE orderNo='WO20260920';
  • WMSDELETE FROM outbound_detail WHERE order_no='WO20260920'; DELETE FROM outbound_order WHERE order_no='WO20260920'; DELETE FROM order_material_ledger WHERE order_no='WO20260920';
  • 回滚库存:UPDATE inventories SET quantity=100 WHERE batch_no='B001'; UPDATE inventories SET status='在库' WHERE material_code='M-B';

测试场景 S8:工位接料

前置数据准备

  • 备料单 M-A(工位1) sentQty=20、status='LOCKED'M4)。

执行步骤(API

  • POST /api/v1/material-requests/receivebody{"requestNo":"<M-A备料单号>","qty":0}qty=0 表示接本批全部剩余)

预期结果

  • material_request(M-A)receivedQty=20、status='DONE'、receiveBy 非空、receivedAt>0。

数量等式断言

  • 在途 = sentQty receivedQty = 0receivedQty ≤ sentQty20≤20)。

清理步骤

  • 随 M4 清理一并删除 material_request。

测试场景 S3:工件上线

前置数据准备

  • 工单 WO20260920 存在。

执行步骤(API

  • POST /api/v1/workpiece/onlinebody{"sn":"SN0001","orderNo":"WO20260920"}

预期结果

  • workpiecesn='SN0001' 新增一行,status='ONLINE'、currentProcess=0、onlineAt 非空。

数量等式断言

  • SELECT count(*) FROM workpiece WHERE sn='SN0001' → 1sn 全局唯一。

清理步骤

  • DELETE FROM workpiece WHERE sn='SN0001';

测试场景 S4:工序报工

前置数据准备

  • 工件 SN0001 已上线(S3),currentProcess=0。
  • 工位 1 已绑定工艺流程(station.flowId>0),流程含工序 1 的步骤与考核标准;BOM 中 M-A processCode=1。

执行步骤(API

  • POST /api/v1/workpiece/process/reportbody{"sn":"SN0001","processCode":1,"stationNo":1,"binds":[{"materialCode":"M-A","batchNo":"B001"}],"steps":[{"stepId":<步骤id>,"name":"步骤1","value":10,"checked":true}],"startedAt":"2026-09-20T09:00:00Z","endedAt":"2026-09-20T09:05:00Z"}

预期结果

  • workpiece_process(sn='SN0001',processCode=1) 新增一行,status='DONE'、result='OK'(步骤均合格)、durationSec=300。
  • step_data:对应步骤行 is_ok=true。
  • workpiece(SN0001)currentProcess=1、status='PROCESSING'。

数量等式断言

  • workpiece.currentProcess = SELECT count(*) FROM workpiece_process WHERE sn='SN0001' AND status='DONE' → 1。
  • durationSec = endedAtstartedAt = 300(≥0)。
  • 负用例:再次以 processCode=1 报工 → 拒绝(工序顺序不符,应报工序 2);以 processCode=3 报工 → 拒绝。

清理步骤

  • DELETE FROM step_data WHERE sn='SN0001'; DELETE FROM workpiece_process WHERE sn='SN0001'; DELETE FROM workpiece_bind WHERE sn='SN0001';

测试场景 S5:完工下线并成品回流

前置数据准备

  • 工件 SN0001 已报完全部工序(本例工序总数=2,先完成工序 2 报工),全部工序物料已绑齐。

执行步骤(API

  • POST /api/v1/workpiece/donebody{"sn":"SN0001","batchItems":["B001"],"serialItems":["SNB0001"]}

预期结果

  • workpiece(SN0001)status='DONE'、doneAt 非空。
  • association_tracefinishedSn='SN0001' 新增/更新,batchItems=['B001']、serialItems=['SNB0001']。
  • work_order(WO20260920)finishedNum 由 0→1daily_plan(2026-09-20)completedQty 由 0→1。
  • WMS inventories:新增成品行 category=3、material_code='CP001'、sn_code='SN0001'、quantity=1、status='在库'、order_no='WO20260920'。
  • WMS order_material_ledgerM-A consumed_qty=2(单台用量2×完工1件)、M-B consumed_qty=4。

数量等式断言

  • work_order.finishedNum=1 且 ≤ quantity(10)。
  • ledger consumed_qty ≤ net_out_qtyM-A:2≤20M-B:4≤40)。
  • SELECT count(*) FROM inventories WHERE sn_code='SN0001' AND category=3 → 1。

清理步骤

  • DELETE FROM association_trace WHERE finishedSn='SN0001';
  • WMSDELETE FROM inventories WHERE sn_code='SN0001' AND category=3; UPDATE order_material_ledger SET consumed_qty=0 WHERE order_no='WO20260920';

测试场景 M15:工件追溯

前置数据准备

  • 工件 SN0001 已完工(S5)。

执行步骤(API

  • GET /api/v1/trace?sn=SN0001

预期结果

  • 返回体含 workpiece、processTimeline(工序记录条数=已报工工序数)、associationTracebatchItems/serialItems)、torqueRecords。

数量等式断言

  • processTimeline 条数 = SELECT count(*) FROM workpiece_process WHERE sn='SN0001'。
  • associationTrace.finishedSn='SN0001' 与入参一致。

清理步骤

  • 无写入,无需清理。