Files
MES/yawei-mes/.tasks/2026-02-27_v2.0.002_ATS接口文档.md
2026-04-02 10:39:03 +08:00

521 lines
14 KiB
Markdown
Raw Permalink 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.

# ATS 批量排产报工接口文档
## 版本信息
- **版本号**v2.0.002
- **创建日期**2026-02-27
- **更新说明**:通过开关参数灵活控制计划、工单、报工单的生成
- **测试地址**
- 前端http://192.168.1.244:80
- 后端http://192.168.1.244:8080
---
## 快速开始
### 核心概念
接口支持通过开关参数灵活控制三个业务模块的生成:
| 模块 | 开关参数 | 默认值 | 说明 |
|------|---------|--------|------|
| 生产计划 | `plan.isGeneratePlan` | `1` | `0`=不生成,`1`=生成 |
| 生产工单 | `workOrder.isGenerateWorkOrder` | `1` | `0`=不生成,`1`=生成 |
| 报工单 | `reportWorkOrder.isGenerateReportWorkOrder` | `1` | `0`=不生成,`1`=生成 |
**核心规则**
- **不传对象** = 使用默认值(生成)
- **传了对象但不传开关** = 使用默认值(生成)
- **传了开关=0** = 明确不生成
- **传了开关=1** = 明确生成
- **传了空字符串 ""** = 使用默认值
- **传了空数组 []** = 使用默认值
- **传了 null** = 使用默认值
**示例**
```json
// 不传plan对象 → 默认生成计划
{"orderNumbers": ["SO001"], "workOrder": {...}}
// 传了plan但不传开关 → 默认生成计划
{"orderNumbers": ["SO001"], "plan": {"assignedUserIds": "101"}}
// 传了开关=0 → 不生成计划
{"orderNumbers": ["SO001"], "plan": {"isGeneratePlan": 0}}
// 传了空字符串 → 使用默认值
{"orderNumbers": ["SO001"], "plan": {"assignedUserIds": ""}} // 从工序路线获取
// 传了空数组 → 使用默认值
{"orderNumbers": ["SO001"], "reportWorkOrder": {"reporters": []}} // 从工序路线获取
```
---
## 常用场景
### 场景1全部生成默认
```json
{
"orderNumbers": ["SO202602270001"]
}
```
**结果**:生成计划 → 生成工单 → 生成报工单
---
### 场景2只生成工单
```json
{
"orderNumbers": ["SO202602270001"],
"plan": {
"isGeneratePlan": 0
},
"workOrder": {
"routeId": 1005,
"processStartTime": "2026-02-27 08:00:00"
},
"reportWorkOrder": {
"isGenerateReportWorkOrder": 0
}
}
```
**结果**:只生成工单,工单状态保持"未完成"
**说明**
- `plan.isGeneratePlan=0` 明确不生成计划
- `workOrder` 传了对象但没传开关,默认生成工单
- `reportWorkOrder.isGenerateReportWorkOrder=0` 明确不生成报工单
---
### 场景3只生成报工单订单已有工单
```json
{
"orderNumbers": ["SO202602270001"],
"plan": {
"isGeneratePlan": 0
},
"workOrder": {
"isGenerateWorkOrder": 0
},
"reportWorkOrder": {
"reporters": [
{"operatorId": 101, "reportTime": "2026-02-27 10:00:00"}
]
}
}
```
**结果**:为已有工单生成报工单,工单状态变为"已完成"
**说明**
- `plan.isGeneratePlan=0` 明确不生成计划
- `workOrder.isGenerateWorkOrder=0` 明确不生成工单
- `reportWorkOrder` 传了对象但没传开关,默认生成报工单
---
### 场景4生成工单+报工单(不生成计划)
```json
{
"orderNumbers": ["SO202602270001"],
"plan": {
"isGeneratePlan": 0
}
}
```
**结果**:生成工单 → 生成报工单(不生成计划)
**说明**:通过设置 `isGeneratePlan=0` 明确不生成计划workOrder和reportWorkOrder使用默认值1会生成工单和报工单
---
### 场景5空值使用默认值
```json
{
"orderNumbers": ["SO202602270001"],
"plan": {
"isGeneratePlan": 1,
"assignedUserIds": ""
},
"workOrder": {
"isGenerateWorkOrder": 1,
"processStartTime": ""
},
"reportWorkOrder": {
"isGenerateReportWorkOrder": 1,
"reporters": []
}
}
```
**结果**:全部生成,所有空值参数都使用系统默认值
**说明**
- `assignedUserIds: ""` → 从工序路线获取所有报工人(去重)
- `processStartTime: ""` → 使用当前时间
- `reporters: []` → 从工序路线获取每个工序的报工人
---
## 接口详情
### 1. 批量自动完成接口
**POST** `http://192.168.1.244:8080/production/autoComplete/batchAutoComplete`
#### 请求参数
##### 必填参数
| 参数 | 类型 | 说明 |
|------|------|------|
| `orderNumbers` | Array\<String\> | 销售订单编号列表 |
##### 可选参数 - plan生产计划
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `isGeneratePlan` | Integer | `1` | `0`=不生成,`1`=生成 |
| `assignedUserIds` | String | 工序路线所有报工人(去重) | 负责人ID逗号分隔`"101,102"`不传、传null或传空字符串 `""` 时,自动从工序路线中获取所有工序的报工人(去重)作为计划负责人 |
##### 可选参数 - workOrder生产工单
| 参数 | 类型 | 默认值 | 说明 |
|------|------|------|------|
| `isGenerateWorkOrder` | Integer | `1` | `0`=不生成,`1`=生成 |
| `routeId` | Long | 自动选择 | 工序路线ID不传、传null时自动选择 |
| `processStartTime` | String | 自动生成 | 首道工序开始时间,格式 `yyyy-MM-dd HH:mm:ss`不传、传null或传空字符串 `""` 时使用当前时间 |
**工序路线选择优先级**
1. `workOrder.routeId`(最高优先级)
2. 订单明细配置的路线
3. 物料默认路线
4. 无路线则返回错误
##### 可选参数 - reportWorkOrder报工单
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `isGenerateReportWorkOrder` | Integer | `1` | `0`=不生成,`1`=生成 |
| `reporters` | Array | 工序路线的报工人 | 报工人列表不传、传null或传空数组 `[]` 时,自动从工序路线中获取每个工序的报工人 |
**reporters 子字段**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `operatorId` | Long | 是 | 报工人用户ID |
| `reportTime` | String | 是 | 报工时间,格式 `yyyy-MM-dd HH:mm:ss` |
**说明**
- 系统通过订单编号反查关联工单
- 只对未完成的工单创建报工记录
- **不传reporters、传null或传空数组 `[]` 时**:系统自动从工序路线中获取每个工序配置的报工人,按工序顺序为每个工单生成报工记录(每个工序一个报工人)
- **传1条reporter时**:该报工人对所有未完成工单均生成报工记录
- **传多条reporters时**:按工序顺序与未完成工单一一映射
---
#### 完整请求示例
```json
{
"orderNumbers": ["SO202602270001", "SO202602270002"],
"plan": {
"isGeneratePlan": 1,
"assignedUserIds": "101,102"
},
"workOrder": {
"isGenerateWorkOrder": 1,
"routeId": 1005,
"processStartTime": "2026-02-27 08:00:00"
},
"reportWorkOrder": {
"isGenerateReportWorkOrder": 1,
"reporters": [
{"operatorId": 101, "reportTime": "2026-02-27 10:00:00"},
{"operatorId": 102, "reportTime": "2026-02-27 14:00:00"}
]
}
}
```
---
#### 响应结果(立即返回)
```json
{
"code": 200,
"msg": "任务已提交,正在后台处理",
"data": {
"taskId": "TASK_20260227_001",
"totalCount": 2,
"estimatedSeconds": 10,
"status": "PENDING",
"message": "任务已创建预计需要10秒完成"
}
}
```
---
### 2. 任务状态查询接口
**GET** `http://192.168.1.244:8080/production/autoComplete/taskStatus/{taskId}`
#### 请求示例
```
GET /production/autoComplete/taskStatus/TASK_20260227_001
```
#### 响应示例(处理中)
```json
{
"code": 200,
"msg": "查询成功",
"data": {
"taskId": "TASK_20260227_001",
"status": "PROCESSING",
"totalCount": 50,
"processedCount": 25,
"successCount": 23,
"failedCount": 2,
"percentage": 50,
"message": "正在处理中已完成50%"
}
}
```
#### 响应示例(已完成)
```json
{
"code": 200,
"msg": "查询成功",
"data": {
"taskId": "TASK_20260227_001",
"status": "COMPLETED",
"totalCount": 50,
"processedCount": 50,
"successCount": 48,
"failedCount": 2,
"percentage": 100,
"message": "任务已完成",
"result": {
"successOrders": ["SO001", "SO002"],
"failedOrders": ["SO025", "SO038"],
"failureReasons": {
"SO025": "订单不存在",
"SO038": "物料未配置工序路线"
}
}
}
}
```
---
## 辅助接口
### 3. 库存式生产自动创建订单
**POST** `http://192.168.1.244:8080/production/plan/autoCreateOrder`
用于库存式生产MTS自动生成以"生产备货"为客户的销售订单。
#### 请求参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `materialId` | Long | 是 | 产品ID |
| `materialName` | String | 建议 | 产品名称 |
| `totalQuantity` | BigDecimal | 是 | 生产数量(必须 > 0 |
| `endTime` | String | 是 | 交货日期,格式 `yyyy-MM-dd HH:mm:ss` |
#### 请求示例
```json
{
"materialId": 101,
"materialName": "产品A",
"totalQuantity": 100,
"endTime": "2026-03-31 18:00:00"
}
```
#### 响应示例
```json
{
"code": 200,
"msg": "订单创建成功",
"data": {
"orderId": 999,
"orderNumber": "PL20260227001"
}
}
```
---
### 4. 按用户查询报工单
**GET** `http://192.168.1.244:8080/production/report/list`
#### 查询参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `reportUserName` | String | 是 | 报工人姓名(模糊匹配) |
| `reportTimeQuery[0]` | String | 否 | 报工时间起,格式 `yyyy-MM-dd` |
| `reportTimeQuery[1]` | String | 否 | 报工时间止,格式 `yyyy-MM-dd` |
| `workOrderId` | Long | 否 | 工单ID |
| `pageNum` | Integer | 否 | 页码默认1 |
| `pageSize` | Integer | 否 | 每页条数默认10 |
#### 请求示例
```
GET /production/report/list?reportUserName=张三&reportTimeQuery[0]=2026-02-01&reportTimeQuery[1]=2026-02-27
```
#### 响应示例
```json
{
"code": 200,
"msg": "查询成功",
"rows": [
{
"id": 501,
"reportUserId": 1,
"reportUserName": "张三",
"reportTime": "2026-02-27 10:00:00",
"reportQuantity": 50,
"qualifiedQuantity": 50,
"workOrderId": 301,
"status": "A"
}
],
"total": 1
}
```
---
## 业务规则
### 开关控制规则
**核心原则**:所有开关默认值都是 `1`(生成),只有明确设置为 `0` 才不生成
1. **不传任何对象**:使用默认值,全部生成(计划+工单+报工单)
```json
{"orderNumbers": ["SO001"]}
```
2. **传了对象但不传开关**:使用默认值,该业务生成
```json
{"orderNumbers": ["SO001"], "plan": {"assignedUserIds": "101"}}
// plan没有传isGeneratePlan默认为1生成计划
```
3. **传了开关=0**:明确不生成
```json
{"orderNumbers": ["SO001"], "plan": {"isGeneratePlan": 0}}
// 明确设置为0不生成计划
```
4. **传了开关=1**:明确生成(与默认行为相同)
```json
{"orderNumbers": ["SO001"], "plan": {"isGeneratePlan": 1}}
// 明确设置为1生成计划
```
### 依赖关系
| 场景 | 说明 |
|------|------|
| 报工单依赖工单 | 如果 `isGenerateWorkOrder=0` 且 `isGenerateReportWorkOrder=1`,则只为已有工单生成报工单;如果订单无工单,跳过该订单 |
| 计划独立 | 计划的生成不依赖工单和报工单 |
| 工单独立 | 工单可以单独生成,不依赖计划和报工单 |
### 异步处理流程
1. **提交任务**<1秒验证参数 → 创建任务记录 → 立即返回任务ID
2. **异步执行**(后台):循环处理订单 → 每5个订单更新一次进度
3. **查询状态**<100ms根据任务ID查询实时进度
### 性能说明
| 订单数 | 预计耗时 | 数据库更新次数 |
|--------|---------|--------------|
| 5个 | ~5秒 | 4次 |
| 10个 | ~10秒 | 5次 |
| 50个 | ~50秒 | 13次 |
| 100个 | ~100秒 | 23次 |
**并发限制**
- 线程池大小10个线程
- 最大并发任务数10个
- 单个任务最大执行时间5分钟
- 建议单次批量不超过100个订单
---
## 场景速查表
| 场景 | 参数配置示例 | 结果 |
|------|------------|------|
| 全部生成 | `{}` 不传任何对象 | 计划+工单+报工单 |
| 只生成计划 | `{plan: {}, workOrder: {isGenerateWorkOrder: 0}, report: {isGenerateReportWorkOrder: 0}}` | 只生成计划 |
| 只生成工单 | `{plan: {isGeneratePlan: 0}, workOrder: {}, report: {isGenerateReportWorkOrder: 0}}` | 只生成工单 |
| 只生成报工单 | `{plan: {isGeneratePlan: 0}, workOrder: {isGenerateWorkOrder: 0}, report: {}}` | 只为已有工单生成报工单 |
| 工单+报工单 | `{plan: {isGeneratePlan: 0}}` | 生成工单和报工单 |
| 计划+工单 | `{report: {isGenerateReportWorkOrder: 0}}` | 生成计划和工单 |
**说明**
- 开关默认值都是1生成
- 不传对象 = 使用默认值1 = 生成
- 传了对象但不传开关 = 使用默认值1 = 生成
- 只有明确设置开关=0才不生成
---
## 版本历史
| 版本号 | 日期 | 变更说明 |
|--------|------|---------|
| v2.0.000 | 2026-02-24 | 初始版本,支持基础批量排产 |
| v2.0.002 | 2026-02-27 | 新增开关参数,支持灵活控制计划、工单、报工单的生成 |
---
## 注意事项
1. **认证方式**:接口已配置匿名访问,无需认证
2. **异步执行**接口立即返回任务ID实际处理在后台进行
3. **进度查询**:通过任务状态查询接口轮询获取进度
4. **错误处理**:单个订单失败不影响其他订单,最终返回详细的成功/失败列表
5. **工序路线**:优先使用 `workOrder.routeId`,其次使用订单/物料配置的路线
6. **默认值逻辑**
- **计划负责人**:不传 `plan.assignedUserIds`、传null或传空字符串 `""` 时,系统自动从工序路线中获取所有工序的报工人(去重)作为计划负责人
- **工序开始时间**:不传 `workOrder.processStartTime`、传null或传空字符串 `""` 时,系统使用当前时间
- **报工单报工人**:不传 `reportWorkOrder.reporters`、传null或传空数组 `[]` 时,系统自动从工序路线中获取每个工序配置的报工人,按工序顺序生成报工记录
7. **空值处理规则**
- 字符串类型:`null`、`""`(空字符串)、不传 → 都使用默认值
- 数组类型:`null`、`[]`(空数组)、不传 → 都使用默认值
- 数值类型:`null`、不传 → 使用默认值