2026-06-25-production-step-dispatch-design.md 16 KB

生产任务 · 工艺步骤级派发 — 需求分析与设计

日期: 2026-06-25
状态: 已评审,可实施
范围: web-admin + backend(生产工单派发、任务执行、我的生产任务)


1. 背景与目标

1.1 现状

项 现状
派发粒度 DispatchTaskDialog.vue 创建 整条生产任务 时指定 单一任务负责人(biz_production_task.current_assignee_user_id)
步骤模型 biz_production_task_step 有工序与执行状态(dzx/jxz/ywc),无负责人、无计划开始时间
我的生产任务 按 current_assignee_user_id = 当前用户 过滤任务
任务执行 TaskExecutionDialog.vue:当前负责人对 全部步骤 可操作
类似实现 质检任务 biz_qc_task_assignee:每检测项多人负责,任一可完成

1.2 客户需求(原文摘要)

  1. 派发按工艺步骤,而非整条生产任务整体派发。
  2. 列表仍按工单 + 生产任务展示;展开/进入执行后,仅派给自己的步骤可操作,其他步骤 只读可见。
  3. 一个工艺步骤可 同时派给多人;任一负责人 可开始/完成该步骤。
  4. 每个步骤派发时可设置 计划开始时间(展示/排序,不限制提前执行)。
  5. 同一生产任务内,多个步骤可派给同一人。
  6. 支持 创建时一并派发(B) 与 工艺配置后单独派发(A) 两种入口。
  7. 已派给 A 的步骤,可改派 给其他人(更新负责人列表)。
  8. 未指定负责人的步骤:仅管理员在 生产工单页 可见可操作;不出现在 任何人的「我的生产任务」。

2. 产品决策

# 问题 决策 状态
D1 「我的生产任务」列表粒度? 工单 + 任务卡片(非步骤级平铺列表) ✅
D2 未派给自己的步骤如何展示? 只读可见(可见完整工艺链路与状态,不可操作) ✅
D3 一步多人时的完成语义? 任一负责人可独立完成(与质检任务一致;completed_by 记实际操作人) ✅
D4 计划开始时间含义? 仅展示/排序,不阻断执行 ✅
D5 派发入口? A + B 均支持,共用同一套步骤派发能力 ✅
D6 未派步骤可见性? 仅管理员(工单页 operateScope=manage);mine 不可见 ✅
D7 数据模型方案? 方案 1:biz_production_task_step_assignee + 步骤 planned_start_time ✅
D8 任务级负责人字段? 创建时 不再必填;「我的生产任务」改按 步骤负责人 过滤 ✅
D9 任务级「转发」? 保留代码但标记 deprecated;协作改由 步骤改派 完成 ✅
D10 原材料/产出/纸质文档? 任一步骤负责人 在 mine 视角均可编辑(与步骤协作一致) ✅
D11 mine 端能否自行改派? 否;改派仅 工单管理页(operateScope=manage) ✅

3. 业务流程(目标态)

┌─────────────────────────────────────────────────────────────────────────┐
│  生产工单 · 派发生产任务                                                  │
│  阶段一:任务名称、工艺路线(可选)、描述 — 【移除任务级负责人】            │
│  阶段二:编辑工艺步骤(现有三栏编辑器)                                    │
└─────────────────────────────────────────────────────────────────────────┘
         │ 若选了工艺路线(B)                    │ 未选路线 / 后补步骤(A)
         ▼                                        ▼
┌────────────────────────────┐          ┌────────────────────────────┐
│ 创建后立即打开「步骤派发」   │          │ 任务卡片 · 「步骤派发」      │
│ 每步:多人 + 计划开始时间    │          │ 同上                        │
└────────────────────────────┘          └────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│  我的生产任务 · 工单 + 任务卡片                                           │
│  过滤:当前用户是 ≥1 个步骤的负责人                                       │
│  展开 → 进入执行:自己的步骤可操作;其他步骤只读;未派步骤 mine 不可见      │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                         管理员工单页 · 步骤改派
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│  sync 步骤负责人列表 + 更新 planned_start_time                            │
│  dzx/jxz:改派后新负责人可操作;ywc:仅影响可见性,不 reopen 步骤          │
└─────────────────────────────────────────────────────────────────────────┘

4. 数据模型

4.1 新增 / 变更

步骤表扩展 biz_production_task_step:

ALTER TABLE biz_production_task_step
  ADD COLUMN planned_start_time datetime DEFAULT NULL COMMENT '计划开始时间' AFTER step_status;

ALTER TABLE biz_production_task_step
  ADD COLUMN completed_by varchar(64) DEFAULT NULL COMMENT '完成步骤的用户ID' AFTER completed_time;

步骤负责人关联表 biz_production_task_step_assignee(对齐 biz_qc_task_assignee):

CREATE TABLE biz_production_task_step_assignee (
  id varchar(64) NOT NULL COMMENT '主键',
  step_id varchar(64) NOT NULL COMMENT '生产任务步骤ID',
  user_id varchar(64) NOT NULL COMMENT '负责人用户ID',
  tenant_no varchar(64) NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
  order_num int DEFAULT 0 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 COMMENT '创建时间',
  update_by varchar(64) DEFAULT NULL COMMENT '更新人id',
  update_time datetime NOT NULL COMMENT '更新时间',
  del_flag tinyint NOT NULL DEFAULT 0 COMMENT '删除标记',
  PRIMARY KEY (id),
  KEY idx_step_assignee_step (step_id),
  KEY idx_step_assignee_user (user_id, tenant_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='生产任务步骤负责人';

4.2 任务级字段(兼容)

字段 处理
biz_production_task.current_assignee_user_id 保留列;新创建任务可为 NULL;API 创建 body 移除 assigneeUserId 必填
biz_production_task_handover 保留;UI 不再主推「任务转发」,文档标注 deprecated

4.3 历史数据迁移(可选脚本)

  • 若旧任务 current_assignee_user_id 非空且无步骤负责人:可将该用户写入 全部现有步骤 的 assignee(一次性迁移),保证旧任务仍在「我的生产任务」可见。
  • 无 assignee 且无步骤负责人的旧任务:行为与「未派步骤」一致,仅 manage 可见。

5. API 设计

5.1 步骤派发(批量)

PUT /api/web/admin/production-tasks/{taskId}/steps/dispatch

Body(camelCase 与现有约定一致):

{
  "steps": [
    {
      "stepId": "uuid",
      "assigneeUserIds": ["u1", "u2"],
      "plannedStartTime": "2026-06-25T09:00:00"
    }
  ]
}

规则:

  • 至少 1 个 step 在请求中且 assigneeUserIds.length >= 1(允许部分步骤暂不派)。
  • 未出现在请求中的步骤:不修改 其负责人与时间。
  • 出现的步骤:全量 sync 负责人(软删旧 + 插入新,复用 qc_task_assignee.sync_assignees 模式)。
  • plannedStartTime 可选;传 null 表示清空。
  • 权限:production:work-order:list(manage);mine 端 403。

响应: 任务详情(含 steps、assignees、plannedStartTime、assigneeNames)。

5.2 创建生产任务

POST /api/web/admin/production-tasks
  • 移除 assigneeUserId 必填校验。
  • 可选扩展:同 body 内嵌 stepDispatch 数组(B 入口一次提交);或创建成功后前端再调 §5.1。

5.3 我的生产任务列表

GET /api/web/admin/production-tasks/mine

过滤逻辑变更:

  • current:存在 biz_production_task_step_assignee.user_id = 当前用户 且 del_flag=0 的 至少一个步骤 的任务。
  • history(若保留):曾出现在步骤 assignee 但当前已不在任一步 assignee 列表的任务(可选首版简化:与 current 合并或暂不实现 history 变更)。

首版:替换 原 current_assignee_user_id = 我 为主过滤条件;history 沿用 handover 逻辑仅作兼容,不作为步骤协作主路径。

5.4 步骤写操作鉴权

操作 mine manage
开始/完成/保存 已派给自己 的步骤 ✅ ✅
操作 未派给自己 的步骤 ❌ 只读 ✅
操作 未派任何人 的步骤 ❌ 不可见 ✅
编辑任务输入/产出/附件 ✅ 若本人是任一步 assignee ✅
步骤派发/改派 ❌ ✅

实现:在 production_task CRUD 增加 assert_step_assignee(step_id, user_id);manage 路径跳过。

5.5 任务详情 / 列表 enrichment

  • _task_to_dict / 步骤 _step_to_dict 增加:
    • assigneeUserIds: string[]
    • assigneeNames: string[](或 assignees: {userId, nickName, userNo}[])
    • plannedStartTime
    • completedBy / completedByName
  • 列表接口批量 _enrich_step_assignees(对齐 QC _enrich_assignee_names)。

6. 前端设计

6.1 新增组件

组件 职责
DispatchStepDialog.vue 步骤派发表格:工序名、负责人多选、计划开始时间;提交 §5.1

6.2 改造组件

组件 变更
DispatchTaskDialog.vue 移除 任务级「负责人」表单项与校验;选工艺路线且创建成功后 可选打开 DispatchStepDialog(B)
WorkOrderTaskSubList.vue 管理视角:任务卡片 meta 展示各步负责人 Tag + 计划开始时间;按钮「步骤派发 / 调整派发」
TaskExecutionDialog.vue mine:canEditStep(step) = 当前用户在 step.assigneeUserIds;否则只读;未派步骤不渲染或 manage 才显示
StepDetailPanel.vue 禁用开始/完成/保存按钮当 !canEditStep
useTaskStepEditor.ts 传入 operateScope;步骤操作前校验 assignee
production-task.ts 新增 fetchDispatchProductionTaskSteps;创建 body 去掉 assigneeUserId
production-mine-task-groups.ts mine 列表依赖后端新过滤(前端无需按 task assignee 过滤)

6.3 步骤派发表格 UI

列 控件
序号 / 工序名称 只读
负责人 el-select multiple filterable remote,展示 nickName(userNo),≥1
计划开始时间 el-date-picker type="datetime",可选
  • 弹窗:dialog-form-layout,label-position="top"。
  • 底栏:取消 / 确定(Close / Check 图标)。

6.4 执行弹窗 · 步骤列表视觉

  • 可操作步骤:现有高亮样式(is-active)。
  • 只读步骤:降低 opacity 或 readonly class;隐藏开始/完成/保存;保留状态 Tag。
  • 未派步骤(mine):不展示(manage 正常展示并可操作)。

6.5 Deprecated UI

  • 任务级「转发」「改派」按钮:管理页 隐藏或替换 为「步骤派发」;API 保留不删。

7. 改派规则

步骤状态 改负责人 改计划开始时间 步骤是否 reopen
dzx ✅ ✅ —
jxz ✅ ✅ 否,新负责人接手进行中步骤
ywc ✅(仅影响 mine 可见性) ✅ 否

8. 任务 / 工单状态联动

  • 任务状态(dpz/jxz/ywc)逻辑 不变:仍由步骤聚合 + 现有 sync_production_work_order_status_from_tasks 驱动。
  • 未派步骤 不参与 mine 过滤;manage 仍可执行未派步骤(管理员兜底)。

9. 权限与菜单

能力 menuCode
生产工单(manage、步骤派发) production:work-order:list
我的生产任务 production:my-task:list

无需新增菜单;步骤派发挂在工单页任务操作区。


10. 测试要点

  1. B 入口:选路线 → 创建 → 步骤派发 → 各 assignee 在 mine 见任务,仅自己步骤可操作。
  2. A 入口:无路线创建 → 手工加步骤 → 步骤派发 → 同上。
  3. 一步多人:A、B 均可见任务;A 完成后 B 见只读已完成。
  4. 同人多步:mine 展开见多个可操作步骤。
  5. 计划开始时间:列表/卡片展示;未到时间仍可执行。
  6. 未派步骤:mine 不可见;manage 可见可操作。
  7. 改派:dzx/jxz/ywc 按 §7;mine 不可改派。
  8. 旧任务兼容(若跑迁移脚本):原 task assignee 仍可见。

11. 文件清单(实施参考)

层 文件
SQL docs/sql/migrations/2026-06-25-production-step-dispatch.sql,同步 docs/sql/zkxw.sql
Backend Model backend/app/models/models.py — BizProductionTaskStepAssignee + 步骤新字段
Backend CRUD backend/app/crud/production_task_step_assignee.py(新建,对齐 qc_task_assignee)
Backend CRUD backend/app/crud/production_task.py — mine 过滤、step assert、complete 写 completed_by
Backend Schema backend/app/schemas/production_task.py — DispatchStepsBody
Backend API backend/app/api/production.py — PUT steps/dispatch;调整 create/mine
Frontend API web-admin/src/api/production-task.ts
Frontend DispatchStepDialog.vue(新建)
Frontend DispatchTaskDialog.vue, WorkOrderTaskSubList.vue, TaskExecutionDialog.vue, StepDetailPanel.vue, useTaskStepEditor.ts

12. 与 OpenSpec / 既有 spec 关系

  • supersede 部分:2026-06-13-production-task-assignee-my-tasks-design.md 中 任务级单一负责人 + 任务转发 产品路径;本 spec 以 步骤级多人 + 步骤改派 为准。
  • 对齐 api-conventions:租户隔离、软删除、operateScope=mine|manage。
  • 对齐 ui-conventions:Fresh Mint 弹窗、按钮图标、Tag 展示负责人。

13. 版本记录

日期 说明
2026-06-25 初稿:步骤级派发方案 1,产品决策 D1–D11 已确认