文件
hyb-oa/.trellis/tasks/09-08-reimbursement-payment-closeout/design.md
T

130 行
17 KiB
Markdown

# 业务闭环方案(规划,未实施)
## 2026-09-11 已批准备注增量
仅修改buildPaymentOrderRows的备注列,使用已验证且已trim的payeeName和entityCode拼成“姓名报销款 单号”。payeeName来自组批冻结的snapshot_json.payee.name;路由将归属人的收款信息冻结为payee,生成器不另查现职员工/提交人。每个batch item保持一行,即使姓名/收款账号相同也不合并。姓名或单号为空沿现有blockers整批拒绝。
不改模板列宽/格式、不缩写或截断、不引入未经银行证明的长度阈值。测试使用合成姓名,逐列xlrd读回用途、备注及文字类型,并证明同名两单独立对应、旧序号不重排。BX/PB编号规则本轮不改;编号说明以PRD最新节为准,不将日期前缀误当每日重置的证据。
## 1. 复用而非重建
现有入口是付款页面的待组批、付款批次、复核及“下载银行制单”。后端 POST /api/payment-batches/:id/payment-order 要求财务角色与 payment.order.export,批次 reviewed,完整且可用的同源收付款快照。生成成功会更新导出计数和审计;不能把这个 POST 当作生产只读预检。
代码入口:server/src/routes/paymentBatches.js、server/src/services/paymentOrderXls.js、server/src/scripts/fill-payment-order-template.py、client/src/pages/PaymentBatchesPage.tsx。历史范围见 archive/2026-08/08-02-corporate-bank-account-payment-order,本 task 不重开已完成实现。
## 2. 模板映射
| 列 | 模板字段 | 报销付款来源/行为 |
| --- | --- | --- |
| 1 | 序号 | 稳定排序的批次行号,文本 |
| 2–3 | 付款方账号/账户名称 | 复核批次冻结的公司付款账户 |
| 4 | 收款方行别代码 | CCB 本行固定文本 01,不生成他行 02 |
| 5–7 | 收款账号/名称/开户行名称 | 同一批次的收款快照 |
| 8 | 收款方联行号 | 沿现有本行制单合同留空 |
| 9 | 客户方流水号 | 批次号+行号,稳定、唯一并满足长度限制 |
| 10 | 金额 | 已批准批次项金额,数值且两位小数 |
| 11 | 用途 | 报销款,不复制工资/公积金用途 |
| 12 | 备注 | 冻结收款人姓名+“报销款 ”+完整报销单号(09-11已批准增量) |
| 13–15 | 短信标志/手机/附加信息 | 0、不通知,后两列空;不读样例手机号 |
用户三个 input 文档的表头完全一致,空白模板与内置模板相同,账号列为文本。检查原件只提取结构与摘要,原件不改、不重新保存、不复制真实行到测试夹具。工资及公积金样例仅用于确定文件格式,不暗中扩为新业务。
## 3. 两条业务线
A:0014 当前已审批待付款 → 核定归属/主体 → 管理员直接维护真实 CCB 收款资料 → 财务重查 readiness → 财务组批 → 独立付款复核 → 财务下载 .xls → 授权人员网银导入核对并付款 → 回单与实际结果匹配 → 系统登记。
B:三张 rejected → 本人逐张修改 → 本人重提 → 实际审批人处理 → 通过后进入下一批付款。不等 A 或 AP 发布;未通过不能直接放入付款批次。
## 4. 停止条件与授权
- 身份、单号、原值不一致,或收付款资料非 CCB:停止对应操作,不按名字/唯一主体猜值。
- 生产 legal_entity_id 修正:单人单字段、前置锁定和原值检查、条件写入、提交后独立回读;须单独授权。失败不自动反复重试,回退另批。
- 银行真实资料由管理员/获授权维护人直接在系统录入;不让财务通过聊天转交卡号给执行端。
- 解密/生成真实制单涉及敏感数据;按明确范围批准,只输出脱敏验收结果。正式下载由财务操作且保留审计,不用管理员或伪身份抵扣。
- 已存在批次、复核不通过、资料变动或旧快照缺失:核实实际状态,不删批次或改数据库状态绕过。是否重建批次另行决定。
- 银行导入失败、部分成功或回单未核对:不标全批成功,不因重下载重复付款。
## 5. AP 发布独立处理
AP task 保留原实施写入面和已通过用户复核。提交/推送后冻结包含 CEO 撤权的完整新 SHA,重新核对发布所需时效、回滚制品和生产漂移;旧 58dcee0 不再是正确候选。没有新发布授权就不部署,不能因业务急付款而默认豁免门禁。
## 6. 验证层级
1. 首轮规划完成静态源码与原件结构检查;用户追加技术审查/修复授权后运行定向合成测试,并在当前生产容器以独立合成密钥和纯合成资料验证制单运行环境。后者不访问数据库、不用真实密钥、不读取真实银行卡、不调用正式导出接口、不落制单文件。
2. 执行阶段先用合成收付款数据核验模板、BIFF8、金额与文本类型、未复核拒绝、非建行拒绝、重下载与审计、付款角色分离;已有测试能复用则不另造。
3. 获准核实生产模板摘要、Python/固定依赖等运行前提时,不顺手触发真实导出;代码基线存在功能不等于生产运行时可用。
4. 真实财务路径、银行导入结果与最终回单属于业务验收,合成测试不能抵扣;分别记录未执行/通过/阻断,不提前全绿。
## 7. 八角度复核与修订
| 角度 | 审查结论 | 处理 |
| --- | --- | --- |
| 业务优先级 | 已审批 0014 和退回三单是不同状态,不互等 | 维持两条业务线,不把 AP/门禁作为重提前置 |
| 角色职责 | 财务可制单不等于可改员工银行卡;admin 通配也不替代制单路由的财务角色要求 | 管理员录资料,真实财务组批/导出,非制单人复核;不加权限 |
| 资料与隐私 | 付款方账户已有,但个人收款资料和所属主体缺失仍是真实阻断 | 按原值另批补 0014 归属人,不批量关联 smoke;敏感资料不进聊天 |
| 财务操作顺序 | 当前详情页未制单先把上传回单作为主动作,下载藏在更多,与原银行制单合同及本轮顺序冲突 | 最小修复动作模型:首次下载→上传回单→登记完成;人工上传保留在更多,不添加硬门禁 |
| 格式兼容 | 原件和内置模板一致;既有测试只验文件头、行数、总额等,缺少独立逐列读回 | 新增 xlrd 对生成文件的表头、列宽、工作表、前导零文本、金额与用途/备注读回断言 |
| 运行环境 | 本地普通 Python 可能无 BIFF8 依赖,不能据此推断生产缺失 | 使用既有固定 venv;生产容器合成生成/独立读回 PASS,不安装新依赖,不改生产 |
| 失败与重试 | 下载有审计写入;导出不等于付款,网络失败后的重下载也不能重复银行划款 | 补下载原因/取消零请求、文件成功下载、重下载警示、失败不推进状态、手工回单入口测试 |
| 发布与实际付款 | 当前正确 AP 修订与本轮界面补丁都未部署;银行文件“验证”和真正导入可能不分离 | 新候选另批;只有网银明确支持不提交的校验模式才做真实文件格式校验,否则不为测试上传文件,实际付款须按业务批准办理 |
本轮界面修复仅改变已选付款详情的动作优先级,继续使用既有按钮/更多/移动端固定操作区,不重画页面、不调整角色、审批、付款状态机、数据快照或后台接口。保留现金/历史批次人工付款、已有回单直接登记及回单查询失败时不冒充空状态的行为。
报销主体和收款资料应在组批前补齐,因为批次冻结的是当时的账户快照;生成文件不能静默取之后变更的个人账号替换已复核快照。已有批次若需取消/重建,重新交审,不直接更新旧快照。
# 2026-09-09 后续主线综合方案(规划,非部署授权)
## 范围与归属
付款体验沿用本 task;退回单删除/历史可见性归 09-04-reimbursement-state-gap-finance-view;选票后自动生成明细与关联归 08-29-reimbursement-expense-policy-invoice-guard。用户已确认该默认操作取向,本轮按要求更新规划;撤回上一版正常路径的“待关联区→手工建明细→再关联”。验证随对应功能共同交付,不为每个按钮、测试或部署后检查新建 task,不启动 09-07 认证任务的历史批量迁移。各 task PRD 的同日增量是本次需求入口,本文组织跨任务依赖,不覆盖旧阶段事实。
当前生产已发布 b87cc55;用户确认付款复核及文件下载可用,尚无实际支付完成证据。原主工作树含其他未提交治理/状态差异,实施从最新已发布/已推送基线的干净独立副本开始;按官方 task current/start 对齐实际执行目录,已部署副本及冻结包不改。两个报销子项有共享文件,可在同一已批准的报销修复副本协调,但必须有各自验收和可审增量;付款变更单独副本,不能将路径隔离冒充文件不重叠。
## 第一批:报销录入与退回重建
先核实删除事务、workflow 历史、材料关系、占用/去重、查询投影及绑定接口,再完成最小设计补充。界面“删除退回单”,存储层保留历史,优先复用能表达该语义的已有机制;不得假定只有删除按钮变化或无需 schema。若发现必须迁移或实质扩大历史访问/数据修复范围,明确变更清单与回滚后再交审,不偷偷切状态掩盖删除。
退回原单修改重提保持可用;不再使用的单据确认删除后停止流转,解除合法发票的有效占用。软删除/取消历史如何读取、原附件如何保留、财务查询/待办如何排除均列入服务端合同。禁止把“可读历史”误扩成“可继续操作旧单”。撤回变 draft 但有历史的单据要单列,保护原审批留痕。
默认点击“添加发票”打开“我的发票”面板,选择可用旧票或上传新 PDF;新票自动腾讯 OCR,识别成功默认勾选且尊重用户取消。点击“添加到报销单”才触发一票一条可编辑明细并自动关联,多选批量生成;不是 OCR 完成就悄悄创建明细。票面价税合计、开票日期、项目说明作可编辑初值,类型仅可靠时推荐,不确定只补必要字段。用户无需再关联,正常明细仅显示发票数量/预览;手动关联仅保留为异常修复。已有明细入口则直接添加票到指定明细,不生成新明细或覆盖原值。允许提前存票,池和报销内使用同一数据来源。明细生成/票据占用原子完成,失败逐票解释、重试幂等;票据门禁仍严格。费用发生日期不能被开票日期无提示替代,不虚构缺失金额/类型;详细数据兼容与事务方案在发票 task 收敛。
## 第二批:付款下载与详情体验
后端输出中文文件名并使用兼容的 Content-Disposition 编码;前端解析中文 filename*,本地回退名一致,浏览器实测下载名而非只断言 toast。保持 BIFF8 模板、列顺序、格式、金额与批次内容不变,文件名不引入敏感资料。
制单接口单独调整原因合同,不放宽共享 REASON_SCHEMA。系统记录用途来源、操作者、批次、生成序次、成功/失败等必要审计;用户不填理由,不以固定文字假装用户说明。首次确认敏感文件用途,再次确认重复付款风险,权限/状态门禁与防双击保留。取消批次、查看完整账号、回单下载/作废的现有理由策略不在本轮改变。
只将 ProcessingProgress 移到付款页操作卡片下方,复用既有组件/样式,桌面与窄屏验证阅读和键盘顺序。本地未提供 frontend-design skill,不引入新视觉系统;不顺手改报销页壳或进行大文件重构。
## 验证先行,执行端负责
1. 实施前用合成数据复现空单添加发票和退回不能删除的原状,明确测试预期是新业务要求还是既有回归;先有可复现用例,避免按现状写出假绿。
2. 每个改动有单测/路由测试,状态、权限、并发、历史可见性有反例。单测可 mock,但证明业务闭环的端到端测试必须使用真实应用后端、隔离 PostgreSQL、附件存储与合法登录;不 mock 核心业务 API 后声称真实流程通过。
3. 使用专用合成申请人、审批人、财务,按角色分别登录操作。独立复核约束必须保留,不能全程拿 admin 通配抵扣角色验收。合成票据不得含真实银行资料;真实腾讯 OCR 自动识别是交付要求,关闭/误配属于异常,不再作为正常成功分支。需要获准样票和调用条件,缺条件时由执行端准备补齐方案,不能用 mock 或数据库 provider 标记冒充真实识别成功,不擅自改生产密钥或发真实票据。
4. 浏览器必跑空单→我的发票弹窗上传→自动 OCR→选新/旧票→自动生成明细并关联→刷新→核对/补必要项→提交→审批→独立付款复核→下载,以及提前存票、多选票、取消选择、已有明细多票、部分失败/重试/并发、退回修改重提、删除退回→释放发票→新单重用→提交。不允许测试夹具预造明细或手工补一次关联来掩盖默认路径失败。网银付款不自动执行,回单/付款登记仅在完全隔离测试环境使用明确标记的合成资料。
5. 桌面/窄屏核验右侧进度布局,实际下载文件名、BIFF8 结构及重复下载提示;截图/日志脱敏,不能输出真实票据、银行账号或凭证。
6. 涉及状态/权限/数据合同,需只读独立复核;inline 不能派 implement/check 代理,准备明确交审包,不能把主会话复测冒充独立复核。
## 发布与部署后验证合同
每批独立提交、集成验证、冻结候选;提交/推送/部署分别按明确授权执行。两批可以分别交付,不让付款的小优化必须等报销模型改造,但不能积压多批未提交差异。既有完整候选门禁仍有缺口,局部业务链全绿不等于完整候选全绿;发布资格按完整门禁或新的明确例外处理,旧 b87cc55 例外不复用。
上线前先确认可执行的部署后检查方式,不能部署完才发现没有测试账号。执行端负责公网版本/资源、权限、接口及浏览器验证,不把员工的日常业务操作当 QA。
生产写入验证必须先形成并获批测试数据清单:专用账户与角色、测试业务主数据/主体及付款资料、标记、允许接口、预期记录数、通知去向和收尾方式。能保证隔离才执行;专用账号本身不保证隔离,要防止真实审批派给员工、真实通知、预算/报表污染及测试制单流入网银。不改真实账号角色、不拿当前真人单据做删除/重提测试。
若生产无法安全隔离写入,先提供与候选同制品的隔离环境完整验证,再做公网只读/无副作用检查;明确生产写入链未验证,不声称等价,也不让员工补测。缺条件时执行端准备补齐方案,需新增权限或生产写入授权才向用户提出具体请求,不反复索取同范围许可。
每批回执分列:代码/本地单测/真实后端 E2E/独立复核/部署/公网验证/剩余缺口/下一动作。未执行、被环境阻断或失败均不能算通过。测试数据只按获批收尾规则处理,不能为清理测试痕迹物理删除审计或正式单据。
## 暂不扩展
不修改六个 view_all、不启用 R1/合同阶段 B、不逐条修 58 条、不实施通用软删除框架、不重构全部报销页面。统一待办投影是后续主线,本轮只保证本次删除/提交产生的待办正确更新;不以此另造待办引擎。错误豁免 10-05 到期事项沿原任务继续跟踪,不能因本轮反馈被遗忘或统一延期。生产磁盘已清理至足够余量的近期观测只是发布输入,下一次发布仍需检查时效,不追加清理。
# 2026-09-10 付款体验实施补记
- 制单接口使用专用可选原因合同;空对象有效,旧客户端的合法真实原因兼容,非法原因/未知字段仍拒绝。共享必填原因合同不变。
- 成功、重复和生成失败审计标明系统用途及来源;不以固定文本冒充用户原因。权限失败/请求校验失败沿既有位置拒绝,不虚报进入生成审计。
- 文件名使用现有安全 Content-Disposition 工具,UTF-8 中文名和 ASCII fallback;前端缺少响应文件名时使用批次号兜底,模板和二进制生成不变。
- 保留敏感文件确认、重下载警告、取消零请求与 pending 防重复点击。下载次数更新后主动作仍切换上传回单,不表示付款完成。
- 右侧操作卡与进度卡相邻;移动端保留底栏快捷动作且正文操作/进度可达。操作卡不独立 sticky,避免滚动覆盖紧随其后的进度。
- 验证:路由与 BIFF8 单测、mock 桌面/移动端真实下载、隔离 PostgreSQL/真实认证 HTTP 创建复核下载,再与退回删除做同候选验证;禁止真实网银付款和伪造回单。