forked from erp-dev/erp
5.6 KiB
5.6 KiB
文档说明
本文档描述 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
{
"printing_job_ids": [101, 102, 103]
}
Response(200)
返回下一待执行节点(统一)及其工艺参数定义:
{
"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
{
"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)。
Response(200)
{
"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:来自ModelBasecreated_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,后端在批量记录表上做去重)。