日期: 2026-06-25
状态: 待评审 / 待实现
范围: web-admin + backend(质检工单、我的质检任务、配置检测 / 调整检测)
前置:2026-05-17-quality-inspection-modules-design.md、2026-06-12-qc-task-assignee-my-tasks-design.md(负责人粒度将变更)
_sync_work_order_* 以 lab_test_item_id / third_party_item_id 为唯一键)。引入 检测批次 作为工单与检测项目之间的容器层:
ypz(已配置)后仍可 追加批次(调整检测);dzx / jxz / ywc;| # | 问题 | 决策 |
|---|---|---|
| 1 | 批次负责人 | 允许多人;完成语义沿用现网:任一负责人可独立开始/填写结果/完成 |
| 2 | 同主数据项目跨批次重复 | 允许(例如批次 1、批次 2 均可含「无菌检测」) |
| 3 | 同批次内同一项目重复 | 不允许 |
| 4 | 批次内 lab + 第三方混合 | 允许 |
| 5 | 配置时机 | dpz 首次可配多批次;ypz 后可追加批次(调整检测) |
| 6 | 批次独立状态 | 否 — 批次仅作容器;不增加批次级开始/完成 |
| 7 | 批次命名 | 自动编号 + 展示名规则:YYYYMMDD检测(创建日);可选附带序号区分同日多批次,见 §4.2 |
| 项 | 2026-06-12(已实现) | 本变更 |
|---|---|---|
| 指派粒度 | 每个检测项目 | 每个检测批次 |
| 存储 | biz_qc_task_assignee 按 task |
批次表 + biz_qc_batch_assignee;任务 assignee 从批次继承同步 |
| 配置 UI | 右栏按项目选负责人 | 每批次一块卡片,批次级多选负责人 |
任务级 biz_qc_task_assignee 保留,作为「我的质检任务」查询与写鉴权的数据源;配置/调整批次负责人时 写入或更新 该批次下所有未删除任务的 assignee。
biz_qc_work_order
│
│ 1 : N
▼
biz_qc_work_order_inspection_batch ← 新增
│
│ 1 : N
├──────────────────────┐
▼ ▼
biz_qc_work_order_lab_item biz_qc_work_order_third_item
(+ batch_id) (+ batch_id)
│ │
│ 1 : 1 │ 1 : 1
▼ ▼
biz_qc_task
│
▼
biz_qc_task_assignee (从批次负责人继承)
工单完成规则不变:工单下 全部任务 ywc → 工单 ywc。
批次进度(仅展示):前端按批次聚合任务状态计算,如 2/3 已完成,不落库批次状态字段。
biz_qc_work_order_inspection_batch| 字段 | 类型 | 说明 |
|---|---|---|
id |
VARCHAR(64) | PK |
work_order_id |
VARCHAR(64) | 工单 ID |
order_source |
VARCHAR(20) | 与工单一致:inbound / outbound / temporary |
batch_no |
VARCHAR(32) | 批次编号,工单内唯一,如 {work_order_no}-B01 |
batch_name |
VARCHAR(200) | 展示名:YYYYMMDD检测;同日多批次可加后缀 -2 |
tenant_no |
VARCHAR(64) | 租户 |
order_num |
INT | 工单内排序 |
| 公共字段 | remark, create_by, create_dept_id, create_time, update_by, update_time, del_flag |
索引:(work_order_id, del_flag)、(tenant_no, batch_no, del_flag)。
不设 batch_status 字段。
batch_no:{work_order_no}-B + 两位序号(B01, B02, …),工单内递增。batch_name:创建日 YYYYMMDD + 字面量 检测 → 例:20260625检测。20260625检测-2、20260625检测-3(避免展示歧义)。biz_qc_batch_assignee结构对齐 biz_qc_task_assignee:
| 字段 | 说明 |
|---|---|
batch_id |
FK → 批次 |
user_id |
负责人 |
tenant_no, order_num, 公共字段 |
唯一性:应用层保证 batch_id + user_id 未删除不重复。
biz_qc_work_order_lab_item、biz_qc_work_order_third_item 各增加:
| 字段 | 说明 |
|---|---|
batch_id |
VARCHAR(64) NOT NULL(迁移后) |
唯一性变更:
lab_test_item_id 唯一(应用层 dict 键)。lab_test_item_id 唯一;跨批次可重复。third_party_item_id 唯一。可选 DB 唯一索引(软删场景用应用层校验):
UNIQUE (batch_id, lab_test_item_id) where del_flag=0(MySQL 5.7 无部分索引,以应用层校验为准)。biz_qc_task 可增加 batch_id 冗余,便于按批次列表查询;非必须(可通过 source_line_id JOIN 明细得 batch_id)。
对已配置工单(存在 lab/third 明细且 del_flag=0):
batch_no = {wo}-B01,batch_name = 配置日或迁移日 YYYYMMDD检测)。batch_id 指向该批次。biz_qc_task_assignee 的 并集 写入 biz_qc_batch_assignee;任务 assignee 保持不变。推荐:扩展 POST /web/admin/qc-work-orders/{id}/configure,body 改为批次数组;废弃扁平 labItemIds + labItemAssignees 作为唯一入口(可保留兼容一版,内部转批次)。
type WorkOrderConfigureBody = {
batches: Array<{
id?: string // 调整时:已有批次传 id;新增批次省略
assigneeUserIds: string[] // ≥1
hasLab: boolean
hasThirdParty: boolean
labItemIds: string[] // 批次内不重复
thirdPartyItemIds: string[]
}>
}
校验:
| 规则 | 说明 |
|---|---|
| 工单状态 | dpz 或 ypz 均可提交(ypz = 追加/调整批次) |
| 每批次 | 至少 1 种检测方式且对应项目非空 |
| 批次负责人 | 每批次 assigneeUserIds.length ≥ 1 |
| 批次内项目 | lab / third 列表各自无重复 ID |
| 删除批次 | 若批次内存在 jxz 或 ywc 任务 → 禁止删除整批(或仅允许删全 dzx 的批次,与现网删项规则对齐) |
| 移除批次内项目 | 沿用现网:进行中/已完成对应任务不可删 |
同步逻辑(替代 _sync_work_order_lab_items 扁平键):
batch_id 维度比对 lab/third 明细行;create_task_for_line + 从批次 assignee 写入 biz_qc_task_assignee;order_num;同步任务 assignee 为批次当前负责人集合;首次配置(dpz):提交后工单 → ypz,写 configured_time / configured_by。
追加批次(ypz):仅新增批次及其明细/任务;不改 configured_time 或更新 update_time 即可。
GET /web/admin/qc-work-orders/{id}/inspection-batches
响应示例:
{
"list": [
{
"id": "...",
"batchNo": "ZJ202606250001-B01",
"batchName": "20260625检测",
"orderNum": 1,
"assigneeUserIds": ["..."],
"assigneeUserNames": "张三、李四",
"taskCount": 3,
"completedTaskCount": 1,
"tasks": [ /* 与现有 task 列表项结构一致 */ ]
}
]
}
或在工单详情中内嵌 batches 字段,减少请求数。
GET /qc-tasks/mine:不变 — 仍按 biz_qc_task_assignee 过滤。
批次负责人变更时 必须同步 该批次下任务的 assignee,保证「我的任务」可见性正确。
qc-work-order/index.vue)由「左项目 + 右负责人」改为「批次卡片列表」:
┌─ 批次 1 · 20260625检测 ──────────────────┐
│ 负责人: [多选用户] *必填 │
│ □ 实验室自检 □ 第三方检测 │
│ 项目多选区(可混合 lab + third) │
│ [删除批次] │
└──────────────────────────────────────────┘
[+ 添加批次]
dpz:可一次添加多批次后提交。ypz:打开「调整检测」→ 回显已有批次 + 允许「添加批次」;已有批次可改负责人、增删项目(受任务状态约束)。层级:工单 → 批次行(可折叠) → 任务卡片(检测项目)。
新建或改造组件,建议 QcWorkOrderBatchSubList.vue:
batchNo、负责人 Tag、进度 n/m、任务状态 Tag 聚合(如全完成显示 success)。QcWorkOrderTaskSubList 任务卡片(传入 presetTasks 为该批次 tasks)。我的质检任务:buildMineCardListModel 由 工单 → tasks[] 改为 工单 → batches[] → tasks[];筛选/关键词仍可按任务字段匹配。
el-collapse 或现有 kanban 子列表样式;遵守 Fresh Mint 规范。| 场景 | 规则 |
|---|---|
| 工单页督办 | 持有 biz:qcTask:list 可操作全部任务 |
| 我的任务页 | 仅 task.assignee 可开始/填结果 |
| 配置/调整检测 | 持有 biz:qcWorkOrder:list |
批次无独立操作按钮;开始/完成仍在任务卡片上。
| 风险 | 缓解 |
|---|---|
| 与 2026-06-12「按项目指派」文档冲突 | 本 spec supersede 指派粒度;迁移脚本合并 assignee 到默认批次 |
| 同项目跨批次导致任务/参数混淆 | 任务仍绑定 明细行 ID + 主数据快照;参数按 item_source + item_id 查模板,与现网一致 |
| 调整批次负责人后「我的任务」不一致 | 配置 API 内 _sync_task_assignees_from_batch 批量更新 |
| 配置弹窗复杂度上升 | 批次卡片 + 校验提示;单测覆盖重复项校验 |
| 工作量 | 分阶段:① 数据模型 + 配置 API ② 配置 UI ③ 列表批次化 ④ 迁移 |
| 阶段 | 内容 | 预估 |
|---|---|---|
| P1 | DDL、Model、迁移脚本、批次 CRUD、configure API 重写 | 3~4 人天 |
| P2 | 配置/调整检测弹窗 UI | 2~3 人天 |
| P3 | 工单展开 + 我的任务列表批次化 | 2~3 人天 |
| P4 | 联调、回归六 Tab、历史数据验证 | 1~2 人天 |
| 合计 | 8~12 人天 |
dpz 工单一次配置 2 个批次,每批不同负责人、不同项目组合 → 工单 ypz,任务数 = 各批项目数之和。sysz + dsfjc 任务。ypz 工单追加批次 3 → 仅新增批次 3 的任务,不影响已完成任务。remark 是否在 UI 暴露(默认隐藏)。状态: 已批准。qc-inspection-batch,与 api-conventions / database-conventions 对齐。writing-plans 拆 tasks.md 后进入开发。如需进入实现,请明确:是否按本文档直接创建 OpenSpec proposal + 实现计划。