1
0
forked from erp-dev/erp
Files
erpnew/docs/api_v2_stateflow_business_object_clone.md
2025-12-16 08:42:53 +08:00

139 lines
4.5 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.
### 文档说明
本文档描述 `api_v2` 的 **BusinessObject 克隆**接口与约束,用于在不影响原对象的情况下,克隆一个“流程实例数据完全一致”的新对象(包含日志与工艺参数历史),同时要求绑定到新的业务对象(`content_type + object_id`)。
---
## 1. 背景与目的
`stateflow.BusinessObject` 通过:
- `process` 指定流程模板;
- `state_logs (StateFlowRecord)` 记录每一步完成情况;
- `StateLogParameterRecord` 记录每次提交的工艺参数 JSON
- `content_type + object_id`GenericForeignKey可选关联到“订单/工单/任务”等业务对象。
克隆的目的:
- **完整复制流程实例的历史数据**(含已撤销记录、含参数记录)用于“另起一份流程实例继续/重跑/复盘”;
- **不影响原对象**
- **必须绑定新的业务对象 ID**,否则克隆出的对象与原对象在业务关联上无差异,容易造成误用。
---
## 2. API 概览
### 2.1 Endpoint
- **POST** `/api/v2/stateflow/business-objects/clone/`
### 2.2 权限
- 需要登录:`IsAuthenticated`
- 鉴权方式:项目统一 JWT同其他 api_v2 端点)
### 2.3 请求参数(必须)
请求体 JSON
- `business_object_id`:源 BusinessObject 的 ID
- `content_type`:源对象的 `content_type_id`(仅用于一致性校验)
- `object_id`:克隆后新对象要绑定的业务对象 ID必须是新的
> 说明:
> - **content_type 仅做 “与源对象是否一致” 校验**,不做额外业务校验。
> - **object_id 必须与源对象不同**;否则克隆没有业务意义,后端会拒绝。
### 2.4 响应
成功:
- 返回 `business_object_id`(克隆后新对象 ID
---
## 3. 请求/响应示例
### 3.1 成功克隆
请求:
```json
{
"business_object_id": 123,
"content_type": 9,
"object_id": 456
}
```
响应200
```json
{
"business_object_id": 789
}
```
含义:
- `123` 是源流程实例
- `789` 是新的流程实例(日志与参数完整复制)
- 新实例会绑定到新的业务对象:`content_type_id=9, object_id=456`
---
## 4. 重要校验规则与错误码
### 4.1 404源对象不存在
`business_object_id` 不存在时:
- 返回 **404**
```json
{ "detail": "business_object 不存在" }
```
### 4.2 400content_type 不一致
当请求体 `content_type` 与源对象的 `content_type_id` 不一致:
- 返回 **400**
```json
{ "detail": "content_type 与源对象不一致,拒绝克隆" }
```
### 4.3 400object_id 相关校验失败
当源对象存在 `content_type_id`(即已绑定业务对象)时:
- **必须提供** `object_id`
-`object_id` **必须与源对象不同**
可能返回的 400
```json
{ "detail": "必须提供新的 object_id" }
```
```json
{ "detail": "object_id 必须与源对象不同" }
```
### 4.4 400源对象未绑定业务对象但传了 object_id
当源对象 `content_type_id``null` 时,要求 `object_id` 也为 `null`
```json
{ "detail": "源对象未绑定 content_typeobject_id 必须为空" }
```
---
## 5. 克隆范围与语义(后端实现约定)
后端通过 `stateflow.services.clone_business_object(...)` 实现克隆,核心语义:
- **克隆 BusinessObject 的基础字段**`name / process / description / content_type`
- **克隆后的 object_id 使用请求体传入的 `object_id`**
- **复制所有 StateFlowRecordstate_logs**
- 包含已撤销记录(`is_cancelled=True`
- 保持 `completed_at / cancelled_at` 等关键字段一致
- **复制每条 StateFlowRecord 的 StateLogParameterRecordparameter_records**
- 复制 `parameters`(深拷贝 JSON
- 复制 `remark`
- 保持 `created_at/updated_at` 一致
- **时间戳一致性(严格)**
- `BusinessObject.created_at/updated_at` 也会被同步为源对象值(通过 update 绕过 auto_now/auto_now_add
- **互不影响**
- 修改克隆对象的参数记录/日志不会影响源对象(复制的是新记录)
---
## 6. 与测试的对应关系
强校验与数据一致性主要由 **service 层严格测试**保证:
- `stateflow/tests/test_clone_business_object.py`
API 层仅做轻量测试:
- `api_v2/tests.py`(成功/404/401/ct不一致
---
## 7. 变更提示(给前端/调用方)
如果你之前使用旧版接口仅传 `business_object_id`
- 现在必须补齐 `content_type` 与新的 `object_id`
- 并且 `object_id` 必须是“新业务对象”的 id例如新订单、复制出来的订单等