|
|
|
|
@ -0,0 +1,912 @@
|
|
|
|
|
# WMS-QMS 质检集成需求与方案文档
|
|
|
|
|
|
|
|
|
|
## 文档版本历史
|
|
|
|
|
|
|
|
|
|
| 版本 | 日期 | 修订内容 | 作者 |
|
|
|
|
|
|-----|------|---------|------|
|
|
|
|
|
| 1.0 | 2026-01-15 | 初始版本,完整需求与方案设计 | zch |
|
|
|
|
|
| 1.1 | 2026-01-15 | 新增独立文件实现,添加代码实现章节 | zch |
|
|
|
|
|
| 1.2 | 2026-01-15 | 修复Code Review问题:创建独立 Dubbo 实现类、修复状态映射、添加批次号过滤 | zch |
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 目录
|
|
|
|
|
|
|
|
|
|
- [1. 需求概述](#1-需求概述)
|
|
|
|
|
- [2. 业务流程](#2-业务流程)
|
|
|
|
|
- [3. 数据模型](#3-数据模型)
|
|
|
|
|
- [4. 接口设计](#4-接口设计)
|
|
|
|
|
- [5. 新增文件清单](#5-新增文件清单)
|
|
|
|
|
- [6. 技术实现方案](#6-技术实现方案)
|
|
|
|
|
- [7. 前端改造](#7-前端改造)
|
|
|
|
|
- [8. 分布式事务处理](#8-分布式事务处理)
|
|
|
|
|
- [9. 让步接收方案(待讨论)](#9-让步接收方案待讨论)
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 1. 需求概述
|
|
|
|
|
|
|
|
|
|
### 1.1 背景
|
|
|
|
|
|
|
|
|
|
WMS(仓储管理系统)与 QMS(质量管理系统)需要实现质检业务闭环,支持以下场景:
|
|
|
|
|
|
|
|
|
|
1. **WMS 主动发起质检**:通过前端界面手动选择批次,调用 QMS 创建质检任务
|
|
|
|
|
2. **QMS 质检完成回调**:质检完成后通知 WMS,更新批次质检状态
|
|
|
|
|
3. **PDA 扫码入库**:根据质检状态,PDA 扫码完成实际入库操作
|
|
|
|
|
4. **让步接收闭环**:不合格品让步接收后,支持 PDA 扫码入库
|
|
|
|
|
|
|
|
|
|
### 1.2 核心需求
|
|
|
|
|
|
|
|
|
|
| 需求点 | 说明 | 优先级 |
|
|
|
|
|
|-------|------|--------|
|
|
|
|
|
| 手动发起质检 | 打印标签后不自动创建质检任务,通过前端界面手动选择批次发起 | 高 |
|
|
|
|
|
| 质检完成通知 | QMS 质检完成后回调 WMS,更新批次质检状态 | 高 |
|
|
|
|
|
| 合格数量入库 | 质检合格的批次,PDA 扫码完成入库 | 高 |
|
|
|
|
|
| 让步接收入库 | 不合格品让步接收后,PDA 扫码完成入库 | 中 |
|
|
|
|
|
| 批次追溯 | 全流程保持批次号一致性,确保可追溯 | 高 |
|
|
|
|
|
|
|
|
|
|
### 1.3 核心数据表
|
|
|
|
|
- 质检qms模块通用模块版本只关注qc_inspection_item、qc_inspection_item_category、qc_inspection_main、qc_inspection_main_file_relation、qc_inspection_result、qc_inspection_template、qc_template_item、qc_unqualified_record、qc_unqualified_review!
|
|
|
|
|
- hwmom-wms核心关注base_measurement_unit_info、base_supplier_info1、base_material_category、base_material_type、base_material_info_copy1 / base_material_info、wms_base_customer、wms_base_area、wms_base_location、wms_base_warehouse、wms_allocate_order、wms_allocate_order_detail、wms_allocate_task、wms_check_task、wms_purchase_order、wms_purchase_order_detail、wms_instock_detail、wms_instock_order、wms_instock_print、wms_instock_record、wms_inventory、wms_inventory_check、wms_inventory_check_record、wms_outstock_detail、wms_outstock_order、wms_outstock_record!
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 2. 业务流程
|
|
|
|
|
|
|
|
|
|
### 2.1 整体业务流程图
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
|
|
|
│ WMS-QMS 质检闭环完整流程 │
|
|
|
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
|
|
|
│ │
|
|
|
|
|
│ 【步骤1】打印标签 │
|
|
|
|
|
│ ├─ 生成 wms_instock_print 记录 │
|
|
|
|
|
│ ├─ inspection_type='0'(未发起) │
|
|
|
|
|
│ └─ inspection_request='0/1'(必检/免检) │
|
|
|
|
|
│ │
|
|
|
|
|
│ 【步骤2】前端发起质检(新功能) │
|
|
|
|
|
│ ├─ qc.vue 界面选择批次 │
|
|
|
|
|
│ ├─ 过滤:inspection_request='0'且 inspection_type='0' │
|
|
|
|
|
│ ├─ 点击"发起质检"按钮 │
|
|
|
|
|
│ └─ POST /wms/instockPrint/createInspection │
|
|
|
|
|
│ │
|
|
|
|
|
│ 【步骤3】WMS 调用 QMS 创建质检任务 │
|
|
|
|
|
│ ├─ @GlobalTransactional(调用方加注解) │
|
|
|
|
|
│ ├─ remoteQmsInspectionService.createInspectionTaskForWMS() │
|
|
|
|
|
│ └─ 更新打印记录:inspection_type='1'(质检中) │
|
|
|
|
|
│ │
|
|
|
|
|
│ 【步骤4】PDA 质检执行 │
|
|
|
|
|
│ ├─ 质检员填写检测结果 │
|
|
|
|
|
│ ├─ 保存到 qc_inspection_result │
|
|
|
|
|
│ └─ 更新 qc_inspection_main:status='1', result='0/1' │
|
|
|
|
|
│ qualifiedQty=?, unqualifiedQty=? │
|
|
|
|
|
│ │
|
|
|
|
|
│ 【步骤5】QMS 回调 WMS(质检完成) │
|
|
|
|
|
│ ├─ @GlobalTransactional(调用方加注解) │
|
|
|
|
|
│ ├─ remoteWmsInspectionService.notifyInspectionComplete() │
|
|
|
|
|
│ ├─ 传递批次号和合格/不合格数量 │
|
|
|
|
|
│ └─ 只更新质检状态,❌ 不创建入库记录 │
|
|
|
|
|
│ ├─ 合格:inspection_type='2' │
|
|
|
|
|
│ └─ 不合格:inspection_type='3' │
|
|
|
|
|
│ │
|
|
|
|
|
│ 【步骤6】PDA 扫码入库(合格批次) │
|
|
|
|
|
│ ├─ POST /pda/instock/submit │
|
|
|
|
|
│ ├─ 过滤:inspection_type='2'(合格) │
|
|
|
|
|
│ ├─ 创建 wms_instock_record 记录 │
|
|
|
|
|
│ ├─ 更新库存 wms_inventory │
|
|
|
|
|
│ └─ 更新打印记录:inbound_status='1'(已入库) │
|
|
|
|
|
│ │
|
|
|
|
|
│ 【步骤7】让步接收(待讨论) │
|
|
|
|
|
│ ├─ 不合格品评审 → 让步接收 │
|
|
|
|
|
│ ├─ QMS 回调 WMS(与步骤5类似) │
|
|
|
|
|
│ ├─ 更新质检状态:inspection_type='2'(合格) │
|
|
|
|
|
│ └─ PDA 扫码入库(与步骤6类似) │
|
|
|
|
|
│ │
|
|
|
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 2.2 状态流转说明
|
|
|
|
|
|
|
|
|
|
#### inspection_type(质检状态)字段
|
|
|
|
|
|
|
|
|
|
| 值 | 说明 | 触发条件 | 后续操作 |
|
|
|
|
|
|---|------|---------|---------|
|
|
|
|
|
| 0 | 未发起 | 打印标签后默认 | 前端发起质检 |
|
|
|
|
|
| 1 | 质检中 | WMS 调用 QMS 创建质检任务后 | PDA 质检执行 |
|
|
|
|
|
| 2 | 合格 | QMS 回调 WMS 更新状态后 | PDA 扫码入库 |
|
|
|
|
|
| 3 | 不合格 | QMS 回调 WMS 更新状态后 | 不合格品评审 |
|
|
|
|
|
|
|
|
|
|
#### inbound_status(入库状态)字段
|
|
|
|
|
|
|
|
|
|
| 值 | 说明 | 触发条件 |
|
|
|
|
|
|---|------|---------|
|
|
|
|
|
| 0 | 待入库 | 打印标签后默认 |
|
|
|
|
|
| 1 | 已入库 | PDA 扫码入库成功 |
|
|
|
|
|
| 2 | 入库中 | 预留,当前未使用 |
|
|
|
|
|
| 3 | 拒收 | 预留,当前未使用 |
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 3. 数据模型
|
|
|
|
|
|
|
|
|
|
### 3.1 核心数据表
|
|
|
|
|
|
|
|
|
|
#### wms_instock_print(入库打印记录表)
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 | 示例 |
|
|
|
|
|
|-----|------|------|------|
|
|
|
|
|
| instock_print_id | bigint | 主键 | 123 |
|
|
|
|
|
| instock_code | varchar(64) | 入库单号 | RK202501150001 |
|
|
|
|
|
| batch_code | varchar(64) | 批次号 | BATCH001 |
|
|
|
|
|
| material_code | varchar(64) | 物料编码 | MAT001 |
|
|
|
|
|
| material_name | varchar(128) | 物料名称 | 橡胶 |
|
|
|
|
|
| apportion_qty | decimal(16,2) | 条码数量(分包数量) | 100.00 |
|
|
|
|
|
| inspection_request | char(1) | 质检要求(0=必检,1=免检) | 0 |
|
|
|
|
|
| inspection_type | char(1) | 质检状态(0未发起,1质检中,2合格,3不合格) | 1 |
|
|
|
|
|
| inbound_status | char(1) | 入库状态(0待入库,1已入库) | 0 |
|
|
|
|
|
| actual_inbound_time | datetime | 实际入库时间 | 2026-01-15 10:00:00 |
|
|
|
|
|
|
|
|
|
|
#### wms_instock_record(入库记录表)
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 | 示例 |
|
|
|
|
|
|-----|------|------|------|
|
|
|
|
|
| instock_record_id | bigint | 主键 | 456 |
|
|
|
|
|
| instock_code | varchar(64) | 入库单号 | RK202501150001 |
|
|
|
|
|
| batch_code | varchar(64) | 批次号 | BATCH001 |
|
|
|
|
|
| material_code | varchar(64) | 物料编码 | MAT001 |
|
|
|
|
|
| instock_qty | decimal(16,2) | 入库数量 | 100.00 |
|
|
|
|
|
| instock_time | datetime | 入库时间 | 2026-01-15 10:00:00 |
|
|
|
|
|
|
|
|
|
|
#### wms_inventory(库存表)
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|
|
|-----|------|------|
|
|
|
|
|
| inventory_id | bigint | 主键 |
|
|
|
|
|
| batch_code | varchar(64) | 批次号 |
|
|
|
|
|
| material_id | bigint | 物料ID |
|
|
|
|
|
| store_id | bigint | 仓库ID |
|
|
|
|
|
| location_code | varchar(64) | 库位编码 |
|
|
|
|
|
| inventory_qty | decimal(16,2) | 库存数量 |
|
|
|
|
|
| lock_state | char(1) | 锁定状态(0未锁定,1锁定) |
|
|
|
|
|
| inventory_status | char(1) | 库存状态(0归零,1正常) |
|
|
|
|
|
|
|
|
|
|
#### qc_inspection_main(质检主表)
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 | 关联关系 |
|
|
|
|
|
|-----|------|------|---------|
|
|
|
|
|
| inspection_id | bigint | 质检主键 | - |
|
|
|
|
|
| inspection_no | varchar(64) | 质检单号 | - |
|
|
|
|
|
| template_id | bigint | 模板ID | - |
|
|
|
|
|
| material_code | varchar(64) | 物料编码 | 关联 wms_instock_print |
|
|
|
|
|
| inspection_qty | decimal(16,2) | 质检数量 | - |
|
|
|
|
|
| qualified_qty | decimal(16,2) | 合格数量 | - |
|
|
|
|
|
| unqualified_qty | decimal(16,2) | 不合格数量 | - |
|
|
|
|
|
| result | char(1) | 质检结果(0合格,1不合格) | - |
|
|
|
|
|
| status | char(1) | 单据状态(0未处理,1完成) | - |
|
|
|
|
|
| batch_no | varchar(64) | 批次号 | 关联 wms_instock_print.batch_code |
|
|
|
|
|
| production_order | varchar(64) | 生产订单号/业务来源单号 | 可存储入库单号 |
|
|
|
|
|
| remark | varchar(512) | 备注 | 可存储入库单号 |
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 4. 接口设计
|
|
|
|
|
|
|
|
|
|
### 4.1 WMS 发起质检接口
|
|
|
|
|
|
|
|
|
|
#### 接口定义
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
/**
|
|
|
|
|
* 批量发起质检任务
|
|
|
|
|
* 前端选择批次后调用此接口创建质检任务
|
|
|
|
|
*
|
|
|
|
|
* @param prints 选中的打印记录列表
|
|
|
|
|
* @return Map<批次号, 质检单号或错误信息>
|
|
|
|
|
*/
|
|
|
|
|
@PostMapping("/createInspection")
|
|
|
|
|
public R<Map<String, String>> createInspection(@RequestBody List<WmsInstockPrintBo> prints)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 请求参数
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
"instockPrintId": 123,
|
|
|
|
|
"instockCode": "RK202501150001",
|
|
|
|
|
"batchCode": "BATCH001",
|
|
|
|
|
"materialCode": "MAT001",
|
|
|
|
|
"materialName": "橡胶",
|
|
|
|
|
"apportionQty": 100.00,
|
|
|
|
|
"inspectionRequest": "0"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"instockPrintId": 124,
|
|
|
|
|
"instockCode": "RK202501150001",
|
|
|
|
|
"batchCode": "BATCH002",
|
|
|
|
|
"materialCode": "MAT001",
|
|
|
|
|
"materialName": "橡胶",
|
|
|
|
|
"apportionQty": 50.00,
|
|
|
|
|
"inspectionRequest": "0"
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 响应结果
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"code": 200,
|
|
|
|
|
"msg": "操作成功",
|
|
|
|
|
"data": {
|
|
|
|
|
"BATCH001": "QC202501150001",
|
|
|
|
|
"BATCH002": "QC202501150002"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 4.2 QMS 质检完成回调接口(WMS 暴露给 QMS)
|
|
|
|
|
|
|
|
|
|
#### Dubbo 接口定义
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
/**
|
|
|
|
|
* WMS 暴露给 QMS 的质检完成回调接口
|
|
|
|
|
* QMS 质检完成后调用此接口通知 WMS
|
|
|
|
|
*/
|
|
|
|
|
public interface RemoteWmsInspectionService {
|
|
|
|
|
/**
|
|
|
|
|
* 质检完成回调
|
|
|
|
|
* @param notification 质检完成通知
|
|
|
|
|
*/
|
|
|
|
|
void notifyInspectionComplete(InspectionCompleteNotification notification);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 回调参数
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
public class InspectionCompleteNotification implements Serializable {
|
|
|
|
|
private String inspectionNo; // 质检单号(必填)
|
|
|
|
|
private String instockCode; // 入库单号(必填)
|
|
|
|
|
private String batchCode; // 批次号(必填,精确匹配)
|
|
|
|
|
private String result; // 质检结果:0=合格,1=不合格(必填)
|
|
|
|
|
private String status; // 质检状态:0=未处理,1=已完成(必填)
|
|
|
|
|
private BigDecimal qualifiedQty; // 合格数量(必填)
|
|
|
|
|
private BigDecimal unqualifiedQty; // 不合格数量(必填)
|
|
|
|
|
private String materialCode; // 物料编码(可选)
|
|
|
|
|
private String inspectionEndTime; // 质检完成时间(可选)
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 5. 新增文件清单
|
|
|
|
|
|
|
|
|
|
### 5.1 设计原则
|
|
|
|
|
|
|
|
|
|
**核心原则**:独立新建Java文件,不修改现有文件,便于查看和调试
|
|
|
|
|
|
|
|
|
|
1. **模块化设计**:将WMS-QMS集成相关的业务逻辑抽离到独立的服务类
|
|
|
|
|
2. **复用现有服务**:新文件可调用现有服务方法,避免重复代码
|
|
|
|
|
3. **便于维护**:独立文件便于定位问题、调试和后续扩展
|
|
|
|
|
4. **职责清晰**:每个文件职责单一,符合SOLID原则
|
|
|
|
|
|
|
|
|
|
### 5.2 WMS模块新增文件
|
|
|
|
|
|
|
|
|
|
| 文件路径 | 类型 | 说明 |
|
|
|
|
|
|---------|------|------|
|
|
|
|
|
| `service/IWmsInspectionInitiationService.java` | 接口 | WMS发起质检服务接口 |
|
|
|
|
|
| `service/impl/WmsInspectionInitiationServiceImpl.java` | 实现 | WMS发起质检服务实现 |
|
|
|
|
|
| `service/IWmsInspectionCallbackService.java` | 接口 | WMS接收QMS回调服务接口 |
|
|
|
|
|
| `service/impl/WmsInspectionCallbackServiceImpl.java` | 实现 | WMS接收QMS回调服务实现(本地服务) |
|
|
|
|
|
| `dubbo/RemoteWmsInspectionCallbackServiceImpl.java` | 实现 | WMS Dubbo服务实现(实现RemoteWmsInstockService) |
|
|
|
|
|
| `controller/api/apiController.java` | 修改 | REST API回调接口(添加@Transactional、批次号过滤、状态映射) |
|
|
|
|
|
| `controller/WmsInstockPrintController.java` | 修改 | 添加`createInspection`端点 |
|
|
|
|
|
|
|
|
|
|
### 5.3 QMS模块新增文件
|
|
|
|
|
|
|
|
|
|
| 文件路径 | 类型 | 说明 |
|
|
|
|
|
|---------|------|------|
|
|
|
|
|
| `service/IQcWmsCallbackService.java` | 接口 | QMS回调WMS服务接口 |
|
|
|
|
|
| `service/impl/QcWmsCallbackServiceImpl.java` | 实现 | QMS回调WMS服务实现 |
|
|
|
|
|
|
|
|
|
|
### 5.4 API模块修改文件
|
|
|
|
|
|
|
|
|
|
| 文件路径 | 类型 | 说明 |
|
|
|
|
|
|---------|------|------|
|
|
|
|
|
| `hwmom-api-qms/src/main/java/org/dromara/qms/api/dto/InspectionCompleteNotification.java` | 修改 | 添加`batchCode`字段 |
|
|
|
|
|
|
|
|
|
|
### 5.5 文件依赖关系图
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
|
|
|
│ 新增文件依赖关系 │
|
|
|
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
|
|
|
│ │
|
|
|
|
|
│ 【WMS模块】 │
|
|
|
|
|
│ ┌──────────────────────────────────────────────────────────┐ │
|
|
|
|
|
│ │ WmsInstockPrintController │ │
|
|
|
|
|
│ │ └── @PostMapping("/createInspection") │ │
|
|
|
|
|
│ │ └── IWmsInspectionInitiationService │ │
|
|
|
|
|
│ └──────────────────────────────────────────────────────────┘ │
|
|
|
|
|
│ ↓ │
|
|
|
|
|
│ ┌──────────────────────────────────────────────────────────┐ │
|
|
|
|
|
│ │ WmsInspectionInitiationServiceImpl │ │
|
|
|
|
|
│ │ ├── @DubboReference RemoteQmsInspectionService │ │
|
|
|
|
|
│ │ └── 复用 IWmsInstockPrintService │ │
|
|
|
|
|
│ └──────────────────────────────────────────────────────────┘ │
|
|
|
|
|
│ ↓ │
|
|
|
|
|
│ 【调用QMS Dubbo】 │
|
|
|
|
|
│ │
|
|
|
|
|
│ 【QMS模块】 │
|
|
|
|
|
│ ┌──────────────────────────────────────────────────────────┐ │
|
|
|
|
|
│ │ QcPDAServiceImpl (现有文件,复用) │ │
|
|
|
|
|
│ │ └── submitInspection() │ │
|
|
|
|
|
│ │ └── 调用 IQcWmsCallbackService.notifyWmsForQualified│ │ │
|
|
|
|
|
│ └──────────────────────────────────────────────────────────┘ │
|
|
|
|
|
│ ↓ │
|
|
|
|
|
│ ┌──────────────────────────────────────────────────────────┐ │
|
|
|
|
|
│ │ QcWmsCallbackServiceImpl (新增) │ │
|
|
|
|
|
│ │ ├── @DubboReference RemoteWmsInspectionService │ │
|
|
|
|
|
│ │ └── 复用 IQcInspectionMainService │ │
|
|
|
|
|
│ └──────────────────────────────────────────────────────────┘ │
|
|
|
|
|
│ ↓ │
|
|
|
|
|
│ 【回调WMS Dubbo】 │
|
|
|
|
|
│ │
|
|
|
|
|
│ 【WMS模块】 │
|
|
|
|
|
│ ┌──────────────────────────────────────────────────────────┐ │
|
|
|
|
|
│ │ WmsInspectionCallbackServiceImpl (@DubboService) │ │
|
|
|
|
|
│ │ └── handleInspectionComplete() │ │
|
|
|
|
|
│ │ └── 复用 IWmsInstockPrintService.updateByBo() │ │
|
|
|
|
|
│ └──────────────────────────────────────────────────────────┘ │
|
|
|
|
|
│ │
|
|
|
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 5.6 关键代码示例
|
|
|
|
|
|
|
|
|
|
#### WMS发起质检服务实现
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
// WmsInspectionInitiationServiceImpl.java
|
|
|
|
|
@Service
|
|
|
|
|
public class WmsInspectionInitiationServiceImpl implements IWmsInspectionInitiationService {
|
|
|
|
|
|
|
|
|
|
@DubboReference(timeout = 300000)
|
|
|
|
|
private RemoteQmsInspectionService remoteQmsInspectionService;
|
|
|
|
|
|
|
|
|
|
private final IWmsInstockPrintService instockPrintService;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Map<String, String> createInspection(List<WmsInstockPrintBo> prints) {
|
|
|
|
|
Map<String, String> result = new LinkedHashMap<>();
|
|
|
|
|
for (WmsInstockPrintBo print : prints) {
|
|
|
|
|
// 1. 校验是否可以发起质检
|
|
|
|
|
String reason = getCannotInitiateReason(print);
|
|
|
|
|
if (reason != null) {
|
|
|
|
|
result.put(print.getBatchCode(), "跳过: " + reason);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// 2. 调用 QMS Dubbo 接口
|
|
|
|
|
String inspectionNo = remoteQmsInspectionService.createInspectionTaskForWMS(request);
|
|
|
|
|
// 3. 更新本地状态
|
|
|
|
|
updateInspectionType(print.getInstockPrintId(), "1");
|
|
|
|
|
result.put(print.getBatchCode(), inspectionNo);
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### QMS回调WMS服务实现
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
// QcWmsCallbackServiceImpl.java
|
|
|
|
|
@Service
|
|
|
|
|
public class QcWmsCallbackServiceImpl implements IQcWmsCallbackService {
|
|
|
|
|
|
|
|
|
|
@DubboReference(timeout = 300000)
|
|
|
|
|
private RemoteWmsInstockService remoteWmsInstockService;
|
|
|
|
|
|
|
|
|
|
private final IQcInspectionMainService qcInspectionMainService;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean notifyWmsForQualified(QcInspectionMainVo main) {
|
|
|
|
|
// 1. 检查是否来自WMS入库
|
|
|
|
|
if (!isFromWmsInspection(main)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// 2. 构建通知参数
|
|
|
|
|
InspectionCompleteNotification notification = buildNotification(main, null, false);
|
|
|
|
|
// 3. 调用 WMS Dubbo 接口
|
|
|
|
|
R<Void> result = remoteWmsInstockService.completeInstockAfterInspection(notification);
|
|
|
|
|
return result != null && result.getCode() == R.SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### WMS接收QMS回调服务实现(本地服务)
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
// WmsInspectionCallbackServiceImpl.java
|
|
|
|
|
@Service
|
|
|
|
|
public class WmsInspectionCallbackServiceImpl implements IWmsInspectionCallbackService {
|
|
|
|
|
|
|
|
|
|
private final IWmsInstockPrintService instockPrintService;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean handleInspectionComplete(InspectionCompleteNotification notification) {
|
|
|
|
|
// 1. 精确查询打印记录(instockCode + batchCode)
|
|
|
|
|
WmsInstockPrintVo printVo = queryByInstockAndBatch(
|
|
|
|
|
notification.getInstockCode(),
|
|
|
|
|
notification.getBatchCode()
|
|
|
|
|
);
|
|
|
|
|
// 2. 根据质检结果更新状态(inspectionType: 2=合格, 3=不合格)
|
|
|
|
|
if ("0".equals(notification.getResult())) {
|
|
|
|
|
return updateToQualified(notification.getInstockCode(), notification.getBatchCode());
|
|
|
|
|
} else {
|
|
|
|
|
return updateToUnqualified(notification.getInstockCode(), notification.getBatchCode());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### WMS Dubbo服务实现(独立类)
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
// RemoteWmsInspectionCallbackServiceImpl.java
|
|
|
|
|
@Service
|
|
|
|
|
@DubboService
|
|
|
|
|
public class RemoteWmsInspectionCallbackServiceImpl implements RemoteWmsInstockService {
|
|
|
|
|
|
|
|
|
|
private final IWmsInspectionCallbackService wmsInspectionCallbackService;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public R<Void> completeInstockAfterInspection(InspectionCompleteNotification notification) {
|
|
|
|
|
// 委托给本地服务处理
|
|
|
|
|
boolean success = wmsInspectionCallbackService.handleInspectionComplete(notification);
|
|
|
|
|
return success ? R.ok("质检回调处理成功") : R.fail("质检回调处理失败");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 6. 技术实现方案
|
|
|
|
|
|
|
|
|
|
### 6.1 模块依赖关系
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
|
|
|
│ 模块依赖关系 │
|
|
|
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
|
|
|
│ │
|
|
|
|
|
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
|
|
|
|
│ │ WMS │────────>│ QMS │<────────│ PDA │ │
|
|
|
|
|
│ │ 模块 │ Dubbo │ 模块 │ Dubbo │ 扫码入库 │ │
|
|
|
|
|
│ └─────────┘ └─────────┘ └─────────┘ │
|
|
|
|
|
│ ▲ ▲ │
|
|
|
|
|
│ │ HTTP │ │
|
|
|
|
|
│ ┌────┴────┐ ┌────┴────┐ │
|
|
|
|
|
│ │前端 qc.vue│ │ PDA设备 │ │
|
|
|
|
|
│ └─────────┘ └─────────┘ │
|
|
|
|
|
│ │
|
|
|
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 6.2 技术栈
|
|
|
|
|
|
|
|
|
|
| 技术点 | 使用方式 | 说明 |
|
|
|
|
|
|-------|---------|------|
|
|
|
|
|
| 微服务框架 | Spring Cloud Alibaba + Dubbo 3.x | 服务间 RPC 调用 |
|
|
|
|
|
| 分布式事务 | Seata @GlobalTransactional | 跨服务数据一致性 |
|
|
|
|
|
| 认证授权 | Sa-Token | 用户身份验证 |
|
|
|
|
|
| 多租户 | TenantHelper | 租户隔离 |
|
|
|
|
|
|
|
|
|
|
### 6.3 核心代码结构
|
|
|
|
|
|
|
|
|
|
#### WMS 模块
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
hwmom/ruoyi-modules/hwmom-wms/
|
|
|
|
|
├── controller/
|
|
|
|
|
│ └── api/
|
|
|
|
|
│ ├── WmsPdaApiController.java # PDA 入库接口
|
|
|
|
|
│ └── WmsInstockPrintController.java # 打印记录管理接口
|
|
|
|
|
├── service/
|
|
|
|
|
│ ├── IWmsInstockPrintService.java # 打印记录服务接口
|
|
|
|
|
│ └── impl/
|
|
|
|
|
│ └── WmsInstockPrintServiceImpl.java # 打印记录服务实现
|
|
|
|
|
└── dubbo/
|
|
|
|
|
└── RemoteQmsInspectionService.java # QMS Dubbo 接口引用
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### QMS 模块
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
hwmom/ruoyi-modules/hwmom-qms/
|
|
|
|
|
├── controller/
|
|
|
|
|
│ └── QcPDAController.java # PDA 质检接口
|
|
|
|
|
├── service/
|
|
|
|
|
│ ├── IQcPDAService.java # PDA 质检服务接口
|
|
|
|
|
│ ├── IQcWmsService.java # WMS 仓储质检服务接口
|
|
|
|
|
│ └── impl/
|
|
|
|
|
│ ├── QcPDAServiceImpl.java # PDA 质检服务实现
|
|
|
|
|
│ └── QcWmsServiceImpl.java # WMS 仓储质检服务实现
|
|
|
|
|
└── dubbo/
|
|
|
|
|
└── RemoteQmsInspectionServiceImpl.java # QMS Dubbo 服务实现
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 7. 前端改造
|
|
|
|
|
|
|
|
|
|
### 7.1 界面文件
|
|
|
|
|
|
|
|
|
|
**文件路径**:`hwmom-ui/src/views/wms/instockPrint/qc.vue`
|
|
|
|
|
|
|
|
|
|
### 7.2 新增按钮
|
|
|
|
|
|
|
|
|
|
```vue
|
|
|
|
|
<!-- 在工具栏添加"发起质检"按钮 -->
|
|
|
|
|
<el-row :gutter="10" class="mb8">
|
|
|
|
|
<el-col :span="1.5">
|
|
|
|
|
<el-button
|
|
|
|
|
type="primary"
|
|
|
|
|
plain
|
|
|
|
|
icon="VideoPlay"
|
|
|
|
|
:disabled="multiple"
|
|
|
|
|
@click="handleCreateInspection"
|
|
|
|
|
v-hasPermi="['wms:instockPrint:createInspection']">
|
|
|
|
|
发起质检
|
|
|
|
|
</el-button>
|
|
|
|
|
</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 7.3 按钮点击处理
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
/** 发起质检按钮操作 */
|
|
|
|
|
const handleCreateInspection = async () => {
|
|
|
|
|
// 1. 过滤:只处理必检(inspectionRequest='0')且未发起(inspectionType='0'或null)的批次
|
|
|
|
|
const validRecords = vos.value.filter(item =>
|
|
|
|
|
item.inspectionRequest === '0' &&
|
|
|
|
|
(!item.inspectionType || item.inspectionType === '0')
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (validRecords.length === 0) {
|
|
|
|
|
proxy?.$modal.msgWarning("请选择需要发起质检的批次(必检且未发起)");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. 确认提示
|
|
|
|
|
await proxy?.$modal.confirm(
|
|
|
|
|
`确认为选中的 ${validRecords.length} 个批次发起质检吗?`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 3. 调用接口
|
|
|
|
|
loading.value = true;
|
|
|
|
|
try {
|
|
|
|
|
const res = await createInspection(validRecords);
|
|
|
|
|
proxy?.$modal.msgSuccess("质检任务创建成功");
|
|
|
|
|
await getList();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("发起质检失败", error);
|
|
|
|
|
} finally {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 7.4 API 定义
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
// api/wms/instockPrint/index.ts
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 批量发起质检任务
|
|
|
|
|
* @param prints 选中的打印记录列表
|
|
|
|
|
*/
|
|
|
|
|
export const createInspection = (prints: InstockPrintVO[]) => {
|
|
|
|
|
return request({
|
|
|
|
|
url: '/wms/instockPrint/createInspection',
|
|
|
|
|
method: 'post',
|
|
|
|
|
data: prints
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 8. 分布式事务处理
|
|
|
|
|
|
|
|
|
|
### 8.1 Dubbo 调用事务规范
|
|
|
|
|
|
|
|
|
|
**重要原则**:调用方(发起方)需要添加 `@GlobalTransactional` 注解
|
|
|
|
|
|
|
|
|
|
#### 场景1:WMS 调用 QMS 创建质检任务
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
// WMS 模块
|
|
|
|
|
@Service
|
|
|
|
|
public class WmsInstockPrintServiceImpl {
|
|
|
|
|
|
|
|
|
|
@DubboReference
|
|
|
|
|
private RemoteQmsInspectionService remoteQmsInspectionService;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@GlobalTransactional(rollbackFor = Exception.class) // ← 调用方加注解
|
|
|
|
|
public Map<String, String> createInspection(List<WmsInstockPrintBo> prints) {
|
|
|
|
|
Map<String, String> result = new LinkedHashMap<>();
|
|
|
|
|
|
|
|
|
|
for (WmsInstockPrintBo print : prints) {
|
|
|
|
|
try {
|
|
|
|
|
// 1. 构建请求参数
|
|
|
|
|
WmsInspectionTaskRequest request = new WmsInspectionTaskRequest();
|
|
|
|
|
request.setInstockCode(print.getInstockCode());
|
|
|
|
|
request.setMaterialCode(print.getMaterialCode());
|
|
|
|
|
request.setInspectionQty(print.getApportionQty());
|
|
|
|
|
request.setBatchCode(print.getBatchCode());
|
|
|
|
|
request.setInspectionType("7"); // 入库检
|
|
|
|
|
|
|
|
|
|
// 2. 调用 QMS Dubbo 接口(远程事务)
|
|
|
|
|
String inspectionNo = remoteQmsInspectionService.createInspectionTaskForWMS(request);
|
|
|
|
|
|
|
|
|
|
log.info("批次 {} 质检任务创建成功,质检单号: {}", print.getBatchCode(), inspectionNo);
|
|
|
|
|
|
|
|
|
|
// 3. 更新本地状态(只有远程调用成功才更新)
|
|
|
|
|
WmsInstockPrintBo updateBo = new WmsInstockPrintBo();
|
|
|
|
|
updateBo.setInstockPrintId(print.getInstockPrintId());
|
|
|
|
|
updateBo.setInspectionType("1"); // 质检中
|
|
|
|
|
instockPrintService.updateByBo(updateBo);
|
|
|
|
|
|
|
|
|
|
result.put(print.getBatchCode(), inspectionNo);
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("批次 {} 创建质检任务失败: {}", print.getBatchCode(), e.getMessage(), e);
|
|
|
|
|
result.put(print.getBatchCode(), "失败: " + e.getMessage());
|
|
|
|
|
// 全局事务会自动回滚
|
|
|
|
|
throw new ServiceException("创建质检任务失败: " + e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 场景2:QMS 调用 WMS 质检完成回调
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
// QMS 模块
|
|
|
|
|
@Service
|
|
|
|
|
public class QcPDAServiceImpl {
|
|
|
|
|
|
|
|
|
|
@DubboReference
|
|
|
|
|
private RemoteWmsInspectionService remoteWmsInspectionService;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 质检完成后的回调方法(抽离独立方法)
|
|
|
|
|
*/
|
|
|
|
|
private void notifyWmsForQualified(QcInspectionMainVo main) {
|
|
|
|
|
// 如果没有合格数量,不回调
|
|
|
|
|
if (main.getQualifiedQty().compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
|
|
log.info("质检单 {} 无合格数量,跳过回调", main.getInspectionNo());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 1. 构建回调参数
|
|
|
|
|
InspectionCompleteNotification notification = buildNotification(main);
|
|
|
|
|
|
|
|
|
|
// 2. 调用 WMS Dubbo 接口(远程事务)
|
|
|
|
|
remoteWmsInspectionService.notifyInspectionComplete(notification);
|
|
|
|
|
|
|
|
|
|
log.info("质检单 {} 回调 WMS 成功", main.getInspectionNo());
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("质检单 {} 回调 WMS 失败: {}", main.getInspectionNo(), e.getMessage(), e);
|
|
|
|
|
// 根据业务需求决定是否抛出异常
|
|
|
|
|
// 如果不影响主流程,可以只记录日志
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 构建回调通知参数
|
|
|
|
|
*/
|
|
|
|
|
private InspectionCompleteNotification buildNotification(QcInspectionMainVo main) {
|
|
|
|
|
InspectionCompleteNotification notification = new InspectionCompleteNotification();
|
|
|
|
|
notification.setInspectionNo(main.getInspectionNo());
|
|
|
|
|
notification.setInstockCode(main.getRemark()); // remark 字段存储入库单号
|
|
|
|
|
notification.setBatchCode(main.getBatchNo()); // 批次号
|
|
|
|
|
notification.setQualifiedQty(main.getQualifiedQty());
|
|
|
|
|
notification.setUnqualifiedQty(main.getUnqualifiedQty());
|
|
|
|
|
notification.setMaterialCode(main.getMaterialCode());
|
|
|
|
|
notification.setResult("0"); // 合格
|
|
|
|
|
notification.setStatus("1"); // 已完成
|
|
|
|
|
notification.setInspectionEndTime(new Date());
|
|
|
|
|
return notification;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 7.2 事务回滚场景
|
|
|
|
|
| 场景 | 回滚范围 | 说明 |
|
|
|
|
|
|-----|---------|------|
|
|
|
|
|
| QMS 创建质检任务失败 | WMS 本地状态不更新 | `@GlobalTransactional` 保证 |
|
|
|
|
|
| WMS 接收回调失败 | 不影响 QMS 主流程 | 捕获异常,记录日志 |
|
|
|
|
|
| 网络超时 | Seata 自动重试 | 配置超时时间和重试次数 |
|
|
|
|
|
|
|
|
|
|
### 7.3 Seata 配置
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
# application.yml
|
|
|
|
|
seata:
|
|
|
|
|
enabled: true
|
|
|
|
|
application-id: hwmom-wms
|
|
|
|
|
tx-service-group: default_tx_group
|
|
|
|
|
registry:
|
|
|
|
|
type: nacos
|
|
|
|
|
nacos:
|
|
|
|
|
server-addr: 127.0.0.1:8848
|
|
|
|
|
namespace: public
|
|
|
|
|
group: SEATA_GROUP
|
|
|
|
|
username: nacos
|
|
|
|
|
password: nacos
|
|
|
|
|
config:
|
|
|
|
|
type: nacos
|
|
|
|
|
nacos:
|
|
|
|
|
server-addr: 127.0.0.1:8848
|
|
|
|
|
namespace: public
|
|
|
|
|
group: SEATA_GROUP
|
|
|
|
|
username: nacos
|
|
|
|
|
password: nacos
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 9. 让步接收方案(待讨论)
|
|
|
|
|
|
|
|
|
|
### 9.1 业务场景
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
批次 BATCH001,总数100
|
|
|
|
|
├─ 质检完成:80合格 + 20不合格
|
|
|
|
|
│ ├─ 合格80 → QMS 回调 WMS → inspection_type='2'
|
|
|
|
|
│ └─ 不合格20 → 创建不合格品评审
|
|
|
|
|
│
|
|
|
|
|
└─ 不合格品评审 → 让步接收(reviewResult='4')
|
|
|
|
|
└─ QMS 回调 WMS → inspection_type='2'(让步接收视为合格)
|
|
|
|
|
└─ PDA 扫码入库 20 件
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 9.2 技术方案(待讨论)
|
|
|
|
|
|
|
|
|
|
#### 方案A:让步接收时单独回调(推荐)
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
// QMS 模块 - 不合格品评审服务
|
|
|
|
|
@Service
|
|
|
|
|
public class QcUnqualifiedReviewServiceImpl {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@GlobalTransactional(rollbackFor = Exception.class)
|
|
|
|
|
public Boolean completeTask(QcUnqualifiedReviewBo bo) {
|
|
|
|
|
QcUnqualifiedReview review = baseMapper.selectById(bo.getReviewId());
|
|
|
|
|
|
|
|
|
|
// 1. 完成工作流审批
|
|
|
|
|
// ... 现有逻辑 ...
|
|
|
|
|
|
|
|
|
|
// 2. 【新增】让步接收回调 WMS
|
|
|
|
|
if ("4".equals(review.getReviewResult())) {
|
|
|
|
|
notifyWmsForConcession(review);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return baseMapper.updateById(review) > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 让步接收完成后回调 WMS(单独抽离的方法)
|
|
|
|
|
* 后续可改为其他实现方式(REST API / 消息队列)
|
|
|
|
|
*/
|
|
|
|
|
private void notifyWmsForConcession(QcUnqualifiedReview review) {
|
|
|
|
|
// 从质检单号获取质检主表信息
|
|
|
|
|
QcInspectionMainVo inspectionMain = qcInspectionMainService.queryByInspectionNo(review.getInspectionNo());
|
|
|
|
|
|
|
|
|
|
// 构建回调参数
|
|
|
|
|
InspectionCompleteNotification notification = new InspectionCompleteNotification();
|
|
|
|
|
notification.setInspectionNo(review.getInspectionNo());
|
|
|
|
|
notification.setInstockCode(inspectionMain.getRemark()); // remark 存储入库单号
|
|
|
|
|
notification.setBatchCode(review.getBatchNo()); // 批次号
|
|
|
|
|
notification.setQualifiedQty(review.getInspectionQty()); // 让步接收数量
|
|
|
|
|
notification.setUnqualifiedQty(BigDecimal.ZERO);
|
|
|
|
|
notification.setResult("0"); // 让步接收视为合格
|
|
|
|
|
notification.setStatus("1"); // 已完成
|
|
|
|
|
|
|
|
|
|
// 调用 WMS Dubbo 接口
|
|
|
|
|
remoteWmsInspectionService.notifyInspectionComplete(notification);
|
|
|
|
|
|
|
|
|
|
log.info("让步接收回调 WMS 成功,批次号: {}, 数量: {}", review.getBatchNo(), review.getInspectionQty());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 方案B:与合格数量回调合并
|
|
|
|
|
|
|
|
|
|
将让步接收也调用 `notifyWmsForQualified()` 方法,统一处理。
|
|
|
|
|
|
|
|
|
|
### 9.3 数据一致性保证
|
|
|
|
|
|
|
|
|
|
| 场景 | 合格数量 | 让步接收数量 | 累计入库 | 最终状态 |
|
|
|
|
|
|-----|---------|-------------|---------|---------|
|
|
|
|
|
| 场景1 | 80 | 20 | 100 | 已入库 |
|
|
|
|
|
| 场景2 | 100 | 0 | 100 | 已入库 |
|
|
|
|
|
| 场景3 | 0 | 100 | 100 | 已入库 |
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 10. 附录
|
|
|
|
|
|
|
|
|
|
### 10.1 字典值定义
|
|
|
|
|
|
|
|
|
|
#### wms_inspection_type(质检状态)
|
|
|
|
|
|
|
|
|
|
| 字典值 | 字典标签 | 说明 |
|
|
|
|
|
|-------|---------|------|
|
|
|
|
|
| 0 | 未发起 | 打印后默认状态 |
|
|
|
|
|
| 1 | 质检中 | 已创建质检任务,等待执行 |
|
|
|
|
|
| 2 | 合格 | 质检合格 |
|
|
|
|
|
| 3 | 不合格 | 质检不合格 |
|
|
|
|
|
|
|
|
|
|
#### inspection_request(质检要求)
|
|
|
|
|
|
|
|
|
|
| 字典值 | 字典标签 | 说明 |
|
|
|
|
|
|-------|---------|------|
|
|
|
|
|
| 0 | 必检 | 需要质检 |
|
|
|
|
|
| 1 | 免检 | 不需要质检 |
|
|
|
|
|
|
|
|
|
|
#### wms_inbound_status(入库状态)
|
|
|
|
|
|
|
|
|
|
| 字典值 | 字典标签 | 说明 |
|
|
|
|
|
|-------|---------|------|
|
|
|
|
|
| 0 | 待入库 | 初始状态 |
|
|
|
|
|
| 1 | 已入库 | PDA 扫码入库成功 |
|
|
|
|
|
| 2 | 入库中 | 预留,当前未使用 |
|
|
|
|
|
| 3 | 拒收 | 预留,当前未使用 |
|
|
|
|
|
|
|
|
|
|
### 10.2 关键文件路径清单
|
|
|
|
|
|
|
|
|
|
| 模块 | 文件路径 | 说明 |
|
|
|
|
|
|-----|---------|------|
|
|
|
|
|
| **WMS** | `hwmom/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/controller/api/WmsInstockPrintController.java` | 打印记录控制器 |
|
|
|
|
|
| **WMS** | `hwmom/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/service/IWmsInstockPrintService.java` | 打印记录服务接口 |
|
|
|
|
|
| **WMS** | `hwmom/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/service/impl/WmsInstockPrintServiceImpl.java` | 打印记录服务实现 |
|
|
|
|
|
| **WMS** | `hwmom/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/dubbo/RemoteWmsInspectionService.java` | WMS 暴露给 QMS 的接口(新增) |
|
|
|
|
|
| **QMS** | `hwmom/ruoyi-api/hwmom-api-qms/src/main/java/org/dromara/qms/api/RemoteQmsInspectionService.java` | QMS Dubbo 接口定义 |
|
|
|
|
|
| **QMS** | `hwmom/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/dubbo/RemoteQmsInspectionServiceImpl.java` | QMS Dubbo 服务实现 |
|
|
|
|
|
| **QMS** | `hwmom/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/IQcWmsService.java` | WMS 仓储质检服务接口 |
|
|
|
|
|
| **QMS** | `hwmom/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/impl/QcWmsServiceImpl.java` | WMS 仓储质检服务实现 |
|
|
|
|
|
| **QMS** | `hwmom/ruoyi-modules/hwmom-qms/src/main/java/org/dromara/qms/service/impl/QcPDAServiceImpl.java` | PDA 质检服务实现 |
|
|
|
|
|
| **API** | `hwmom/ruoyi-api/hwmom-api-qms/src/main/java/org/dromara/qms/api/dto/InspectionCompleteNotification.java` | 质检完成通知 DTO |
|
|
|
|
|
| **API** | `hwmom/ruoyi-api/hwmom-api-qms/src/main/java/org/dromara/qms/api/dto/WmsInspectionTaskRequest.java` | WMS 入库质检请求 DTO |
|
|
|
|
|
| **前端** | `hwmom-ui/src/views/wms/instockPrint/qc.vue` | 质检入库任务界面 |
|
|
|
|
|
| **前端** | `hwmom-ui/src/api/wms/instockPrint/index.ts` | 打印记录前端 API |
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 11. 待确认事项
|
|
|
|
|
|
|
|
|
|
1. ~~批次号传递方式~~ ✓ 已确认:必须传递 `batchCode`
|
|
|
|
|
2. ~~入库时机~~ ✓ 已确认:由 PDA 扫码入库,回调只更新状态
|
|
|
|
|
3. ~~分布式事务~~ ✓ 已确认:调用方加 `@GlobalTransactional`
|
|
|
|
|
4. 让步接收具体实现方式(待讨论)
|
|
|
|
|
5. 是否需要新增 WMS 暴露给 QMS 的 Dubbo 接口(待确认)
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**文档结束**
|