9.2 KiB
9.2 KiB
审批退回驳回语义与动作布局
Goal
基于系统真实后果而不是行业常识,厘清“退回”与“驳回”的实体差异;优先收敛唯一真实使用的报销审批链路,使审批人只面对必要动作,并修复当前“通栏主按钮 + 零散小按钮”的割裂布局。
Background
当前报销审批右栏把“通过”作为通栏主按钮,“退回”“驳回”作为下一行两个内在宽度按钮,“转审”再单独分组。该布局既失衡,也把两个对报销申请人后果近似的动作同时交给审批人判断。
报销现有“驳回”并未兑现通常意义上的终止:rejected 报销仍可在原单编辑并重提。因此移除报销审批端的“驳回”不损失已存在的终止能力,而是撤掉一个与真实后果不符的语义承诺。审批人若认为该笔费用根本不应申报,现阶段在退回意见中说明,申请人收到后可删除草稿;真正的审批人终止能力如有现实需求,必须另立状态机任务,不能继续借用名不副实的 reject。
只读核查确认五类实体不能全局合并:
| 实体 | 退回后 | 驳回后 | 后续能力 | 结论 |
|---|---|---|---|---|
| 报销 | 原单回 draft |
原单为 rejected |
两者均可在原单修改、重提,并创建新 workflow instance | 新审批只保留“退回修改” |
| 请假 | 原单回 draft |
原单为 rejected |
两者均可修改、重提并重新预留假期;但只有驳回发送结果通知 | 本次不改 |
| 补卡 | 不提供退回 | 原单为 rejected |
无原单编辑/重提 | 本次不改 |
| 采购 | 原单回 draft |
原单为 rejected |
只有退回后能修改、重提 | 两动作有实质差异,本次不改 |
| 差旅 | 原单回 draft |
原单为 rejected |
只有退回后能修改、重提 | 两动作有实质差异,本次不改 |
服务端证据与文件锚点见 research/return-reject-semantics.md。国内 OA 的通行叫法仅作为参考,目标口径由本系统状态、编辑/重提、通知和释放副作用共同决定。
Scope
- 按五类实体建立服务端动作矩阵,修改新报销待办的
allowedActions投影。 - 收敛报销 PC 与移动审批动作文案、分组和渐进展开方式。
- 增加服务端矩阵测试、报销 PC/移动交互测试和四类非报销回归。
- 保留历史状态与旧接口兼容,必要时同步审批规约和稳定工程 spec。
Requirements
R1:按实体投影动作
- 服务端
allowedActions必须按实体后果产生,不再默认给所有非补卡实体同一组动作。 - 新报销待办只宣告
approve / return,有既有转审权限时再宣告transfer;不再向 PC 或移动客户端宣告reject。 - 请假、采购、差旅继续宣告
approve / reject / return;补卡继续宣告approve / reject;各实体的转审仍沿用现有权限。
R2:报销只保留“退回修改”
- 报销审批界面将 return 展示为“退回修改”,继续调用既有 return 事务。
- 退回后必须保持:报销单回
draft、原单号保留、历史追加 returned、申请人可修改并重提、重提新建 workflow instance。 - 不得把 reject 改名后继续调用 reject,也不得把历史 rejected 重写为 returned。
R3:PC 动作布局收敛
- 报销 PC 右栏的“通过”和“退回修改”必须在同一个两列动作组中,同高、铺满可用宽度,以颜色和样式表达主次,不再使用一枚通栏按钮加零散小按钮。
- “转审”保持现有低频区域、权限和展开行为;不恢复“更多”菜单。
- 点击“退回修改”后才展开意见、异常优先引用清单与确认入口。
R4:移动动作布局收敛
- 报销移动端 sticky action bar 必须直接显示“退回修改”和“通过”,触控高度不小于 44px。
- 退回编辑内容在点击后渐进展开;转审继续留在低频处理区。
- 报销离线仍 fail-closed,不因减少一个按钮而开放任何远程审批动作。
R5:安全与解释不退化
- 不增加或删除现有
decisionReady、B1/B2、权限、自审批或内容完整性条件。 - fail-closed 原因继续紧邻动作组上方;被阻断时所有可见动作全部禁用。
- 通过、退回修改和转审继续使用现有二次确认、必填意见与审计规则。
R6:历史和接口兼容
- 既有 rejected 报销继续显示“已驳回”,仍按现有规则允许修改重提;打印、处理进度、审批历史和通知映射不得删除 reject。
- 本任务不迁移数据库、不修改 schema、不改写 task/instance/history/outcome。
- 旧单项 reject endpoint 和隐藏的 batch reject endpoint 作为兼容入口暂时保留,但不得新增或恢复任何报销可见入口;其最终退役另行立项。
R7:其他实体零行为变化
- 请假、补卡、采购、差旅的动作集合、状态写入、通知、释放逻辑、确认文案和页面布局本次不变。
- 请假/采购/差旅 return 缺少结果通知属于已识别既有缺口,另记待办,不在本任务顺手修复。
Acceptance Criteria
- AC1:服务端测试逐项证明 reimbursement=
approve,return[,transfer]、leave/purchase/travel=approve,reject,return[,transfer]、attendance_correction=approve,reject[,transfer];无权限或已处理任务仍返回空动作。 - AC2:报销 PC 和移动 fixture 的
allowedActions及可见 UI 均不含 reject;页面上“驳回”“确认驳回”按钮数为 0。 - AC3:PC 报销右栏“通过 / 退回修改”同处一个两列动作组、等高且无横向溢出;不存在旧的一通栏加两个小按钮布局。
- AC4:移动报销 sticky action bar 默认直接包含“退回修改 / 通过”,两者触控高度至少 44px;转审不进入该主动作组。
- AC5:展开退回修改前,意见输入和引用清单不存在;展开后意见必填、异常引用项优先、确认弹窗准确说明回到申请人修改态。
- AC6:任一现有 fail-closed 条件成立时,原因紧贴动作组上方,通过、退回修改、转审全部禁用;正常报销的可见动作不被误伤。
- AC7:执行退回修改后,服务端响应和持久化仍为 returned/draft;修改后重提创建新 workflow instance 并从重新匹配的首个可执行节点开始。
- AC8:历史 rejected 报销仍可读取、显示、编辑和重提;打印/时间线仍正确显示“驳回”,不发生数据迁移或历史改写。
- AC9:旧 reject endpoint 的既有兼容测试继续通过;产品 UI 和新
allowedActions不再为报销提供调用路径。 - AC10:请假、补卡、采购、差旅分别通过动作集合与确认流程回归;共享
BusinessDetailActionPanel的其他消费者 DOM 顺序不变。 - AC11:typecheck、build、相关后端测试、PC/移动 E2E、UI strict/self-test、process contract、Trellis governance 与
git diff --check全部通过。 - AC12:面向用户可测试前,需另行批准 push/部署,并通过公网 bundle、PC 1280px、移动端和五类审批回归。
Test Plan
- 服务端:五类实体
allowedActions矩阵、无权限/已处理负向分支、报销 return 状态与重提新实例、旧 reject endpoint 兼容。 - PC:报销两列动作组、无驳回入口、退回渐进展开、引用与确认、正常态及 fail-closed;四类通用审批动作回归。
- 移动:报销 sticky 双动作、44px 触控、离线 fail-closed、退回编辑;通用移动审批不受影响。
- 历史:rejected 报销读取、编辑、重提、打印和 timeline 映射不变。
- 门禁:前后端聚焦测试、typecheck/build、UI strict/self-test、process contract、Trellis governance、
git diff --check。
Out of Scope
- 删除 reject/batch-reject API、迁移或清理历史 rejected 数据。
- 调整请假、补卡、采购、差旅的动作语义或页面布局。
- 修复请假/采购/差旅 return 通知缺口。
- 新增退回上一节点、退回指定人或续接旧 workflow instance 的能力。
- B1/B2、审批链配置、权限模型、自审批规则和状态机的其他改造。
- 转审入口归属、全局按钮体系或其他页面视觉重构。
- 生产部署和真实数据写入。
Risks And Deferred Items
- 旧 bundle 在发布切换窗口仍可能调用兼容 reject endpoint,因此短暂兼容期内仍可能产生 rejected 报销;不自动修正此类历史。
- 采购和差旅页面存在“驳回后补材料”类文案与服务端只允许 draft 编辑之间的既有漂移,需独立任务处理,不混入本次报销收敛。
- 请假/采购/差旅 return 不发送结果通知;需按各模块实际使用优先级另行治理。
- 请假/采购/差旅 return 结果通知缺口应作为本任务之后的独立高优先级任务,优先于一般视觉和代码清理债;不得在本任务中夹带实现。
- 转审是否隐藏、保留或进入更多菜单,继续等待真实使用证据。
Planning Gate
本任务为复杂 workflow + UI 改动,design.md、implement.md 和研究记录已齐备。只有用户审批本版最终规划后,才可执行 task.py start 并修改产品代码。