8.2 KiB
详情页结构统一与付款处理时间线设计
1. 设计边界
本任务不合并报销 workflow 与付款批次状态机,只建立共享的只读付款阶段投影,并在两个业务视角中组装各自 DTO。数据库、付款写接口、权限和审计均保持不变。
前端复用现有详情工作区、时间线、固定底栏、确认弹窗和按钮组件。项目声明的 frontend-design skill 当前不可用,本轮不发明新的视觉体系;规划阶段已使用可用的 ui-ux-pro-max 检查 sticky 遮挡、异步反馈、派生状态和移动端安全区原则,最终以仓库既有成熟详情模式为实现依据。
2. 服务端共享语义层
新增一个无数据库依赖的付款进度服务模块,例如 server/src/services/paymentProcessingProgress.js。模块导出:
- 唯一的阶段定义:
payment_batch_created / 批次创建、payment_batch_review / 付款复核、payment_and_receipt / 付款完成。 - 唯一状态集合:
completed | current | pending | exception | terminated。 buildPaymentProcessingSemantics(input):输入批次状态、复核/执行/取消时间、取消原因、requiresBankReceipt、回单数和制单次数,返回三个阶段的 state、result、detail、comment、actorSource 与 occurredAt。
actorSource 只使用 creator/reviewer/executor/canceller 这类内部语义引用,不在共享层查询姓名,也不产生页面链接。状态矩阵:
| 批次事实 | 批次创建 | 付款复核 | 付款完成 |
|---|---|---|---|
| draft | completed | current | pending |
| reviewed,需要回单、无回单、未制单 | completed | completed | current:等待线下付款并上传回单 |
| reviewed,需要回单、无回单、已制单 | completed | completed | current:已生成制单,等待付款并上传回单 |
| reviewed,需要回单、已有回单 | completed | completed | current:等待登记付款完成 |
| reviewed,不需要回单 | completed | completed | current:等待登记付款完成 |
| executed | completed | completed | completed |
| failed | completed | completed | exception |
cancelled,reviewedAt=null |
completed | exception(取消) | terminated |
cancelled,reviewedAt!=null |
completed | completed | exception(取消) |
取消节点使用取消人、取消时间与原因;失败节点使用最后执行人和执行时间。语义函数不猜测缺失人员,时间戳缺失时保持 null。
requiresBankReceipt 必须复用付款执行门禁的渠道判断:只要仍待处理/失败的批次项中存在有效付款渠道为 bank 的项目即为 true。路由不得为时间线再发明一套渠道判断;最小实现是提取并共享现有 requiresBankReceipt 计算函数。只有该值为 true 时,制单次数才参与阶段文案。
3. 两个视图组装层
3.1 报销详情
buildProcessingProgress 继续组装提交与真实 workflow task。付款部分调用共享语义函数并只选择 payment_batch_review、payment_and_receipt:
- 通过已有
paymentActorNames把 actorSource 对应 ID 解析为姓名。 - 按现有权限决定
targetHref。 - 无付款批次时保留“待财务安排付款”的报销专属投影。
- 历史
paid且无批次时继续用报销paid_by/paid_at完成最后阶段。
报销组装层不得重新按 batch status 写 switch/if;批次存在时的 state、result 和基础 detail 一律来自共享语义。
3.2 付款批次详情
付款批次详情 DTO 新增 processingProgress.stages[],使用共享语义的三个阶段:
mapBatch列表响应保持轻量,不额外查姓名。mapBatchForResponse仅为详情及写操作返回结果收集 created/reviewed/executed/cancelled actor ID,以一次employee.findMany解析姓名,然后组装 progress。- API 类型拆成列表基础类型与带必需
processingProgress的详情类型,避免把详情字段伪装成所有列表项都存在。 - progress 只含姓名和时间,不增加员工号、角色、账号、快照或相邻批次信息。
服务端结构测试直接导入共享阶段定义/构建器,并验证两个路由没有各自状态矩阵,防止未来再次分叉。
4. 共享时间线组件
将 ReimbursementProcessingProgress 改名并移动到共享 patterns/common 目录,例如 ProcessingProgress.tsx。保持单个 stages.map:
- 组件自带通用
ProcessingStage/ProcessingProgress类型,报销与付款 API 类型复用或结构兼容。 - props 参数化
ariaLabel、testId、mobile与目标链接文案;报销仍显示“查看所在付款批次”,付款批次本身不生成自指链接。 - 新增 terminated 的中性图标、灰色连接/节点与“已终止”,不使用红色异常或绿色完成视觉。
- current/exception/comment 继续展开 detail;pending/terminated 不显示会误导为下一步的说明。
5. 页面结构
5.1 报销 PC
- hero 仅保留标题和状态;现有 primary/secondary business actions 迁入右侧
BusinessDetailActionPanel。 BusinessDetailMain顺序为概况、处理进度、明细、材料。BusinessDetailAside承载一个操作面板;提交、打印、催办、撤回、删除等继续使用现有权限、mutation 和确认逻辑。- 删除
ReimbursementActions的独立卡片实现及三个进度锚点;不复制动作。
5.2 报销移动端
只移动现有处理进度 section 到概况后;明细、材料随后,底部操作 section 与现有固定提交栏保持末尾/safe-area 合同。
5.3 付款批次响应式详情
BusinessDetailMain为概况、处理进度、明细、回单;旧payment-batch-current-processing事实卡删除。BusinessDetailAside在lg+显示BusinessDetailActionPanel。- 同一
paymentActionModel从权限、批次状态、制单次数、回单查询和 mutation 状态派生唯一 primary、secondary、more action;PC 面板和移动端只负责渲染。 <lg使用现有mobile-sticky-action-surface:一个 primary,其他动作进入“更多”。有固定栏时给页面增加安全底部 padding;无可执行动作时不渲染空栏。- 上传回单后通过既有 query 刷新让 action model 从“上传银行回单”切到“登记付款完成”。持续可见操作区就是就近入口;回单 section 不再额外复制一个同名按钮。
6. 共享断点
把 detail-workspace-grid 的双栏断点与 BusinessDetailActionPanel sticky 同步从 xl 降到 lg;同步清理 WorkflowTaskDetailPage 的 xl:top-* 覆盖,避免同一组件存在冲突断点。
回归 AssetRegistryPage 与 WorkflowTaskDetailPage:右栏最小宽度、焦点菜单 z-index、sticky top offset 和页面滚动均不得回退。sticky 元素不设置超过视口的固定高度,不能遮挡主内容或底部操作。
7. 测试与验收数据
- 纯函数表驱动测试锁定五状态、取消时间戳分支、需要/不需要回单、制单/回单文案和 actorSource。
- 报销路由保留既有动态 workflow task 测试并将五种 batch 状态期望改为共享语义。
- 付款批次详情路由测试断言三阶段、actor name/time、无敏感字段;列表不额外依赖 progress。
- Playwright 通过 synthetic API fixtures 覆盖五状态,不写生产数据;断言每个 viewport 只有一个可见主操作而非全 DOM 只有一个按钮。
- 报销动作 E2E 逐项覆盖:draft 提交与删除、reviewing 催办与撤回、paid 打印,并核对权限隐藏、原因/确认交互、mutation 请求及刷新后的状态;操作区迁移不能降低既有写操作证据强度。
- 生产验收只观察真实存在的 draft/reviewed;后三态无真实数据是已知限制,不阻塞交付。
8. 兼容、发布与回滚
- API 是加字段的向后兼容变化,无迁移;旧前端忽略 progress,新前端部署必须与新增 DTO 同批发布。
- 回滚只需恢复旧路由投影与页面布局,付款写状态和数据不受影响。
- 面向用户测试仍需单独批准部署,跑标准聚合体检、公网构建标识/ready 检查后才通知。
- 下一笔制单是否进入网银由“存在明确仅校验步骤”决定;无该步骤时只执行离线验证和人工付款。