文件
hyb-oa/.trellis/tasks/archive/2026-10/09-02-reimbursement-readonly-content-consistency/design.md
T
wangsli和Claude Opus 5.5 b85ff6a9bf 归档 11 个已上线 Trellis 任务并补收口记录(09-17-company-loan-principal-repayment 任务整理)
- 报销一页式审批工作台父任务及 B-2a/B-2b/只读一致性子任务(AC11 依用户 2026-09-27 确认)
- 报销详情材料预览修复及其部署子任务(由候选 59dc5f6 发布覆盖,原步骤未执行,记录保留)
- 资产事前批准纠偏、Trellis 流程对齐、ERP 遗留精简、预算池并发、采购提交超时
- 各任务 prd 顶部新增收口记录,实现均包含于生产 4a5cd8f2;原未勾清单保留不补勾
- B 组与有真实待办的任务保持进行中

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 10:19:21 +08:00

5.1 KiB

Design:报销只读内容一致性与审批上下文收敛

1. Information Classification Contract

采用来源驱动的三分法,不按页面、区块位置或当前用户分类:

ReimbursementDeclaredContent(报销人申报)
├─ header / description
├─ expense items / authoritative total
├─ invoice and attachment facts
└─ declared project / travel association

ReimbursementProcessingContext(审批人或系统形成)
├─ expense-policy / budget snapshot
├─ invoice amount-evidence state / B2 result
├─ processing progress
├─ workflow history
└─ decision actions

ReimbursementArchiveMetadata(打印动作形成)
└─ QR code / printedAt / printedBy

字段是否出现在打印页不决定类别。打印页可以组合正文、处理上下文和归档元数据;三模式一致性只约束 ReimbursementDeclaredContent。

2. Workspace Model Boundary

保持 B-2b 的壳/适配器边界,不建立第二套页面模型。共享工作台模型增加一个明确的权威明细汇总投影,PC/移动语义组件都消费同一值:

type ReimbursementAmountSummary = {
  authoritativeTotalAmount: string | null;
  integrity: "ready" | "mismatch" | "unavailable";
};

authoritativeTotalAmount 只来自 reimbursement detail 的服务端 totalAmount。PC tfoot、移动汇总行和页头均格式化同一字段;任何页面或渲染组件不得用 items.reduce() 生成展示总额。

完整性判断只在共享模型构建边界执行一次。明细金额以严格十进制字符串解析为整数分后求和,仅生成 integrity,派生和不得暴露为第二个业务总额或参与提交。无法安全解析时使用 unavailable,不伪造 mismatch;服务端仍是业务权威。

3. Integrity Failure Behavior

  • ready:只显示普通合计,不显示说明。
  • mismatch:在明细合计附近显示“报销总额与明细汇总不一致,请联系管理员”,并作为 blocking issue 注入审批 readiness,使通过、退回、驳回、转审全部 fail-closed。
  • unavailable:保留服务端权威总额展示,同时说明“明细金额无法完整核对,请联系管理员”,并按既有“关键内容未就绪不得审批”合同 fail-closed;它不是 mismatch,也不得显示虚构差额。

异常不提供“修改总额”入口,不改变 B2 或服务端 recompute 合同。

4. Desktop and Mobile Amount Presentation

PC 在现有语义表格中使用真正的 <tfoot>,列跨度随 edit 操作列存在与否调整;标签为“明细合计”,金额单元格保持右对齐、tabular numerals,并通过 scope/可访问文本说明这是服务端权威总额。

移动端不模拟表格,在明细卡片组末尾渲染同一 ReimbursementAmountSummary 的汇总行。它与页头金额允许重复,因为两者分别服务“整单识别”和“逐条核对后的闭合”,但值与可访问名称必须一致。

5. Approval History Placement

PC approval 由适配器组合右栏内容,不让共享壳判断模式:

BusinessDetailAside
├─ sticky DecisionActionPanel
└─ WorkflowHistoryPanel

审批动作卡继续 sticky;历史卡位于动作之后但不并入 sticky 容器,避免 6 条历史或长意见改变动作可达性。PC 主列不再传 timeline。移动适配器继续把相同完整历史传入正文末尾,底部动作保持独立安全区。

不新增历史摘要,不截断最近一条意见,不保留主列隐藏副本。历史空状态仍可见,但不使用告警视觉。

6. Progress Versus History

ProcessingProgress 和 workflow timeline 不合并:

  • 普通详情的进度模型面向申请人,包含未来阶段、当前阶段和唯一付款批次入口。
  • 审批 timeline 面向处理人,只呈现已发生 workflow 事件及意见。

共享的是格式化与动作/状态语义,不强求同一 DOM。测试使用同一 workflow fixture 对照已发生事件,证明名称、人员、时间和结果不矛盾;未来阶段只允许出现在进度模型。

7. Print and Compatibility Boundary

打印页继续作为组合归档视图:明细合计仍直接显示服务端 totalAmount,审批记录和归档元数据保持现状。本任务不把打印页迁入工作台,也不删除它的审批记录。

不改 API、schema、migration 或状态机。现有 B2、材料查看审计、离线缓存白名单和 capability 注入全部保持。

8. UI/UX Constraints

沿用 ui-ux-pro-max 适用规则:使用语义表格元素;长历史意见可自然换行且不得溢出;异步内容预留稳定位置;金额采用本地化格式;异常不能只靠颜色。PC 1280px 无页面级横向滚动,移动 375px/横屏无内容遮挡,触控目标不小于 44×44。

9. Rollout Boundary

本设计经最新规划评审批准后可以进入实施,不再等待父任务 AC11。commit、push、部署继续使用独立批准门。部署后由 AC11 检查三项假设:财务是否认可明细区合计、右栏历史是否更利于决策、申请人是否混淆进度与审批历史;反馈若推翻方案,再以新事实开启修订,不现场扩 scope。