fruit_machine_charge.go 7.09 KB
Newer Older
hujiebin's avatar
hujiebin committed
1 2 3 4 5 6 7 8 9 10
package main

import (
	"fmt"
	"git.hilo.cn/hilo-common/script/mysql"
	"github.com/tealeg/xlsx"
	"time"
)

type FruitDayChargeData struct {
11 12 13 14 15 16 17 18 19 20
	Date                 string   // 日期
	FruitUserNum         int      // 水果机参与人数
	Recycle              float64  // 总回收 M
	DayChargeCnt         int      // 当日充值用户数
	DayChargeUserIds     []uint64 // 当日充值用户id
	DayChargeMoney       int64    // 当日充值金额
	ChargeRecycle        float64  // 充值用户回收 M
	Top100DayChargeCnt   int      // 投注榜TOP100的充值用户数
	Top100DayChargeMoney int64    // 投注榜TOP100的当日充值金额
	Top100ChargeRecycle  float64  // 投注榜TOP100的回收
hujiebin's avatar
hujiebin committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
}

func ats2(a interface{}) string {
	return fmt.Sprintf("%v", a)
}

type UserAndMoney struct {
	UserId uint64
	Money  int64 // 美分
}

// 1月的所有充值用户明细
func main() {
	startTime := time.Date(2023, time.January, 1, 0, 0, 0, 0, time.Local)
	endTime := time.Date(2023, time.March, 1, 0, 0, 0, 0, time.Local)
	var data []FruitDayChargeData
	for startTime.Before(endTime) {
38
		var userIds []uint64
39
		var top100UserIds []uint64
hujiebin's avatar
hujiebin committed
40
		date := startTime.Format("2006-01-02")
41 42 43
		if err := mysql.ProdReadOnlyDB.Table("fruit_machine_stake").Where("`date` = ?", date).Group("user_id").Select("user_id").Scan(&userIds).Error; err != nil {
			panic(err)
		}
44 45 46 47 48 49 50 51 52
		if err := mysql.ProdReadOnlyDB.Table("fruit_machine_stake").Where("`date` = ?", date).Group("user_id").
			Order("SUM(stake) DESC").Limit(100).
			Select("user_id").Scan(&top100UserIds).Error; err != nil {
			panic(err)
		}
		top100UserIdMap := make(map[uint64]struct{})
		for _, userId := range top100UserIds {
			top100UserIdMap[userId] = struct{}{}
		}
53
		um1, err := GetDateChargeUserAndMoney(date, userIds)
hujiebin's avatar
hujiebin committed
54 55 56
		if err != nil {
			panic(err)
		}
57
		um2, err := GetUserDealerTransferUserAndMoney(date, userIds)
hujiebin's avatar
hujiebin committed
58 59 60 61
		if err != nil {
			panic(err)
		}
		userChargeNum := make(map[uint64]struct{})
62
		top100UserChargeNum := make(map[uint64]struct{})
hujiebin's avatar
hujiebin committed
63
		userChargeMoney := int64(0)
64
		top100UserChargeMoney := int64(0)
hujiebin's avatar
hujiebin committed
65 66 67
		for _, um := range um1 {
			userChargeNum[um.UserId] = struct{}{}
			userChargeMoney += um.Money
68 69 70 71
			if _, ok := top100UserIdMap[um.UserId]; ok {
				top100UserChargeNum[um.UserId] = struct{}{}
				top100UserChargeMoney += um.Money
			}
hujiebin's avatar
hujiebin committed
72 73 74 75
		}
		for _, um := range um2 {
			userChargeNum[um.UserId] = struct{}{}
			userChargeMoney += um.Money
76 77 78 79
			if _, ok := top100UserIdMap[um.UserId]; ok {
				top100UserChargeNum[um.UserId] = struct{}{}
				top100UserChargeMoney += um.Money
			}
hujiebin's avatar
hujiebin committed
80
		}
81
		var chargeUserIds []uint64
hujiebin's avatar
hujiebin committed
82
		for userId := range userChargeNum {
83
			chargeUserIds = append(chargeUserIds, userId)
hujiebin's avatar
hujiebin committed
84
		}
85 86 87 88
		var top100ChargeUserIds []uint64
		for userId := range top100UserChargeNum {
			top100ChargeUserIds = append(top100ChargeUserIds, userId)
		}
hujiebin's avatar
hujiebin committed
89 90 91 92 93 94 95 96
		userNum, err := GetFruitUserNum(date)
		if err != nil {
			panic(err)
		}
		fruitRecycle, err := GetFruitRecycle(date)
		if err != nil {
			panic(err)
		}
97
		fruitChargeRecycle, err := GetFruitChargeRecycle(date, chargeUserIds)
hujiebin's avatar
hujiebin committed
98 99 100
		if err != nil {
			panic(err)
		}
101 102 103 104
		top100FruitChargeRecycle, err := GetFruitChargeRecycle(date, top100ChargeUserIds)
		if err != nil {
			panic(err)
		}
hujiebin's avatar
hujiebin committed
105
		data = append(data, FruitDayChargeData{
106 107 108 109 110 111 112 113 114 115
			Date:                 date,
			FruitUserNum:         userNum,
			Recycle:              float64(fruitRecycle) * 0.05 / 1000000, // 1M
			DayChargeCnt:         len(userChargeNum),
			DayChargeUserIds:     userIds,
			DayChargeMoney:       userChargeMoney,
			ChargeRecycle:        float64(fruitChargeRecycle) * 0.05 / 1000000, // 1M
			Top100DayChargeCnt:   len(top100UserChargeNum),
			Top100DayChargeMoney: top100UserChargeMoney,
			Top100ChargeRecycle:  float64(top100FruitChargeRecycle) * 0.05 / 1000000, // 1M
hujiebin's avatar
hujiebin committed
116 117 118 119 120 121 122 123
		})
		startTime = startTime.AddDate(0, 0, 1)
	}

	excelFileName := fmt.Sprintf("./水果机充值数据%s.xlsx", time.Now().Format("20060102"))
	xlFile := xlsx.NewFile()
	sheet, _ := xlFile.AddSheet("charge")
	row := sheet.AddRow()
124 125 126
	c1, c2, c3, c4, c5, c6, c7, c8, c9 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
	c1.Value, c2.Value, c3.Value, c4.Value, c5.Value, c6.Value, c7.Value, c8.Value, c9.Value = "日期", "参与人数", "总回收 M", "当日充值用户数", "当日充值金额(美分)", "充值用户回收 M",
		"投注榜TOP100的充值用户数", "投注榜TOP100的当日充值金额(美分)", "投注榜TOP100的回收"
hujiebin's avatar
hujiebin committed
127 128
	for _, d := range data {
		row := sheet.AddRow()
129
		c1, c2, c3, c4, c5, c6, c7, c8, c9 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
hujiebin's avatar
hujiebin committed
130
		c1.Value, c2.Value, c3.Value, c4.Value, c5.Value, c6.Value = d.Date, ats2(d.FruitUserNum), ats2(d.Recycle), ats2(d.DayChargeCnt), ats2(d.DayChargeMoney), ats2(d.ChargeRecycle)
131
		c7.Value, c8.Value, c9.Value = ats2(d.Top100DayChargeCnt), ats2(d.Top100DayChargeMoney), ats2(d.Top100ChargeRecycle)
hujiebin's avatar
hujiebin committed
132 133 134 135 136 137
	}
	_ = xlFile.Save(excelFileName)
}

// 获取充值用户以及金额
// return 充值userIds,充值金额
138
func GetDateChargeUserAndMoney(date string, userIds []uint64) ([]UserAndMoney, error) {
hujiebin's avatar
hujiebin committed
139 140 141 142 143
	var money []UserAndMoney
	if err := mysql.ProdReadOnlyDB.Table("diamond_account_detail AS d").
		Joins("INNER JOIN pay_order AS p ON d.origin_id = p.id").
		Where("DATE(d.created_time) >= ? AND DATE(d.created_time) <= ? AND operate_type in (?) AND add_reduce = 1",
			date, date, []int{int(4), int(42), int(55), int(68)}).
144
		Where("d.user_id in ?", userIds).
hujiebin's avatar
hujiebin committed
145 146 147 148 149 150 151 152 153
		Group("d.user_id").
		Select("d.user_id,SUM(p.price) as money").Scan(&money).Error; err != nil {
		return nil, err
	}
	return money, nil
}

// 获取代理充值用户以及金额
// return 充值userIds,充值金额
154
func GetUserDealerTransferUserAndMoney(date string, userIds []uint64) ([]UserAndMoney, error) {
hujiebin's avatar
hujiebin committed
155 156 157 158
	var money []UserAndMoney
	if err := mysql.ProdReadOnlyDB.Table("diamond_account_detail AS d").
		Joins("INNER JOIN dealer_transfer_detail AS t ON d.origin_id = t.id").
		Where("DATE(d.created_time) >= ? AND DATE(d.created_time) <= ? AND operate_type = ? AND add_reduce = 1",
159 160 161
			date, date, 26).
		Where("d.user_id in ?", userIds).
		Select("d.user_id,SUM(t.dollar) as money").
hujiebin's avatar
hujiebin committed
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
		Group("d.user_id").
		Scan(&money).Error; err != nil {
		return nil, err
	}
	return money, nil
}

// 获取参与人数
func GetFruitUserNum(date string) (int, error) {
	var stake int
	if err := mysql.ProdReadOnlyDB.Table("fruit_machine_stake").Where("`date`= ?", date).Select("count(DISTINCT user_id) as total").Scan(&stake).Error; err != nil {
		return stake, err
	}
	return stake, nil
}

// 总回收
func GetFruitRecycle(date string) (int, error) {
	var total int
	if err := mysql.ProdReadOnlyDB.Table("fruit_machine").Where("`date`= ?", date).Select("SUM(stake) as total").Scan(&total).Error; err != nil {
		return total, err
	}
	return total, nil
}

// 充值用户回收
func GetFruitChargeRecycle(date string, userIds []uint64) (int, error) {
	var total int
	if err := mysql.ProdReadOnlyDB.Table("fruit_machine_stake").Where("`date`= ?", date).Where("user_id in ?", userIds).
		Select("SUM(stake) as total").Scan(&total).Error; err != nil {
		return total, err
	}
	return total, nil
}