# 临时工单模块设计文档
> 日期: 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 `入库`
- `temporary` → 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()` 机制,与入库生产工单完全一致(步骤+试剂+耗材+产出物+数据采集项全部深拷贝)