From 5367abf7f20baee10e1b5f6cf2d8637c1565e432 Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Mon, 31 Aug 2026 14:30:21 +0800 Subject: [PATCH] docs: add production cascade complete design for task and work order Document cascading status completion when finishing a production task or work order, removing incomplete-step gates. Co-authored-by: Cursor --- ...8-31-production-cascade-complete-design.md | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-31-production-cascade-complete-design.md diff --git a/docs/superpowers/specs/2026-08-31-production-cascade-complete-design.md b/docs/superpowers/specs/2026-08-31-production-cascade-complete-design.md new file mode 100644 index 00000000..1eaaa94b --- /dev/null +++ b/docs/superpowers/specs/2026-08-31-production-cascade-complete-design.md @@ -0,0 +1,167 @@ +# 生产「完成任务 / 完成工单」状态级联 — 设计文档 + +> 日期: 2026-08-31 +> 状态: 待实现 +> 范围: 生产工单、生产任务、工艺步骤(web-admin + backend) +> 页面: 【生产工单】`/#/production-group/production/production-work-order`、【我的生产任务】`/#/production-group/production/my-production-task`(共用任务执行弹窗) + +## 1. 背景 + +当前行为: + +| 入口 | 现状 | +|------|------| +| 任务执行弹窗 ·「完成任务」 | 前后端均校验「全部工艺步骤已完成」;未完成则拦截。步骤上仍有「执行此步骤」「完成步骤」。 | +| 卡片 ·「完成工单」 | 仅将工单标为 `ywc`,**不**同步完成下属任务与步骤。 | +| 我的生产任务 | 不展示「完成工单」;与生产工单共用 `TaskExecutionDialog`。 | + +用户诉求:完成上级时**自动级联完成下级状态**,不再因下级未完成而阻止操作;业务明细(投入产出、步骤填报等)不强制补全。 + +## 2. 已确认的产品决策 + +| 问题 | 决策 | +|------|------| +| 实现路径 | **方案 B**:在现有「完成任务」「完成工单」接口内做级联(同一事务) | +| 完成工单时未完成任务的结论 | **弹窗统一选择**成功(`cg`)/失败(`sb`),再级联写入所有本次新完成的任务 | +| 级联完成步骤的完成人/时间 | **当前操作人 + 当前时间**(与手动「完成步骤」一致) | +| 完成任务时的 I/O、储物格、步骤完整性校验 | **全部去掉**;只改状态,不因明细未填拦截 | +| 完成工单级联任务范围 | 工单下所有未删除且未完成任务(含 `dpz` / `dzx` / `jxz`) | +| 已完成任务 | **不动**(结论与步骤保持原样) | +| 单步「执行此步骤 / 完成步骤」 | **保留**,可继续逐步操作 | +| 我的生产任务 · 完成工单入口 | **不新增**(卡片仍不展示) | + +## 3. 行为与范围 + +### 3.1 完成任务(任务执行弹窗顶栏) + +1. 仍弹出结论弹窗(成功/失败 + 可选备注)。 +2. 不再因「尚有未完成工艺步骤」拦截(前端 + 后端同步去掉)。 +3. 不再因投入/产出未填、储物格未分配而拦截。 +4. 提交时后端在置任务 `ywc` 前,将该任务下所有未删除且 `step_status != ywc` 的步骤一次性置为 `ywc`: + - `completed_by` = 当前操作人 + - `completed_time` = 当前时间 + - 已有 `started_time` 的步骤保留;未开始的步骤可不补 `started_time`(与手动完成步骤路径对齐即可) +5. 结论必填、任务 `completed_time`、投入物消耗 `_consume_task_input_cell_products`、以及 `sync_production_work_order_status_from_tasks` **保持现状**(完成任务本身不把工单直接标成 `ywc`)。 + +### 3.2 完成工单(生产工单卡片) + +1. 点击后**先弹统一结论弹窗**(成功/失败,可选备注),不再只是简单 `confirm`。 +2. 弹窗可提示:将同步完成该工单下所有未完成任务及其工艺步骤。 +3. 确认后同一事务内级联: + - 未完成步骤 → `ywc`(完成人/时间同上) + - 未完成任务 → `ywc`,写入统一 `conclusion`;弹窗有备注时写入任务 `remark` + - 工单 → `ywc`;弹窗备注写入工单 `remark`(若有) +4. 已是 `ywc` 的任务:结论、步骤不动。 + +### 3.3 明确不做 + +- 不自动补全步骤/任务业务明细(试剂、产出物、数据采集等) +- 不改派发、步骤负责人权限、单步执行流程 +- 不改工单 Tab / 列表卡片布局(仅完成工单交互从 confirm → 结论弹窗) +- 不在「我的生产任务」开放完成工单 + +## 4. 后端设计 + +### 4.1 共享内部方法 + +`_force_complete_task_steps(db, task_id, tenant_no, user_id, now)`: + +- 条件:`BizProductionTaskStep.del_flag=0` 且 `step_status != 'ywc'` +- 写入:`step_status='ywc'`,`completed_by=user_id`,`completed_time=now`,`update_by` / `update_time` +- 不单独 `commit` + +### 4.2 完成任务 + +入口不变:现有更新任务状态为 `ywc` 的路径(`update_task_status`)。 + +变更: + +1. 删除「尚有未完成的工艺步骤,请完成全部步骤后再完成任务」校验。 +2. 置任务 `ywc` 之前调用 `_force_complete_task_steps`。 +3. 其余逻辑(结论校验、消耗、工单状态同步)不变。 + +### 4.3 完成工单 + +入口不变:`PUT /production-work-orders/{wo_id}/complete`。 + +`ProductionWorkOrderComplete` 扩展: + +| 字段 | 必填 | 说明 | +|------|------|------| +| `conclusion` | 是 | `cg` / `sb`,写入所有**本次新完成**的任务 | +| `remark` | 否 | 写入工单备注;若有值则同时写入本次新完成任务的 `remark` | + +级联顺序(**同一事务、一次 commit**): + +``` +1. 校验工单存在且非 ywc;conclusion 合法 +2. 查工单下 del_flag=0 且 task_status != ywc 的任务 +3. 对每个上述任务: + a. _force_complete_task_steps + b. task_status=ywc,conclusion=统一结论,completed_time=now(若空) + c. 走与「完成任务」一致的侧效(含投入物消耗) +4. 工单 work_order_status=ywc,写 remark(若有) +5. sync_schedule_from_production_work_order +6. commit +``` + +实现约束: + +- 级联过程中**不要**对每个任务单独 `commit`。 +- 级联过程中**跳过** `sync_production_work_order_status_from_tasks`(避免中途把工单写成 `jxz`),最后一步直接置工单 `ywc`。 +- 工单下无未完成任务:仍要求选结论;仅改工单状态(结论不落任务)。 + +### 4.4 错误边界 + +| 条件 | 行为 | +|------|------| +| 工单已 `ywc` | 400「工单已完成」 | +| `conclusion` 缺失或非法 | 400 | +| 权限 | 沿用现有 complete 接口,不新增 | + +## 5. 前端设计 + +### 5.1 完成任务 + +- 文件:`useTaskStepEditor.ts`(`handleCompleteTask`) +- 去掉:`validateAllStepsComplete()`、投入/产出完整校验、储物格确认 +- 保留:`CompleteProductionTaskDialog` → 现有完成任务 API +- 成功后刷新任务详情;步骤应全部为 `ywc` + +### 5.2 完成工单 + +- 文件:`production-work-order/index.vue` 的 `handleCompleteSingle` +- 用结论弹窗替换简单 `confirm`(可复用/轻抽 `CompleteProductionTaskDialog`,标题「完成工单」,增加级联说明文案) +- 提交:`fetchCompleteProductionWorkOrder(id, { conclusion, remark })` +- **API 传参**:当前实现用 query `params`;后端期望 Body。实现时改为请求体 `data` 传 `conclusion`/`remark`,并核对后端能收到 +- 「我的生产任务」:不展示完成工单;调用形态可顺带对齐,不新增入口 + +### 5.3 文案 + +| 场景 | 文案 | +|------|------| +| 完成任务成功 | 保持现有「任务已完成」类提示 | +| 完成工单弹窗标题 | 完成工单 | +| 完成工单成功 | 工单已完成 | + +## 6. 主要改动文件 + +| 层 | 文件 | +|----|------| +| Backend | `app/crud/production_task.py`、`app/crud/production_work_order.py`、`app/schemas/production_work_order.py` | +| Frontend | `useTaskStepEditor.ts`、`production-work-order/index.vue`、结论弹窗复用/抽取、`api/production-work-order.ts` | + +## 7. 测试要点 + +1. 任务有未完成步骤 → 完成任务并选结论 → 任务与全部步骤变 `ywc`,完成人/时间为当前用户。 +2. 任务步骤已全部完成 → 完成任务行为与改前一致(含结论写入)。 +3. 工单含 `dpz`/`dzx`/`jxz` 任务与未完成步骤 → 完成工单选「失败」→ 工单 `ywc`;上述任务均为 `ywc`+`sb`;步骤均为 `ywc`;已完成任务结论不变。 +4. 工单已完成 → 仍拒绝。 +5. 完成工单不传结论 → 400。 +6. 回归:单步执行/完成步骤、派发、我的生产任务执行弹窗仍可用。 + +## 8. 非目标回顾 + +- 不做前端循环调多接口的半成功方案 +- 不新建独立 force-complete API(方案 C) +- 不强制补全业务明细数据