1
0
forked from erp-dev/erp

feat: mes module

This commit is contained in:
2026-05-11 21:37:41 +08:00
parent d7b388e935
commit 9359013b4c
20 changed files with 3232 additions and 133 deletions

378
docs/api_v2_mes_api.md Normal file
View File

@@ -0,0 +1,378 @@
# API v2 MES 模块接口文档
本文档面向前端和业务评审,描述当前已经开放的 `MES` 公开接口,以及每个接口当前真实可用的字段。
## 基本约定
- Base URL: `/api/v2/mes`
- 认证:所有接口都需要登录。
- 人员身份:后端使用 `request.user.employee` 作为当前员工身份。
- 多商户隔离:所有接口只允许访问当前员工所属商户的数据。
- 创建审计:`created_by` 由当前登录用户自动写入。
- 操作审计:`operator` 由当前登录员工自动写入。
- `extra`:自由结构 JSON 字段,后端不解释业务内容。
## 枚举定义
### 产能单位 `capacity_unit`
| 值 | 显示值 |
|------|------|
| `1` | `米` |
| `2` | `码` |
### 生产指派状态 `status`
| 值 | 显示值 |
|------|------|
| `1` | `Draft` |
| `2` | `已发布` |
| `3` | `已接收` |
| `4` | `已取消` |
| `5` | `已完工` |
## 返回对象
### DeviceCategory 对象
```json
{
"id": 1,
"merchant": 10,
"name": "打印机",
"created_by": {
"id": 5,
"username": "admin"
},
"operator": {
"id": 20,
"name": "张三",
"merchant_id": 10
},
"created_at": "2026-05-08T12:00:00+08:00",
"updated_at": "2026-05-08T12:00:00+08:00"
}
```
字段说明:
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | integer | 主键 |
| `merchant` | integer | 所属商户 ID |
| `name` | string | 设备分类名称 |
| `created_by` | object | 创建用户信息,包含 `id``username` |
| `operator` | object | 操作员工信息,包含 `id``name``merchant_id` |
| `created_at` | datetime string | 创建时间 |
| `updated_at` | datetime string | 更新时间 |
### Device 对象
```json
{
"id": 100,
"merchant": 10,
"category": 1,
"category_name": "打印机",
"name": "A-01",
"peak_capacity": 120,
"capacity_unit": 1,
"capacity_unit_label": "米",
"extra": {
"capacity": {
"per_hour": 120
}
},
"created_by": {
"id": 5,
"username": "admin"
},
"operator": {
"id": 20,
"name": "张三",
"merchant_id": 10
},
"created_at": "2026-05-08T12:00:00+08:00",
"updated_at": "2026-05-08T12:00:00+08:00"
}
```
字段说明:
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | integer | 主键 |
| `merchant` | integer | 所属商户 ID |
| `category` | integer | 设备分类 ID |
| `category_name` | string | 设备分类名称 |
| `name` | string | 设备名称 |
| `peak_capacity` | integer | 峰值产能,必须大于 `0` |
| `capacity_unit` | integer | 产能单位枚举值 |
| `capacity_unit_label` | string | 产能单位显示值 |
| `extra` | object/null | 自由结构 JSON 扩展字段 |
| `created_by` | object | 创建用户信息,包含 `id``username` |
| `operator` | object | 操作员工信息,包含 `id``name``merchant_id` |
| `created_at` | datetime string | 创建时间 |
| `updated_at` | datetime string | 更新时间 |
### ProductionAssignment 对象
```json
{
"id": 200,
"merchant": 10,
"device": 100,
"device_name": "A-01",
"content_type": 45,
"object_id": 9001,
"assigner": {
"id": 20,
"name": "张三",
"merchant_id": 10
},
"assignee": {
"id": 21,
"name": "李四",
"merchant_id": 10
},
"production_quantity": 300,
"status": 1,
"status_label": "Draft",
"extra": {
"batch": "A1"
},
"created_by": {
"id": 5,
"username": "admin"
},
"operator": {
"id": 20,
"name": "张三",
"merchant_id": 10
},
"created_at": "2026-05-08T12:00:00+08:00",
"updated_at": "2026-05-08T12:00:00+08:00"
}
```
字段说明:
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | integer | 主键 |
| `merchant` | integer | 所属商户 ID |
| `device` | integer | 设备 ID |
| `device_name` | string | 设备名称 |
| `content_type` | integer | 关联业务对象类型 ID |
| `object_id` | integer | 关联业务对象主键 |
| `assigner` | object | 指派者员工信息,包含 `id``name``merchant_id` |
| `assignee` | object/null | 被指派人员工信息,包含 `id``name``merchant_id`,可空 |
| `production_quantity` | integer | 生产数量,必须大于 `0`,单位跟随设备 `capacity_unit` |
| `status` | integer | 状态枚举值 |
| `status_label` | string | 状态显示值 |
| `extra` | object/null | 自由结构 JSON 扩展字段 |
| `created_by` | object | 创建用户信息,包含 `id``username` |
| `operator` | object | 操作员工信息,包含 `id``name``merchant_id` |
| `created_at` | datetime string | 创建时间 |
| `updated_at` | datetime string | 更新时间 |
## 设备分类接口
### 设备分类列表
- URL: `/api/v2/mes/device-categories/`
- Method: `GET`
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `name` | string | 否 | 按名称模糊匹配 |
### 创建设备分类
- URL: `/api/v2/mes/device-categories/`
- Method: `POST`
请求字段:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `name` | string | 是 | 设备分类名称 |
### 设备分类详情
- URL: `/api/v2/mes/device-categories/{category_id}/`
- Method: `GET`
### 更新设备分类
- URL: `/api/v2/mes/device-categories/{category_id}/`
- Method: `PATCH`
请求字段:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `name` | string | 否 | 设备分类名称 |
### 删除设备分类
- URL: `/api/v2/mes/device-categories/{category_id}/`
- Method: `DELETE`
错误示例:
```json
{
"detail": "设备分类已被设备引用,不能删除"
}
```
## 设备接口
### 设备列表
- URL: `/api/v2/mes/devices/`
- Method: `GET`
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `name` | string | 否 | 按设备名称模糊匹配 |
| `category` | integer | 否 | 按设备分类 ID 过滤 |
| `extra_path` | string | 否 | `extra` 中的 JSON 路径,使用 `.` 分隔,例如 `capacity.per_hour` |
| `extra_value` | string | 否 | 与 `extra_path` 配套使用,支持 JSON 字面量字符串,例如 `120``"A1"``true` |
说明:
- `extra_path``extra_value` 必须同时传入。
- 当前仅支持精确匹配。
- 后端不解释 `extra` 的业务语义,只按路径和值匹配。
### 创建设备
- URL: `/api/v2/mes/devices/`
- Method: `POST`
请求字段:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `name` | string | 是 | 设备名称 |
| `category` | integer | 是 | 设备分类 ID |
| `peak_capacity` | integer | 是 | 峰值产能,必须大于 `0` |
| `capacity_unit` | integer | 否 | 产能单位,省略时默认 `1=米` |
| `extra` | object/null | 否 | 自由结构 JSON 扩展字段 |
### 设备详情
- URL: `/api/v2/mes/devices/{device_id}/`
- Method: `GET`
### 更新设备
- URL: `/api/v2/mes/devices/{device_id}/`
- Method: `PATCH`
请求字段:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `name` | string | 否 | 设备名称 |
| `category` | integer | 否 | 设备分类 ID |
| `peak_capacity` | integer | 否 | 峰值产能,必须大于 `0` |
| `capacity_unit` | integer | 否 | 产能单位 |
| `extra` | object/null | 否 | 传 `null` 可清空扩展字段 |
补充说明:
- 模型层历史迁移曾使用一次性兼容默认值处理旧数据,但前端不应依赖省略 `peak_capacity` 让系统自动补值。
### 删除设备
- URL: `/api/v2/mes/devices/{device_id}/`
- Method: `DELETE`
- 成功返回 `204 No Content`
## 生产指派接口
### 生产指派列表
- URL: `/api/v2/mes/production-assignments/`
- Method: `GET`
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `device` | integer | 否 | 按设备 ID 过滤 |
| `content_type` | integer | 否 | 按关联对象类型 ID 过滤 |
| `object_id` | integer | 否 | 按关联对象 ID 过滤 |
| `status` | integer | 否 | 按状态过滤 |
### 创建生产指派
- URL: `/api/v2/mes/production-assignments/`
- Method: `POST`
请求字段:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `device` | integer | 是 | 设备 ID |
| `content_type` | integer | 是 | 关联业务对象类型 ID |
| `object_id` | integer | 是 | 关联业务对象主键 |
| `assigner` | integer | 是 | 指派者员工 ID |
| `assignee` | integer/null | 否 | 被指派人员工 ID可空 |
| `production_quantity` | integer | 是 | 生产数量,必须大于 `0` |
| `status` | integer | 否 | 状态,省略时默认 `1=Draft` |
| `extra` | object/null | 否 | 自由结构 JSON 扩展字段 |
说明:
- `device``assigner``assignee` 必须属于当前商户。
- `production_quantity` 单位跟随设备 `capacity_unit`
### 生产指派详情
- URL: `/api/v2/mes/production-assignments/{assignment_id}/`
- Method: `GET`
### 更新生产指派
- URL: `/api/v2/mes/production-assignments/{assignment_id}/`
- Method: `PATCH`
请求字段:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `device` | integer | 否 | 设备 ID |
| `assignee` | integer/null | 否 | 被指派人员工 ID可空 |
| `production_quantity` | integer | 否 | 生产数量,必须大于 `0` |
| `status` | integer | 否 | 目标状态 |
| `extra` | object/null | 否 | 扩展字段,传 `null` 可清空 |
状态流转说明:
- 主流程:`Draft -> 已发布 -> 已接收 -> 已完工`
- `Draft` 可以改为 `已取消`
- `已发布` 可以改为 `已取消`
- `已接收``已完工` 不能改为 `已取消`
- `已取消``已完工` 视为终态,不能回退
错误示例:
```json
{
"detail": "当前状态不允许变更为目标状态"
}
```
### 删除生产指派
- URL: `/api/v2/mes/production-assignments/{assignment_id}/`
- Method: `DELETE`