Appearance
财务结算中心实施计划
1. 交付目标
直接建立独立的新财务结算体系,完成卖家账单确认、平台对卖家结算和商店街卖家账单汇总。 未来实现必须从订单终态交接、物流费用、税务、退款终态、汇率等业务源事实生成新体系 订单快照和月度冻结账单,并为 seller/admin 页面及 Excel 导出提供同一份数据。数据表权威契约见 DATA_MODEL.md。
本计划只建设卖家结算。物流费用是卖家账单扣减项,物流数据是来源证据;不建设平台与 物流方之间的应收应付,不生成物流方独立账单、确认、付款、追偿、余额或结算状态。
首版进一步限定为契约设计阶段:只定义 dropship 订单域的 finance_ready_at、终态事实 交接和新财务数据模型,不扫描、回填、迁移或消费真实订单,也不生成生产账单数据。 异常订单专项契约见 ABNORMAL_ORDER_FINANCE_HANDOFF.md。
实施顺序固定为:新体系领域与 Seller API → Admin 领域与 API → Seller UI → Admin UI → 文档与验收。不要先做 mock 页面。旧 Finance V2 保持原状,新代码不得写旧财务派生表。
2. 已确定的技术契约
2.1 金额和时间
- 结算期为
Asia/Shanghai自然月,API 使用YYYY-MM。 - 订单域未来新增
finance_ready_at timestamptz null,作为进入财务的唯一时间。正常订单取order.completed_at原值,异常订单取权威异常处理完成时间;空值不得交接。 - 15 天保护期和异常终态完全属于订单域。财务不读取
buyer_signed_at/protection_ends_at计算资格,也不从派生页面状态、updated_at或当前时间推断异常完成。 - 财务归属期为
finance_ready_at所在Asia/Shanghai自然月,API 时间使用 ISO 8601。 - 业务金额为 TWD 主单位,数据库使用
numeric(20,2),API 返回两位小数字符串,服务端使用BigNumber计算。 - 汇率继续使用
numeric(24,12)和现有 Exchange Rate 服务;前端不得参与金额重算。 - 最终结算金额固定为:
商品收入 + 平台赔付 - 物流费用 - 平台扣点 - 税费 - 平台处罚 + 其他有符号调整。物流费用独立统计并参与一次扣减;若上游终态事实净额已含物流影响,必须拆分后核对,禁止重复扣减。 - 订单进入财务即冻结初始快照;终态禁止转换,交接后的纠正只使用调整或冲正。首版无 结算后退款链路,处罚和真实差异进入原未确认账单或之后最早的未确认结算期。
- 新财务边界固定为
2026-08-01 00:00:00 Asia/Shanghai;不清空或迁移旧 Finance V2 派生数据,仅从业务源事实生成 2026 年 8 月及未来的新体系数据。
2.2 状态
generation_status:generating | ready | failedseller_confirmation_status:unconfirmed | confirmedplatform_settlement_status:pending | settled- 卖家仅能执行
unconfirmed → confirmed,该动作冻结并认可账单。 - 平台仅能对卖家已确认账单执行
pending → settled;settled不可退回。 settled表示平台财务已经完成线下结算并人工确认,操作可填写备注。- 本期不建设
posted状态、发款台账或发款任务;实际付款与负余额处理在线下完成。 - 平台批量状态变更必须单事务全成或全败。
2.3 数据来源
| 账单字段 | 权威来源 |
|---|---|
| 订单及成交金额 | rt_order、rt_order_item,生成后冻结为 rt_settlement_snapshot* |
| 平台扣点、税费 | 正式费率/税务源事实,生成后冻结为 rt_settlement_snapshot_line |
| 物流费用、运单 | rt_shipment_cost、fulfillment/local order/tracking 数据 |
| 往期退款 | 首版不接入,页面与导出 Sheet 保留,汇总固定 0.00 |
| 平台处罚 | 本任务新增的处罚台账,不从 metadata 推断 |
| 卖家/店铺 | rt_tenant |
| 报关资料 | rt_shipment_document 中已存在且字段可验证的单据数据 |
| 广告、图片翻译、报关/供应商模板字段 | 当前无完整金额事实表;Admin 导出保留 Sheet 与表头,只能返回可追溯到卖家冻结账单的正式数据或空集,不计算物流方/供应商应付 |
3. 新体系数据库建设
T01. 建立订单财务事实层
按 DATA_MODEL.md 新建 rt_settlement_system_config、 rt_settlement_record、rt_settlement_blocker、rt_settlement_snapshot 和 rt_settlement_snapshot_line。实现状态、币种、金额精度、外币字段完整性、来源幂等、 租户隔离、FK 和索引约束。不得修改或写入旧 Finance V2 表。
首版只落实数据模型文档和独立新表设计,不修改 rt_order。后续订单域批次必须先审计 completed_at 的全部写入语义、持久化异常终态完成时间,再新增并维护 rt_order.finance_ready_at。该前置完成前不得启用真实财务交接。
B0 还必须落实异常专项前置:持久化四类异常终态;建立正式赔付审批事实与 Admin 赔付 操作契约;以事务或 outbox 防止普通完成和退款重复交接;正常/异常终态分别生成 buyer/seller 末端责任默认值,并提供带操作人、时间、原因和版本的异常责任改判;为 物流段、拦截结果和费用版本提供稳定来源。未发货取消、已发货取消、赔付、退款的时点、 最终责任人与金额不得在财务 service 中重新推断。
T02. 建立冻结账单与调整层
新建 rt_settlement_statement、rt_settlement_statement_order、 rt_settlement_adjustment 和 rt_settlement_statement_adjustment。三个账单状态轴独立; 订单快照和调整通过绑定表冻结;处罚、补贴、人工差异和冲正使用追加式调整,禁止原地改账。
T03. 建立审计层
新建 rt_settlement_statement_event。建表 migration 只能创建 rt_settlement_* 对象, 不含旧数据 INSERT ... SELECT、清空或回填脚本,也不创建 payout 表或发款状态机。
4. 后端实现
T04. 定义订单交接与账单生成器契约
- 定义未来独立 service,将生成流程拆成订单终态交接、证据校验、订单快照、调整项归集、账单绑定、 汇总计算、恒等校验和持久化;现有
generateMonthlyStatements不作为新体系写入口。 - 未来只选择
finance_ready_at IS NOT NULL且未交接的dropship订单;财务不得计算 15 天 或判断异常完成。正常值必须等于completed_at,异常值必须等于权威异常完成时间。 - 交接载荷必须包含租户、订单、
finance_ready_at、终态类型/版本、末端最终责任人及责任 来源版本、最终金额、正式跨境包裹实际重量和来源证据;订单快照冻结逐包裹整数克实际 重量、订单实际总重量及单独的 kg 计费重量; 幂等键固定为(order_id, finance_ready_at, source_version)。 dropship没有物流记录时物流费为0.00;存在但证据冲突时阻断。交接前退款完成的 订单由订单域交付商品收入和平台费0.00;末端责任默认卖家,授权改判为买家时末端费 扣0.00,其他已确认物流费和税费按各自规则处理。- 已发货取消按交接时已有事实先生成财务记录;后到物流费用使用
late_logistics幂等调整, 原账单未确认时追加绑定原账单,已确认时进入之后最早的未确认期;均不得修改初始快照。 - 首版不得启动每月任务、恢复任务、事件消费或真实账单生成;这里只定义未来行为和测试夹具。
- 同一卖家/期次在事务内加锁,并依赖唯一约束保证重复任务幂等。
rt_settlement_statement_order绑定 record 与 snapshot,rt_settlement_statement_adjustment绑定 adjustment;汇总必须从这些冻结绑定计算,不从 实时订单或旧财务快照重算。- 首版不创建
prior_refund调整;往期退款页面和 Sheet 仅保留待接入空结构。 - 生成结束前校验各分类合计和最终金额。失败写
generation_status=failed与明确原因,不产生可确认账单。 - 初始订单快照禁止刷新;交接后只有物流费用调整,不存在迟到订单或第二次初始交接。
T05. Seller API
新建 /api/seller/settlements 边界;验收期不复用旧 /api/seller/finance 路由,避免新旧 体系 ID 和状态混用:
| Method | Path | 行为 |
|---|---|---|
| GET | /monthly-statements | 按期次、卖家确认状态分页返回汇总 |
| GET | /monthly-statements/:id | 返回冻结汇总与分类计数 |
| POST | /monthly-statements/:id/confirm | 卖家不可逆确认;条件更新防并发 |
| GET | /monthly-statements/:id/export | 下载商家 4 Sheet Excel |
| GET | /monthly-statements/:id/orders | 订单结算明细分页 |
| GET | /monthly-statements/:id/shipments | 运单明细分页 |
| GET | /monthly-statements/:id/refunds | 往期退款明细分页 |
| GET | /monthly-statements/:id/penalties | 平台处罚明细分页 |
所有接口强制当前 tenant;跨租户 ID 返回 404。确认失败使用 409 invalid_statement_transition,生成失败账单不可确认或导出。
T06. Admin API 与 RBAC
新增 /api/admin/finance/settlement-statements:
| Method | Path | 行为 |
|---|---|---|
| GET | /settlement-statements | 按期次、tenant、两类状态分页查询 |
| GET | /settlement-statements/:id | 单店单期账单详情和事件 |
| PATCH | /settlement-statements/:id/platform-status | 单条更新 pending/settled,可附结算备注 |
| POST | /settlement-statements/platform-status/batch | 批量全事务更新,共用本次结算备注 |
| GET | /settlement-statements/:id/export | 下载单店 Admin 7 Sheet Excel |
| GET | /mall-settlements | 按期次聚合商店街结算 |
| GET | /mall-settlements/:period | 单期店铺下钻 |
| GET | /mall-settlements/:period/export | 下载当期平台汇总 Excel |
| POST | /penalties | 创建处罚台账 |
| POST | /penalties/:id/reverse | 追加式撤销处罚 |
权限键:
finance-settlement-statements:readfinance-settlement-statements:writefinance-mall-settlements:readfinance-settlement-exports:write
平台状态更新必须验证卖家已确认;批量请求包含无权限、未确认、错误状态或不存在记录时整体失败,并返回逐项失败原因。
服务端只在平台已完成线下结算并人工确认后写入 settled,拒绝任何 settled -> pending 请求并返回 409;可选备注随追加式事件审计,不触发发款或会计 posting。
T07. Excel 导出服务
- 使用后端现有
xlsx依赖,建立统一 workbook builder;不得从前端生成。 - 商家严格 4 Sheet,Admin 严格 7 Sheet,名称、顺序、表头逐列读取本目录模板落实。
- 空分类保留 Sheet 和表头;无正式来源的 Admin 扩展 Sheet 返回空数据,不生成示例行或推测金额。
- Admin 的
报关&商店街结算&供应商结算Sheet 只是固定模板组成;供应商或物流方侧 金额不得由卖家物流扣减额反推,没有卖家冻结账单内的正式字段时保持空列/空表头。 - 文件名
【period】结算账单_YYYYMMDDHHmmss.xlsx;冻结首行、金额两位小数、列宽可读。 - 导出数据全部来自同一冻结账单;导出事件写审计表。
5. 前端实现
T08. Seller 页面
在现有 /finance 下落地:
/finance/settlements:结算中心汇总、指标卡、期次筛选、确认、导出。/finance/order-settlements:订单结算中心。/finance/shipments:运单管理。/finance/prior-refunds:往期已结算订单退款。/finance/penalties:平台处罚明细。
验收期新增页面与旧 /finance/monthly-statements、/finance/income 并存,不重定向或删除旧 菜单。新页面筛选和分页进入 route search params;数据通过类型化 API + TanStack Query 获取;确认使用项目 Dialog 并说明不可撤销。正式菜单切换另案处理。
T09. Admin 页面
/finance/settlement-statements:结算汇总管理,支持单条/批量平台状态操作。/finance/mall-settlements:商店街按期汇总。/finance/mall-settlements/$period:店铺下钻明细。
新页面只使用冻结账单和平台结算状态。旧「全托管货款」和旧 payout task 在本任务中保持 原状;菜单切换及旧入口下线另案处理。新菜单权限统一写入 ADMIN_MENU_PERMISSION_TREE,不手改 routeTree.gen.ts。
市场口径订单筛选的运营中心菜单与接口迁移不在本期实现;本期只确保新财务页面和接口不返回该口径数据。
T10. UI 约束
- 参考两个 ZIP 的整体结构:页面标题/主操作、4 个左右指标卡、筛选条、表格、状态 Badge、分页;不做逐像素复刻。
- 复用
@ruten/ui的 Card、Table、Badge、Dialog、ListState、Pagination、PageSizeSelect、RTSelect、RTDatePicker。 - seller 保持中/繁双语,admin 保持英/中/繁三语。
- 所有数据页实现 loading、error、empty、success;mutation 期间禁用按钮,服务端错误保持可见。
- 375/768/1024px 验证响应式;宽表允许横向滚动,主操作在窄屏堆叠。
6. 测试与验收
T11. 后端测试
- 2026-08-01 切换边界、
finance_ready_at月份边界、包含物流扣减和有符号调整的金额公式、两位小数舍入和冻结快照恒等式。 - 跨境重量快照覆盖逐包裹实际克重、订单实际总重量求和、计费重量,以及预估重量不得 替代正式
SHIP_PACK_OUT重量。 - 交接契约覆盖
finance_ready_at=null、正常值等于completed_at、异常值等于正式异常完成 时间、异常终态缺失、重复版本、证据不完整和月份边界。 - 异常专项覆盖未发货取消全零、集货仓拦截、跨境中拦截、末端已发生、后到费用、物流 丢失赔付、交接前退款、普通完成/退款竞态、正常买家默认、异常卖家默认、交接前责任 改判、无实际末端费用为零及交接后责任纠正调整。
- 重复/并发生成只产生一张账单;失败事务不留下半成品。
- 退款终态必须在订单交接前完成;首版往期退款接口保持空集且账单退款汇总固定
0.00。 - 卖家确认幂等与跨租户隔离;已确认账单禁止刷新。
- 卖家不同意时保持
unconfirmed并线下沟通,不产生拒绝、争议或平台代确认状态。 - 平台不能结算未确认账单;批量操作全成或全败。
- 平台结算不可退回,不触发
posted或发款任务;零、正、负账单均只改变结算状态。 - 处罚创建、撤销、迟到入账和审计事件。
- 4/7 Sheet 名称、顺序、表头、空 Sheet、金额与账单一致。
- Admin RBAC、分页、查询参数清理、404/409 错误契约。
T12. 前端与交付验证
- seller 五页、admin 三页的四态、筛选、分页、详情、确认、批量操作和下载。
- 卖家不可见平台状态;运营账号不可见财务菜单;财务账号可见 Admin 两菜单。
- 新路由和新菜单无死链、生成路由树可更新;旧路由保持原状,不在本任务重定向。
- 执行后端定向 Jest 测试和 backend/seller/admin/docs build。
- 按仓库约束,本沙盒不启动 dev server,不执行会改写文件的 ESLint/TSX 检查;交付时报告未执行项并给出命令。
7. 可直接执行的工作批次
| 批次 | 任务 | 前置 | 完成定义 |
|---|---|---|---|
| D0 | 本轮文档契约收敛 | 无 | finance_ready_at、异常专项、终态交接、金额、状态和非范围文档一致 |
| B0 | 订单域交接前置 | D0、另行授权 | completed_at 审计、四类异常终态/完成时间、赔付事实、交接竞态与 finance_ready_at 实现及测试通过;不回填历史数据 |
| B1 | T01–T03 新体系 schema 与建表迁移 | B0、重新授权 | Drizzle schema、仅建新表的 migration、约束与隔离测试通过 |
| B2 | T04 生成器与调整项 | B1 | 核心金额、幂等、订单终态交接与调整测试通过 |
| B3 | T05 Seller API | B2 | tenant 隔离、确认、四类明细契约通过 |
| B4 | T06 Admin API/RBAC | B2 | 单条/批量/商店街/处罚契约通过 |
| B5 | T07 Excel | B3、B4 | 模板结构与金额自动化测试通过 |
| B6 | T08 Seller UI | B3、B5 | 五页与确认/下载验收通过 |
| B7 | T09–T10 Admin UI | B4、B5 | 三页与批量/下钻/下载验收通过 |
| B8 | T11–T12 文档、回归、下线清单 | B6、B7 | builds/tests 通过,新入口无死链,旧体系未被修改 |
本轮只执行 D0。一个开发代理每次只领取一个批次;禁止跨过失败的前置批次。B0、B1、 真实订单交接、生产迁移、数据清理或部署均必须另行取得用户明确授权。
8. 当前状态与立即执行
当前状态
- 两份 PRD、两份 Excel 模板、seller/admin UI 原型和现有 Finance V2 schema/API/UI 已完成核对。
- UI 只参考信息架构,不要求逐像素复刻。
- D0 文档契约及异常订单专项已收敛;尚未开始订单/财务业务代码、数据库迁移、真实数据处理、生产写入、 数据清理或部署。
下一步
- 完成本轮文档契约收敛,不修改订单或财务业务代码。
- 后续另立订单域前置任务:审计
completed_at、持久化异常完成时间、实现finance_ready_at,但仍不回填历史数据。 - 前置任务验证通过后,再重新授权 B1 新表实现和真实增量交接。
9. 已知风险与边界
- 广告、图片翻译、报关/供应商模板字段尚无完整正式金额来源;Admin 对应 Sheet 只能输出卖家冻结账单中的已验证数据或空表头,禁止从示例、metadata 或卖家物流扣减反推物流方/供应商应付。
- 现有
monthly_statement.status与confirmed_by/at表达 Admin 确认,新实现必须拆为生成、卖家确认和平台结算三条状态轴。 - Finance V2 已在生产使用;本任务不得修改、清理或迁移其派生数据。后续流量切换和旧体系 下线必须另立任务并取得生产授权。
- 平台
settled不可退回;真实金额差异只能进入后续期受控调整或追加式冲销。 - 原 Seller Finance V2 和跨境物流月结是历史事实与独立领域,不由本任务文档覆盖。
- 物流方结算是独立领域;即使来源数据包含物流商、运单和费用,也不得在本计划中扩展为 物流方账单、付款或结算状态。
- 当前异常订单状态为运行时派生,尚无权威异常处理完成时间;该来源未补齐前不能为异常 订单写入
finance_ready_at。
10. 实施技能路由与规划记录
auto-code:按 Seller 领域/API、Admin 领域/API、Seller UI、Admin UI 的顺序实施。api-docs:API 稳定后更新 seller/admin 财务契约、金额、状态、错误和导出说明。perfect-form-input:Admin 处罚录入及所有新增表单字段必须按表单规范实现。shadcn:复用现有组件和项目设计系统,不另建平行 UI 基础设施。- 2026-08-20:拉取 UI ZIP,完成 PRD、模板、代码和原型核对,形成 B1–B8 初版计划。
- 2026-08-21:明确物流费参与扣减、Admin 手工处罚、扩展 Sheet 空表头和运营迁移后置。
- 2026-08-22:裁决为直接建立独立新体系;不迁移、清空、回填或复用旧 Finance V2 派生 数据,新表统一使用
rt_settlement_*,旧体系下线另案处理。 - 2026-08-22:明确本期唯一结算对象为卖家;物流费仅作为卖家账单扣减和来源证据, 不单独核算物流方。
- 2026-08-23:订单域新增独立
finance_ready_at契约;正常订单取completed_at,异常订单 取权威异常处理完成时间。首版不接真实订单,不建设 posting、payout、状态回退或负额结转。 - 2026-08-23:单独建立异常订单进入财务专项,明确未发货取消全零、已发货取消先入账后 自动补物流调整、物流丢失以赔付收入替代商品收入、交接前退款和末端费用承担方边界。
- 2026-08-23:末端责任统一为正常终态默认买家、异常终态默认卖家;退款等人工处理流程 在异常交接前允许有审计地改判,财务冻结最终责任人并据此扣实际末端费用或扣
0.00。 - 2026-08-23:补充流程备注:退款因存在人工操作过程,可在完成前修改责任人;有末端 物流且未签收即取消为自动流程,默认卖家承担并直接交接,不预留人工修改时间。
- 2026-08-23:订单进入财务即冻结初始快照且异常终态禁止转换;后到物流只追加调整或 冲正。赔付仅使用 TWD 人工核准金额;合包订单按各订单自身重量独立计费;平台费分项 舍入后求和;
settled表示线下结算完成并允许记录备注。