1
0
forked from erp-dev/erp
Files
erpnew/docs/PlateOrder_API.md

764 lines
18 KiB
Markdown
Raw 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.
# PlateOrder API 文档
## 概述
开版订单PlateOrder管理接口提供开版订单的完整 CRUD 操作、作废/恢复功能。
**基础路径**: `/api/v1/plate-orders/`
**认证方式**: 需要用户认证和相应权限
---
## 接口列表
### 1. 获取开版订单列表
**请求**
```
GET /api/v1/plate-orders/
```
**查询参数**
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| customer | integer | 否 | 客户ID精确匹配 |
| customer_name | string | 否 | 客户名称(模糊查询) |
| customer_phone | string | 否 | 客户电话(模糊查询) |
| salesperson | integer | 否 | 业务员ID |
| merchandiser | integer | 否 | 跟单员ID |
| designer | integer | 否 | 设计师ID |
| plate_type | string | 否 | 版型(模糊查询) |
| urgency_level | string | 否 | 紧急程度(模糊查询) |
| is_invalid | boolean | 否 | 是否作废true/false |
| is_ordered | boolean | 否 | 是否已下单true/false |
| is_mark_frame | boolean | 否 | 是否打样架true/false |
| fabric | string | 否 | 面料(模糊查询) |
| style_name | string | 否 | 款式名称(模糊查询) |
| plate_date_from | date | 否 | 开版日期起始YYYY-MM-DD |
| plate_date_to | date | 否 | 开版日期结束YYYY-MM-DD |
| required_completion_date_from | datetime | 否 | 要求完成时间起始ISO86012025-11-20T08:00:00Z |
| required_completion_date_to | datetime | 否 | 要求完成时间结束ISO8601 |
| created_date_from | date | 否 | 创建日期起始 |
| created_date_to | date | 否 | 创建日期结束 |
| search | string | 否 | 全文搜索(搜索设计编号、款式名称、客户名称、面料) |
| ordering | string | 否 | 排序字段,前加"-"表示倒序,如:`-created_at` |
| limit | integer | 否 | 每页条数 |
| offset | integer | 否 | 偏移量 |
**可排序字段**: `id`, `created_at`, `updated_at`, `plate_date`, `required_completion_date`, `completion_date`, `urgency_level`, `is_ordered`, `is_invalid`
**响应示例**
```json
{
"count": 100,
"next": "http://example.com/api/v1/plate-orders/?limit=20&offset=20",
"previous": null,
"results": [
{
"id": 1,
"design_code": "DESIGN001",
"plate_type": "圆网",
"plate_date": "2025-11-10T10:00:00Z",
"urgency_level": "加急",
"is_invalid": false,
"customer": 5,
"customer_name": "测试客户",
"area": "广州",
"salesperson": 3,
"salesperson_name": "张三",
"merchandiser": 4,
"merchandiser_name": "李四",
"designer": 8,
"designer_name": "王五",
"style_name": "花朵印染",
"fabric": "棉布",
"width": "150cm",
"required_completion_date": "2025-11-20T18:00:00Z",
"completion_date": null,
"is_ordered": false,
"process": 1,
"process_name": "开版流程",
"status": "进行中",
"progress_percentage": 50,
"created_at": "2025-11-10T09:00:00Z",
"updated_at": "2025-11-10T10:00:00Z"
}
]
}
```
---
### 2. 获取开版订单详情
**请求**
```
GET /api/v1/plate-orders/{id}/
```
**路径参数**
| 参数名 | 类型 | 说明 |
|--------|------|------|
| id | integer | 开版订单ID |
**响应示例**
```json
{
"id": 1,
"design_code": "DESIGN001",
"plate_type": "圆网",
"plate_date": "2025-11-10T10:00:00Z",
"plate_method": "手工",
"plate_image": [
{
"file_id": 12,
"name": "主图",
"url": "https://example.com/media/uploads/2025/11/plate-a.jpg",
"path": "uploads/2025/11/plate-a.jpg"
},
{
"file_id": 13,
"name": "细节图",
"url": "https://example.com/media/uploads/2025/11/plate-b.jpg",
"path": "uploads/2025/11/plate-b.jpg"
}
],
"plate_image_url": [
"https://example.com/media/uploads/2025/11/plate-a.jpg",
"https://example.com/media/uploads/2025/11/plate-b.jpg"
],
"plate_notes": "注意色彩还原",
"reprint_reason": null,
"urgency_level": "加急",
"is_invalid": false,
"customer": 5,
"customer_name": "测试客户",
"customer_phone": "13900139000",
"area": "广州",
"default_address": "广州市天河区XX路XX号",
"salesperson": 3,
"salesperson_name": "张三",
"merchandiser": 4,
"merchandiser_name": "李四",
"designer": 8,
"designer_name": "王五",
"style_name": "花朵印染",
"fabric": "棉布",
"width": "150cm",
"production_method": "批量生产",
"is_mark_frame": true,
"drawing_rating": "优秀",
"color_matching_rating": "良好",
"sample_rating": "优秀",
"difficulty_rating": "中等",
"sample_meter": "5米",
"required_sample_meters": 10.00,
"required_completion_date": "2025-11-20T18:00:00Z",
"completion_date": null,
"approval_result": "通过",
"is_ordered": false,
"customer_feedback": "满意",
"process": 1,
"process_name": "开版流程",
"status": "进行中",
"status_id": 2,
"is_completed": false,
"has_started": true,
"progress_percentage": 50,
"business_object_id": 10,
"created_at": "2025-11-10T09:00:00Z",
"updated_at": "2025-11-10T10:00:00Z"
}
```
---
### 3. 创建开版订单
**请求**
```
POST /api/v1/plate-orders/
Content-Type: application/json
```
**请求体**
```json
{
"customer": 5,
"design_code": "DESIGN002",
"plate_type": "平网",
"style_name": "条纹印染",
"fabric": "涤纶",
"width": "160cm",
"urgency_level": "正常",
"salesperson": 3,
"merchandiser": 4,
"designer": 8,
"plate_image": [
{"file_id": 21, "name": "主图"},
{"file_id": 22, "name": "细节图"}
],
"required_completion_date": "2025-11-25T06:30:00Z",
"is_mark_frame": false,
"plate_method": "机器",
"production_method": "小批量",
"process": 1
}
```
**必填字段**
- `customer`: 客户ID
**可选字段**
- `design_code`: 设计编号
- `plate_type`: 版型
- `plate_date`: 开版日期
- `plate_method`: 开版方式
- `plate_image`: 开版图片引用列表(数组,元素包含 `file_id` 与可选 `name`,需要先通过 `/api/v1/upload/` 上传文件)
- `plate_notes`: 打版注意事项
- `reprint_reason`: 复版原因
- `urgency_level`: 紧急程度
- `area`: 区域
- `default_address`: 默认地址
- `salesperson`: 业务员ID
- `merchandiser`: 跟单员ID
- `designer`: 设计师ID
- `style_name`: 款式名称
- `fabric`: 面料
- `fabric_source`: 布料来源(可空字符串,如“客户提供”)
- `width`: 幅宽
- `production_method`: 做货方式
- `is_mark_frame`: 是否套唛架
- `drawing_rating`: 画图评级
- `color_matching_rating`: 调色评级
- `sample_rating`: 套样评级
- `difficulty_rating`: 难度评级
- `sample_meter`: 米样
- `required_sample_meters`: 所需样品米数
- `required_completion_date`: 要求完成时间(日期+具体时间UTC 推荐)
- `completion_date`: 完成时间
- `approval_result`: 审批结果
- `is_ordered`: 是否已下单
- `customer_feedback`: 客户反馈
- `process`: 流程ID如果不传递则使用默认流程
**响应**
- 状态码: `201 Created`
- 响应体: 创建的开版订单详情(同详情接口)。若 `design_code` 为空,返回值会自动使用 6 位补零的主键(如 `000123`)。
**错误响应**
```json
{
"customer": ["客户不能为空"]
}
```
---
### 4. 更新开版订单(完整更新)
**请求**
```
PUT /api/v1/plate-orders/{id}/
Content-Type: application/json
```
**请求体**: 同创建接口,需提供所有字段
**响应**
- 状态码: `200 OK`
- 响应体: 更新后的开版订单详情
---
### 5. 更新开版订单(部分更新)
**请求**
```
PATCH /api/v1/plate-orders/{id}/
Content-Type: application/json
```
**请求体示例**
```json
{
"urgency_level": "特急",
"is_mark_frame": true,
"completion_date": "2025-11-15"
}
```
**说明**: 只需提供要更新的字段
**响应**
- 状态码: `200 OK`
- 响应体: 更新后的开版订单详情
---
### 6. 删除开版订单(不支持)
**请求**
```
DELETE /api/v1/plate-orders/{id}/
```
**响应**
```json
{
"detail": "开版订单不支持删除操作,请使用作废功能"
}
```
- 状态码: `405 Method Not Allowed`
**说明**: 开版订单不支持物理删除,请使用作废功能进行软删除。
---
### 7. 作废开版订单
**请求**
```
POST /api/v1/plate-orders/{id}/invalidate/
```
**权限要求**: `printing.can_invalidate_plateorder`
**响应示例**
```json
{
"detail": "开版订单已作废",
"data": {
"id": 1,
"is_invalid": true,
// ... 其他字段
}
}
```
**错误响应**
1. 无权限
```json
{
"detail": "您没有权限作废开版订单"
}
```
- 状态码: `403 Forbidden`
2. 订单已作废
```json
{
"detail": "该开版订单已经作废"
}
```
- 状态码: `400 Bad Request`
---
### 8. 恢复开版订单
**请求**
```
POST /api/v1/plate-orders/{id}/activate/
```
**权限要求**: `printing.can_activate_plateorder`
**响应示例**
```json
{
"detail": "开版订单已恢复",
"data": {
"id": 1,
"is_invalid": false,
// ... 其他字段
}
}
```
**错误响应**
1. 无权限
```json
{
"detail": "您没有权限恢复开版订单"
}
```
- 状态码: `403 Forbidden`
2. 订单未作废
```json
{
"detail": "该开版订单未作废,无需恢复"
}
```
- 状态码: `400 Bad Request`
---
### 9. 推进到下一个状态
**请求**
```
POST /api/v1/plate-orders/{id}/advance-to-next-state/
```
**权限要求**: 需要登录和相应权限
**响应示例**
```json
{
"detail": "已推进到下一个状态",
"data": {
"id": 1,
"status": "调色",
"status_id": 2,
"progress_percentage": 33,
// ... 其他字段
}
}
```
**错误响应**
1. 没有流程实例
```json
{
"detail": "该开版订单没有关联的流程实例"
}
```
- 状态码: `400 Bad Request`
2. 流程已完成或其他错误
```json
{
"detail": "流程已完成,无法继续推进"
}
```
- 状态码: `400 Bad Request`
---
### 10. 回退一步
**请求**
```
POST /api/v1/plate-orders/{id}/step-back-one-state/
```
**权限要求**: 需要登录和相应权限
**响应示例**
```json
{
"detail": "已回退到上一个状态",
"data": {
"id": 1,
"status": "画图",
"status_id": 1,
"progress_percentage": 0,
// ... 其他字段
}
}
```
**错误响应**
1. 没有流程实例
```json
{
"detail": "该开版订单没有关联的流程实例"
}
```
- 状态码: `400 Bad Request`
2. 没有可回退的状态
```json
{
"detail": "没有可回退的状态"
}
```
- 状态码: `400 Bad Request`
---
### 11. 查询已完成的流程列表
**请求**
```
GET /api/v1/plate-orders/{id}/completed-states/
```
**查询参数**
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| include_cancelled | boolean | 否 | 是否包含已撤销的流程true/false默认 false |
**响应示例**
```json
{
"count": 2,
"results": [
{
"id": 1,
"state_id": 1,
"state_name": "画图",
"completed_at": "2025-11-11T10:00:00Z",
"completed_by": "user123",
"completed_by_name": "张三",
"is_cancelled": false,
"cancelled_at": null
},
{
"id": 2,
"state_id": 2,
"state_name": "调色",
"completed_at": "2025-11-12T15:30:00Z",
"completed_by": "user456",
"completed_by_name": "李四",
"is_cancelled": false,
"cancelled_at": null
}
]
}
```
---
### 12. 获取流程时间线
**请求**
```
GET /api/v1/plate-orders/{id}/timeline/
```
**说明**: 返回完整的流程时间线,包括未开始、进行中和已完成的状态,不包含已撤销的记录
**响应示例**
```json
{
"count": 3,
"results": [
{
"state_id": 1,
"state_name": "画图",
"state_description": "设计图纸绘制",
"order": 0,
"status": "completed",
"completed_at": "2025-11-11T10:00:00Z",
"completed_by": "user123",
"completed_by_name": "张三"
},
{
"state_id": 2,
"state_name": "调色",
"state_description": "颜色调配",
"order": 1,
"status": "in_progress",
"completed_at": null,
"completed_by": null,
"completed_by_name": null
},
{
"state_id": 3,
"state_name": "套样",
"state_description": "样品套制",
"order": 2,
"status": "not_started",
"completed_at": null,
"completed_by": null,
"completed_by_name": null
}
]
}
```
**状态说明**
- `not_started`: 未开始
- `in_progress`: 进行中
- `completed`: 已完成
---
## 数据模型
### PlateOrder开版订单
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | integer | 主键ID |
| design_code | string | 设计编号 |
| plate_type | string | 版型(首版/复版等) |
| plate_date | datetime | 开版时间 |
| plate_method | string | 开版方式 |
| plate_image | array<object> | 开版图片引用列表(通过 `UploadedFile` ID 关联) |
| plate_notes | text | 打版注意事项 |
| reprint_reason | text | 复版原因 |
| urgency_level | string | 紧急程度 |
| is_invalid | boolean | 是否作废 |
| customer | FK | 客户(外键) |
| area | string | 区域 |
| default_address | string | 默认地址 |
| salesperson | FK | 业务员(外键) |
| merchandiser | FK | 跟单员(外键) |
| designer | FK | 设计师(外键) |
| process | integer | 流程ID无外键约束 |
| style_name | string | 款式名称 |
| fabric | string | 面料 |
| width | string | 幅宽 |
| production_method | string | 做货方式 |
| is_mark_frame | boolean | 是否套唛架 |
| drawing_rating | string | 画图评级 |
| color_matching_rating | string | 调色评级 |
| sample_rating | string | 套样评级 |
| difficulty_rating | string | 难度评级 |
| sample_meter | string | 米样 |
| required_sample_meters | decimal | 所需样品米数 |
| required_completion_date | datetime | 要求完成时间ISO8601 字符串) |
| completion_date | datetime | 完成时间 |
| approval_result | string | 审批结果 |
| is_ordered | boolean | 是否已下单 |
| customer_feedback | text | 客户反馈 |
| created_at | datetime | 创建时间 |
| updated_at | datetime | 更新时间 |
---
## 权限说明
### 基础权限DjangoModelPermissions
- `printing.view_plateorder` - 查看开版订单
- `printing.add_plateorder` - 添加开版订单
- `printing.change_plateorder` - 修改开版订单
- `printing.delete_plateorder` - 删除权限(但实际不允许删除)
### 自定义权限
- `printing.can_invalidate_plateorder` - 作废开版订单
- `printing.can_activate_plateorder` - 恢复开版订单
---
## 使用示例
### 示例1: 搜索特定客户的加急订单
```bash
curl -X GET "http://api.example.com/api/v1/plate-orders/?customer_name=测试&urgency_level=加急" \
-H "Authorization: Token your-auth-token"
```
### 示例2: 创建开版订单
```bash
curl -X POST "http://api.example.com/api/v1/plate-orders/" \
-H "Authorization: Token your-auth-token" \
-H "Content-Type: application/json" \
-d '{
"customer": 5,
"design_code": "DESIGN003",
"plate_type": "圆网",
"style_name": "新款印染",
"fabric": "纯棉",
"urgency_level": "加急",
"required_completion_date": "2025-11-20T18:00:00Z",
"process": 1
}'
```
### 示例3: 作废订单
```bash
curl -X POST "http://api.example.com/api/v1/plate-orders/1/invalidate/" \
-H "Authorization: Token your-auth-token"
```
### 示例4: 按日期范围查询
```bash
curl -X GET "http://api.example.com/api/v1/plate-orders/?plate_date_from=2025-11-01&plate_date_to=2025-11-30&ordering=-plate_date" \
-H "Authorization: Token your-auth-token"
```
### 示例5: 推进流程状态
```bash
curl -X POST "http://api.example.com/api/v1/plate-orders/1/advance-to-next-state/" \
-H "Authorization: Token your-auth-token"
```
### 示例6: 回退流程状态
```bash
curl -X POST "http://api.example.com/api/v1/plate-orders/1/step-back-one-state/" \
-H "Authorization: Token your-auth-token"
```
### 示例7: 获取流程时间线
```bash
curl -X GET "http://api.example.com/api/v1/plate-orders/1/timeline/" \
-H "Authorization: Token your-auth-token"
```
---
## 错误代码
| 状态码 | 说明 |
|--------|------|
| 200 | 请求成功 |
| 201 | 创建成功 |
| 400 | 请求参数错误 |
| 403 | 权限不足 |
| 404 | 资源不存在 |
| 405 | 方法不允许 |
| 500 | 服务器内部错误 |
---
## 注意事项
1. **软删除机制**: 开版订单不支持物理删除,使用 `is_invalid` 字段进行软删除
2. **权限控制**: 作废和恢复操作需要特定权限
3. **日期格式**: 所有日期字段使用 ISO 8601 格式YYYY-MM-DD 或 YYYY-MM-DDTHH:MM:SSZ
4. **分页**: 列表接口默认支持分页,使用 `limit``offset` 参数控制
5. **文件引用**: 需先调用 `/api/v1/upload/` 上传文件并获取 `file_id`,再通过 `plate_image` 数组提交引用(无需 multipart
6. **自动创建流程实例**: 创建开版订单时,如果提供了 `process` 字段,系统会自动创建对应的 BusinessObject 流程实例。如果不提供则使用默认流程
7. **流程验证**: 提供的 `process` ID 必须在系统中存在,否则会返回验证错误
8. **流程操作**:
- 推进/回退操作需要订单已关联 BusinessObject
- timeline 接口不包含已撤销的流程记录
- completed-states 接口默认不包含已撤销记录,可通过 `include_cancelled=true` 参数包含
9. **设计编号回退**: 所有响应中若 `design_code` 为空,会自动使用主键生成 6 位补零字符串(如 `000123`),确保前端始终有值可显示
10. **布料来源**: `fabric_source` 为可选字段,建议用于区分客户提供、仓库调拨等不同来源信息
---
## 更新日志
### v1.2.0 (2025-11-14)
- 添加流程控制接口:
- `advance-to-next-state`: 推进到下一个状态
- `step-back-one-state`: 回退一步
- `completed-states`: 查询已完成的流程列表
- `timeline`: 获取流程时间线
### v1.1.0 (2025-11-14)
- 添加 `process` 字段支持指定流程ID
- 添加 `process_name` 只读字段:自动返回流程名称
- 自动创建 BusinessObject创建订单时根据 process 自动创建流程实例
- 流程验证确保提供的流程ID有效
### v1.0.0 (2025-11-13)
- 初始版本
- 支持完整的 CRUD 操作
- 添加作废/恢复功能
- 支持多维度过滤和搜索