# 工单表合并重构实施计划 > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** 将入库+临时工单表合并为单表(`work_order_type` 字段区分类型),彻底消除多表 JOIN 复杂度。 **Architecture:** 质检工单合并为 `biz_qc_work_order`(加 `work_order_type`),生产工单合并为 `biz_production_work_order`(加 `work_order_type`)。任务表保持不变(`biz_qc_task` / `biz_production_task` 的 `order_source` 保留)。前端每个工单类型一个页面,根据 `work_order_type` 条件展示不同字段。 **Tech Stack:** MySQL 5.7 DDL / Python 3.9 FastAPI SQLAlchemy / Vue 3 TypeScript Element Plus --- ## 影响文件清单 ### 删除(合并后不再需要) - `backend/app/models/models.py` 中 `BizTempQcWorkOrder`、`BizTempProductionWorkOrder` 两个 class - `backend/app/schemas/temp_qc_work_order.py` - `backend/app/schemas/temp_production_work_order.py` - `backend/app/crud/temp_qc_work_order.py` - `backend/app/crud/temp_production_work_order.py` - `web-admin/src/api/temp-qc-work-order.ts` - `web-admin/src/api/temp-production-work-order.ts` - `web-admin/src/views/quality-inspection/temp-qc-work-order/index.vue` - `web-admin/src/views/production/temp-production-work-order/index.vue` - `web-admin/src/router/modules/sqxp.ts` 中临时工单路由条目 ### 修改 - `docs/sql/` — 新建迁移 SQL - `backend/app/models/models.py` — 加 `work_order_type`,reception 字段改 nullable,删 temp model - `backend/app/crud/qc_work_order.py` — 合并临时工单的创建/配置/完成逻辑 - `backend/app/crud/production_work_order.py` — 合并临时工单的创建/配置/完成逻辑 - `backend/app/crud/qc_task.py` — **恢复** INNER JOIN(不再需要 LEFT JOIN + 子查询 hack) - `backend/app/crud/production_task.py` — 同上,简化批量查询 - `backend/app/api/qc.py` — 合并临时工单 API 端点,删除 temp import - `backend/app/api/production.py` — 同上 - `backend/app/schemas/qc_work_order.py` — 新增 `work_order_type` 字段 - `web-admin/src/api/qc-work-order.ts` 或 `business.ts` — 新增临时工单 API - `web-admin/src/views/quality-inspection/qc-work-order/index.vue` — 支持临时工单创建/筛选 - `web-admin/src/views/production/production-work-order/index.vue` — 同上 --- ## Task 1: DDL 迁移 SQL **Files:** - Create: `docs/sql/merge_work_order_tables.sql` - [ ] **Step 1: 编写迁移 SQL** ```sql -- ============================================================ -- 工单表合并迁移:入库+临时 → 单表 + work_order_type -- Date: 2026-05-24 -- 执行顺序:必须先执行,再部署后端代码 -- ============================================================ -- 1. biz_qc_work_order: 加 work_order_type,现有数据全部设 inbound ALTER TABLE biz_qc_work_order ADD COLUMN work_order_type VARCHAR(20) NOT NULL DEFAULT 'inbound' COMMENT '工单类型: inbound=入库, temporary=临时' AFTER work_order_no; -- 2. biz_qc_work_order: reception 关联字段改为可空(临时工单不需要) ALTER TABLE biz_qc_work_order MODIFY COLUMN reception_id VARCHAR(64) NULL COMMENT '样本接收ID', MODIFY COLUMN protocol_sample_id VARCHAR(64) NULL COMMENT '协议样本ID', MODIFY COLUMN collection_protocol_id VARCHAR(64) NULL COMMENT '采集协议ID', MODIFY COLUMN reception_source VARCHAR(20) NULL DEFAULT 'cell_storage' COMMENT '来源: cell_storage/research_donation'; -- 3. 迁移临时质检工单数据到主表 INSERT INTO biz_qc_work_order ( id, work_order_no, work_order_type, work_order_status, has_lab, has_third_party, third_party_fee_total, configured_time, configured_by, tenant_no, order_num, remark, create_by, create_dept_id, create_time, update_by, update_time, del_flag ) SELECT id, work_order_no, 'temporary', work_order_status, has_lab, has_third_party, third_party_fee_total, configured_time, configured_by, tenant_no, order_num, remark, create_by, create_dept_id, create_time, update_by, update_time, del_flag FROM biz_temp_qc_work_order; -- 4. biz_production_work_order: 加 work_order_type ALTER TABLE biz_production_work_order ADD COLUMN work_order_type VARCHAR(20) NOT NULL DEFAULT 'inbound' COMMENT '工单类型: inbound=入库, temporary=临时' AFTER work_order_no; -- 5. biz_production_work_order: 加 configured_time/configured_by(临时工单需要) ALTER TABLE biz_production_work_order ADD COLUMN configured_time DATETIME NULL COMMENT '配置时间' AFTER work_order_status, ADD COLUMN configured_by VARCHAR(64) NULL COMMENT '配置人' AFTER configured_time; -- 6. biz_production_work_order: reception 关联字段改为可空 ALTER TABLE biz_production_work_order MODIFY COLUMN reception_id VARCHAR(64) NULL COMMENT '样本接收ID', MODIFY COLUMN protocol_sample_id VARCHAR(64) NULL COMMENT '协议样本ID', MODIFY COLUMN collection_protocol_id VARCHAR(64) NULL COMMENT '采集协议ID', MODIFY COLUMN reception_source VARCHAR(20) NULL DEFAULT 'cell_storage' COMMENT '来源'; -- 7. 迁移临时生产工单数据到主表 INSERT INTO biz_production_work_order ( id, work_order_no, work_order_type, work_order_status, configured_time, configured_by, tenant_no, order_num, remark, create_by, create_dept_id, create_time, update_by, update_time, del_flag ) SELECT id, work_order_no, 'temporary', work_order_status, configured_time, configured_by, tenant_no, order_num, remark, create_by, create_dept_id, create_time, update_by, update_time, del_flag FROM biz_temp_production_work_order; -- 8. 删除临时表(确认数据迁移成功后执行) DROP TABLE IF EXISTS biz_temp_qc_work_order; DROP TABLE IF EXISTS biz_temp_production_work_order; ``` - [ ] **Step 2: 手动执行前备份** ```bash mysqldump -u root -p zkxw biz_qc_work_order biz_temp_qc_work_order biz_production_work_order biz_temp_production_work_order > /tmp/work_order_backup_$(date +%Y%m%d).sql ``` --- ## Task 2: 后端 Model 更新 **Files:** - Modify: `backend/app/models/models.py` - [ ] **Step 1: 更新 BizQcWorkOrder 模型** - 在 `work_order_no` 后加 `work_order_type = Column(String(20), nullable=False, default="inbound")` - 将 `reception_id`、`protocol_sample_id`、`collection_protocol_id` 改为 `nullable=True` - 将 `reception_source` 改为 `nullable=True` - [ ] **Step 2: 更新 BizProductionWorkOrder 模型** - 加 `work_order_type = Column(String(20), nullable=False, default="inbound")` - 加 `configured_time = Column(DateTime, nullable=True)` - 加 `configured_by = Column(String(64), nullable=True)` - 将 `reception_id`、`protocol_sample_id`、`collection_protocol_id` 改为 `nullable=True` - 将 `reception_source` 改为 `nullable=True` - [ ] **Step 3: 删除 BizTempQcWorkOrder 和 BizTempProductionWorkOrder 类** - [ ] **Step 4: 验证 import** ```bash cd backend && source venv/bin/activate && python -c "from app.main import app; print('OK')" ``` --- ## Task 3: 后端 CRUD 合并 — 质检工单 **Files:** - Modify: `backend/app/crud/qc_work_order.py` - Delete: `backend/app/crud/temp_qc_work_order.py` - [ ] **Step 1: 在 qc_work_order.py 中新增临时工单函数** - 将 `temp_qc_work_order.py` 中的 `create_temp_qc_work_order`、`configure_temp_qc_work_order`、`list_temp_qc_work_orders`、`get_temp_qc_work_order_detail`、`try_complete_temp_qc_work_order`、`delete_temp_qc_work_order` 合并进 `qc_work_order.py` - 修改工单号生成逻辑:根据 `work_order_type` 选择前缀(inbound=ZJ,temporary=LSZJ) - 修改 list 查询:加 `work_order_type` 过滤 - 修改 configure 逻辑:使用同一个 `BizQcWorkOrder` 模型 - 修改 task 生成:保持 `order_source` 逻辑不变 - [ ] **Step 2: 删除 temp_qc_work_order.py** --- ## Task 4: 后端 CRUD 合并 — 生产工单 **Files:** - Modify: `backend/app/crud/production_work_order.py` - Delete: `backend/app/crud/temp_production_work_order.py` - [ ] **Step 1: 合并临时生产工单函数** - 同 Task 3 思路:将 temp 函数合并进主文件 - 工单号前缀:inbound=SC,temporary=LSSC - 保留工艺路线克隆逻辑 - 保留 `order_source` 逻辑 - [ ] **Step 2: 删除 temp_production_work_order.py** --- ## Task 5: 后端 API + Schema 更新 **Files:** - Modify: `backend/app/api/qc.py` - Modify: `backend/app/api/production.py` - Modify: `backend/app/schemas/qc_work_order.py` - Delete: `backend/app/schemas/temp_qc_work_order.py` - Delete: `backend/app/schemas/temp_production_work_order.py` - [ ] **Step 1: 更新 qc_work_order schema** - 在 `QcWorkOrderCreateBody` 中加 `work_order_type: str = "inbound"` - 新增 `TempQcWorkOrderCreateBody`(remark only)或复用现有 schema - 新增 `QcWorkOrderConfigureBody`(合并临时工单配置的 schema) - [ ] **Step 2: 合并 qc.py API 端点** - 将临时质检工单的 5 个端点合并到现有工单端点 - 新增 `POST /web/admin/qc-work-orders` 支持 `work_order_type` 参数 - 新增 `GET /web/admin/qc-work-orders` 支持 `work_order_type` 过滤 - 新增 `POST /web/admin/qc-work-orders/{id}/configure` 端点(从 temp 端点移过来) - 删除 temp 相关 import 和端点 - [ ] **Step 3: 合并 production.py API 端点** - 同上思路 - [ ] **Step 4: 删除 temp schema 文件** - [ ] **Step 5: 验证 import** --- ## Task 6: 恢复 qc_task.py 的简单 INNER JOIN **Files:** - Modify: `backend/app/crud/qc_task.py` - [ ] **Step 1: 恢复 list_tasks 为 INNER JOIN** - 将 `outerjoin(BizQcWorkOrder, ...)` 恢复为 `join(BizQcWorkOrder, ...)` - 删除 `BizTempQcWorkOrder` import - 删除临时工单子查询(`temp_wo_sq`) - 删除临时工单后处理(`temp_wo_ids`、`temp_wo_map`、if/elif 分支) - 恢复原来的 ORDER BY 子句(含 `BizQcWorkOrder.work_order_no.desc()`) - [ ] **Step 2: 验证** ```bash cd backend && source venv/bin/activate && python -c "from app.crud.qc_task import list_tasks; print('OK')" ``` --- ## Task 7: 简化 production_task.py **Files:** - Modify: `backend/app/crud/production_task.py` - [ ] **Step 1: 简化 list_tasks 批量查询** - 删除 `BizTempProductionWorkOrder` import - 删除临时工单子查询和批量补充逻辑 - 恢复为只查 `BizProductionWorkOrder` 的简单模式 --- ## Task 8: 前端 API + 页面合并 **Files:** - Modify: `web-admin/src/api/qc-work-order.ts` 或 `business.ts` - Modify: `web-admin/src/api/production-work-order.ts` 或 `business.ts` - Modify: `web-admin/src/views/quality-inspection/qc-work-order/index.vue` - Modify: `web-admin/src/views/production/production-work-order/index.vue` - Delete: `web-admin/src/api/temp-qc-work-order.ts` - Delete: `web-admin/src/api/temp-production-work-order.ts` - Delete: `web-admin/src/views/quality-inspection/temp-qc-work-order/index.vue` - Delete: `web-admin/src/views/production/temp-production-work-order/index.vue` - Modify: `web-admin/src/router/modules/sqxp.ts` - [ ] **Step 1: 将临时工单 API 合并到主 API 模块** - 在 qc-work-order API 中新增 configure 端点调用 - 新增 work_order_type 参数支持 - 删除 temp API 文件 - [ ] **Step 2: 更新 qc-work-order/index.vue** - 新增"工单类型"筛选(入库/临时) - 新增创建时选择类型(入库走接收流程,临时直接创建) - 新增配置检测弹窗(从 temp 页面移植) - 条件显示 reception 相关列(仅入库类型显示样本编码、协议号等) - [ ] **Step 3: 更新 production-work-order/index.vue** - 同上思路 - [ ] **Step 4: 更新路由 sqxp.ts** - 删除临时工单路由条目 - 主工单路由保持不变 - [ ] **Step 5: 删除临时工单页面和 API 文件** - [ ] **Step 6: 前端构建验证** ```bash cd web-admin && pnpm build ``` --- ## Task 9: 全局验证 - [ ] **Step 1: 后端 import 验证** ```bash cd backend && source venv/bin/activate && python -c "from app.main import app; print('OK')" ``` - [ ] **Step 2: 前端构建验证** ```bash cd web-admin && pnpm build ``` - [ ] **Step 3: 手动测试流程** - 创建入库质检工单 → 配置 → 生成任务 ✓ - 创建临时质检工单 → 配置 → 生成任务 ✓ - 质检任务列表显示两种来源 ✓ - 创建入库生产工单 → 配置 → 生成任务 ✓ - 创建临时生产工单 → 配置 → 生成任务 ✓