1
0
forked from erp-dev/erp

feat: log formatted

This commit is contained in:
2026-06-26 17:03:54 +08:00
parent e8bf4b5e49
commit cb6589c884
26 changed files with 1410 additions and 50 deletions

View File

@@ -0,0 +1,483 @@
# API v1 印染任务接口说明printing-jobs
本文档汇总 `/api/v1/printing-jobs/` 相关接口,按当前代码实现整理,重点覆盖列表和详情接口。
## 基础信息
- 基础路径:`/api/v1/printing-jobs/`
- 资源模型:`printing.PrintingJob`
- 认证:需要已登录用户
- 权限:
- 用户必须属于印染工厂商户
- 常规 CRUD 受 Django model permission 控制,例如 `printing.view_printingjob`
- 默认按 `printing_order.customer` 做客户可见性过滤
- 拥有 `printing.view_all_printingorders` 权限可突破客户可见性限制
- 分页:`limit/offset`
- 默认 `limit=800`
- 最大 `limit=1000`
## 接口总览
| 方法 | 路径 | 说明 |
| --- | --- | --- |
| `GET` | `/api/v1/printing-jobs/` | 获取印染任务列表 |
| `GET` | `/api/v1/printing-jobs/{id}/` | 获取印染任务详情 |
| `POST` | `/api/v1/printing-jobs/` | 创建印染任务 |
| `PUT` | `/api/v1/printing-jobs/{id}/` | 全量更新印染任务 |
| `PATCH` | `/api/v1/printing-jobs/{id}/` | 部分更新印染任务 |
| `DELETE` | `/api/v1/printing-jobs/{id}/` | 已禁用,返回 405 |
| `POST` | `/api/v1/printing-jobs/mark-production-completed/` | 显式标记任务完成生产 |
| `POST` | `/api/v1/printing-jobs/{id}/advance-to-next-state/` | 推进到下一个流程节点 |
| `POST` | `/api/v1/printing-jobs/{id}/step-back-one-state/` | 回退一个流程节点 |
| `GET` | `/api/v1/printing-jobs/{id}/completed-states/` | 查询已完成流程节点 |
| `GET` | `/api/v1/printing-jobs/{id}/timeline/` | 查询流程时间线 |
## 1. 列表
`GET /api/v1/printing-jobs/`
### Schema 注意事项
- 列表响应固定为分页对象:`count``next``previous``results`
- `results[]` 中除下表特别说明外,字段会稳定返回;没有值时通常返回 `null`、空字符串、空数组或 `false`
- `is_sales_order_bound` 是条件字段:默认返回;当查询参数 `include_sales_order_bound=false``0``no` 时,该字段不会出现在 `results[]` 对象中。
- 列表接口不返回详情专属字段 `product_code``status_id`
### 查询参数
| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `printing_order` | integer | 否 | 按印染订单内部 ID 精确过滤 |
| `external_order_id` | string | 否 | 按所属订单 `external_order_id` 模糊过滤 |
| `product` | integer | 否 | 按产品 ID 精确过滤 |
| `product_name` | string | 否 | 按产品名称模糊过滤 |
| `unit` | string | 否 | 按单位模糊过滤 |
| `quantity_min` | number | 否 | 最小数量 |
| `quantity_max` | number | 否 | 最大数量 |
| `pieces_min` | number | 否 | 最小件数 |
| `pieces_max` | number | 否 | 最大件数 |
| `is_production_completed` | boolean | 否 | 是否已显式标记完成生产 |
| `include_sales_order_bound` | boolean/string | 否 | 是否返回 `is_sales_order_bound`;传 `false`/`0`/`no` 时不返回该字段 |
| `search` | string | 否 | 全文搜索:产品名称、单位、尺寸、备注 |
| `ordering` | string | 否 | 排序字段,支持 `id``created_at``updated_at``quantity``pieces`;前缀 `-` 表示倒序 |
| `limit` | integer | 否 | 每页条数,默认 800最大 1000 |
| `offset` | integer | 否 | 分页偏移量 |
默认排序:`-created_at`
### 响应字段
列表使用 `PrintingJobListSerializer`
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | integer | 印染任务 ID |
| `original_id` | integer/null | 克隆来源任务 ID外部同步场景保存外部 record `ID` |
| `sub_id` | integer/null | 外部明细子 ID外部同步场景来自 `SubID` |
| `merchant_id` | integer/null | 所属商户 ID |
| `printing_order` | integer | 印染订单内部 ID |
| `printing_order_id` | string | 印染订单 `human_id` |
| `external_order_id` | string/null | 所属订单外部编号 |
| `product` | integer | 产品 ID |
| `product_name` | string/null | 产品名称 |
| `product_image_url` | string/null | 产品主图 URL |
| `has_started` | boolean | 是否已有未撤销流程记录 |
| `quantity` | integer | 数量 |
| `billed_quantity` | decimal string | 已关联非作废销售单明细数量合计 |
| `unit` | string | 单位 |
| `size` | string/null | 一段尺寸 |
| `pieces` | integer/null | 件数 |
| `description` | string/null | 备注 |
| `work_state` | integer | 业务进展枚举值 |
| `work_state_display` | string | 业务进展展示值 |
| `status` | string | 当前流程状态展示名 |
| `is_completed` | boolean | 流程是否完成 |
| `is_production_completed` | boolean | 是否显式标记完成生产 |
| `progress_percentage` | number | 流程进度百分比 |
| `last_completed_state` | string | 最后完成的流程节点名称 |
| `business_object_id` | integer/null | 关联流程实例 ID |
| `is_sales_order_bound` | boolean/可能不存在 | 是否已被非作废销售单明细绑定;可通过 `include_sales_order_bound=false` 关闭,关闭后字段不返回 |
| `batch_advance_records` | array | 与该任务相关的批量流程操作记录 |
| `saleitems` | array | 关联的有效销售品明细 |
| `fabric` | string | 所属印染订单面料 |
| `created_at` | datetime | 创建时间 |
| `updated_at` | datetime | 更新时间 |
### 示例
```bash
curl "http://localhost:8100/api/v1/printing-jobs/?external_order_id=KD20410611&limit=50" \
-H "Authorization: Bearer <token>"
```
响应示例:
```json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 101,
"original_id": 1190494,
"sub_id": 1,
"merchant_id": 1,
"printing_order": 55,
"printing_order_id": "20260626000055",
"external_order_id": "KD20410611",
"product": 88,
"product_name": "Tj1712#12号色-24码",
"product_image_url": null,
"has_started": false,
"quantity": 10,
"billed_quantity": "0.00",
"unit": "段",
"size": "2.68",
"pieces": 10,
"description": null,
"work_state": 0,
"work_state_display": "生产中",
"status": "待印染",
"is_completed": false,
"is_production_completed": false,
"progress_percentage": 0.0,
"last_completed_state": "",
"business_object_id": 2001,
"is_sales_order_bound": false,
"batch_advance_records": [],
"saleitems": [],
"fabric": "120克本白四面弹单定",
"created_at": "2026-06-26T15:35:00+08:00",
"updated_at": "2026-06-26T15:35:00+08:00"
}
]
}
```
## 2. 详情
`GET /api/v1/printing-jobs/{id}/`
详情使用 `PrintingJobDetailSerializer`,比列表多返回 `product_code``status_id`
### Schema 注意事项
- 详情响应是单个对象,不包在 `results` 中。
- 除下表特别说明外,字段会稳定返回;没有值时通常返回 `null`、空字符串、空数组或 `false`
- `is_sales_order_bound` 是条件字段:默认返回;当查询参数 `include_sales_order_bound=false``0``no` 时,该字段不会出现在响应对象中。
- 详情接口不返回列表专属字段 `product_image_url`
### 路径参数
| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `id` | integer | 是 | 印染任务 ID |
### 查询参数
| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `include_sales_order_bound` | boolean/string | 否 | 是否返回 `is_sales_order_bound`;传 `false`/`0`/`no` 时不返回该字段 |
### 响应字段
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | integer | 印染任务 ID |
| `original_id` | integer/null | 克隆来源任务 ID外部同步场景保存外部 record `ID` |
| `sub_id` | integer/null | 外部明细子 ID外部同步场景来自 `SubID` |
| `merchant_id` | integer/null | 所属商户 ID |
| `printing_order` | integer | 印染订单内部 ID |
| `printing_order_id` | string | 印染订单 `human_id` |
| `external_order_id` | string/null | 所属订单外部编号 |
| `product` | integer | 产品 ID |
| `product_name` | string/null | 产品名称 |
| `product_code` | string/null | 产品 `human_id` |
| `quantity` | integer | 数量 |
| `billed_quantity` | decimal string | 已关联非作废销售单明细数量合计 |
| `unit` | string | 单位 |
| `size` | string/null | 一段尺寸 |
| `pieces` | integer/null | 件数 |
| `description` | string/null | 备注 |
| `work_state` | integer | 业务进展枚举值 |
| `work_state_display` | string | 业务进展展示值 |
| `status` | string | 当前流程状态展示名 |
| `status_id` | integer/null | 当前待执行流程节点 ID已完成时为空 |
| `is_completed` | boolean | 流程是否完成 |
| `is_production_completed` | boolean | 是否显式标记完成生产 |
| `has_started` | boolean | 是否已有未撤销流程记录 |
| `progress_percentage` | number | 流程进度百分比 |
| `last_completed_state` | string | 最后完成的流程节点名称 |
| `business_object_id` | integer/null | 关联流程实例 ID |
| `is_sales_order_bound` | boolean/可能不存在 | 是否已被非作废销售单明细绑定;可通过 `include_sales_order_bound=false` 关闭,关闭后字段不返回 |
| `batch_advance_records` | array | 与该任务相关的批量流程操作记录 |
| `saleitems` | array | 关联的有效销售品明细 |
| `fabric` | string | 所属印染订单面料 |
| `created_at` | datetime | 创建时间 |
| `updated_at` | datetime | 更新时间 |
### 示例
```bash
curl "http://localhost:8100/api/v1/printing-jobs/101/" \
-H "Authorization: Bearer <token>"
```
响应示例:
```json
{
"id": 101,
"original_id": 1190494,
"sub_id": 1,
"merchant_id": 1,
"printing_order": 55,
"printing_order_id": "20260626000055",
"external_order_id": "KD20410611",
"product": 88,
"product_name": "Tj1712#12号色-24码",
"product_code": "TP00088",
"quantity": 10,
"billed_quantity": "0.00",
"unit": "段",
"size": "2.68",
"pieces": 10,
"description": null,
"work_state": 0,
"work_state_display": "生产中",
"status": "待印染",
"status_id": 1,
"is_completed": false,
"is_production_completed": false,
"has_started": false,
"progress_percentage": 0.0,
"last_completed_state": "",
"business_object_id": 2001,
"is_sales_order_bound": false,
"batch_advance_records": [],
"saleitems": [],
"fabric": "120克本白四面弹单定",
"created_at": "2026-06-26T15:35:00+08:00",
"updated_at": "2026-06-26T15:35:00+08:00"
}
```
## 3. 创建
`POST /api/v1/printing-jobs/`
### Schema 注意事项
创建成功响应使用 `PrintingJobCreateUpdateSerializer`,不是列表/详情 serializer。因此响应只包含创建/更新字段集:`id``original_id``sub_id``printing_order``external_order_id``product``quantity``unit``size``pieces``description``work_state``batch_advance_records`
创建成功响应不会返回这些列表/详情字段:`merchant_id``printing_order_id``product_name``product_code``product_image_url``status``status_id``has_started``is_completed``is_production_completed``progress_percentage``last_completed_state``business_object_id``is_sales_order_bound``saleitems``fabric``created_at``updated_at`
### 请求体
| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `printing_order` | integer | 是 | 印染订单 ID |
| `product` | integer | 是 | 产品 ID |
| `quantity` | integer | 是 | 数量,必须大于 0 |
| `unit` | string | 是 | 单位 |
| `original_id` | integer/null | 否 | 克隆来源任务 ID外部同步通常由系统写入 |
| `sub_id` | integer/null | 否 | 外部明细子 ID |
| `size` | string/null | 否 | 一段尺寸 |
| `pieces` | integer/null | 否 | 件数 |
| `description` | string/null | 否 | 备注 |
| `work_state` | integer | 否 | 业务进展,默认 `0` |
创建接口会通过 service 自动绑定当前用户和商户,并在所属订单配置了流程时创建 `BusinessObject`
## 4. 更新
`PUT /api/v1/printing-jobs/{id}/`
`PATCH /api/v1/printing-jobs/{id}/`
可更新字段同创建接口。更新时不允许修改 `printing_order` 绑定关系;若传入不同订单,会返回 `400 Bad Request`
### Schema 注意事项
更新成功响应同样使用 `PrintingJobCreateUpdateSerializer`。字段出现规则与创建接口一致,不等同于列表/详情响应。
## 5. 删除
`DELETE /api/v1/printing-jobs/{id}/`
删除被禁用。
响应:
```json
{
"detail": "印染款式明细不支持删除操作"
}
```
状态码:`405 Method Not Allowed`
## 6. 标记完成生产
`POST /api/v1/printing-jobs/mark-production-completed/`
请求体:
```json
{
"printing_job_id": 101
}
```
成功响应:
```json
{
"message": "OK"
}
```
说明:
- 该接口只设置 `is_production_completed=true`
- 不等同于流程完成状态
- 不能跨商户操作
## 7. 推进流程
`POST /api/v1/printing-jobs/{id}/advance-to-next-state/`
请求体:
```json
{
"parameters": {
"temperature": "25.5",
"operator": "张三"
}
}
```
`parameters` 可为空;若下一流程节点定义了必填参数,则必须提供。
成功响应:
```json
{
"detail": "推进成功",
"data": {
"id": 101
}
}
```
`data` 使用 `PrintingJobDetailSerializer`
### Schema 注意事项
`data` 是详情对象,但该接口内部直接序列化,没有传入请求上下文;因此 `is_sales_order_bound` 当前会返回,不受 `include_sales_order_bound=false` 控制。
## 8. 回退流程
`POST /api/v1/printing-jobs/{id}/step-back-one-state/`
成功响应:
```json
{
"detail": "回退成功",
"data": {
"id": 101
}
}
```
`data` 使用 `PrintingJobDetailSerializer`
### Schema 注意事项
`data` 是详情对象,但该接口内部直接序列化,没有传入请求上下文;因此 `is_sales_order_bound` 当前会返回,不受 `include_sales_order_bound=false` 控制。
## 9. 已完成流程节点
`GET /api/v1/printing-jobs/{id}/completed-states/`
查询参数:
| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `include_cancelled` | boolean/string | 否 | 是否包含已撤销流程记录,默认 `false` |
响应示例:
```json
{
"count": 1,
"results": [
{
"id": 3001,
"state_id": 1,
"state_name": "待印染",
"completed_at": "2026-06-26T15:35:00+08:00",
"completed_by": "testuser",
"completed_by_name": "测试员工",
"is_cancelled": false,
"cancelled_at": null
}
]
}
```
## 10. 流程时间线
`GET /api/v1/printing-jobs/{id}/timeline/`
返回该任务的完整流程时间线,不包含已撤销记录。
响应示例:
```json
{
"count": 2,
"results": [
{
"state_id": 1,
"state_name": "待印染",
"state_description": "",
"order": 1,
"status": "completed",
"completed_at": "2026-06-26T15:35:00+08:00",
"completed_by": "testuser",
"completed_by_name": "测试员工"
},
{
"state_id": 2,
"state_name": "印染中",
"state_description": "",
"order": 2,
"status": "in_progress",
"completed_at": null,
"completed_by": null,
"completed_by_name": null
}
]
}
```
## 字段补充
### `work_state`
当前枚举来自 `PrintingJobWorkStateEnum`
| 值 | 展示 |
| --- | --- |
| `0` | 生产中 |
| `1` | 待送货 |
| `2` | 待开单 |
| `3` | 已完结 |
### `sub_id`
`sub_id` 是可空整数。外部印染 records 同步时从外部字段 `SubID` 写入,用于保留外部明细行的子编号。

View File

@@ -0,0 +1,364 @@
# API v1 印染订单接口说明printing-orders
版本日期2026-06-26
本文档仅汇总 `/api/v1/printing-orders/` 相关接口,按当前代码实现整理,用于前端核对和更新字段。
## 基本信息
- 基础路径:`/api/v1/printing-orders/`
- 认证:需要登录认证。
- 权限:使用 `DjangoModelPermissions`,且用户必须关联印染工厂类型商户。
- 数据范围:默认按客户可见性过滤;拥有 `printing.view_all_printingorders` 权限可查看全部客户订单。
- 分页:列表接口使用 `limit` / `offset`,响应为 DRF LimitOffset 格式:`count``next``previous``results`
- 列表缓存:列表接口有 20 秒缓存。
- 删除:不支持物理删除,请使用作废接口。
## 本版重点字段变更
以下字段是当前接口已返回/支持、前端需要重点核对的字段:
- `merchant_id`:列表和详情返回,当前订单所属商户 ID可能为 `null`
- `external_order_id`:外部订单编号;列表、详情返回;创建/更新也允许传入;支持过滤。
- `external_customer_id`:外部客户 ID列表、详情返回。
- `external_customer_name`:外部客户名称;列表、详情返回。
- `external_employee_name`:外部员工名称;列表、详情返回。
- `created_by`:列表返回,创建人用户 ID。
- `created_by_name`:列表、详情返回,创建人关联员工姓名,可能为 `null`
- `order_number`:新增查询参数,支持同时按 `external_order_id` 和内部订单号逻辑检索。
- `jobs_status_summary`:仅列表返回,订单下任务当前状态汇总。
- `jobs_last_status_summary`:仅列表返回,订单下任务最后完成状态汇总。
## 接口清单
| 方法 | 路径 | 说明 |
| --- | --- | --- |
| `GET` | `/api/v1/printing-orders/` | 印染订单列表 |
| `POST` | `/api/v1/printing-orders/` | 创建印染订单 |
| `GET` | `/api/v1/printing-orders/{id}/` | 印染订单详情 |
| `PUT` | `/api/v1/printing-orders/{id}/` | 全量更新印染订单 |
| `PATCH` | `/api/v1/printing-orders/{id}/` | 部分更新印染订单 |
| `DELETE` | `/api/v1/printing-orders/{id}/` | 已禁用,返回 405 |
| `POST` | `/api/v1/printing-orders/{id}/invalidate/` | 作废订单 |
| `POST` | `/api/v1/printing-orders/{id}/activate/` | 恢复订单 |
| `POST` | `/api/v1/printing-orders/{id}/mark_fabric_received/` | 标记布料已收 |
## 列表接口
`GET /api/v1/printing-orders/`
### 查询参数
列表查询参数全部可选;不传任何过滤条件时,默认返回当前权限范围内的未作废订单。
| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `limit` | number | 否 | 每页条数,默认 800最大 1000 |
| `offset` | number | 否 | 偏移量 |
| `customer` | number | 否 | 客户 ID |
| `external_order_id` | string | 否 | 外部订单编号,模糊匹配 |
| `order_number` | string | 否 | 订单号检索:模糊匹配 `external_order_id`,并尝试匹配内部 `id` / `human_id` 后 6 位 |
| `customer_name` | string | 否 | 客户名称,模糊匹配 |
| `customer_phone` | string | 否 | 客户电话,模糊匹配 |
| `fabric` | string | 否 | 面料,模糊匹配 |
| `is_urgent` | boolean | 否 | 是否紧急 |
| `is_fabric_received` | boolean | 否 | 布料是否已收 |
| `is_invalid` | boolean | 否 | 是否作废;未传时默认只返回未作废订单 |
| `area` | string | 否 | 地区,模糊匹配 |
| `outgoing_date_from` | date/datetime | 否 | 出货日期起始;支持 `YYYY-MM-DD` 或日期时间 |
| `outgoing_date_to` | date/datetime | 否 | 出货日期结束;传 `YYYY-MM-DD` 时包含整天 |
| `created_date_from` | date | 否 | 创建日期起始 |
| `created_date_to` | date | 否 | 创建日期结束;包含整天 |
| `search` | string | 否 | 搜索客户名称、面料、地区、工艺、描述 |
| `ordering` | string | 否 | 排序字段,支持 `id``created_at``updated_at``outgoing_date``is_urgent``is_fabric_received``is_invalid`,默认 `-created_at` |
### 列表响应字段
`results[]` 每项字段:
列表响应字段均会返回;“可为空”表示字段值可能为 `null`、空字符串或空数组。
| 字段 | 类型 | 是否返回 | 可为空 | 说明 |
| --- | --- | --- | --- | --- |
| `id` | number | 是 | 否 | 内部订单 ID |
| `human_id` | string | 是 | 否 | 人类可读订单号,格式为 `YYYYMMDD + 6 位 ID` |
| `merchant_id` | number/null | 是 | 是 | 所属商户 ID |
| `customer` | number | 是 | 否 | 客户 ID |
| `customer_name` | string | 是 | 否 | 客户名称 |
| `customer_phone` | string/null | 是 | 是 | 客户手机号 |
| `fabric` | string | 是 | 否 | 面料 |
| `width` | string | 是 | 否 | 幅宽 |
| `is_urgent` | boolean | 是 | 否 | 是否紧急 |
| `area` | string/null | 是 | 是 | 地区 |
| `address` | string/null | 是 | 是 | 地址 |
| `curve` | string/null | 是 | 是 | 曲线 |
| `is_fabric_received` | boolean | 是 | 否 | 布料是否已收 |
| `outgoing_date` | datetime/null | 是 | 是 | 出货日期时间 |
| `is_invalid` | boolean | 是 | 否 | 是否作废 |
| `new_curve` | string/null | 是 | 是 | 新加曲线 |
| `process` | number/null | 是 | 是 | 印染流程 ID |
| `process_name` | string/null | 是 | 是 | 印染流程名称 |
| `progress` | number | 是 | 否 | 订单进度百分比;无任务时为 0 |
| `position` | string/null | 是 | 是 | 位置 |
| `print_count` | number | 是 | 否 | 打印次数 |
| `jobs_status_summary` | array | 是 | 是 | 订单下任务按当前状态汇总;无任务时为空数组 |
| `jobs_last_status_summary` | array | 是 | 是 | 订单下任务按最后完成状态汇总;无已完成状态时为空数组 |
| `external_order_id` | string/null | 是 | 是 | 外部订单编号 |
| `external_customer_id` | string/null | 是 | 是 | 外部客户 ID |
| `external_customer_name` | string/null | 是 | 是 | 外部客户名称 |
| `external_employee_name` | string/null | 是 | 是 | 外部员工名称 |
| `created_by` | number/null | 是 | 是 | 创建人用户 ID |
| `created_by_name` | string/null | 是 | 是 | 创建人关联员工姓名 |
| `created_at` | datetime | 是 | 否 | 创建时间 |
| `updated_at` | datetime | 是 | 否 | 更新时间 |
`jobs_status_summary` 格式:
```json
[
{
"state_name": "待印染",
"state_id": 1,
"count": 3
}
]
```
`jobs_last_status_summary` 格式:
```json
[
{
"state_name": "印染中",
"count": 2
}
]
```
## 详情接口
`GET /api/v1/printing-orders/{id}/`
### 详情响应字段
详情响应字段均会返回;“可为空”表示字段值可能为 `null` 或空字符串。
| 字段 | 类型 | 是否返回 | 可为空 | 说明 |
| --- | --- | --- | --- | --- |
| `id` | number | 是 | 否 | 内部订单 ID |
| `human_id` | string | 是 | 否 | 人类可读订单号 |
| `merchant_id` | number/null | 是 | 是 | 所属商户 ID |
| `customer` | number | 是 | 否 | 客户 ID |
| `customer_name` | string | 是 | 否 | 客户名称 |
| `customer_phone` | string/null | 是 | 是 | 客户手机号 |
| `customer_area` | string/null | 是 | 是 | 客户区域 |
| `fabric` | string | 是 | 否 | 面料 |
| `width` | string | 是 | 否 | 幅宽 |
| `is_urgent` | boolean | 是 | 否 | 是否紧急 |
| `area` | string/null | 是 | 是 | 地区 |
| `address` | string/null | 是 | 是 | 地址 |
| `fabric_source` | string/null | 是 | 是 | 布料来源 |
| `is_fabric_received` | boolean | 是 | 否 | 布料是否已收 |
| `craft` | string/null | 是 | 是 | 工艺 |
| `description` | string/null | 是 | 是 | 订单描述 |
| `outgoing_date` | datetime/null | 是 | 是 | 出货日期时间 |
| `curve` | string/null | 是 | 是 | 曲线 |
| `new_curve` | string/null | 是 | 是 | 新加曲线 |
| `position` | string/null | 是 | 是 | 位置 |
| `created_by_name` | string/null | 是 | 是 | 创建人关联员工姓名 |
| `printing_warn` | string/null | 是 | 是 | 打印注意事项 |
| `rolling_warn` | string/null | 是 | 是 | 滚筒注意事项 |
| `production_warn` | string/null | 是 | 是 | 生产注意事项 |
| `external_order_id` | string/null | 是 | 是 | 外部订单编号 |
| `external_customer_id` | string/null | 是 | 是 | 外部客户 ID |
| `external_customer_name` | string/null | 是 | 是 | 外部客户名称 |
| `external_employee_name` | string/null | 是 | 是 | 外部员工名称 |
| `is_invalid` | boolean | 是 | 否 | 是否作废 |
| `process` | number/null | 是 | 是 | 印染流程 ID |
| `process_name` | string/null | 是 | 是 | 印染流程名称 |
| `progress` | number | 是 | 否 | 订单进度百分比 |
| `print_count` | number | 是 | 否 | 打印次数 |
| `created_at` | datetime | 是 | 否 | 创建时间 |
| `updated_at` | datetime | 是 | 否 | 更新时间 |
注意:详情接口不返回 `jobs_status_summary``jobs_last_status_summary`,这两个字段是列表专用字段。
## 创建接口
`POST /api/v1/printing-orders/`
### 请求字段
| 字段 | 类型 | 必填 | 可传空 | 默认/说明 |
| --- | --- | --- | --- | --- |
| `customer` | number | 是 | 否 | 客户 ID |
| `fabric` | string | 是 | 否 | 面料 |
| `width` | string | 是 | 否 | 幅宽 |
| `is_urgent` | boolean | 否 | 否 | 默认 `false`,是否紧急 |
| `area` | string/null | 否 | 是 | 地区 |
| `address` | string/null | 否 | 是 | 地址 |
| `fabric_source` | string/null | 否 | 是 | 布料来源 |
| `is_fabric_received` | boolean | 否 | 否 | 默认 `false`,布料是否已收 |
| `craft` | string/null | 否 | 是 | 工艺 |
| `description` | string/null | 否 | 是 | 订单描述 |
| `outgoing_date` | date/datetime/null | 否 | 是 | 出货日期时间;支持 `YYYY-MM-DD``YYYY-MM-DD HH:mm``YYYY-MM-DD HH:mm:ss`、ISO8601仅传日期时按当天 `00:00:00` 处理 |
| `curve` | string/null | 否 | 是 | 曲线 |
| `new_curve` | string/null | 否 | 是 | 新加曲线 |
| `position` | string/null | 否 | 是 | 位置 |
| `printing_warn` | string/null | 否 | 是 | 打印注意事项 |
| `rolling_warn` | string/null | 否 | 是 | 滚筒注意事项 |
| `production_warn` | string/null | 否 | 是 | 生产注意事项 |
| `is_invalid` | boolean | 否 | 否 | 默认 `false`,是否作废 |
| `process` | number/null | 否 | 创建可空,更新不可改为空 | 印染流程 ID创建不传或传空时使用系统默认流程更新时不能改为空 |
| `external_order_id` | string/null | 否 | 是 | 外部订单编号 |
创建时后端会自动写入:
- `merchant`:从当前用户关联员工的商户取得。
- `created_by`:当前登录用户。
- `process`:未传时尝试使用系统默认印染流程。
### 创建请求示例
```json
{
"customer": 12,
"fabric": "纯棉布料",
"width": "150cm",
"is_urgent": true,
"area": "白云区",
"address": "白云区xxx",
"fabric_source": "客户提供",
"is_fabric_received": false,
"craft": "活性印花",
"description": "测试订单描述",
"outgoing_date": "2026-06-26",
"printing_warn": "注意颜色",
"rolling_warn": "注意温度",
"production_warn": "质量检查",
"external_order_id": "KD20410611"
}
```
成功响应使用创建/更新序列化器字段,通常包含请求字段及 `id`
## 更新接口
`PUT /api/v1/printing-orders/{id}/`
`PATCH /api/v1/printing-orders/{id}/`
更新请求字段与创建接口一致。
必填规则:
- `PUT` 是全量更新,建议至少传 `customer``fabric``width`;未传的可写字段可能按 DRF 全量更新规则校验。
- `PATCH` 是部分更新,只需要传要修改的字段。
- `id``human_id``merchant_id``created_by``created_by_name``external_customer_id``external_customer_name``external_employee_name``created_at``updated_at` 等不作为请求字段提交。
### 流程修改限制
- 当订单下没有任务,或所有任务都未开始时,可以修改 `process`
- 修改 `process` 时,后端会重建/重新绑定订单下未开始任务的流程实例。
- 如果存在任何已开始的 `PrintingJob`,修改 `process` 会返回 `400`
- `process` 不能更新为空,否则返回错误。
错误示例:
```json
{
"process": ["存在已开始的印染任务,无法修改流程"]
}
```
或:
```json
"存在已开始的印染任务,无法修改流程"
```
## 作废订单
`POST /api/v1/printing-orders/{id}/invalidate/`
权限:需要 `printing.can_invalidate_printingorder`
成功响应:
```json
{
"detail": "订单已作废",
"data": {
"id": 1
}
}
```
失败情况:
- 无权限:`403``{"detail": "您没有权限作废订单"}`
- 已作废:`400``{"detail": "该订单已经作废"}`
## 恢复订单
`POST /api/v1/printing-orders/{id}/activate/`
权限:需要 `printing.can_activate_printingorder`
成功响应:
```json
{
"detail": "订单已恢复",
"data": {
"id": 1
}
}
```
失败情况:
- 无权限:`403``{"detail": "您没有权限恢复订单"}`
- 未作废:`400``{"detail": "该订单未作废,无需恢复"}`
## 标记布料已收
`POST /api/v1/printing-orders/{id}/mark_fabric_received/`
成功后将 `is_fabric_received` 置为 `true`
成功响应:
```json
{
"detail": "已标记布料已收",
"data": {
"id": 1,
"is_fabric_received": true
}
}
```
失败情况:
- 已经标记为已收:`400``{"detail": "布料已经标记为已收"}`
## 删除接口
`DELETE /api/v1/printing-orders/{id}/`
该接口已禁用,固定返回 `405`
```json
{
"detail": "印染订单不支持删除操作,请使用作废功能"
}
```
## 前端核对建议
- 列表页应优先使用 `human_id` 展示内部订单号,外部来源订单可同时展示 `external_order_id`
- 默认列表不包含作废订单;作废订单列表需要显式传 `is_invalid=true`
- 若前端有“订单号搜索”输入框,建议接入 `order_number`,不用同时拼多个参数。
- `outgoing_date_to=YYYY-MM-DD` 会包含当天整天,前端无需手动补 `23:59:59`
- 外部字段 `external_customer_id``external_customer_name``external_employee_name` 当前只读返回,创建/更新接口只暴露 `external_order_id`

View File

@@ -0,0 +1,66 @@
# API v1: 按 external_order_id 获取印染订单详情
## Endpoint
`GET /api/v1/printing-orders/by-external-order-id/{external_order_id}/`
用于通过外部订单编号精确查询本地印染订单详情,响应结构与 `GET /api/v1/printing-orders/{id}/` 使用同一个 `PrintingOrderDetailSerializer`
## Path 参数
| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `external_order_id` | string | 是 | 外部订单编号,对应 `PrintingOrder.external_order_id` |
## 权限
`printing-orders` ViewSet 保持一致:
- 用户必须已登录
- 用户必须属于印染工厂商户
- 用户需要具备 `printing.view_printingorder` 权限
- 仍受客户可见性过滤影响;拥有 `printing.view_all_printingorders` 可查看全部客户订单
## 成功响应
状态码:`200 OK`
```json
{
"id": 123,
"human_id": "20260626000123",
"merchant_id": 1,
"customer": 10,
"customer_name": "测试客户",
"customer_phone": "13900139000",
"customer_area": "测试地区",
"fabric": "通过外部编号查询",
"width": "150cm",
"external_order_id": "KD20410611",
"external_customer_id": null,
"external_customer_name": null,
"external_employee_name": null,
"is_invalid": false,
"created_at": "2026-06-26T15:35:00+08:00",
"updated_at": "2026-06-26T15:35:00+08:00"
}
```
实际返回字段以 `PrintingOrderDetailSerializer` 为准。
## 未找到
状态码:`404 Not Found`
```json
{
"detail": "未找到该 external_order_id 对应的印染订单"
}
```
## 示例
```bash
curl -X GET "http://localhost:8100/api/v1/printing-orders/by-external-order-id/KD20410611/" \
-H "Authorization: Bearer <token>"
```