167 lines
6.9 KiB
Markdown
167 lines
6.9 KiB
Markdown
# 结算后订单利润调整方案
|
||
|
||
## 1. 背景与目标
|
||
|
||
订单完成结算后,用户可能继续发生售后补偿、部分退款、号主收入修正等情况。需要在不破坏正式结算快照和历史资金流水的前提下,记录每次调整,并展示订单的最终实际收入和平台利润。
|
||
|
||
本方案针对正常租赁订单,提号订单已有类似实现,可复用其“追加调整流水”的思路。
|
||
|
||
## 2. 当前系统结算口径
|
||
|
||
- 正式结算基准使用最终结算记录 `order_checkouts` 的正式金额,不能使用发布价格、预计价格或订单初始价格。
|
||
- 号主正式收入为 `order_checkouts.owner_income_amount_cent`。
|
||
- 普通订单结算时通过 `wallet_ledger` 给号主入账。
|
||
- 平台代管订单结算时把待付号主金额记录在 `rental_orders.offline_settlement_amount_cent`。
|
||
- 订单过程留痕使用 `process_events`,管理员操作审计使用 `audit_logs`。
|
||
- 财务明细目前通过结算记录、号主钱包入账和平台代管线下结算金额计算平台净额。
|
||
|
||
相关代码:
|
||
|
||
- `backend/internal/modules/order/checkout_finalize.go`
|
||
- `backend/internal/modules/order/queries.go`
|
||
- `backend/internal/modules/adminfinance/detail.go`
|
||
- `backend/internal/model/order_checkout.go`
|
||
- `backend/internal/modules/pickup/repository.go`
|
||
|
||
## 3. 核心设计
|
||
|
||
不要修改原始结算记录、订单线下结算金额或已有钱包流水。新增不可变的订单财务调整流水:
|
||
|
||
```text
|
||
admin_order_financial_adjustments
|
||
```
|
||
|
||
建议字段:
|
||
|
||
```text
|
||
id
|
||
order_id
|
||
adjustment_no 唯一调整单号,用于幂等
|
||
settlement_mode owner_wallet / platform_managed
|
||
owner_income_delta_cent 号主收入调整,可正可负
|
||
renter_compensation_cent 本次租客补偿金额
|
||
compensation_bearer platform / owner
|
||
platform_profit_delta_cent 系统计算的利润变化,不允许前端直接填写
|
||
owner_settlement_status settled / pending / recovery_pending
|
||
renter_refund_status none / pending / refunded / failed
|
||
reason
|
||
reference_no 售后单号或外部凭证号
|
||
created_by
|
||
processed_by
|
||
processed_at
|
||
remark
|
||
created_at
|
||
```
|
||
|
||
最终结果按流水累计:
|
||
|
||
```text
|
||
最终号主收入 = 正式结算号主收入 + 所有有效 owner_income_delta_cent
|
||
最终租客退款 = 正式结算退款 + 所有已完成 renter_compensation_cent
|
||
最终平台利润 = 正式结算利润 + 所有 platform_profit_delta_cent
|
||
```
|
||
|
||
`platform_profit_delta_cent` 由服务端根据补偿承担方和号主收入变化自动计算,避免出现“号主收入、租客退款、平台利润”三者不一致。
|
||
|
||
## 4. 后台操作口径
|
||
|
||
后台输入“目标最终金额”,系统自动计算差额,不建议让客服手工输入差额:
|
||
|
||
1. 展示正式结算号主收入和当前实际号主收入。
|
||
2. 输入调整后的号主最终收入(可不调整)。
|
||
3. 输入本次售后补偿金额。
|
||
4. 选择补偿承担方:平台或号主。
|
||
5. 填写售后单号、原因和备注。
|
||
6. 提交前预览本次差额、最终号主收入、最终平台利润和待处理资金状态。
|
||
|
||
示例:正式号主收入 100 元,平台利润 20 元,售后补偿 3 元:
|
||
|
||
- 平台承担:号主仍为 100 元,平台利润减少 3 元。
|
||
- 号主承担:号主最终收入减少 3 元,并产生 3 元退款;平台利润原则上不变。
|
||
|
||
## 5. 资金处理
|
||
|
||
### 普通号主钱包订单
|
||
|
||
- 增加号主收入:在同一数据库事务中追加钱包入账流水。
|
||
- 减少号主收入:余额足够时追加钱包扣款流水。
|
||
- 余额不足:记录 `recovery_pending`,不能把钱包扣成负数,后续由财务处理追回。
|
||
- 平台承担租客补偿:提交支付退款任务,退款完成后再将调整标记为已处理。
|
||
|
||
### 平台代管订单
|
||
|
||
- 原线下款尚未支付:调整金额并入待打款任务,原始结算金额保持不变。
|
||
- 原线下款已支付:增加新的待补款或待追回任务。
|
||
- 不直接覆盖 `offline_settlement_amount_cent`,否则会丢失首次结算记录。
|
||
|
||
### 退款幂等
|
||
|
||
当前退款逻辑按订单和 `biz_type` 查找已有退款单。多次售后不能共用同一个退款业务键,应使用 `adjustment_no` 作为每次退款的唯一幂等键,并补充退款重试和失败状态。
|
||
|
||
## 6. API、权限与页面
|
||
|
||
建议接口:
|
||
|
||
```text
|
||
GET /admin/orders/:id/financial-adjustments
|
||
POST /admin/orders/:id/financial-adjustments
|
||
POST /admin/order-financial-adjustments/:id/settle
|
||
```
|
||
|
||
新增权限:
|
||
|
||
```text
|
||
order:financial_adjust
|
||
```
|
||
|
||
不建议复用订单关闭或标记异常权限。
|
||
|
||
订单详情的结算区域增加:
|
||
|
||
- 正式结算号主收入
|
||
- 售后调整合计
|
||
- 当前实际号主收入
|
||
- 正式退款与售后补偿
|
||
- 当前实际平台利润
|
||
- 调整流水、退款状态、补款/追回状态
|
||
- “新增售后补偿/修改利润”按钮
|
||
|
||
需要同步修改订单详情、财务明细、财务仪表盘和线下出款待办的聚合查询。
|
||
|
||
## 7. 状态与审计
|
||
|
||
号主资金和租客退款可能分别处于不同状态,因此不能只使用一个总状态。建议分别保存号主结算状态和租客退款状态,再由接口计算调整单的整体状态。
|
||
|
||
创建调整、钱包入账/扣款、退款任务创建、退款完成/失败、线下补款/追回确认,都要写入 `process_events` 和 `audit_logs`,并记录调整前后金额、操作人、原因和凭证号。
|
||
|
||
## 8. 测试范围
|
||
|
||
- 普通订单增加或减少号主收入。
|
||
- 钱包余额不足进入待追回。
|
||
- 平台代管未打款时调整。
|
||
- 平台代管已打款后补款或追回。
|
||
- 平台承担补偿与号主承担补偿。
|
||
- 退款失败、重试和重复请求幂等。
|
||
- 同一订单多次售后调整的累计结果。
|
||
- 正式结算记录和原始钱包流水不可被修改。
|
||
- 财务明细、仪表盘和出款待办金额一致。
|
||
|
||
## 9. 分支核查(2026-08-30)
|
||
|
||
- 当前 `main`:`98f6ee9`,包含最近的客服上传账号统计。
|
||
- 本地 `dev`:`85332df`。
|
||
- 远端 `gitea/dev`:`85332df`,与本地 `dev` 一致。
|
||
- `dev` 包含 `80e55ba 支持提号完成后财务调整`,相关实现位于 `admin_pickup_financial_adjustments`、提号仓库/服务和提号管理页面。
|
||
- `dev` 尚未包含正常租赁订单的结算后利润调整。
|
||
- `dev` 与 `main` 的共同基点为 `f48da14`;`dev` 有 1 个独有提交,`main` 有 49 个后续提交。不能直接整体合并 `dev`,如需保留其中的接口最小化和私有文件加固,应单独评审后再移植 `85332df`。
|
||
|
||
## 10. 实施顺序
|
||
|
||
1. 增加迁移和 `AdminOrderFinancialAdjustment` 模型。
|
||
2. 增加订单调整仓库、服务、接口、权限和审计。
|
||
3. 接入钱包、退款幂等键、平台代管补款/追回。
|
||
4. 修改订单详情和财务聚合查询。
|
||
5. 补齐普通订单、平台代管、余额不足、退款失败和重复调整测试。
|
||
|
||
实施前需要确认:补偿承担方规则、退款是否全部原路退回、以及是否统一采用“目标最终金额”输入。推荐采用本文方案。
|