fix: 优化报销制单下载与付款进度(09-08-reimbursement-payment-closeout)
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s

这个提交包含在:
2026-09-10 16:39:01 +08:00
父节点 73fcd5a65a
当前提交 fe025e65cf
共修改 15 个文件,包含 364 行新增和 42 行删除
+8 -1
查看文件
@@ -84,8 +84,15 @@ explicit deferred decision, not a completed scope restriction.
`payment_order_export_*` fields.
- Reveal APIs use `POST` with JSON `{ "reason": "2-500 chars" }`; ordinary read
APIs return only bank name and masked account.
- Payment-order API: `POST /api/payment-batches/:id/payment-order` with a reason;
- Payment-order API: `POST /api/payment-batches/:id/payment-order` with `{}`;
success is an in-memory BIFF8 `.xls` download with `Cache-Control: no-store`.
- Payment-order download confirms sensitive-file handling, but does not require
a typed reason. Re-download warns about duplicate bank import/payment.
Audit records system purpose `reimbursement_bank_transfer` with
`purposeSource: system`; optional legacy user reasons remain genuine input,
never fabricated. Account reveal, cancellation and receipt policies stay unchanged.
- Filename is `报销制单_<batchNo>.xls`, sent with RFC 5987 UTF-8 encoding and
ASCII fallback. No names, amounts or account numbers enter the filename.
- Runtime: Node passes validated row JSON through stdin to the fixed
`fill-payment-order-template.py`; the dedicated Python runtime returns BIFF8
bytes on stdout. `PAYMENT_ORDER_PYTHON_BIN` may select the fixed interpreter,