文件
hyb-oa/.trellis/tasks/09-04-approval-return-reject-actions/design.md
T

4.9 KiB
原始文件 Blame 文件历史

技术设计:审批退回驳回语义与动作布局

1. 决策

采用按实体区分的动作模型,不全局合并状态机:

  • 报销:新待办对客户端宣告 approve / return / transfer,不宣告 reject;界面文案为“通过 / 退回修改 / 转审”。
  • 请假、采购、差旅:保留 approve / reject / return;补卡保留 approve / reject。
  • 本任务只调整报销动作投影与报销 PC/移动布局;通用审批页仍消费其他四类实体的既有动作。

这不是把 reject 改名为 return,也不改写任何已存在的 outcome。新报销审批的修改诉求统一走原有 return 事务。

2. 服务端边界

在 listAllowedActionsForTask 中按实体产生对外 capability:

reimbursement       -> approve, return, [transfer]
attendance_correction -> approve, reject, [transfer]
leave/purchase/travel -> approve, reject, return, [transfer]

transfer 仍由既有权限决定。本任务不增加或删除审批权限。

兼容策略:

  • /workflow/tasks/:taskId/reject 与 /workflow/batch-reject 暂不删除,避免旧页面、离线队列或内部调用在同一版本中发生破坏性变化。
  • 新页面以 allowedActions 为可见能力来源,不为报销渲染 reject。
  • 既有 rejected 业务单、task、instance、history 和 notification 原样保留;报销 draft/rejected 的编辑与重提能力不变。
  • 不迁移数据库、不改 Prisma schema、不重写历史状态。

3. PC 报销动作区

默认态只保留一个紧凑动作组:

审批决定
────────────────────────
[      通过      ] [ 退回修改 ]
────────────────────────
转审
  • “通过”和“退回修改”同一行、同高;主按钮使用实心主色,退回使用次级描边。
  • 两列在右栏宽度内稳定铺满,不使用一个通栏按钮加若干内在宽度小按钮。
  • “转审”保持现有 ghost/低频区域,不恢复更多菜单,也不改变其能力条件。
  • 点击“退回修改”后才展开意见和引用清单;确认仍二次确认。
  • fail-closed 原因继续紧贴动作组上方;被阻断时通过、退回修改、转审全部禁用。

为避免影响共享组件的其他消费者,优先由 ReimbursementApprovalAdapter 注入一个报销专用 action-group 节点;不改变 BusinessDetailActionPanel 其他消费者的 DOM 顺序。

4. 移动报销动作区

默认 sticky action bar 改为两个直接动作:

[ 退回修改 ] [      通过      ]
  • 两个按钮均不小于 44px 高;通过保持主视觉,退回为次级样式。
  • 点击退回后,在正文动作卡中渐进展开意见、异常优先引用清单和确认动作。
  • 转审继续留在正文的低频处理区,不塞入 sticky 主动作组。
  • 离线报销继续全动作 fail-closed,不因本次减少按钮而开放离线退回或驳回。

5. 数据与历史

  • 新退回历史仍写 workflow_history.action=return、task outcome=returned、instance status=terminated、报销 status=draft。
  • 历史 rejected 报销仍显示“已驳回”,并可按既有规则修改重提。
  • 打印页、处理进度和审批历史继续同时认识 return/reject;不得因为新 UI 不再产生报销 reject 而删除历史映射。
  • 通知继续使用 reimbursement.returned;历史 reimbursement.rejected 类型保留。

6. 测试边界

  • 服务端:五类实体的 allowedActions 矩阵;报销新任务不含 reject,其他实体保持原样。
  • 报销 PC:默认动作区只有通过、退回修改、转审;无驳回按钮;两项核心动作同组;退回展开/引用/确认保持。
  • 报销移动:sticky 包含退回修改与通过;无驳回入口;离线全部禁用。
  • 兼容:历史 rejected 报销仍可编辑重提,history/print 显示不变;旧 reject endpoint 的既有测试继续通过。
  • 回归:请假、补卡、采购、差旅动作集合、确认文案和页面布局不变。

7. 风险与回滚

  • 风险:allowedActions fixture 广泛硬编码,需只修改报销 fixture,不能全局删除 reject。
  • 风险:移动通用审批页与报销专用工作台并存,必须验证报销路由最终只呈现一套动作。
  • 风险:旧 bundle 在切换窗口仍可能调用兼容 reject endpoint;因此首轮上线后仍可能出现少量新 rejected 历史,这是兼容期预期,不做数据修正。
  • 回滚:纯代码回滚即可恢复原动作投影和三按钮布局;无数据库回滚步骤。

8. 延后事项

  • 请假/采购/差旅 return 缺少结果通知类型与发送,是独立通知治理问题。
  • 是否最终退役报销 reject 与 batch-reject API,需在兼容期和调用审计后另立任务。
  • 转审是否隐藏或进入“更多”仍等待真实使用证据。