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

912 lines
33 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.
# 临时工单模块实施计划
> **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:** 新增临时质检工单和临时生产工单两个模块,复用现有任务生成机制,在任务表中记录工单来源。
**Architecture:** 新建 2 张独立临时工单表(极简字段),现有任务表新增 `order_source` 字段区分入库/临时来源。后端 CRUD 独立,复用现有任务创建函数。前端新增 2 个标准列表页,现有任务列表新增"来源"Tag 列。
**Tech Stack:** Python 3.9 / FastAPI / SQLAlchemy / Pydantic v2 / MySQL 5.7 / Vue 3 / TypeScript / Element Plus / Tailwind CSS 4
**Design Spec:** `docs/superpowers/specs/2026-05-24-temporary-work-order-design.md`
---
## File Map
### 新建文件
| 文件 | 职责 |
|------|------|
| `backend/app/crud/temp_qc_work_order.py` | 临时质检工单 CRUD(创建、列表、详情、配置检测项目→生成任务、删除) |
| `backend/app/crud/temp_production_work_order.py` | 临时生产工单 CRUD(创建、列表、详情、配置→生成任务、删除) |
| `backend/app/schemas/temp_qc_work_order.py` | 临时质检工单 Pydantic Schema |
| `backend/app/schemas/temp_production_work_order.py` | 临时生产工单 Pydantic Schema |
| `web-admin/src/api/temp-qc-work-order.ts` | 临时质检工单前端 API 类型+函数 |
| `web-admin/src/api/temp-production-work-order.ts` | 临时生产工单前端 API 类型+函数 |
| `web-admin/src/views/quality-inspection/temp-qc-work-order/index.vue` | 临时质检工单列表页 |
| `web-admin/src/views/production/temp-production-work-order/index.vue` | 临时生产工单列表页 |
| `docs/sql/temp_work_order_tables.sql` | 新建表 + ALTER 语句 |
### 修改文件
| 文件 | 修改内容 |
|------|---------|
| `backend/app/models/models.py` | 新增 2 个模型类;4 个现有模型新增 `order_source` 列 |
| `backend/app/crud/qc_task.py` | `create_task_for_line()` 新增 `order_source` 参数;`_task_to_dict()` 序列化 `order_source`;`list_tasks()` 支持按 `order_source` 过滤 |
| `backend/app/crud/production_task.py` | `create_production_task()` 新增 `order_source` 参数;序列化 `order_source`;列表支持按来源过滤 |
| `backend/app/api/qc.py` | 新增临时质检工单路由组(5 个端点) |
| `backend/app/api/production.py` | 新增临时生产工单路由组(5 个端点) |
| `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 列 |
---
### Task 1: 数据库 DDL — 新建表 + ALTER 语句
**Files:**
- Create: `docs/sql/temp_work_order_tables.sql`
- [ ] **Step 1: 创建 SQL 文件**
```sql
-- ============================================================
-- 临时工单模块 DDL
-- Date: 2026-05-24
-- ============================================================
-- 1. 新建临时质检工单表
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. 新建临时生产工单表
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='临时生产工单';
-- 3. 质检任务表新增来源字段
ALTER TABLE biz_qc_task
ADD COLUMN order_source VARCHAR(20) NOT NULL DEFAULT 'inbound'
COMMENT '工单来源: inbound=入库, temporary=临时' AFTER work_order_id;
-- 4. 生产任务表新增来源字段
ALTER TABLE biz_production_task
ADD COLUMN order_source VARCHAR(20) NOT NULL DEFAULT 'inbound'
COMMENT '工单来源: inbound=入库, temporary=临时' AFTER work_order_id;
-- 5. 实验室项目明细表新增来源字段
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;
-- 6. 第三方项目明细表新增来源字段
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;
```
- [ ] **Step 2: 在数据库执行 DDL**
Run: `mysql -u root -p zkxw < docs/sql/temp_work_order_tables.sql`
Expected: 所有表和字段创建成功,无错误
- [ ] **Step 3: Commit**
```bash
git add docs/sql/temp_work_order_tables.sql
git commit -m "feat(db): add temp work order tables and order_source columns"
```
---
### Task 2: 后端 Model — 新增模型类 + 修改现有模型
**Files:**
- Modify: `backend/app/models/models.py`
- [ ] **Step 1: 在 BizQcTask 模型中新增 `order_source` 列**
在 `BizQcTask` 类中,`work_order_id` 行之后添加:
```python
class BizQcTask(Base):
"""质检任务 biz_qc_task"""
__tablename__ = "biz_qc_task"
id = Column(String(64), primary_key=True, comment="主键ID")
work_order_id = Column(String(64), nullable=False, comment="工单ID")
order_source = Column(String(20), nullable=False, default="inbound", comment="工单来源: inbound=入库, temporary=临时")
task_no = Column(String(32), nullable=False, comment="任务号")
# ... 其余字段保持不变
```
- [ ] **Step 2: 在 BizProductionTask 模型中新增 `order_source` 列**
在 `BizProductionTask` 类中,`work_order_id` 行之后添加:
```python
class BizProductionTask(Base):
"""生产任务 biz_production_task"""
__tablename__ = "biz_production_task"
id = Column(String(64), primary_key=True, comment="主键ID")
task_no = Column(String(32), nullable=False, comment="任务号")
work_order_id = Column(String(64), nullable=False, comment="工单ID")
order_source = Column(String(20), nullable=False, default="inbound", comment="工单来源: inbound=入库, temporary=临时")
task_type = Column(String(20), nullable=False, default="cell_storage", comment="任务类型")
# ... 其余字段保持不变
```
- [ ] **Step 3: 在 BizQcWorkOrderLabItem 模型中新增 `order_source` 列**
在 `BizQcWorkOrderLabItem` 类中,`work_order_id` 行之后添加:
```python
class BizQcWorkOrderLabItem(Base):
"""质检工单-实验室项目明细 biz_qc_work_order_lab_item"""
__tablename__ = "biz_qc_work_order_lab_item"
id = Column(String(64), primary_key=True, comment="主键ID")
work_order_id = Column(String(64), nullable=False, comment="工单ID")
order_source = Column(String(20), nullable=False, default="inbound", comment="工单来源: inbound=入库, temporary=临时")
lab_test_item_id = Column(String(64), nullable=False, comment="实验室项目ID")
# ... 其余字段保持不变
```
- [ ] **Step 4: 在 BizQcWorkOrderThirdItem 模型中新增 `order_source` 列**
在 `BizQcWorkOrderThirdItem` 类中,`work_order_id` 行之后添加:
```python
class BizQcWorkOrderThirdItem(Base):
"""质检工单-第三方项目明细 biz_qc_work_order_third_item"""
__tablename__ = "biz_qc_work_order_third_item"
id = Column(String(64), primary_key=True, comment="主键ID")
work_order_id = Column(String(64), nullable=False, comment="工单ID")
order_source = Column(String(20), nullable=False, default="inbound", comment="工单来源: inbound=入库, temporary=临时")
third_party_item_id = Column(String(64), nullable=False, comment="第三方项目ID")
# ... 其余字段保持不变
```
- [ ] **Step 5: 新增 BizTempQcWorkOrder 模型类**
在 `BizQcWorkOrder` 类定义之后(约行 1253)添加:
```python
class BizTempQcWorkOrder(Base):
"""临时质检工单 biz_temp_qc_work_order"""
__tablename__ = "biz_temp_qc_work_order"
id = Column(String(64), primary_key=True, comment="主键ID")
work_order_no = Column(String(64), nullable=False, comment="工单号(LSZJ+日期+序号)")
work_order_status = Column(String(20), nullable=False, default="dpz", comment="状态: dpz=待配置, ypz=已配置, ywc=已完成")
configured_time = Column(DateTime, nullable=True, comment="配置时间")
configured_by = Column(String(64), nullable=True, comment="配置人")
has_lab = Column(SmallInteger, nullable=False, default=0, comment="是否含实验室自检")
has_third_party = Column(SmallInteger, nullable=False, default=0, comment="是否含第三方检测")
third_party_fee_total = Column(Numeric(18, 2), nullable=True, comment="第三方费用合计")
tenant_no = Column(String(64), nullable=False, default="zkxw", comment="租户编号")
order_num = Column(Integer, nullable=True, comment="排序号")
remark = Column(String(512), nullable=True, comment="备注")
create_by = Column(String(64), nullable=True, comment="创建人id")
create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
update_by = Column(String(64), nullable=True, comment="更新人id")
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记")
```
- [ ] **Step 6: 新增 BizTempProductionWorkOrder 模型类**
在 `BizProductionWorkOrder` 类定义之后(约行 2292)添加:
```python
class BizTempProductionWorkOrder(Base):
"""临时生产工单 biz_temp_production_work_order"""
__tablename__ = "biz_temp_production_work_order"
id = Column(String(64), primary_key=True, comment="主键ID")
work_order_no = Column(String(64), nullable=False, comment="工单号(LSSC+日期+序号)")
work_order_status = Column(String(20), nullable=False, default="dpz", comment="状态: dpz=待配置, jxz=进行中, ywc=已完成")
configured_time = Column(DateTime, nullable=True, comment="配置时间")
configured_by = Column(String(64), nullable=True, comment="配置人")
tenant_no = Column(String(64), nullable=False, default="zkxw", comment="租户编号")
order_num = Column(Integer, nullable=True, comment="排序号")
remark = Column(String(512), nullable=True, comment="备注")
create_by = Column(String(64), nullable=True, comment="创建人id")
create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
update_by = Column(String(64), nullable=True, comment="更新人id")
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记")
```
- [ ] **Step 7: Commit**
```bash
git add backend/app/models/models.py
git commit -m "feat(models): add temp work order models and order_source columns to task models"
```
---
### Task 3: 后端 — 修改现有 qc_task CRUD 支持 order_source
**Files:**
- Modify: `backend/app/crud/qc_task.py`
- [ ] **Step 1: `create_task_for_line()` 新增 `order_source` 参数**
将函数签名改为:
```python
def create_task_for_line(
db: Session,
*,
work_order, # BizQcWorkOrder 或 BizTempQcWorkOrder
task_type: str,
source_line_id: str,
item_code: str,
item_name: str,
tenant_no: str,
user_id: Optional[str] = None,
create_dept_id: str = "",
seq: int = 1,
company_id: Optional[str] = None,
company_name: Optional[str] = None,
fee_amount: Optional[Decimal] = None,
order_source: str = "inbound", # 新增参数
) -> BizQcTask:
obj = BizQcTask(
id=generate_uuid(),
work_order_id=work_order.id,
order_source=order_source, # 新增
task_no=_gen_task_no(db, work_order, seq),
task_type=task_type,
source_line_id=source_line_id,
sample_code=getattr(work_order, "sample_code", None) or None,
item_code=item_code,
item_name=item_name,
company_id=company_id,
company_name=company_name,
fee_amount=fee_amount,
task_status="dzx",
tenant_no=tenant_no,
order_num=seq,
create_by=user_id,
create_dept_id=create_dept_id or "",
create_time=datetime.now(),
update_by=user_id,
update_time=datetime.now(),
del_flag=0,
)
db.add(obj)
db.flush()
return obj
```
- [ ] **Step 2: `_task_to_dict()` 序列化 `order_source`**
在 `_task_to_dict` 返回的字典中添加 `"orderSource"` 字段:
```python
def _task_to_dict(
t: BizQcTask,
work_order_no: str = "",
db: Optional[Session] = None,
tenant_no: Optional[str] = None,
) -> Dict[str, Any]:
tn = tenant_no or t.tenant_no
return {
"id": t.id,
"workOrderId": t.work_order_id,
"orderSource": getattr(t, "order_source", "inbound") or "inbound", # 新增
"workOrderNo": work_order_no,
# ... 其余字段保持不变
}
```
- [ ] **Step 3: Commit**
```bash
git add backend/app/crud/qc_task.py
git commit -m "feat(qc-task): support order_source parameter for task creation"
```
---
### Task 4: 后端 — 修改现有 production_task CRUD 支持 order_source
**Files:**
- Modify: `backend/app/crud/production_task.py`
- [ ] **Step 1: `create_production_task()` 新增 `order_source` 参数**
在函数签名中添加 `order_source: str = "inbound"` 参数,在创建 BizProductionTask 时设置:
```python
# 在创建 task 对象时添加 order_source
task = BizProductionTask(
id=generate_uuid(),
task_no=task_no,
work_order_id=data.get("work_order_id", ""),
order_source=order_source, # 新增
task_type=data.get("task_type") or "cell_storage",
# ... 其余保持不变
)
```
- [ ] **Step 2: 任务序列化函数添加 `orderSource` 字段**
在 `_task_to_dict()` 或相应的序列化函数中添加 `"orderSource"` 字段。
- [ ] **Step 3: Commit**
```bash
git add backend/app/crud/production_task.py
git commit -m "feat(production-task): support order_source parameter for task creation"
```
---
### Task 5: 后端 — 临时质检工单 Schema + CRUD + API
**Files:**
- Create: `backend/app/schemas/temp_qc_work_order.py`
- Create: `backend/app/crud/temp_qc_work_order.py`
- Modify: `backend/app/api/qc.py`
- [ ] **Step 1: 创建 Schema**
Create `backend/app/schemas/temp_qc_work_order.py`:
```python
"""临时质检工单 Schema"""
from __future__ import annotations
from typing import List, Optional
from pydantic import BaseModel, ConfigDict, Field
class TempQcWorkOrderCreateBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
remark: Optional[str] = Field("", alias="remark")
class TempQcWorkOrderConfigureBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
has_lab: bool = Field(False, alias="hasLab")
has_third_party: bool = Field(False, alias="hasThirdParty")
lab_item_ids: List[str] = Field(default_factory=list, alias="labItemIds")
third_party_item_ids: List[str] = Field(default_factory=list, alias="thirdPartyItemIds")
```
- [ ] **Step 2: 创建 CRUD**
Create `backend/app/crud/temp_qc_work_order.py`。核心函数:
1. `_gen_daily_no(db, tenant_no)` — 生成 `LSZJ{YYYYMMDD}{序号:04d}`
2. `_wo_to_dict(wo)` — 序列化(极简字段)
3. `create_temp_qc_work_order(db, *, tenant_no, user_id, create_dept_id, remark)` — 创建
4. `list_temp_qc_work_orders(db, *, page, page_size, keyword, work_order_status, tenant_no, user_info)` — 列表
5. `get_temp_qc_work_order(db, id, tenant_no)` — 获取单条
6. `get_temp_qc_work_order_detail(db, id, tenant_no)` — 详情(含 labItems, thirdPartyItems, tasks)
7. `configure_temp_qc_work_order(db, id, *, has_lab, has_third_party, lab_item_ids, third_party_item_ids, tenant_no, user_id, create_dept_id)` — 配置检测项目→自动生成任务(复用 `qc_task.create_task_for_line(order_source='temporary')`)
8. `try_complete_temp_qc_work_order(db, work_order_id, tenant_no)` — 所有临时任务完成时标记工单完成
9. `delete_temp_qc_work_order(db, id, tenant_no, user_id)` — 软删除
配置逻辑参照现有 `qc_work_order.configure_work_order()`,区别:
- 创建 BizQcWorkOrderLabItem/BizQcWorkOrderThirdItem 时设 `order_source='temporary'`
- 调用 `task_svc.create_task_for_line(order_source='temporary')`
- `try_complete` 查询时过滤 `order_source='temporary'`
- [ ] **Step 3: 在 api/qc.py 中新增路由组**
在文件末尾添加 5 个路由端点:
```python
# ---------- 临时质检工单 ----------
@router.post("/temp-qc-work-orders")
async def create_temp_qc_work_order(
body: TempQcWorkOrderCreateBody,
db: Session = Depends(get_db),
user: dict = Depends(require_menu_code("biz:tempQcWorkOrder:list")),
):
...
@router.get("/temp-qc-work-orders")
async def list_temp_qc_work_orders(...):
...
@router.get("/temp-qc-work-orders/{work_order_id}")
async def get_temp_qc_work_order_detail(...):
...
@router.delete("/temp-qc-work-orders/{work_order_id}")
async def delete_temp_qc_work_order(...):
...
@router.post("/temp-qc-work-orders/{work_order_id}/configure")
async def configure_temp_qc_work_order(
work_order_id: str,
body: TempQcWorkOrderConfigureBody,
db: Session = Depends(get_db),
user: dict = Depends(require_menu_code("biz:tempQcWorkOrder:list")),
):
...
```
- [ ] **Step 4: 启动后端验证 API 可达**
Run: `cd backend && source venv/bin/activate && python -c "from app.main import app; print('OK')"`
Expected: OK,无 import 错误
- [ ] **Step 5: Commit**
```bash
git add backend/app/schemas/temp_qc_work_order.py backend/app/crud/temp_qc_work_order.py backend/app/api/qc.py
git commit -m "feat(temp-qc): add temp QC work order backend (schema, CRUD, API)"
```
---
### Task 6: 后端 — 临时生产工单 Schema + CRUD + API
**Files:**
- Create: `backend/app/schemas/temp_production_work_order.py`
- Create: `backend/app/crud/temp_production_work_order.py`
- Modify: `backend/app/api/production.py`
- [ ] **Step 1: 创建 Schema**
Create `backend/app/schemas/temp_production_work_order.py`:
```python
"""临时生产工单 Schema"""
from __future__ import annotations
from typing import Optional
from pydantic import BaseModel, ConfigDict, Field
class TempProductionWorkOrderCreateBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
remark: Optional[str] = Field("", alias="remark")
class TempProductionWorkOrderConfigureBody(BaseModel):
"""配置→创建生产任务(与入库生产工单一致:选择工艺路线+克隆步骤)"""
model_config = ConfigDict(populate_by_name=True)
task_name: Optional[str] = Field("", alias="taskName")
task_type: Optional[str] = Field("cell_storage", alias="taskType")
route_id: Optional[str] = Field(None, alias="routeId")
description: Optional[str] = Field("", alias="description")
remark: Optional[str] = Field("", alias="remark")
```
- [ ] **Step 2: 创建 CRUD**
Create `backend/app/crud/temp_production_work_order.py`。核心函数:
1. `_gen_daily_no(db, tenant_no)` — 生成 `LSSC{YYYYMMDD}{序号:04d}`
2. `_wo_to_dict(wo)` — 序列化
3. `create_temp_production_work_order(db, *, tenant_no, user_id, create_dept_id, remark)` — 创建
4. `list_temp_production_work_orders(db, *, page, page_size, keyword, work_order_status, tenant_no, user_info)` — 列表
5. `get_temp_production_work_order(db, id, tenant_no)` — 获取单条
6. `get_temp_production_work_order_detail(db, id, tenant_no)` — 详情(含 tasks,每个 task 含 steps+子表)
7. `configure_temp_production_work_order(db, id, *, task_name, task_type, route_id, description, remark, tenant_no, user_id, create_dept_id)` — 配置→创建生产任务,**复用 `production_task.create_production_task(order_source='temporary')`,自动触发 `_clone_route_to_task()` 克隆工艺路线步骤+4类子表**
8. `delete_temp_production_work_order(db, id, tenant_no, user_id)` — 软删除
关键:`configure_temp_production_work_order` 直接调用 `production_task.create_production_task()`,传入 `order_source='temporary'` 和 `route_id`,由 `create_production_task` 内部自动执行 `_clone_route_to_task()` 克隆路线步骤。
同时需要调用 `sync_production_work_order_status_from_tasks` 的临时版本来同步工单状态。
- [ ] **Step 3: 在 api/production.py 中新增路由组**
添加 5 个路由端点(POST/GET/GET/{id}/DELETE/{id}/POST/{id}/configure),路由路径前缀 `/temp-production-work-orders`。
- [ ] **Step 4: 启动后端验证 API 可达**
Run: `cd backend && source venv/bin/activate && python -c "from app.main import app; print('OK')"`
Expected: OK
- [ ] **Step 5: Commit**
```bash
git add backend/app/schemas/temp_production_work_order.py backend/app/crud/temp_production_work_order.py backend/app/api/production.py
git commit -m "feat(temp-production): add temp production work order with route cloning support"
```
---
### Task 7: 前端 — 临时质检工单页面
**Files:**
- Create: `web-admin/src/api/temp-qc-work-order.ts`
- Create: `web-admin/src/views/quality-inspection/temp-qc-work-order/index.vue`
- [ ] **Step 1: 创建 API 文件**
Create `web-admin/src/api/temp-qc-work-order.ts`,参照 `api/qc-work-order.ts` 简化版:
```typescript
import request from '@/utils/http'
type PageList<T> = {
list: T[]
total: number
page: number
pageSize: number
totalPages: number
}
export type TempQcWorkOrder = {
id: string
workOrderNo: string
workOrderStatus: string
hasLab: boolean
hasThirdParty: boolean
configuredTime?: string
configuredBy?: string
thirdPartyFeeTotal?: number
remark?: string
createTime?: string
updateTime?: string
}
export type TempQcWorkOrderDetail = TempQcWorkOrder & {
labItems?: Array<{ id: string; labTestItemId: string; itemCode: string; itemName: string }>
thirdPartyItems?: Array<{
id: string
thirdPartyItemId: string
companyId: string
companyName: string
itemCode: string
itemName: string
feeAmount: number
}>
tasks?: Array<{
id: string
taskNo: string
taskType: string
itemCode?: string
itemName?: string
taskStatus: string
conclusion?: string
conclusionLabel?: string
}>
}
export function fetchTempQcWorkOrderList(params?: {
page?: number
pageSize?: number
keyword?: string
workOrderStatus?: string
}) {
return request.get<PageList<TempQcWorkOrder>>({
url: '/web/admin/temp-qc-work-orders',
params
})
}
export function fetchTempQcWorkOrderDetail(id: string) {
return request.get<TempQcWorkOrderDetail>({
url: `/web/admin/temp-qc-work-orders/${id}`
})
}
export function fetchCreateTempQcWorkOrder(data: { remark?: string }) {
return request.post<TempQcWorkOrder>({
url: '/web/admin/temp-qc-work-orders',
data
})
}
export function fetchConfigureTempQcWorkOrder(
id: string,
data: {
hasLab: boolean
hasThirdParty: boolean
labItemIds: string[]
thirdPartyItemIds: string[]
}
) {
return request.post<TempQcWorkOrder>({
url: `/web/admin/temp-qc-work-orders/${id}/configure`,
data
})
}
export function fetchDeleteTempQcWorkOrder(id: string) {
return request.del({ url: `/web/admin/temp-qc-work-orders/${id}` })
}
```
- [ ] **Step 2: 创建列表页面**
Create `web-admin/src/views/quality-inspection/temp-qc-work-order/index.vue`
参照模板页 `src/views/system/unit/index.vue`(标准列表页模式),包含:
- **列表列**:工单号、状态(Tag: dpz→info/ypz→warning/ywc→success)、是否含实验室自检、是否含第三方、配置时间、创建时间、操作
- **创建弹窗**:仅备注字段(el-input type="textarea")
- **配置弹窗**:复用现有配置检测项目组件逻辑(选择实验室自检/第三方检测项目)
- **详情弹窗**:工单基本信息 + 关联任务列表
- **Toolbar**:搜索(keyword)、状态筛选、新增按钮
- **注意**:遵循 AGENTS.md UI 规范(Tag 用 el-tag、dialog label-position="top"、2列 form-grid 等)
- [ ] **Step 3: 验证前端编译**
Run: `cd web-admin && pnpm build`
Expected: 构建成功,无 TypeScript 错误
- [ ] **Step 4: Commit**
```bash
git add web-admin/src/api/temp-qc-work-order.ts web-admin/src/views/quality-inspection/temp-qc-work-order/index.vue
git commit -m "feat(temp-qc): add temp QC work order frontend page"
```
---
### Task 8: 前端 — 临时生产工单页面
**Files:**
- Create: `web-admin/src/api/temp-production-work-order.ts`
- Create: `web-admin/src/views/production/temp-production-work-order/index.vue`
- [ ] **Step 1: 创建 API 文件**
Create `web-admin/src/api/temp-production-work-order.ts`,参照 `api/production-work-order.ts` 简化版:
```typescript
import request from '@/utils/http'
type PageList<T> = {
list: T[]
total: number
page: number
pageSize: number
totalPages: number
}
export type TempProductionWorkOrder = {
id: string
workOrderNo: string
workOrderStatus: string
configuredTime?: string
configuredBy?: string
remark?: string
createTime?: string
updateTime?: string
}
export type TempProductionWorkOrderDetail = TempProductionWorkOrder & {
tasks?: Array<{
id: string
taskNo: string
taskType: string
taskName?: string
taskStatus: string
}>
}
export function fetchTempProductionWorkOrderList(params?: {
page?: number
pageSize?: number
keyword?: string
workOrderStatus?: string
}) {
return request.get<PageList<TempProductionWorkOrder>>({
url: '/web/admin/temp-production-work-orders',
params
})
}
export function fetchTempProductionWorkOrderDetail(id: string) {
return request.get<TempProductionWorkOrderDetail>({
url: `/web/admin/temp-production-work-orders/${id}`
})
}
export function fetchCreateTempProductionWorkOrder(data: { remark?: string }) {
return request.post<TempProductionWorkOrder>({
url: '/web/admin/temp-production-work-orders',
data
})
}
export function fetchConfigureTempProductionWorkOrder(
id: string,
data: {
taskName?: string
taskType?: string
routeId?: string
description?: string
remark?: string
}
) {
return request.post<TempProductionWorkOrder>({
url: `/web/admin/temp-production-work-orders/${id}/configure`,
data
})
}
export function fetchDeleteTempProductionWorkOrder(id: string) {
return request.del({ url: `/web/admin/temp-production-work-orders/${id}` })
}
```
- [ ] **Step 2: 创建列表页面**
Create `web-admin/src/views/production/temp-production-work-order/index.vue`
参照模板页 `src/views/system/unit/index.vue`(标准列表页),包含:
- **列表列**:工单号、状态(Tag: dpz→info/jxz→primary/ywc→success)、配置时间、创建时间、操作
- **创建弹窗**:仅备注字段
- **配置弹窗**:与入库生产工单的 DispatchTaskDialog 类似,包含任务名称(task_name)、任务类型(task_type cell_storage/outbound)、**工艺路线选择(route_id,选择后自动克隆步骤)**、描述(description)、备注(remark)。参照 `views/production/production-work-order/DispatchTaskDialog.vue` 的表单结构。
- **详情弹窗**:工单基本信息 + 关联任务列表
- **遵循 UI 规范**
- [ ] **Step 3: 验证前端编译**
Run: `cd web-admin && pnpm build`
Expected: 构建成功
- [ ] **Step 4: Commit**
```bash
git add web-admin/src/api/temp-production-work-order.ts web-admin/src/views/production/temp-production-work-order/index.vue
git commit -m "feat(temp-production): add temp production work order frontend page"
```
---
### Task 9: 前端 — 现有任务列表新增"来源"Tag 列
**Files:**
- Modify: `web-admin/src/api/qc-task.ts`
- Modify: `web-admin/src/views/quality-inspection/qc-task/index.vue`
- Modify: `web-admin/src/api/production-task.ts`
- Modify: `web-admin/src/views/production/production-task/index.vue`
- [ ] **Step 1: qc-task.ts 类型新增 orderSource**
在 `QcTask` 类型定义中添加:
```typescript
export type QcTask = {
// ... 现有字段
orderSource?: string // 'inbound' | 'temporary'
// ...
}
```
- [ ] **Step 2: 质检任务列表新增"来源"列**
在 `quality-inspection/qc-task/index.vue` 的 el-table 中添加列:
```vue
<el-table-column label="来源" prop="orderSource" min-width="100">
<template #default="{ row }">
<el-tag
:type="row.orderSource === 'temporary' ? 'warning' : 'success'"
size="small"
>
{{ row.orderSource === 'temporary' ? '临时' : '入库' }}
</el-tag>
</template>
</el-table-column>
```
位置放在"工单号"列之后。
- [ ] **Step 3: production-task.ts 类型新增 orderSource**
同 Step 1,在 ProductionTask 类型中添加 `orderSource`。
- [ ] **Step 4: 生产任务列表新增"来源"列**
同 Step 2,在 `production/production-task/index.vue` 的 el-table 中添加来源 Tag 列。
- [ ] **Step 5: 验证前端编译**
Run: `cd web-admin && pnpm build`
Expected: 构建成功
- [ ] **Step 6: Commit**
```bash
git add web-admin/src/api/qc-task.ts web-admin/src/views/quality-inspection/qc-task/index.vue web-admin/src/api/production-task.ts web-admin/src/views/production/production-task/index.vue
git commit -m "feat(tasks): add orderSource column with tag display to task lists"
```
---
### Task 10: 菜单配置 + 最终验证
**Files:**
- Modify: 数据库 `sys_menu` 表(通过 SQL INSERT)
- [ ] **Step 1: 插入菜单记录**
在数据库中执行 SQL,为临时质检工单和临时生产工单各插入菜单记录。具体 menu_id 和 parent_id 需要根据现有菜单树确定。INSERT 语句参考现有菜单数据格式。
- [ ] **Step 2: 全栈验证**
1. 启动后端:`cd backend && source venv/bin/activate && ./start-local.sh`
2. 启动前端:`cd web-admin && pnpm dev`
3. 登录系统,导航到临时质检工单页面
4. 测试:创建工单 → 配置检测项目 → 查看生成任务 → 完成任务 → 工单自动完成
5. 导航到临时生产工单页面
6. 测试:创建工单 → 配置生成任务 → 查看任务
7. 导航到质检任务/生产任务页面,确认"来源"Tag 列正确显示
- [ ] **Step 3: Commit**
```bash
git add docs/sql/temp_work_order_tables.sql
git commit -m "feat(menu): add temp work order menu items"
```
---
## Self-Review Checklist
- [x] **Spec coverage**: 每个设计文档章节都有对应 Task(数据库→Task1/2,后端→Task3/4/5/6,前端→Task7/8/9,菜单→Task10)
- [x] **Placeholder scan**: 无 TBD/TODO,所有步骤有具体代码或指令
- [x] **Type consistency**: order_source 字段名在 model/schema/crud/api/typescript 中一致使用