Files
junhong_cmp_fiber/openspec/changes/fix-order-price-semantics/proposal.md
Break 944526d9ef
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m17s
修复订单金额落库不对的问题
2026-06-01 11:21:29 +08:00

2.8 KiB
Raw Blame History

Why

后台代购/钱包支付场景下,Order.TotalAmount 被覆盖为成本价,导致 C 端订单列表和详情展示的是成本价(甚至 0 元),而非客户应看到的零售售价。同时,/api/admin/assets/{identifier}/packages/api/admin/assets/{identifier}/current-package 两个接口的套餐价格字段(paid_amount)对所有后台账号一视同仁地返回成本价,非平台账号(代理商)不应看到平台进货成本。

What Changes

  • 修正 Order.TotalAmount 语义:始终存储零售价(客户面值),不再被成本价覆盖
  • 修正 Order.ActualPaidAmount 语义:存储实际支付的成本价,钱包扣款改用此字段
  • 新增 OrderItem.CostPrice 字段:在 tb_order_item 存储成本单价快照,零售单价保留在 UnitPrice
  • 新增 PackageUsage.RetailAmount 字段:在 tb_package_usage 快照零售价,来源为 order.TotalAmount;现有 PaidAmount 继续快照成本价(来源为 order.ActualPaidAmount
  • 资产套餐接口按角色过滤/packages/current-package 对非平台账号隐藏 paid_amount(成本价),仅返回 retail_amount(零售价);平台账号两个字段均返回

Capabilities

New Capabilities

无新增 Capability。

Modified Capabilities

  • admin-order-creationTotalAmount 语义修正为零售价;新增 OrderItem.CostPrice 字段;钱包扣款改用 ActualPaidAmount
  • client-order-purchaseC 端订单列表/详情的 total_amount 和套餐 price 字段改为展示零售价
  • package-usage-paid-amount-snapshot:新增 RetailAmount 字段快照零售价;PaidAmount 继续快照成本价;资产套餐接口按调用方角色决定是否返回 paid_amount

Impact

数据库

  • tb_order_item 新增 cost_price BIGINT NOT NULL DEFAULT 0
  • tb_package_usage 新增 retail_amount BIGINT NULLABLE

代码

  • internal/service/order/service.goadmin 下单逻辑中 totalAmount 始终用零售价,成本价只写 ActualPaidAmountOrderItem.CostPrice;钱包扣款改用 ActualPaidAmount
  • internal/service/order/service.go:套餐激活时同步写入 PackageUsage.RetailAmount
  • internal/task/auto_purchase.go:同步写入 PackageUsage.RetailAmount
  • internal/service/asset/service.goGetPackages / GetCurrentPackage 接收调用方账号类型参数,按角色决定是否返回 paid_amount
  • internal/handler/admin/asset.go:传入调用方账号类型
  • internal/model/dto/asset_dto.goAssetPackageResponse 新增 RetailAmount 字段
  • internal/model/order.goOrderItem 新增 CostPrice 字段
  • internal/model/package.goPackageUsage 新增 RetailAmount 字段

迁移:需要两条迁移 SQL 回填存量数据