Files
MES/yawei-mes/.tasks/2026-02-27_v2.0.002_ATS接口文档.md

521 lines
14 KiB
Markdown
Raw Permalink Normal View History

2026-04-02 10:38:23 +08:00
# 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`、不传 → 使用默认值