文件
hyb-oa/.trellis/tasks/archive/2026-08/08-03-detail-page-structure-progress-actions/design.md
T

8.2 KiB
原始文件 Blame 文件历史

详情页结构统一与付款处理时间线设计

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 检查后才通知。
  • 下一笔制单是否进入网银由“存在明确仅校验步骤”决定;无该步骤时只执行离线验证和人工付款。