2026-06-13-production-task-assignee-my-tasks-design.md 18 KB

生产任务负责人、转发与「我的生产任务」— 需求分析与设计

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


1. 背景与目标

1.1 现状

项 现状
派发入口 生产工单 → DispatchTaskDialog.vue(任务名称、工艺路线、描述、备注)
任务模型 biz_production_task 无负责人字段
任务可见性 工单展开行 WorkOrderTaskSubList 对持有 production:work-order:list 的用户展示全部任务
任务执行 TaskExecutionDialog.vue:开始执行 / 工序步骤 / 完成任务
独立任务入口 旧菜单 生产任务 已重定向至 生产工单,无「我的任务」视角
类似实现 已实现「我的质检任务」(2026-06-12-qc-task-assignee-my-tasks-design.md)

1.2 客户需求(原文摘要)

  1. 派发时指定负责人:派发生产任务时必须选择负责人;该负责人在「我的生产任务」中可见并操作,其他人不可见。
  2. 新增菜单:在二级菜单 【生产管理】 下新增 【我的生产任务】。
  3. 任务执行:负责人在该页面查看并执行任务(复用现有执行能力)。
  4. 多人协作 / 转发:负责人 A 完成本段工作后,可将任务 转发 给负责人 B 继续执行;转发后 A 不再出现在「当前任务」,仅在 「历史执行」 Tab 中只读查看。
  5. 双 Tab:「当前任务」(可操作)+ 「历史执行」(仅查看,不可编辑/执行/转发)。

1.3 与「我的质检任务」的关键差异

维度 质检任务(已实现) 生产任务(本需求)
负责人数量 多人并行(任一可完成) 单人当前负责人(串行协作)
协作方式 同时多人负责 转发给下一位负责人
我的任务列表 单列表 双 Tab(当前 / 历史)
历史视角 无独立历史 Tab 曾负责但已转出的任务
存储 biz_qc_task_assignee 多行 建议 current_assignee_user_id + 转发表

2. 业务流程(目标态)

┌─────────────────────────────────────────────────────────────────────────┐
│                        生产工单 · 派发任务                               │
│  填写任务信息 + 【必选】负责人 ──► 创建任务 (dpz) + 设置 current_assignee │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                     我的生产任务 · Tab「当前任务」                        │
│  过滤: current_assignee = 当前用户                                       │
│  操作: 配置工艺(dpz) / 开始执行 / 执行工序 / 完成任务 / 【转发】          │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                         负责人 A 点击「转发」
                         选择负责人 B + 备注
                                    │
                                    ▼
┌──────────────────────────┐    ┌──────────────────────────────────────────┐
│ A · 当前任务 Tab         │    │ B · 当前任务 Tab                          │
│  任务消失                │    │  任务出现,可继续执行                      │
└──────────────────────────┘    └──────────────────────────────────────────┘
            │
            ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                     我的生产任务 · Tab「历史执行」                        │
│  过滤: 当前用户曾出现在 biz_production_task_handover.from_user_id        │
│        且 current_assignee ≠ 当前用户                                    │
│  操作: 仅「查看」TaskExecutionDialog readonly                             │
└─────────────────────────────────────────────────────────────────────────┘

2.1 任务状态与操作矩阵(当前负责人视角)

任务状态 含义 当前 Tab 可用操作
dpz 待配置 已创建,工艺可编辑 进入执行(配置步骤)、转发、查看
jxz 进行中 已开始执行 继续执行、转发、查看
ywc 已完成 整单任务结束 查看、转发(接收方继承已完成状态,通常仅查看/归档交接)

D3 已确认:任何任务状态(dpz / jxz / ywc)均可转发;转发不改变任务状态与已填写的执行数据,仅变更 current_assignee。


3. 产品决策

# 问题 决策 状态
D1 派发时负责人是否必填? 是 ✅ 已确认
D2 负责人是单人还是多人? 单人当前负责人(转发串行协作) ✅ 已确认
D3 转发时机? 任何状态均可转发(dpz / jxz / ywc) ✅ 已确认
D4 转发后 A 的执行数据? 保留(B 在 A 进度上继续;ywc 转发后仍为 ywc) ✅ 已确认
D5 任务完成后是否还允许转发? 是(与 D3 一致,ywc 可转发) ✅ 已确认
D6 生产工单页是否仍展示全部任务? 管理覆盖 — 持有 production:work-order:list 可查看全部任务 ✅ 已确认
D7 工单页非负责人能否执行任务? 能(operateScope=manage);「我的生产任务」页 不能(operateScope=mine) ✅ 已确认
D8 派发后能否改负责人? 可以 — 工单页管理员「改派」+ 负责人「转发」 ✅ 已确认
D9 历史 Tab 是否包含「我创建但未转发就完成的」? 否 — 历史仅 曾转出/被改派离开 的任务 ✅ 已确认
D10 用户选项范围? 本租户有效用户 ✅ 已确认

4. 功能清单

4.1 派发任务(DispatchTaskDialog.vue)

  • 阶段一表单新增 负责人(el-select,filterable,必选)。
  • 展示:nickName(userNo)。
  • 创建 API body 增加 assigneeUserId。
  • 阶段二工艺编辑:派发人或负责人均可编辑;工单页 manage 视角管理员亦可编辑(D6/D7)。

4.2 生产工单 · 任务子列表(WorkOrderTaskSubList.vue)

  • 任务卡片 meta 展示 当前负责人。
  • 管理视角(operateScope=manage):保持现有操作 + 改派(管理员,见 §6.4)。
  • 非负责人但持有工单 list 权限:仍可督办(D6/D7 已确认)。

4.3 任务执行(TaskExecutionDialog.vue)

  • operateScope=mine:仅 current_assignee 可写;否则只读。
  • 新增工具栏按钮 「转发任务」(当前负责人且非 readonly / 非 history 模式;不限任务状态):
    • 弹窗选择下一负责人 + 可选备注;
    • 成功后关闭执行弹窗,刷新列表。
  • 任务卡片操作区亦提供 「转发」 入口(与执行弹窗能力一致)。
  • operateScope=history:强制 readonly,无转发/完成按钮。

4.4 我的生产任务(新页面)

项 说明
路由 /#/production-group/production/my-production-task
组件 web-admin/src/views/production/my-production-task/index.vue
菜单 生产管理 → 我的生产任务
menuCode production:my-task:list(建议,与 production:task:list 区分)
UI 模式 P02 + P21 任务卡片;参考 my-qc-task/index.vue + WorkOrderTaskSubList 卡片样式

Tab 结构

Tab API 说明
当前任务 GET /production-tasks/mine?scope=current current_assignee_user_id = 我
历史执行 GET /production-tasks/mine?scope=history 我曾转出且当前负责人不是我

筛选区(两 Tab 共用,可选字段略减):

字段 类型
关键词 任务号 / 任务名称 / 工单号 / 样本编码
任务状态 dpz / jxz / ywc
工单类型 inbound / outbound / temporary

列表 / 卡片信息

  • 任务号、任务名称、任务状态 Tag、生产结论 Tag(若有)
  • 关联工单号、样本编码、工单类型、当前负责人
  • 当前 Tab:主操作「执行」/「查看」;历史 Tab:仅「查看」

4.5 菜单与权限

三处对齐(参照 QC my-qc-task):

  1. web-admin/src/router/modules/sqxp.ts
  2. backend/app/api/menu.py
  3. docs/sql/migrations/2026-06-13-my-production-task-menu.sql + docs/sql/zkxw.sql
菜单 path perms order_num(建议)
我的生产任务 my-production-task production:my-task:list 生产工单之后(如 4)

5. 数据模型(建议方案)

5.1 方案对比

方案 描述 优点 缺点
A(推荐) biz_production_task.current_assignee_user_id + 转发表 查询简单;语义清晰 任务表增字段
B 纯 biz_production_task_assignee 多行 + is_current 与 QC 表结构类似 单人场景略重;历史需额外逻辑
C 仅转发表推导当前负责人 无任务表字段 查询复杂、易错

推荐方案 A。

5.2 任务表扩展

biz_production_task 新增:

ALTER TABLE `biz_production_task`
  ADD COLUMN `current_assignee_user_id` varchar(64) DEFAULT NULL COMMENT '当前负责人用户ID' AFTER `task_status`;

响应字段(_task_to_dict):

字段 类型 说明
currentAssigneeUserId string 当前负责人 ID
currentAssigneeUserName string 当前负责人姓名

5.3 转发历史表(新)

CREATE TABLE `biz_production_task_handover` (
  `id` varchar(64) NOT NULL COMMENT '主键',
  `task_id` varchar(64) NOT NULL COMMENT '生产任务ID',
  `from_user_id` varchar(64) NOT NULL COMMENT '转出用户ID',
  `to_user_id` varchar(64) NOT NULL COMMENT '接收用户ID',
  `handover_time` datetime NOT NULL COMMENT '转发时间',
  `remark` varchar(512) DEFAULT NULL COMMENT '转发说明',
  `tenant_no` varchar(64) NOT NULL COMMENT '租户编号',
  `order_num` int DEFAULT 0,
  `create_by` varchar(64) DEFAULT NULL,
  `create_dept_id` varchar(64) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  `update_by` varchar(64) DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  `del_flag` tinyint DEFAULT 0,
  PRIMARY KEY (`id`),
  KEY `idx_prod_task_handover_task` (`task_id`, `del_flag`),
  KEY `idx_prod_task_handover_from` (`from_user_id`, `tenant_no`, `del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='生产任务转发记录';

5.4 创建 / 转发请求体

创建任务 POST /production-tasks:

assignee_user_id: str = Field(..., alias="assigneeUserId")  # 必填

转发任务 POST /production-tasks/{id}/forward:

to_user_id: str = Field(..., alias="toUserId")
remark: Optional[str] = None

校验:

  • to_user_id ≠ 当前用户;
  • 不校验任务状态(D3:dpz / jxz / ywc 均可);
  • 仅 current_assignee 可转发(operateScope=mine);工单页 operateScope=manage 下持有 production:work-order:list 的管理员也可代为转发;
  • 目标用户属于当前租户且有效。

5.5 历史数据

  • 已有任务 current_assignee_user_id 为 NULL:不出现在「我的生产任务」;
  • 生产工单页仍可见、可操作(管理覆盖);
  • v1 不做批量回填;如需补录,通过工单页 改派 指定负责人。

6. API 设计

6.1 我的任务列表(新)

GET /web/admin/production-tasks/mine

  • 权限:production:my-task:list
  • Query:page, pageSize, keyword, taskStatus, workOrderType, scope=current|history
  • current:current_assignee_user_id = 当前用户
  • history:EXISTS handover WHERE from_user_id = 当前用户 AND current_assignee_user_id <> 当前用户
  • 排序:create_time DESC(current)/ handover_time DESC(history,取最近一条转出记录时间展示)
  • 响应:与 GET /production-tasks 列表项一致 + 工单摘要 + handoverTime(history Tab)

6.2 转发(新)

POST /web/admin/production-tasks/{id}/forward

  • 权限:production:my-task:list + assignee 校验
  • 事务:插入 handover → 更新 current_assignee_user_id

6.3 写操作鉴权(operateScope)

复用 QC 模式,Query 或 Header:operateScope=mine|manage

端点 mine manage
步骤 CRUD、状态变更、完成任务 须 current_assignee production:work-order:list 或 task list
转发 须 current_assignee 持有 production:work-order:list 可代为转发

前端:

  • my-production-task 写请求带 operateScope=mine
  • WorkOrderTaskSubList / TaskExecutionDialog 从工单打开时 operateScope=manage

6.4 管理员改派(v1 纳入)

PUT /web/admin/production-tasks/{id}/assignee

  • 权限:production:work-order:list
  • Body:assigneeUserId(新负责人,必填)
  • 行为:
    • 更新 current_assignee_user_id;
    • 写入 biz_production_task_handover(from_user_id = 原负责人或操作人,to_user_id = 新负责人,remark 标注「管理员改派」),便于历史 Tab 与审计;
    • 不校验任务状态(与 D3 一致)。
  • 用于:派发遗漏、人员调整、管理员主动调配。
  • 前端:工单任务卡片 dropdown 增加「改派」→ 选人弹窗。

7. 前端实现要点

7.1 组件复用策略

组件 改造
WorkOrderTaskSubList.vue 增加 listMode: 'workOrder' \| 'mine-current' \| 'mine-history';mine 模式调 /mine API
TaskExecutionDialog.vue 增加 operateScope、转发按钮与 ForwardTaskDialog
DispatchTaskDialog.vue 负责人选择 + 校验

避免复制 500+ 行执行逻辑;优先 props 驱动 而非新建平行页面。

7.2 用户选择器

  • 复用 QC 配置检测中的租户用户加载方式(fetchUserList 或现有 admin API)。
  • 派发、转发、改派三处共用 composable(如 useTenantUserOptions)。

7.3 规范对齐

  • Fresh Mint 列表骨架、filter-block、任务卡片 Tag 语义色;
  • 按钮带 @element-plus/icons-vue 图标;
  • 转发弹窗 label-position="top"、dialog-form-layout;
  • App.vue → panelTitleBarTextRules 注册「我的生产任务」。

8. 测试要点

场景 预期
派发未选负责人 前端 + 后端 400
派发选 A A 的「当前任务」可见;B 不可见
A 转发给 B(jxz) B 当前可见;A 仅历史可见;任务进度保留
A 在 dpz 阶段转发给 B B 成为负责人,可继续配置工艺
A 在 ywc 阶段转发给 B B 当前 Tab 可见;任务仍为 ywc;B 仅查看(不可再执行)
A 历史 Tab 打开任务 只读,无完成/转发
B 完成任务 B 当前 Tab 显示 ywc,只读
非 assignee 调 mine API 写操作 403
工单页管理员非 assignee 执行 成功(manage)
历史无 assignee 的旧任务 不出现在我的任务;工单页仍可操作
转发给自己 拒绝

9. 改动文件清单(预估)

层级 文件
SQL docs/sql/migrations/2026-06-13-production-task-assignee.sql, 2026-06-13-my-production-task-menu.sql, docs/sql/zkxw.sql
Backend models.py, production_task.py, production.py (API), schemas/production_task.py, menu.py
Frontend sqxp.ts, DispatchTaskDialog.vue, WorkOrderTaskSubList.vue, TaskExecutionDialog.vue, my-production-task/index.vue, production-task.ts, 类型定义
图谱 ./scripts/update-graph.sh backend frontend

10. 不在 v1 范围

  • 消息通知(指派 / 转发提醒)
  • 按角色 / 部门自动解析负责人
  • 小程序端生产任务
  • 转发审批流
  • 一次指派多人并行执行

11. 实施顺序建议

  1. 数据模型 + 派发选负责人(创建链路闭环)
  2. 我的生产任务 · 当前 Tab + mine 列表 API + 严格鉴权
  3. 转发 + 历史 Tab
  4. 工单页展示负责人 + 管理改派
  5. 菜单 SQL、权限、回归测试

12. OpenSpec 跟进(实现阶段)

  • api-conventions:生产任务 current_assignee、operateScope、转发 API
  • ui-conventions:「我的生产任务」参考页登记(P02 + P21)

请评审本文档。 全部产品决策(D1–D10)已确认。实现计划见 docs/superpowers/plans/2026-06-13-production-task-assignee-my-tasks.md。