bindbox-game/cmd/channel_stats_compare/profit_loss_query.go
2026-03-17 16:00:23 +08:00

148 lines
6.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//go:build ignore
package main
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func main() {
dsn := "root:bindbox2025kdy@tcp(150.158.78.154:3306)/dev_game?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
fmt.Println("连接失败:", err)
return
}
filter := "users.deleted_at IS NULL AND orders.status = 2 AND orders.total_amount > 0 AND orders.actual_amount > 0 AND orders.source_type IN (2,3,4) AND (orders.ext_order_id = '' OR orders.ext_order_id IS NULL)"
// 1. 各字段使用分布
type FieldStats struct {
Label string
Count int64
Sum int64
}
fmt.Println("========== GMV 支付方式拆分数据探查 ==========")
fmt.Println()
// actual_amount (现金)
var cash FieldStats
db.Table("orders").Joins("JOIN users ON users.id = orders.user_id").
Select("'现金(actual_amount)' as label, COUNT(*) as count, COALESCE(SUM(actual_amount),0) as sum").
Where(filter).Scan(&cash)
// discount_amount (优惠券)
var coupon FieldStats
db.Table("orders").Joins("JOIN users ON users.id = orders.user_id").
Select("'优惠券(discount_amount)' as label, COUNT(*) as count, COALESCE(SUM(discount_amount),0) as sum").
Where(filter + " AND discount_amount > 0").Scan(&coupon)
// points_amount (积分)
var points FieldStats
db.Table("orders").Joins("JOIN users ON users.id = orders.user_id").
Select("'积分(points_amount)' as label, COUNT(*) as count, COALESCE(SUM(points_amount),0) as sum").
Where(filter + " AND points_amount > 0").Scan(&points)
// 道具卡 (item_card_id > 0)
var itemCard FieldStats
db.Table("orders").Joins("JOIN users ON users.id = orders.user_id").
Select("'道具卡(item_card_id)' as label, COUNT(*) as count, 0 as sum").
Where(filter + " AND item_card_id > 0").Scan(&itemCard)
// 总 GMV
var totalGMV FieldStats
db.Table("orders").Joins("JOIN users ON users.id = orders.user_id").
Select("'总GMV(total_amount)' as label, COUNT(*) as count, COALESCE(SUM(total_amount),0) as sum").
Where(filter).Scan(&totalGMV)
fmt.Printf("%-25s %8s %14s\n", "字段", "订单数", "金额(元)")
fmt.Println("--------------------------------------------------")
for _, f := range []FieldStats{totalGMV, cash, coupon, points, itemCard} {
fmt.Printf("%-25s %8d %14.2f\n", f.Label, f.Count, float64(f.Sum)/100)
}
// 2. 验证: total = actual + discount + points ?
fmt.Println()
fmt.Println("========== 验证: total_amount = actual + discount + points ? ==========")
type MismatchRow struct {
Count int64
}
var mismatch MismatchRow
db.Table("orders").Joins("JOIN users ON users.id = orders.user_id").
Select("COUNT(*) as count").
Where(filter + " AND total_amount != (actual_amount + discount_amount + points_amount)").
Scan(&mismatch)
fmt.Printf(" 不等式成立的订单数: %d\n", mismatch.Count)
if mismatch.Count > 0 {
type DetailRow struct {
ID int64
TotalAmount int64
ActualAmount int64
DiscountAmount int64
PointsAmount int64
Diff int64
}
var details []DetailRow
db.Table("orders").Joins("JOIN users ON users.id = orders.user_id").
Select("orders.id, orders.total_amount, orders.actual_amount, orders.discount_amount, orders.points_amount, (orders.total_amount - orders.actual_amount - orders.discount_amount - orders.points_amount) as diff").
Where(filter + " AND total_amount != (actual_amount + discount_amount + points_amount)").
Limit(5).Scan(&details)
fmt.Println(" 抽样:")
for _, d := range details {
fmt.Printf(" #%d total=%d actual=%d discount=%d points=%d diff=%d\n",
d.ID, d.TotalAmount, d.ActualAmount, d.DiscountAmount, d.PointsAmount, d.Diff)
}
}
// 3. 次卡购买订单的支付方式拆分
fmt.Println()
fmt.Println("========== source_type=4 购买次卡的支付方式 ==========")
var gpCash, gpCoupon, gpPoints FieldStats
gpFilter := "users.deleted_at IS NULL AND orders.status = 2 AND orders.total_amount > 0 AND orders.actual_amount > 0 AND orders.source_type = 4 AND orders.order_no LIKE 'GP%' AND (orders.ext_order_id = '' OR orders.ext_order_id IS NULL)"
db.Table("orders").Joins("JOIN users ON users.id = orders.user_id").
Select("'现金' as label, COUNT(*) as count, COALESCE(SUM(actual_amount),0) as sum").
Where(gpFilter).Scan(&gpCash)
db.Table("orders").Joins("JOIN users ON users.id = orders.user_id").
Select("'优惠券' as label, COUNT(*) as count, COALESCE(SUM(discount_amount),0) as sum").
Where(gpFilter + " AND discount_amount > 0").Scan(&gpCoupon)
db.Table("orders").Joins("JOIN users ON users.id = orders.user_id").
Select("'积分' as label, COUNT(*) as count, COALESCE(SUM(points_amount),0) as sum").
Where(gpFilter + " AND points_amount > 0").Scan(&gpPoints)
fmt.Printf(" 现金: %d单 %.2f元\n", gpCash.Count, float64(gpCash.Sum)/100)
fmt.Printf(" 优惠券: %d单 %.2f元\n", gpCoupon.Count, float64(gpCoupon.Sum)/100)
fmt.Printf(" 积分: %d单 %.2f元\n", gpPoints.Count, float64(gpPoints.Sum)/100)
// 4. 按 source_type 拆分 GMV 构成
fmt.Println()
fmt.Println("========== 按游戏类型 × 支付方式 ==========")
srcNames := map[int]string{2: "小程序抽奖", 3: "对对碰", 4: "一番赏/次卡"}
for _, st := range []int{2, 3, 4} {
stFilter := fmt.Sprintf("users.deleted_at IS NULL AND orders.status = 2 AND orders.total_amount > 0 AND orders.actual_amount > 0 AND orders.source_type = %d AND (orders.ext_order_id = '' OR orders.ext_order_id IS NULL)", st)
var total, actual, discount, pts FieldStats
db.Table("orders").Joins("JOIN users ON users.id = orders.user_id").
Select("'total' as label, COUNT(*) as count, COALESCE(SUM(total_amount),0) as sum").
Where(stFilter).Scan(&total)
db.Table("orders").Joins("JOIN users ON users.id = orders.user_id").
Select("'actual' as label, COUNT(*) as count, COALESCE(SUM(actual_amount),0) as sum").
Where(stFilter).Scan(&actual)
db.Table("orders").Joins("JOIN users ON users.id = orders.user_id").
Select("'discount' as label, COUNT(*) as count, COALESCE(SUM(discount_amount),0) as sum").
Where(stFilter).Scan(&discount)
db.Table("orders").Joins("JOIN users ON users.id = orders.user_id").
Select("'points' as label, COUNT(*) as count, COALESCE(SUM(points_amount),0) as sum").
Where(stFilter).Scan(&pts)
fmt.Printf(" %s(type=%d): %d单 GMV=%.2f 现金=%.2f 优惠券=%.2f 积分=%.2f\n",
srcNames[st], st, total.Count,
float64(total.Sum)/100, float64(actual.Sum)/100,
float64(discount.Sum)/100, float64(pts.Sum)/100)
}
}