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

3.9 KiB
Raw Blame History

1. 数据库迁移

  • 1.1 创建迁移文件,在 tb_order_item 新增 cost_price BIGINT NOT NULL DEFAULT 0 字段
  • 1.2 创建迁移文件,在 tb_package_usage 新增 retail_amount BIGINT NULLABLE 字段
  • 1.3 在迁移文件中添加存量数据回填 SQLtb_package_usage.retail_amount 从关联订单 total_amount 回填(order_id != 0 的记录)
  • 1.4 执行迁移,验证两个字段已成功添加到数据库

2. 数据模型更新

  • 2.1 在 internal/model/order.goOrderItem 结构体中新增 CostPrice int64 字段GORM tag + 中文注释)
  • 2.2 在 internal/model/package.goPackageUsage 结构体中新增 RetailAmount *int64 字段GORM tag + 中文注释)
  • 2.3 在 internal/model/dto/asset_dto.goAssetPackageResponse 中新增 RetailAmount *int64 字段json tag retail_amount,omitempty + description

3. 修正 Admin 下单价格语义

  • 3.1 在 internal/service/order/service.go 中,修正各场景的 totalAmount 赋值:始终使用 retailTotalAmount,不再被 buyerTotalCost 覆盖(覆盖平台代购、代理自购、代理代购、平台代扣四个子场景)
  • 3.2 在 internal/service/order/service.go 中,修正 buildOrderItemsUnitPrice 改从零售价 map 取值,CostPrice 从成本价 map 取值(需同时传入两个 map
  • 3.3 在 internal/service/order/service.go 中,修正 createOrderWithWalletPayment:钱包扣款金额改用 order.ActualPaidAmount,不再使用 order.TotalAmount
  • 3.4 验证:通过 PostgreSQL MCP 查询新建的后台代购订单,确认 total_amount = 零售价,actual_paid_amount = 成本价,order_item.unit_price = 零售单价,order_item.cost_price = 成本单价

4. 修正套餐激活时的价格快照

  • 4.1 在 internal/service/order/service.goactivateMainPackage() 中,写入 PackageUsage.RetailAmount = order.TotalAmount
  • 4.2 在 internal/service/order/service.goactivateAddonPackage() 中,写入 PackageUsage.RetailAmount = order.TotalAmount
  • 4.3 在 internal/task/auto_purchase.goactivateMainPackage() 中,写入 PackageUsage.RetailAmount = order.TotalAmount
  • 4.4 在 internal/task/auto_purchase.goactivateAddonPackage() 中,写入 PackageUsage.RetailAmount = order.TotalAmount
  • 4.5 验证:通过 PostgreSQL MCP 查询新激活的套餐使用记录,确认 retail_amount = 零售价,paid_amount = 成本价

5. 资产套餐接口按角色过滤成本价

  • 5.1 修改 internal/service/asset/service.goGetPackages() 签名,新增 callerAccountType string 参数;当 callerAccountType != "platform" 时,AssetPackageResponse.PaidAmount 置为 nil
  • 5.2 修改 internal/service/asset/service.goGetCurrentPackage() 签名,新增 callerAccountType string 参数;同上过滤逻辑
  • 5.3 在两个方法中,将 PackageUsage.RetailAmount 赋值给 AssetPackageResponse.RetailAmount
  • 5.4 修改 internal/handler/admin/asset.goPackages() 方法:从 middleware 读取调用方账号类型,传入 GetPackages()
  • 5.5 修改 internal/handler/admin/asset.goCurrentPackage() 方法:从 middleware 读取调用方账号类型,传入 GetCurrentPackage()
  • 5.6 验证:用平台账号调用 /api/admin/assets/{identifier}/packages,确认响应包含 paid_amountretail_amount;用代理账号调用,确认响应只有 retail_amount,无 paid_amount

6. 验证 C 端订单价格展示

  • 6.1 通过 PostgreSQL MCP 查询一条后台代购订单,确认 total_amount 已为零售价(历史数据为成本价,已知;新建订单需运行时验证)
  • 6.2 调用 GET /api/c/v1/orders?identifier=xxx,确认列表中 total_amount 展示零售价
  • 6.3 调用 GET /api/c/v1/orders/:id,确认详情中 total_amount 和套餐 price 均为零售价