bindbox-game/.claude/plan/gmv-payment-breakdown.md
2026-03-17 16:00:23 +08:00

4.1 KiB
Raw Permalink Blame History

实施计划GMV 支付方式拆分展示

需求分析

当前渠道统计只展示一个"累计实付金额"(GMV 总数),用户无法看到这笔钱的构成。需要拆分为:

  • 现金支付 (actual_amount) — 用户通过微信支付的真金白银
  • 优惠券抵扣 (discount_amount) — 优惠券抵扣部分
  • 积分抵扣 (points_amount) — 积分抵扣部分当前数据为0但字段已预留

验证:total_amount = actual_amount + discount_amount + points_amount 在所有订单上完全成立0条不等式

数据现状dev 环境)

支付方式 订单数 金额(元) 占比
GMV 总额 3,595 124,526.80 100%
现金 3,595 90,067.85 72.3%
优惠券 1,896 34,458.95 27.7%
积分 0 0.00 0%

技术方案

orders 表已有完整的拆分字段,无需新建表或字段,只需在查询和展示层增加维度。

实施步骤

Step 1: 后端 — 扩展数据结构

文件:internal/service/channel/channel.go

1.1 StatsOverview 结构体新增字段:

CashCents     int64 `json:"cash_cents"`     // 现金支付(分)
CouponCents   int64 `json:"coupon_cents"`   // 优惠券抵扣(分)
PointsCents   int64 `json:"points_cents"`   // 积分抵扣(分)

1.2 StatsDailyItem 结构体新增字段:

CashCents   int64 `json:"cash_cents"`
CouponCents int64 `json:"coupon_cents"`
PointsCents int64 `json:"points_cents"`

Step 2: 后端 — 修改 GMV 查询方法

文件:internal/service/channel/channel.go

2.1 calcGMVByTotalAmount 改为同时返回 actual_amount / discount_amount / points_amount 的分组统计:

type GMVBreakdown struct {
    Total    int64
    Cash     int64
    Coupon   int64
    Points   int64
}

func calcGMVByTotalAmount(...) (GMVBreakdown, map[string]GMVBreakdown)

查询 SELECT 增加:orders.actual_amount, orders.discount_amount, orders.points_amount

2.2 GetStats 方法中将拆分数据写入 Overview 和 Daily

out.Overview.CashCents = breakdown.Cash
out.Overview.CouponCents = breakdown.Coupon
out.Overview.PointsCents = breakdown.Points

Step 3: 后端 — List 接口也返回拆分数据(可选)

文件:internal/service/channel/channel.go

ChannelWithStat 结构体和 List 方法中的 GMV 查询也增加拆分统计,用于渠道列表页 tooltip 展示。

Step 4: 前端 — API 类型更新

文件:web/admin/src/api/channels.ts

interface StatsOverview {
  // ... existing fields
  cash_cents?: number
  coupon_cents?: number
  points_cents?: number
}

interface StatsDailyItem {
  // ... existing fields
  cash_cents?: number
  coupon_cents?: number
  points_cents?: number
}

Step 5: 前端 — Stats 概览卡片展示

文件:web/admin/src/views/operations/channels/index.vue

在"累计实付金额"卡片下方或旁边展示支付构成:

  • 显示 3 个子指标:现金 / 优惠券 / 积分
  • 各自显示金额和占比百分比
  • 积分为 0 时可隐藏或灰显

Step 6: 前端 — 每日趋势图支持

文件:web/admin/src/views/operations/channels/index.vue

在 revenue tab 的折线图中,可以选择查看:

  • GMV 总额(默认)
  • 现金 / 优惠券 / 积分 分层堆叠

Step 7: 测试

文件:internal/service/channel/channel_stats_test.go

更新测试用例,验证 GMV 拆分字段的正确性。

关键文件

文件 操作 说明
internal/service/channel/channel.go 修改 数据结构 + 查询逻辑
internal/service/channel/channel_stats_test.go 修改 测试覆盖拆分字段
web/admin/src/api/channels.ts 修改 API 类型定义
web/admin/src/views/operations/channels/index.vue 修改 概览卡片 + 图表展示

风险与缓解

风险 缓解措施
旧版前端未适配新字段 新字段均为可选,不影响旧版展示
积分字段当前全为0 字段预留,后续开启积分抵扣时自动生效
查询性能 无额外 JOIN只增加 3 个 SUM 列,影响可忽略