2026-06-25-qc-inspection-batch-design.md 13 KB

质检检测批次 — 设计文档

日期: 2026-06-25
状态: 待评审 / 待实现
范围: web-admin + backend(质检工单、我的质检任务、配置检测 / 调整检测)
前置: 2026-05-17-quality-inspection-modules-design.md、2026-06-12-qc-task-assignee-my-tasks-design.md(负责人粒度将变更)

1. 背景与目标

1.1 现状问题

  • 配置检测时,同一工单内 每个检测主数据项目只能选一次(_sync_work_order_* 以 lab_test_item_id / third_party_item_id 为唯一键)。
  • 负责人按 每个检测项目 独立指派,配置弹窗右侧「负责人配置」与左侧项目一一对应。
  • 工单展开区、我的质检任务中,列表 平铺展示每条质检任务(≈ 每个检测项目一张卡片)。

1.2 目标

引入 检测批次 作为工单与检测项目之间的容器层:

  • 一个质检工单可配置 多个检测批次;
  • 每个批次内勾选 lab / 第三方项目(批次内项目不重复;跨批次允许重复同一主数据项目);
  • 每个批次配置 多名负责人,负责该批次下全部项目的任务;
  • ypz(已配置)后仍可 追加批次(调整检测);
  • 批次 无独立状态机,仅作分组容器;任务仍保留 dzx / jxz / ywc;
  • 列表 UI:先展示批次,展开后展示批次内检测项目/任务。

2. 已确认的产品决策(2026-06-25)

# 问题 决策
1 批次负责人 允许多人;完成语义沿用现网:任一负责人可独立开始/填写结果/完成
2 同主数据项目跨批次重复 允许(例如批次 1、批次 2 均可含「无菌检测」)
3 同批次内同一项目重复 不允许
4 批次内 lab + 第三方混合 允许
5 配置时机 dpz 首次可配多批次;ypz 后可追加批次(调整检测)
6 批次独立状态 否 — 批次仅作容器;不增加批次级开始/完成
7 批次命名 自动编号 + 展示名规则:YYYYMMDD检测(创建日);可选附带序号区分同日多批次,见 §4.2

2.1 与 2026-06-12 负责人设计的差异

项 2026-06-12(已实现) 本变更
指派粒度 每个检测项目 每个检测批次
存储 biz_qc_task_assignee 按 task 批次表 + biz_qc_batch_assignee;任务 assignee 从批次继承同步
配置 UI 右栏按项目选负责人 每批次一块卡片,批次级多选负责人

任务级 biz_qc_task_assignee 保留,作为「我的质检任务」查询与写鉴权的数据源;配置/调整批次负责人时 写入或更新 该批次下所有未删除任务的 assignee。


3. 目标架构

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 已完成,不落库批次状态字段。


4. 数据模型

4.1 新表 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 字段。

4.2 批次编号与命名规则

  • batch_no:{work_order_no}-B + 两位序号(B01, B02, …),工单内递增。
  • batch_name:创建日 YYYYMMDD + 字面量 检测 → 例:20260625检测。
  • 若同一工单同一天创建多个批次:第二个起为 20260625检测-2、20260625检测-3(避免展示歧义)。

4.3 新表 biz_qc_batch_assignee

结构对齐 biz_qc_task_assignee:

字段 说明
batch_id FK → 批次
user_id 负责人
tenant_no, order_num, 公共字段

唯一性:应用层保证 batch_id + user_id 未删除不重复。

4.4 改表现有明细表

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 无部分索引,以应用层校验为准)。

4.5 任务表(可选冗余)

biz_qc_task 可增加 batch_id 冗余,便于按批次列表查询;非必须(可通过 source_line_id JOIN 明细得 batch_id)。

4.6 历史数据迁移

对已配置工单(存在 lab/third 明细且 del_flag=0):

  1. 每个工单插入 默认批次 1(batch_no = {wo}-B01,batch_name = 配置日或迁移日 YYYYMMDD检测)。
  2. 现有明细行 batch_id 指向该批次。
  3. 批次负责人:取该批次下各任务现有 biz_qc_task_assignee 的 并集 写入 biz_qc_batch_assignee;任务 assignee 保持不变。

5. API 设计

5.1 配置 / 调整检测(扩展或 v2)

推荐:扩展 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 为批次当前负责人集合;
  • 删除行 → 软删明细 + 软删任务 + 软删任务 assignee。

首次配置(dpz):提交后工单 → ypz,写 configured_time / configured_by。

追加批次(ypz):仅新增批次及其明细/任务;不改 configured_time 或更新 update_time 即可。

5.2 批次列表(供展开 UI)

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 字段,减少请求数。

5.3 我的质检任务

GET /qc-tasks/mine:不变 — 仍按 biz_qc_task_assignee 过滤。

批次负责人变更时 必须同步 该批次下任务的 assignee,保证「我的任务」可见性正确。


6. 前端改造

6.1 配置检测 / 调整检测弹窗(qc-work-order/index.vue)

由「左项目 + 右负责人」改为「批次卡片列表」:

┌─ 批次 1 · 20260625检测 ──────────────────┐
│ 负责人: [多选用户] *必填                    │
│ □ 实验室自检  □ 第三方检测                  │
│ 项目多选区(可混合 lab + third)            │
│                              [删除批次]    │
└──────────────────────────────────────────┘
[+ 添加批次]
  • dpz:可一次添加多批次后提交。
  • ypz:打开「调整检测」→ 回显已有批次 + 允许「添加批次」;已有批次可改负责人、增删项目(受任务状态约束)。

6.2 工单展开 / 我的质检任务列表

层级:工单 → 批次行(可折叠) → 任务卡片(检测项目)。

新建或改造组件,建议 QcWorkOrderBatchSubList.vue:

  • 批次头:批次名、batchNo、负责人 Tag、进度 n/m、任务状态 Tag 聚合(如全完成显示 success)。
  • 展开:复用现有 QcWorkOrderTaskSubList 任务卡片(传入 presetTasks 为该批次 tasks)。

我的质检任务:buildMineCardListModel 由 工单 → tasks[] 改为 工单 → batches[] → tasks[];筛选/关键词仍可按任务字段匹配。

6.3 UI 模式

  • 配置弹窗:参考 P21 + 多卡片表单(可参考生产工单多步骤配置)。
  • 批次折叠列表:参考 el-collapse 或现有 kanban 子列表样式;遵守 Fresh Mint 规范。

7. 权限与操作(沿用现网)

场景 规则
工单页督办 持有 biz:qcTask:list 可操作全部任务
我的任务页 仅 task.assignee 可开始/填结果
配置/调整检测 持有 biz:qcWorkOrder:list

批次无独立操作按钮;开始/完成仍在任务卡片上。


8. 风险与缓解

风险 缓解
与 2026-06-12「按项目指派」文档冲突 本 spec supersede 指派粒度;迁移脚本合并 assignee 到默认批次
同项目跨批次导致任务/参数混淆 任务仍绑定 明细行 ID + 主数据快照;参数按 item_source + item_id 查模板,与现网一致
调整批次负责人后「我的任务」不一致 配置 API 内 _sync_task_assignees_from_batch 批量更新
配置弹窗复杂度上升 批次卡片 + 校验提示;单测覆盖重复项校验
工作量 分阶段:① 数据模型 + 配置 API ② 配置 UI ③ 列表批次化 ④ 迁移

9. 实现阶段建议

阶段 内容 预估
P1 DDL、Model、迁移脚本、批次 CRUD、configure API 重写 3~4 人天
P2 配置/调整检测弹窗 UI 2~3 人天
P3 工单展开 + 我的任务列表批次化 2~3 人天
P4 联调、回归六 Tab、历史数据验证 1~2 人天
合计 8~12 人天

10. 验收场景(摘要)

  1. dpz 工单一次配置 2 个批次,每批不同负责人、不同项目组合 → 工单 ypz,任务数 = 各批项目数之和。
  2. 两批次均含同一 lab 项目 → 生成 2 条明细、2 条任务,参数模板相同、结果独立填写。
  3. 同批次内勾选重复 lab 项目 → 前端 + 后端拒绝。
  4. 单批次同时含 lab + third 项目 → 正常生成 sysz + dsfjc 任务。
  5. ypz 工单追加批次 3 → 仅新增批次 3 的任务,不影响已完成任务。
  6. 修改批次负责人 → 该批次未完成任务在新负责人「我的任务」中可见。
  7. 工单列表展开:显示批次列表;展开批次显示项目任务卡片。
  8. 历史工单迁移后:显示为「批次 1」,行为与迁移前一致。

11. 开放项(可选,不阻塞开工)

  • 批次 remark 是否在 UI 暴露(默认隐藏)。
  • 删除「空批次」(无项目)是否允许在保存时自动剔除。
  • 第三方费用合计:工单级汇总不变;是否在批次头展示该批 third 费用小计。

12. 下一步

  1. 评审本文档 — 确认无遗漏后标记 状态: 已批准。
  2. OpenSpec 变更 — 建议 capability:qc-inspection-batch,与 api-conventions / database-conventions 对齐。
  3. 实现计划 — 使用 writing-plans 拆 tasks.md 后进入开发。

如需进入实现,请明确:是否按本文档直接创建 OpenSpec proposal + 实现计划。