Files
zkxw/docs/superpowers/specs/2026-05-24-temporary-work-order-design.md
T
2026-05-24 16:58:51 +08:00

313 lines
14 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.
# 临时工单模块设计文档
> 日期: 2026-05-24
> 状态: 待审核
> 模块: 临时质检工单 + 临时生产工单
## 1. 背景与目标
### 现状
系统已有 4 个模块:
| 模块 | 表名 | 说明 |
|------|------|------|
| 入库质检工单 | `biz_qc_work_order` | 关联样本接收记录和协议 |
| 质检任务 | `biz_qc_task` | 由入库质检工单配置检测项目后自动生成 |
| 入库生产工单 | `biz_production_work_order` | 关联样本接收记录和协议 |
| 生产任务 | `biz_production_task` | 由入库生产工单手动派发创建 |
### 目标
新增 2 个临时工单模块,复用现有任务生成机制,在任务表中记录工单来源:
1. **临时质检工单** — 独立工单(不关联样本/协议),配置检测项目后自动生成质检任务
2. **临时生产工单** — 独立工单(不关联样本/协议),选择工艺路线后创建生产任务(自动克隆路线步骤+子表,流程与入库生产工单一致)
### 设计决策记录
| 决策项 | 选择 | 原因 |
|--------|------|------|
| 关联关系 | 完全不关联 reception/protocol | 临时工单独立于入库流程 |
| 来源追踪 | 任务表新增 `order_source` 字段 | 最小侵入,清晰区分来源 |
| 任务生成方式 | 配置→自动批量生成 | 和入库模式一致 |
| 工单字段 | 极简(工单号+状态+备注) | 用户要求简单 |
| 工单号前缀 | LSZJ(临时质检)、LSSC(临时生产) | 区分于入库前缀 |
| 实现方案 | 新建独立临时工单表 | 和入库完全解耦,避免混合复杂度 |
---
## 2. 数据库设计
### 2.1 新建 `biz_temp_qc_work_order`(临时质检工单)
```sql
DROP TABLE IF EXISTS biz_temp_qc_work_order;
CREATE TABLE biz_temp_qc_work_order (
id VARCHAR(64) NOT NULL COMMENT '主键ID',
work_order_no VARCHAR(64) NOT NULL COMMENT '工单号(LSZJ+日期+序号)',
work_order_status VARCHAR(20) NOT NULL DEFAULT 'dpz' COMMENT '状态: dpz=待配置, ypz=已配置, ywc=已完成',
configured_time DATETIME DEFAULT NULL COMMENT '配置时间',
configured_by VARCHAR(64) DEFAULT NULL COMMENT '配置人',
has_lab TINYINT DEFAULT 0 COMMENT '是否含实验室自检: 0=否, 1=是',
has_third_party TINYINT DEFAULT 0 COMMENT '是否含第三方检测: 0=否, 1=是',
third_party_fee_total DECIMAL(12,2) DEFAULT NULL COMMENT '第三方费用合计',
tenant_no VARCHAR(64) NOT NULL DEFAULT '' COMMENT '租户编号',
order_num INT DEFAULT NULL COMMENT '排序号',
remark VARCHAR(512) DEFAULT NULL COMMENT '备注',
create_by VARCHAR(64) DEFAULT NULL COMMENT '创建人id',
create_dept_id VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建人部门ID',
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_by VARCHAR(64) DEFAULT NULL COMMENT '更新人id',
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
del_flag TINYINT NOT NULL DEFAULT 0 COMMENT '删除标记: 0=正常, 1=已删除',
PRIMARY KEY (id),
KEY idx_temp_qc_wo_tenant (tenant_no, del_flag),
KEY idx_temp_qc_wo_no (work_order_no, tenant_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='临时质检工单';
```
### 2.2 新建 `biz_temp_production_work_order`(临时生产工单)
```sql
DROP TABLE IF EXISTS biz_temp_production_work_order;
CREATE TABLE biz_temp_production_work_order (
id VARCHAR(64) NOT NULL COMMENT '主键ID',
work_order_no VARCHAR(64) NOT NULL COMMENT '工单号(LSSC+日期+序号)',
work_order_status VARCHAR(20) NOT NULL DEFAULT 'dpz' COMMENT '状态: dpz=待配置, jxz=进行中, ywc=已完成',
configured_time DATETIME DEFAULT NULL COMMENT '配置时间',
configured_by VARCHAR(64) DEFAULT NULL COMMENT '配置人',
tenant_no VARCHAR(64) NOT NULL DEFAULT '' COMMENT '租户编号',
order_num INT DEFAULT NULL COMMENT '排序号',
remark VARCHAR(512) DEFAULT NULL COMMENT '备注',
create_by VARCHAR(64) DEFAULT NULL COMMENT '创建人id',
create_dept_id VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建人部门ID',
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_by VARCHAR(64) DEFAULT NULL COMMENT '更新人id',
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
del_flag TINYINT NOT NULL DEFAULT 0 COMMENT '删除标记: 0=正常, 1=已删除',
PRIMARY KEY (id),
KEY idx_temp_prod_wo_tenant (tenant_no, del_flag),
KEY idx_temp_prod_wo_no (work_order_no, tenant_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='临时生产工单';
```
### 2.3 任务表新增 `order_source` 字段
```sql
-- 质检任务表新增来源字段
ALTER TABLE biz_qc_task
ADD COLUMN order_source VARCHAR(20) NOT NULL DEFAULT 'inbound'
COMMENT '工单来源: inbound=入库, temporary=临时' AFTER work_order_id;
-- 生产任务表新增来源字段
ALTER TABLE biz_production_task
ADD COLUMN order_source VARCHAR(20) NOT NULL DEFAULT 'inbound'
COMMENT '工单来源: inbound=入库, temporary=临时' AFTER work_order_id;
```
### 2.4 明细表处理(复用现有表)
临时质检工单复用现有 `biz_qc_work_order_lab_item` 和 `biz_qc_work_order_third_item` 表,通过 `order_source` 字段区分来源。
```sql
-- 实验室项目明细表新增来源字段
ALTER TABLE biz_qc_work_order_lab_item
ADD COLUMN order_source VARCHAR(20) NOT NULL DEFAULT 'inbound'
COMMENT '工单来源: inbound=入库, temporary=临时' AFTER work_order_id;
-- 第三方项目明细表新增来源字段
ALTER TABLE biz_qc_work_order_third_item
ADD COLUMN order_source VARCHAR(20) NOT NULL DEFAULT 'inbound'
COMMENT '工单来源: inbound=入库, temporary=临时' AFTER work_order_id;
```
### 2.5 关联关系
```
biz_temp_qc_work_order
├─(work_order_id + order_source='temporary')→ biz_qc_work_order_lab_item
├─(work_order_id + order_source='temporary')→ biz_qc_work_order_third_item
└─(work_order_id + order_source='temporary')→ biz_qc_task
→ biz_qc_task_result
biz_temp_production_work_order
└─(work_order_id + order_source='temporary')→ biz_production_task
→ biz_production_task_step + 子表
```
---
## 3. 后端架构
### 3.1 新增文件清单
| 层 | 临时质检工单 | 临时生产工单 |
|----|-------------|-------------|
| Model | `models.py` 新增 `BizTempQcWorkOrder` | `models.py` 新增 `BizTempProductionWorkOrder` |
| Schema | 新建 `schemas/temp_qc_work_order.py` | 新建 `schemas/temp_production_work_order.py` |
| CRUD | 新建 `crud/temp_qc_work_order.py` | 新建 `crud/temp_production_work_order.py` |
| API | `api/qc.py` 新增路由组 | `api/production.py` 新增路由组 |
### 3.2 API 路由设计
**临时质检工单:**
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/api/admin/temp-qc-work-orders` | 创建 |
| GET | `/api/admin/temp-qc-work-orders` | 列表 |
| GET | `/api/admin/temp-qc-work-orders/{id}` | 详情 |
| DELETE | `/api/admin/temp-qc-work-orders/{id}` | 删除(软删除) |
| POST | `/api/admin/temp-qc-work-orders/{id}/configure` | 配置检测项目(→自动生成任务) |
**临时生产工单:**
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/api/admin/temp-production-work-orders` | 创建 |
| GET | `/api/admin/temp-production-work-orders` | 列表 |
| GET | `/api/admin/temp-production-work-orders/{id}` | 详情 |
| DELETE | `/api/admin/temp-production-work-orders/{id}` | 删除(软删除) |
| POST | `/api/admin/temp-production-work-orders/{id}/configure` | 配置→自动生成任务 |
### 3.3 核心业务逻辑
#### 3.3.1 工单号生成
- 临时质检:`LSZJ` + `YYYYMMDD` + 4位序号(如 `LSZJ202605240001`)
- 临时生产:`LSSC` + `YYYYMMDD` + 4位序号(如 `LSSC202605240001`)
- 生成逻辑:参照现有 `_gen_qc_work_order_no()` 模式,按日期+租户查询当日最大序号+1
#### 3.3.2 创建工单
极简创建:仅需 `remark`(可选),自动生成工单号,状态默认 `dpz`(待配置)。
#### 3.3.3 配置检测项目(临时质检工单)
流程与入库质检工单的 `configure_work_order()` 一致:
```
用户选择检测项目 (lab_item_ids, third_party_ids)
├─ 校验工单状态 (dpz/ypz)
├─ 清除旧的待执行任务(order_source='temporary')
├─ 遍历 lab_item_ids:
│ ├─ 创建 BizQcWorkOrderLabItem (order_source='temporary')
│ └─ 调用 qc_task.create_task_for_line(order_source='temporary')
├─ 遍历 third_party_ids:
│ ├─ 创建 BizQcWorkOrderThirdItem (order_source='temporary')
│ └─ 调用 qc_task.create_task_for_line(order_source='temporary')
└─ 更新工单状态为 'ypz'
```
#### 3.3.4 配置→生成任务(临时生产工单)
与入库生产工单完全一致,选择工艺路线后创建生产任务(自动克隆路线步骤+4类子表):
```
用户配置任务信息 (task_name, task_type, route_id 工艺路线, description 可选)
├─ 创建 BizProductionTask (order_source='temporary', task_status='dpz')
├─ 如果选择了工艺路线: _clone_route_to_task() — 深拷贝路线步骤 + 子表
├─ 工单状态更新为 'jxz'
└─ 流程与入库生产工单的 create_production_task() 完全一致
```
后需复用 `production_task.create_production_task()` + `_clone_route_to_task()` 机制。
#### 3.3.5 状态同步
- **质检**:任务完成时检查同工单下所有任务(order_source='temporary')是否都已完成,若是则工单标记 `ywc`
- **生产**:任务完成时同步工单状态(复用 `sync_production_work_order_status_from_tasks()` 逻辑)
#### 3.3.6 删除
软删除(`del_flag=1`),级联删除关联的任务(仅 `order_source='temporary'`)和明细行。
---
## 4. 前端架构
### 4.1 新增文件清单
| 类型 | 临时质检工单 | 临时生产工单 |
|------|-------------|-------------|
| API | 新建 `api/temp-qc-work-order.ts` | 新建 `api/temp-production-work-order.ts` |
| 视图 | 新建 `views/quality-inspection/temp-qc-work-order/index.vue` | 新建 `views/production/temp-production-work-order/index.vue` |
### 4.2 页面设计
#### 临时质检工单页
参照模板页 `views/system/unit/index.vue`(标准列表页),功能简化:
- **列表列**:工单号、状态(Tag)、是否含实验室自检、是否含第三方、配置时间、创建时间、操作
- **创建弹窗**:仅备注字段
- **配置弹窗**:复用现有配置检测项目组件(选择实验室自检项目/第三方检测项目+公司+费用)
- **详情弹窗**:工单基本信息 + 关联任务列表
- **状态 Tag**:dpz→待配置(info)、ypz→已配置(warning)、ywc→已完成(success)
#### 临时生产工单页
同样参照标准列表页:
- **列表列**:工单号、状态(Tag)、配置时间、创建时间、操作
- **创建弹窗**:仅备注字段
- **配置弹窗**:简单表单(任务名称、任务类型 cell_storage/outbound、描述)
- **详情弹窗**:工单基本信息 + 关联任务列表
- **状态 Tag**:dpz→待配置(info)、jxz→进行中(primary)、ywc→已完成(success)
### 4.3 任务来源展示
在现有质检任务和生产任务列表页中:
- 新增"来源"列,使用 Tag 展示:
- `inbound` → Tag `<el-tag type="success" size="small">入库</el-tag>`
- `temporary` → Tag `<el-tag type="warning" size="small">临时</el-tag>`
### 4.4 路由配置
在 `src/router/modules/` 中对应的质量检验和生产管理路由组下新增子路由:
```typescript
// 质量检验路由组下
{ path: 'temp-qc-work-order', name: 'TempQcWorkOrder', component: () => import('@views/quality-inspection/temp-qc-work-order/index.vue') }
// 生产管理路由组下
{ path: 'temp-production-work-order', name: 'TempProductionWorkOrder', component: () => import('@views/production/temp-production-work-order/index.vue') }
```
### 4.5 菜单配置
需要在系统菜单管理中添加对应菜单项(数据库 `sys_menu` 表插入)。
---
## 5. 修改现有代码清单
以下列出需要修改的现有文件(非新增文件):
| 文件 | 修改内容 |
|------|---------|
| `backend/app/models/models.py` | 新增 `BizTempQcWorkOrder`、`BizTempProductionWorkOrder` 模型;`BizQcTask`、`BizProductionTask` 新增 `order_source` 列;`BizQcWorkOrderLabItem`、`BizQcWorkOrderThirdItem` 新增 `order_source` 列 |
| `backend/app/crud/qc_task.py` | `create_task_for_line()` 接受 `order_source` 参数;`list_tasks()` 展示 `order_source`;`_task_to_dict()` 序列化 `order_source` |
| `backend/app/crud/production_task.py` | `create_production_task()` 接受 `order_source` 参数;`list_production_tasks()` 展示 `order_source`;序列化 `order_source` |
| `backend/app/api/qc.py` | 新增临时质检工单路由组 |
| `backend/app/api/production.py` | 新增临时生产工单路由组 |
| `backend/app/api/__init__.py` | 如有新路由文件则注册 |
| `web-admin/src/api/qc-task.ts` | 类型定义新增 `orderSource` 字段 |
| `web-admin/src/api/production-task.ts` | 类型定义新增 `orderSource` 字段 |
| `web-admin/src/views/quality-inspection/qc-task/index.vue` | 列表新增"来源"Tag 列 |
| `web-admin/src/views/production/production-task/index.vue` | 列表新增"来源"Tag 列 |
| `docs/sql/zkxw.sql` | 同步新增表和 ALTER 语句 |
---
## 6. 风险与注意事项
1. **order_source 默认值**:所有现有数据默认为 `inbound`,无需数据迁移
2. **现有查询兼容**:所有现有查询 `work_order_id` 关联时,默认只查 `order_source='inbound'` 或不加过滤(因为现有数据的 work_order_id 不会和临时工单冲突——指向不同表的主键)
3. **工单号唯一性**:LSZJ/LSSC 前缀确保不与 ZJ/SC 冲突
4. **权限**:临时工单菜单需要在系统中配置,遵循现有 RBAC 权限体系
5. **软删除级联**:删除临时工单时,仅删除 `order_source='temporary'` 的任务,不影响入库任务
6. **工艺路线克隆**:临时生产工单复用 `_clone_route_to_task()` 机制,与入库生产工单完全一致(步骤+试剂+耗材+产出物+数据采集项全部深拷贝)