Supersede same-instance multi-round return and source-instance linking; document copy-form restart for returned, cancelled, and rejected. Co-authored-by: Cursor <cursoragent@cursor.com>
10 KiB
10 KiB
OA 审批进度展示与实例流转设计(钉钉对齐)
部分废止(2026-07-15)
打回「同实例多轮再提交」、进度「第 N 轮」、撤销/再提「关联旧单」等语义已改对齐钉钉:打回=本单终态;再办=复制表单开新实例(拒绝/撤销同)。
权威修订见:docs/superpowers/specs/2026-07-15-oa-return-copy-new-instance-design.md。
本文仍有效:P0 进度树序、拒绝≠打回文案、抄送排序、终态不展示未到达。
| 项 | 内容 |
|---|---|
| 状态 | 部分废止;树序进度仍有效(见上) |
| 日期 | 2026-07-15 |
| 范围 | web-admin 审批详情「审批进度」;拒绝 / 撤销 / 打回 的实例语义 |
| 权威对齐 | 钉钉 OA 审批详情(tasks + operation_records 思路) |
| 关联 | 2026-07-14-oa-approval-dingtalk-design.md(本文件修订其中「驳回 = 整单结束、V1 不做回退」——拆成「拒绝」与「打回」) |
1. 背景与问题
产品与研发对齐过程中发现两处易混:
- 进度排序:流程设计为「发起人 → 抄送 → 审批 → 结束」,详情曾因同秒创建任务、仅按
create_time排序导致抄送/审批颠倒。 - 打回 vs 拒绝 vs 撤销后再提:口语「打回」常被当成「拒绝结束」;实际上需要三套语义,且「同实例第二次提交」主要出现在打回路径。
本文件固定:实例怎么活 + 进度怎么画,并与钉钉主流体感对齐。
2. 目标
- 审批进度可读、可审计,与流程设计顺序在「同一轮」内一致。
- 明确拒绝 / 撤销 / 打回三种动作对实例生命周期的影响。
- 分阶段落地:先稳单轮 + 拒绝/撤销收尾;再做打回同实例多轮与撤销关联新单。
非目标(本文件不展开实现细节到接口字段级,留给实现计划):
- 转交、评论独立墙、代理人等钉钉全量操作类型的 UI 一一复刻。
- 小程序端进度 UI(语义同本章,交互另规)。
3. 三种动作(SHALL)
| 动作 | 操作者 | 本单命运 | 再次进入审批 | 钉钉类比 |
|---|---|---|---|---|
| 拒绝 | 审批人 | 结束(结果:已拒绝) | 只能新开实例 | 任务 REFUSE + 实例完结 |
| 撤销 | 发起人(受高级设置约束) | 终止(已撤销) | 新实例再提(可关联旧单) | TERMINATE;重提常带 biz_action=REVOKE / 附属实例 |
| 打回(退回) | 审批人 | 不结束 | 同一实例改表单后再次提交 | REDIRECT_PROCESS |
3.1 禁止混淆的表述
- 不得将「打回」实现为「拒绝结束」。
- 不得将「拒绝」实现为「退回发起人改单」。
- 「撤销后再提交」不是同实例复活(见 §3.2);「打回后再提交」才是同实例第二轮(见 §3.3)。
3.2 撤销 → 修改 → 再提交(钉钉思路)
实例 #1:… → 发起人撤销 → 状态终态「已撤销」
实例 #2:重新发起(新 instanceId)→ 可选关联 #1
- 列表:旧单「已撤销」,新单「审批中 / 已完成 …」。
- 详情:各自独立进度轴;新单详情可展示「由某某已撤销单重提」并跳转旧单。
- SHALL NOT 在已撤销实例上直接改状态为 running 并清空历史后重跑(避免审计与待办混乱)。
3.3 打回 → 修改 → 再提交(同实例多轮)
同一实例:
第 1 轮提交 → … → 审批人打回(附意见)
→ 发起人改表单 → 第 2 轮提交 → 按退回策略重走节点 …
- 进度轴保留第 1 轮记录,再追加第 2 轮,不得覆盖抹掉。
- 退回后中间已通过节点是否重审:默认与钉钉宜搭高级流程一致——需要重新审批(从退回目标之后的路径重走;V1 打回目标默认为「发起人 / 开始节点」)。若日后支持「退回到指定节点」,另开变更,默认仍「退回后至结束前节点重审」。
3.4 拒绝(打回≠拒绝)
- 当前审批人拒绝 → 实例进入终态「已拒绝」。
- 进度:拒绝节点结果 + 「流程结束(已拒绝)」;不得再展示后续未到达节点为待处理。
- 业务上若需继续办理:发起人新开一张审批(与旧单无强制引擎关联;产品可选「复制表单发起」属后续增强)。
4. 审批进度展示模型(SHALL)
对齐钉钉:对外一条时间轴,对内区分「流程快照感」与「操作/轮次事件」。
4.1 推荐模型:混合
| 层级 | 规则 |
|---|---|
| 轮次(大序) | 同一实例内按「提交轮 / 打回事件」分段或打标(第 1 轮、打回、第 2 轮…) |
| 轮内(小序) | 严格按该版本流程树设计节点顺序(抄送在审批前则展示在审批前) |
| 同节点多人 | 会签 / 或签 / 加签:一人一条结果,不合并成一条含糊节点 |
| 未到达 | 仅当前轮且实例 running 时可灰显「未到达」;终态(通过 / 拒绝 / 撤销)后不再挂未达节点 |
| 抄送 | 不阻断;创建即记入进度(知会),排序仍服从设计序 |
| 结束 | 通过 →「流程结束」;拒绝 →「流程结束(已拒绝)」;撤销 →「已撤销」(可不展示虚假「流程正常结束」) |
4.2 单轮 happy path 示意
发起人 · 张三 · 已提交 · t0
抄送人 · … · 已抄送 · t1 ← 设计在审批前则在上
审批人 · … · 待处理 / 已同意 · t2
(可选)后续节点 · 未到达
(全部通过后)流程结束
4.3 打回多轮示意
—— 第 1 轮 ——
发起人 · 已提交
审批人甲 · 已同意
审批人乙 · 打回(意见:请补充附件)
—— 第 2 轮 ——
发起人 · 再次提交
审批人甲 · 待处理 / …
…
4.4 撤销后再提(跨实例)示意
【实例 #1 详情】
… → 已撤销
【实例 #2 详情】
提示:本单由「实例 #1」撤销后重提
发起人 · 已提交
…
4.5 排序与数据权威
- 展示排序权威:流程树节点序(
node_key在 flow tree 先序/路径序中的位置)→ 同节点内order_num→create_time→id。 - 禁止仅依赖同秒精度的
create_time作为唯一排序键(会导致抄送/审批颠倒)。 - 新建任务时 SHALL 写入递增
order_num,便于同节点加签等场景稳定排序。 - 长期演进:可引入独立
operation_records(或等价事件表),与钉钉operation_records对齐;在引入前,允许由「实例事件 + oa_task」投影生成时间轴,但语义须符合本章。
4.6 与「发起页流程预览」的关系
- 发起页底部预览(见
2026-07-15-oa-start-flow-preview-design.md):提交前的预期链。 - 详情审批进度:提交后的实际发生 + 当前轮预期未达。
- 两者节点名与顺序在同一发布版本下应一致;条件分支以实际表单路径为准。
5. 分阶段落地
5.1 阶段 P0(当前可验收,不依赖打回引擎)
- 详情进度按流程树节点序排列任务(兼容历史
order_num=0同秒数据)。 - 时间轴含:发起人(已提交);任务节点;终态时 流程结束 / 已拒绝 / 已撤销。
- 拒绝、撤销行为保持:本单结束,无同实例第二轮。
- 撤销后再提:用户从发起入口新开实例(关联旧单可为 P1)。
5.2 阶段 P1(钉钉完整语义)
- 审批人操作拆分:同意 / 拒绝 / 打回(打回需意见;高级设置可开关)。
- 打回后:取消当前及后续未完成待办;实例进入「待发起人修改」类状态(命名实现时确定);发起人可改表单并再次提交;引擎按 §3.3 重走。
- 进度轴支持多轮展示(§4.3)。
- 撤销后重提:创建新实例时写入关联(如
oa_relation或实例字段prev_instance_id/biz_action=revoke_resubmit),双方详情可跳转。
5.3 与旧规格的关系
2026-07-14-oa-approval-dingtalk-design.md §5.2 原文:
结束:实例
completed/rejected(驳回策略:整单结束,V1 不做复杂回退多版本)
修订为:
- 「驳回」一词废弃;改为「拒绝 = 整单结束」。
- 「打回 = 同实例退回重提」列入 P1,不再用「V1 永不做回退」表述封死产品方向。
- P0 仍可不实现打回引擎,但产品文案与按钮不得把拒绝叫做打回。
6. 验收要点
P0
- 设计为「抄送 → 审批」时,详情进度在同秒创建下仍为抄送在上、审批在下。
- 进度首条为发起人已提交;拒绝/撤销/通过后有正确终态文案。
- 拒绝后列表与详情均为已结束,无法在同单再提交。
P1
- 打回后同实例可再次提交,轴上可见两轮提交与中间打回意见。(引擎+UI 已实现;需业务侧走查)
- 打回后中间已同意节点默认需重审。
- 撤销后重提为新
instanceId,可从新单跳到旧单。 - 拒绝与打回按钮/结果文案互不混用。
7. 决议记录
| 日期 | 决议 |
|---|---|
| 2026-07-15 | 按钉钉思路:拒绝结束本单;撤销后再提 = 新实例;打回 = 同实例再提交;进度 = 轮次时间轴 + 轮内设计序。 |
| 2026-07-15 | 未到达节点:进行中可展示;终态不展示(在混合模型中确认)。 |
| 2026-07-15 | 修订:打回改为终态 + 复制开新单;废止同实例多轮与旧单关联。见 2026-07-15-oa-return-copy-new-instance-design.md。 |
8. 开放问题(已在实现计划收口)
- 打回后实例状态 =
returned(待发起人修改再提交)。 - P1 打回目标 仅退回发起人(start)。
- 使用独立表
oa_instance_event(对齐钉钉 operation_records)。