2026-07-15-oa-approval-progress-timeline-design.md 10.0 KB

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. 背景与问题

产品与研发对齐过程中发现两处易混:

  1. 进度排序:流程设计为「发起人 → 抄送 → 审批 → 结束」,详情曾因同秒创建任务、仅按 create_time 排序导致抄送/审批颠倒。
  2. 打回 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(当前可验收,不依赖打回引擎)

  1. 详情进度按流程树节点序排列任务(兼容历史 order_num=0 同秒数据)。
  2. 时间轴含:发起人(已提交);任务节点;终态时 流程结束 / 已拒绝 / 已撤销。
  3. 拒绝、撤销行为保持:本单结束,无同实例第二轮。
  4. 撤销后再提:用户从发起入口新开实例(关联旧单可为 P1)。

5.2 阶段 P1(钉钉完整语义)

  1. 审批人操作拆分:同意 / 拒绝 / 打回(打回需意见;高级设置可开关)。
  2. 打回后:取消当前及后续未完成待办;实例进入「待发起人修改」类状态(命名实现时确定);发起人可改表单并再次提交;引擎按 §3.3 重走。
  3. 进度轴支持多轮展示(§4.3)。
  4. 撤销后重提:创建新实例时写入关联(如 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. 开放问题(已在实现计划收口)

  1. 打回后实例状态 = returned(待发起人修改再提交)。
  2. P1 打回目标 仅退回发起人(start)。
  3. 使用独立表 oa_instance_event(对齐钉钉 operation_records)。