1
0
forked from erp-dev/erp

feat: added plate order clone

This commit is contained in:
2025-12-16 08:42:53 +08:00
parent 4c9b8e6a42
commit 0638dd1ad3
25 changed files with 46174 additions and 8 deletions

View File

@@ -0,0 +1,160 @@
### 文档说明
本文档描述 `api_v2` 中 **PrintingJob 批量推进流程状态**的两个接口preview + submit用于前端生成批量表单与提交批量推进。
### 背景与术语
- **PrintingJob**:概念上等同于“订单明细对象”,归属一个 `PrintingOrder`
- **Stateflow**PrintingJob 通过 `business_object``stateflow.BusinessObject`)承载流程实例;推进逻辑复用 `stateflow.services.advance_to_next_state(...)`
- **批量推进**:对多个 PrintingJob要求同一订单、同一待执行节点使用同一份工艺参数推进一个节点。
### 权限与鉴权
- **鉴权**:需要登录(`IsAuthenticated`),使用系统统一 JWT 认证。
- **业务权限**:需要印染工厂身份(`IsPrintingFactory`),即 `request.user.employee.merchant.type == FACTORY`
### 路由与代码位置
- **Base**`/api/v2/`
- **实现文件**`api_v2/views/printing.py`
- **路由定义**`api_v2/urls.py`
### 统一校验规则preview 与 submit 共用)
批量推进(或预览)必须同时满足:
- **ID 存在**`printing_job_ids` 全部存在,否则 400。
- **同一订单**:所有 job 必须属于同一个 `printing_order`,否则 400。
- **必须绑定流程实例**:每个 job 必须有 `business_object`,否则 400。
- **同一待执行节点**:所有 job 的 `next_pending_state` 必须一致,否则 400。
- **可推进**:任一 job 的 `next_pending_state``None`(流程已完成或无节点)则 400。
> 备注:当前 **不做 preview→submit 竞态处理**(例如 preview 通过后,期间有人推进了其中部分 job。submit 会重新校验;如需更好的用户体验,后续可引入 snapshot token / 幂等键。
---
## 批量推进预览(用于生成批量表单)
### Endpoint
- **POST** `api/v2/printing-jobs/batch-advance/preview/`
### Request Body
```json
{
"printing_job_ids": [101, 102, 103]
}
```
### Response200
返回下一待执行节点(统一)及其工艺参数定义:
```json
{
"printing_order_id": 55,
"printing_job_ids": [101, 102, 103],
"next_state": {
"id": 7,
"name": "染色",
"description": "染色工序",
"order": 0,
"parameters": [
{
"id": 12,
"key": "temperature",
"value": "",
"attachment": null,
"attachment_url": null,
"description": "温度(必填)",
"is_required": true,
"is_image_path": false
}
]
}
}
```
### 典型错误400
返回 `{"detail": "<原因>"}` 或字段级错误,例如:
- 不同订单:`所选明细不属于同一个 printing_order无法批量推进`
- 缺 business_object`以下 printing_job 未关联流程实例business_object无法推进: ...`
- next_state 不一致:`所选明细当前待执行节点不一致,无法批量推进...`
- 已完成/无节点:`没有待执行节点(流程已完成或无节点)`
---
## 批量推进提交(全成功/全失败)
### Endpoint
- **POST** `api/v2/printing-jobs/batch-advance/`
### 语义(重要)
- **事务全成功/全失败**:接口使用数据库事务包裹:
- 创建批量推进记录(审计表)
- 逐个调用 `stateflow.services.advance_to_next_state(...)` 推进每个 job 的 `business_object`
- 任意一个 job 推进失败:**整体回滚**(不会产生任何 stateflow 日志,也不会产生批量记录)
### Request Body
```json
{
"printing_job_ids": [101, 102, 103],
"parameters": {
"temperature": "25.5",
"operator": "张三"
}
}
```
说明:
- `parameters` 会作为 `**kwargs` 传入 `stateflow.services.advance_to_next_state(...)`
- 若下一节点存在必填参数(`is_required=true`),则必须提供对应 key否则返回 400错误信息形如 `缺失必填参数: temperature`)。
### Response200
```json
{
"detail": "已完成状态: 染色",
"batch_id": 9,
"printing_order_id": 55,
"printing_job_ids": [101, 102, 103],
"jobs": [
{
"id": 101,
"printing_order": 55,
"product": { "id": 1, "...": "..." },
"work_state": 0,
"quantity": 10,
"width": "150cm",
"fabric": "棉",
"unit": "米",
"size": null,
"pieces": null,
"description": null,
"business_object_id": 888,
"created_at": "2025-12-12T10:00:00+08:00",
"updated_at": "2025-12-12T10:01:00+08:00",
"billed_quantity": "0.00"
}
]
}
```
说明:
- `jobs` 使用 `PrintingJobV2Serializer`:其中 `product` 为嵌套对象(不是纯 ID
### 典型错误400
- 参数缺失:`{"detail": "缺失必填参数: temperature"}`
- 不满足一致性校验:同 preview 的错误列表。
---
## 批量推进审计表PrintingJobBatchAdvanceRecord
### 模型
`printing.models.PrintingJobBatchAdvanceRecord`
### 字段(核心)
- `created_at` / `updated_at`:来自 `ModelBase`
- `created_by`:操作人(可空,删除用户后保留记录)
- `printing_order`:所属主订单
- `state`:本次被“完成”的流程节点(推进时的 next_pending_state
- `parameters`本次批量推进提交的参数JSON
- `printing_jobs`本次批量推进涉及的明细集合ManyToMany
### 迁移
- `printing/migrations/0024_printingjobbatchadvancerecord.py`
---
## 前端联调建议
- 先调用 preview 获取 `next_state.parameters` 生成批量表单(必填项根据 `is_required`)。
- 表单提交调用 submit如返回 400提示 `detail` 并建议用户刷新列表后重试。
- 当前未实现竞态 token/幂等键;如需要防重复提交,建议后续加 `Idempotency-Key`(前端生成 UUID后端在批量记录表上做去重