Align with DingTalk: returned/rejected/cancelled are terminal; progress shows return on the approver task only; done list includes returned; deprecate same-instance resubmit and source-instance linking. Co-authored-by: Cursor <cursoragent@cursor.com>
3.9 KiB
OA 打回钉钉化:终态 + 复制开新单 Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 将打回改为本单终态;进度不再出现独立「打回」节点与多轮轴;已处理含打回;已打回/已撤销/已拒绝均可复制表单开新实例(无旧单关联)。
Architecture: 引擎侧修正 list_tasks/build_progress_items,废弃同实例 resubmit 与 source_instance_id 业务写入;前端统一「复制并重新发起」走 copyFromInstanceId 预填后 start。
Tech Stack: FastAPI / SQLAlchemy / Vue 3 / Element Plus;单测 backend/tests/test_oa_engine.py
Spec: docs/superpowers/specs/2026-07-15-oa-return-copy-new-instance-design.md
Task 1: 后端 — done 含 returned;progress 去重复打回节点;returned 终态收尾
Files:
-
Modify:
backend/app/services/oa_engine.py(list_tasks,build_progress_items,return_task注释) -
Modify:
backend/tests/test_oa_engine.py -
Step 1:
list_tasks的kind=="done"改为status.in_(("approved", "rejected", "returned")) -
Step 2:
build_progress_items:删除对returns_by_round/kind=return的追加;在终态分支增加returned→_terminal_item("returned", "已打回", inst);轮次循环可保留字段但前端不再标「第 N 轮」(引擎仍可只投当前已有任务) -
Step 3: 单测:
test_done_list_includes_returned:任务 status=returned 出现在 donetest_progress_return_no_duplicate_return_kind:task returned + return event 时 progress 无kind==return,仅有 task.status=returned,且有 terminal returned- 删除或改写
test_resubmit_starts_new_round为test_resubmit_raises_deprecated
-
Step 4:
pytest backend/tests/test_oa_engine.py -q通过后 commit
Task 2: 后端 — 废弃 resubmit;start 不再写关联;详情不回显关联
Files:
-
Modify:
backend/app/services/oa_engine.py(start_instance,get_instance_detail,resubmit_instance) -
Modify:
backend/app/api/oa_approval.py(resubmit 路由返回 410/业务错误或保留但引擎抛错) -
Step 1:
resubmit_instance改为直接raise OaEngineError("同实例再次提交已废弃,请复制表单重新发起") -
Step 2:
start_instance不再将source_instance_id写入实例(参数可忽略) -
Step 3:
get_instance_detail不再查/返回有意义的resubmittedInstanceId关联跳转(置空);sourceInstanceId恒返回空字符串(兼容前端字段) -
Step 4: 更新测试 + commit
Task 3: 前端 — 详情/列表/发起页
Files:
-
Modify:
web-admin/src/views/oa-approval/instances/detail.vue -
Modify:
web-admin/src/views/oa-approval/_placeholder/RuntimeList.vue -
Modify:
web-admin/src/views/oa-approval/start/index.vue -
Modify:
web-admin/src/api/oaApproval.ts(可选保留 fetchResubmit 不再使用) -
Step 1: 详情:
returned文案「已打回」;三种终态显示「复制并重新发起」→start?appId=©FromInstanceId=;去掉同单 resubmit、原单/重提单提示、轮次标题、kind===return标签 -
Step 2: RuntimeList:mine 在
returned|cancelled|rejected显示同一按钮;文案「已打回」;query 用copyFromInstanceId -
Step 3: start:读
copyFromInstanceId预填 formData;submit 不传sourceInstanceId -
Step 4: commit
Task 4: 验收勾选 + 图谱
- 勾选 spec §7 验收项(实现完成项)
./scripts/update-graph.sh backend(若改了 backend)- commit docs if needed
Self-review: Spec §3–§7 均有对应 Task;无 TBD;copyFromInstanceId 命名前后一致。