...
 
Commits (108)
......@@ -93,22 +93,22 @@ const (
GameAward OperateType = 66 //游戏结算奖励
GameRefund OperateType = 67 //游戏退费
Paypal OperateType = 68 //paypal充值
H5GameSlotJoin OperateType = 69 //加入游戏扣费
H5GameSlotAward OperateType = 70 //游戏结算奖励
H5GameSlotJoin OperateType = 69 //slot加入游戏扣费
H5GameSlotAward OperateType = 70 //slot游戏结算奖励
ActFruitPutRankAward OperateType = 71 //水果机排行榜奖励
H5GameSlotLevelAward OperateType = 72 //游戏等级奖励
ActSlotWeekRankAward OperateType = 75 //slot周活动排行榜奖励
ActSlotWeekDailyAward OperateType = 76 //slot周活动每日福利奖励
ActFruitWeekDailyAward OperateType = 78 //水果机周活动每日福利奖励
ActSlotMonthAward OperateType = 79 //slot月度活动奖励
H5GameCandyJoin OperateType = 80 //加入游戏扣费
H5GameCandyAward OperateType = 81 //游戏结算奖励
H5GameCandyLevelAward OperateType = 82 //游戏等级奖励
H5GameCandyJoin OperateType = 80 //candy加入游戏扣费
H5GameCandyAward OperateType = 81 //candy游戏结算奖励
H5GameCandyLevelAward OperateType = 82 //candy游戏等级奖励
H5GameSlotStageAward OperateType = 83 //slot阶梯奖励
H5GameCandyStageAward OperateType = 84 //candy阶梯奖励
H5GameGreedyJoin OperateType = 85 //加入游戏扣费
H5GameGreedyAward OperateType = 86 //游戏结算奖励
H5GameGreedyLevelAward OperateType = 87 //游戏等级奖励
H5GameGreedyJoin OperateType = 85 //greedy加入游戏扣费
H5GameGreedyAward OperateType = 86 //greedy游戏结算奖励
H5GameGreedyLevelAward OperateType = 87 //greedy游戏等级奖励
ActCandyWeekRankAward OperateType = 88 //candy周活动排行榜奖励
ActCandyWeekDailyAward OperateType = 89 //candy周活动每日福利奖励
GemToDiamondYellow OperateType = 90 //粉钻转黄钻(黄钻)
......@@ -136,6 +136,14 @@ const (
ActGameSlotWeekDailyAward OperateType = 114 //多财多福game slot周活动每日福利奖励
ActGameChargePink OperateType = 115 //游戏充值金币(粉钻)档位活动
ActGameSlotWeekRankAward OperateType = 116 //多财多福gameSlot周活动排行榜奖励
GameRaceBet OperateType = 117 //赛车投注
GameRaceAward OperateType = 118 //赛车奖励
H5GameGameEgyptSlotJoin OperateType = 119 //egyptSlot加入游戏扣费
H5GameGameEgyptSlotAward OperateType = 120 //egyptSlot游戏结算奖励
ActEgyptSlotMonthAward OperateType = 121 //egyptSlot月度活动奖励-黄钻
ActOldUserAward OperateType = 122 //老用户召回奖励-黄钻
GameAwardUNO OperateType = 123 //游戏结算奖励-UNO
GameAwardDomino OperateType = 124 //游戏结算奖励-Domino
)
const (
......
......@@ -120,6 +120,7 @@ const (
GemAward = 58 // 粉钻奖励
GemPlatformAward = 63 // Congratulations on your get gold reward! Please play in the game!>
GemPlatformAward2 = 64 // To celebrate the launch of the new version 4.0.0 of Hilo, we will reward Hilo users with gold coins for free, as shown in the form. Thanks for everyone's support and love, Hilo will continue to provide you with better services and fun!
RaceWeekMedal = 65 // 赛车周榜勋章
)
type MsgSysUserType = mysql.Type
......
......@@ -49,4 +49,20 @@ const (
ActImeiGetAwardTimes = "act:imeiAwardTimes:%d:%d:%d:%s" // 一个设备在活动中的领奖次数 活动id:领奖类型:level:设备号
ExchangePinkCostDiamond = "finance:exPinkDiamond:%s:%d" // 某天兑换粉钻所花费的黄钻 日期:用户id
GameAutoMathEnterRoom = "game:autoEnter:%d:%s" // 快速游戏,进入某个房间
Game1V1EnterRoom = "game:oneAndOne:%s" // 1v1游戏,进入某个房间,%s: txGroupId
Game1V1GameChannel = "game:gameChannel:%s" // 1v1游戏,发布订阅channel,游戏创建成功后的通知,%s: imGroupId
Game1V1ResetGameRoom = "game:resetGameRoom:%s" // 1v1游戏,把某个房间重新放回匹配池,%s: txGroupId
Game1V1RoomRobot = "game:oneAndOneRobot:%s" // 1v1游戏,某个房间匹配到的机器人,%s: txGroupId, val: 机器人uid
Game1V1GameTimesRecord = "game:timesRecord:%s:%d:%d:%d" // 1v1游戏,游戏次数活动记录,天日期:玩家Id:游戏gameId:对方玩家id
Game1V1GameWinTimesRecord = "game:winTimesRecord:%s:%d:%d:%d" // 1v1游戏,游戏获胜次数活动记录,天日期:获胜玩家Id:游戏gameId:对方玩家id
GroupSupportConsumeSummary = "group:support:consumeSummary:%s" // 群组扶持,周流水记录,zset数据,%s:日期 member:imGroupId, score:diamond
GroupSupportCountSupporter = "group:support:supporter:%s:%s" // 群组扶持,日期:imGroupId,SADD新的支持者
RoomVisitCount = "room_visit_count" // 15天内进入房间的人数
GroupCountrySortList = "group:sortCountryList:%s" // 国家群组列表,%s:countryName
ActTemplateRanking = "act:ranking:%d:%d:%d" // 排行榜数据 活动id:排行榜类型:teamId
ActOldUserAllCharge = "act:oldUser:%d:%d" // 老用户回归,领奖时的累充黄钻 活动id:userId
)
......@@ -103,3 +103,55 @@ func GetExchangePinkCostDiamond(userId uint64) string {
func GetOpenRamadanSendGiftLeftDiamond(actId, userId uint64) string {
return fmt.Sprintf(OpenRamadanSendGiftLeftDiamond, actId, userId)
}
func GetAutoMathEnterRoom(userId uint64, imGroupId string) string {
return fmt.Sprintf(GameAutoMathEnterRoom, userId, imGroupId)
}
func GetGame1V1EnterRoom(txGroupId string) string {
return fmt.Sprintf(Game1V1EnterRoom, txGroupId)
}
func GetGame1V1GameChannel(imGroupId string) string {
return fmt.Sprintf(Game1V1GameChannel, imGroupId)
}
func GetGame1V1ResetGameRoom(txGroupId string) string {
return fmt.Sprintf(Game1V1ResetGameRoom, txGroupId)
}
func GetGame1V1RoomRobot(txGroupId string) string {
return fmt.Sprintf(Game1V1RoomRobot, txGroupId)
}
func GetGame1V1GameTimesRecord(userId1, userId2 uint64, gameId int) string {
return fmt.Sprintf(Game1V1GameTimesRecord, time.Now().Format(utils.COMPACT_DATE_FORMAT), userId1, gameId, userId2)
}
func GetGame1V1GameWinTimesRecord(userId1, userId2 uint64, gameId int) string {
return fmt.Sprintf(Game1V1GameWinTimesRecord, time.Now().Format(utils.COMPACT_DATE_FORMAT), userId1, gameId, userId2)
}
func GetGroupSupportConsumeSummary(period string) string {
return fmt.Sprintf(GroupSupportConsumeSummary, period)
}
func GetGroupSupportCountSupporter(period, imGroupId string) string {
return fmt.Sprintf(GroupSupportCountSupporter, period, imGroupId)
}
func GetPrefixRoomVisitCount() string {
return RoomVisitCount
}
func GetGroupCountrySortList(country string) string {
return fmt.Sprintf(GroupCountrySortList, country)
}
func GetActTemplateRanking(actId, teamId uint64, rankType int) string {
return fmt.Sprintf(ActTemplateRanking, actId, rankType, teamId)
}
func GetActOldUserAllCharge(actId, userId uint64) string {
return fmt.Sprintf(ActOldUserAllCharge, actId, userId)
}
......@@ -10,4 +10,5 @@ type CtxAndDb struct {
Db *gorm.DB
*mycontext.MyContext
Redis *redis.Client
RedisCluster *redis.Client
}
......@@ -24,6 +24,7 @@ func CreateModelContext(myContext *mycontext.MyContext) *Model {
Db: mysql.Db,
MyContext: myContext,
Redis: redisCli.GetRedis(),
RedisCluster: redisCli.GetClusterRedis(),
},
}
}
......@@ -34,6 +35,7 @@ func CreateModelNil() *Model {
Db: mysql.Db,
MyContext: mycontext.CreateMyContext(nil),
Redis: redisCli.GetRedis(),
RedisCluster: redisCli.GetClusterRedis(),
},
}
}
......
......@@ -26,12 +26,14 @@ func CreateService(myContext *mycontext.MyContext) *Service {
Db: mysql.Db,
MyContext: mycontext.CreateMyContext(nil),
Redis: redisCli.GetRedis(),
RedisCluster: redisCli.GetClusterRedis(),
}}
} else {
return &Service{CtxAndDb: &CtxAndDb{
Db: mysql.Db,
MyContext: myContext,
Redis: redisCli.GetRedis(),
RedisCluster: redisCli.GetClusterRedis(),
}}
}
}
......
......@@ -111,6 +111,7 @@ const (
TemplateSmsCode = 40 // 通用模板活动奖励提醒
AddUserBag = 50 // 赠送背包礼物
GemAward = 58 // 粉钻奖励
RaceWeekMedal = 65 // 赛车周榜勋章
)
type MsgSysUserType = mysql.Type
......
......@@ -36,6 +36,11 @@ type DiamondAccountDetail struct {
diamondAccount *DiamondAccount `gorm:"-"`
}
func (DiamondAccountDetail) TableName() string {
month := time.Now().Format("200601")
return fmt.Sprintf("diamond_account_detail_%s", month)
}
// 粉钻详情
type DiamondPinkAccountDetail struct {
mysql.Entity
......@@ -107,7 +112,7 @@ func (diamondAccount *DiamondAccount) addDiamondAccountDetail(operateType diamon
var count int64
if diamondOperateSet.FrequencyDay == -1 {
if diamondOperateSet.FrequencyNum != -1 {
diamondAccount.Db.Model(&DiamondAccountDetail{}).Where(&DiamondAccountDetail{
diamondAccount.DB().Table(DiamondAccountDetail{}.TableName()).Where(&DiamondAccountDetail{
UserId: diamondAccount.UserId,
OperateType: operateType,
}).Count(&count)
......@@ -121,7 +126,7 @@ func (diamondAccount *DiamondAccount) addDiamondAccountDetail(operateType diamon
return nil, err
}
//一天的次数
diamondAccount.Db.Model(&DiamondAccountDetail{}).Where(&DiamondAccountDetail{
diamondAccount.DB().Table(DiamondAccountDetail{}.TableName()).Where(&DiamondAccountDetail{
UserId: diamondAccount.UserId,
OperateType: operateType,
}).Where("created_time >= ? ", beginTime).Count(&count)
......@@ -129,7 +134,7 @@ func (diamondAccount *DiamondAccount) addDiamondAccountDetail(operateType diamon
return nil, fmt.Errorf("bizerr.DiamondFrequency")
}
//终极拦截,利用
diamondAccount.SetCheckUpdateCondition(" EXISTS (SELECT * from (SELECT COUNT(1) as n from diamond_account_detail d where d.user_id = " + strconv.FormatUint(diamondAccount.UserId, 10) + " and d.operate_type = " + strconv.FormatUint(uint64(operateType), 10) + " and d.created_time >= from_unixtime(" + strconv.FormatInt(getZeroTime(time.Now()).Unix(), 10) + ")) t where t.n < " + strconv.Itoa(diamondOperateSet.FrequencyNum) + " )")
diamondAccount.SetCheckUpdateCondition(" EXISTS (SELECT * from (SELECT COUNT(1) as n from " + DiamondAccountDetail{}.TableName() + " d where d.user_id = " + strconv.FormatUint(diamondAccount.UserId, 10) + " and d.operate_type = " + strconv.FormatUint(uint64(operateType), 10) + " and d.created_time >= from_unixtime(" + strconv.FormatInt(getZeroTime(time.Now()).Unix(), 10) + ")) t where t.n < " + strconv.Itoa(diamondOperateSet.FrequencyNum) + " )")
}
//-1,代表值无效,由参数给与
......
......@@ -33,8 +33,11 @@ func (diamondAccountDetail *DiamondAccountDetail) Persistent() error {
}
//持久化diamondAccountDetail
if err := domain.Persistent(diamondAccountDetail.Db, diamondAccountDetail); err != nil {
return err
//if err := domain.Persistent(diamondAccountDetail.Db, diamondAccountDetail); err != nil {
// return err
//}
if err := diamondAccountDetail.DB().Table(diamondAccountDetail.TableName()).Save(diamondAccountDetail).Error; err != nil {
return myerr.WrapErr(err)
}
//改变diamondAccount值
if diamondAccountDetail.diamondAccount == nil {
......
......@@ -22,6 +22,12 @@ func (ub *UserNoble) UpdateEndTime(db *gorm.DB, endTime time.Time) (int64, error
return r.RowsAffected, r.Error
}
// 延长贵族
func (ub *UserNoble) ExtenedEndTime(db *gorm.DB, day int) (int64, error) {
r := db.Model(&UserNoble{}).Where("user_id = ? AND level = ?", ub.UserId, ub.Level).Update("end_time", gorm.Expr("DATE_ADD(end_time,INTERVAL ? day)", day))
return r.RowsAffected, r.Error
}
// 查询用户未过期的贵族
func (ub *UserNoble) Find(db *gorm.DB) ([]UserNoble, error) {
rows := make([]UserNoble, 0)
......
......@@ -113,6 +113,7 @@ message AddTimeGift {
string svgaUrl = 9;
string senderAvatar = 10;
string receiverAvatar = 11;
uint32 nobleLevel = 12;
}
/* id == 104 免费加时 */
......@@ -213,6 +214,7 @@ message GlobalGiftBanner {
uint32 bannerType = 14; // 类型:0.普通礼物 1.cp直接送礼 2.cp告白礼物
uint32 cpLevel = 15; // cp等级
string receiveUserAvatar = 16;
uint32 nobleLevel = 17; // 贵族等级
}
/* id == 116 横幅的回应,用来测量RTT */
......@@ -289,6 +291,7 @@ message GlobalBroadcast {
string msg = 6;
string groupId = 7;
uint32 senderNobleLevel = 8;
bool isPinned = 9;
}
/* id == 124 全球消息 */
......@@ -377,6 +380,11 @@ message SheepMatchSuccess {
User user = 2;
User otherUser = 3;
uint64 game_id = 4;
string channelId = 5;
string token = 6;
uint32 agoraId = 7;
uint32 provider = 8;
uint32 otherAgoraId = 9;
}
message SheepGamePlayer {
......@@ -464,3 +472,27 @@ message MicUserData {
string headwearIcon = 15;
Svip svip = 16;
}
/* id == 157 游戏大厅匹配成功 */
message LobbyMatchSuccess {
uint64 game_id = 1;
uint64 mode = 2;
string group_id = 3;
User user = 4;
User otherUser = 5;
string gameCode = 6;
}
/* id == 158 H5游戏静音 */
message H5GameVoiceMute {
}
/* id == 159 H5游戏打开语音 */
message H5GameVoiceUnMute {
}
/* id == 160 退出房间 */
message QuitRoom {
uint32 reason = 1; // 原因1.被拉黑;2.被踢出
string group_id = 2;
}
......@@ -28,6 +28,8 @@ type MysqlCodeConfig struct {
type RedisConfig struct {
REDIS_HOST string
REDIS_PASSWORD string
REDIS_CLUSTER_HOST string
REDIS_CLUSTER_PASSWORD string
}
//jwt
......@@ -200,6 +202,7 @@ type H5Config struct {
RANKING_PINK_DIAMOND_URL string
AGENT_SHARE_URL string
AGENT_SHARE_ICON string
ACT_ACTIVE_GAME_URL string
}
type GroupImConfig struct {
......
......@@ -51,8 +51,8 @@ func init() {
if d, err := Db.DB(); err == nil {
d.SetConnMaxLifetime(time.Minute * 30) // 连接可复用的最大时间。
d.SetMaxIdleConns(300) // 空闲连接数
d.SetMaxOpenConns(300) // 最大连接数
d.SetMaxIdleConns(400) // 空闲连接数
d.SetMaxOpenConns(400) // 最大连接数
if err := d.Ping(); err != nil {
fmt.Printf("database ping error %v", err)
}
......
package redisCli
import (
"context"
"git.hilo.cn/hilo-common/mylogrus"
"git.hilo.cn/hilo-common/resource/config"
"github.com/go-redis/redis/v8"
)
var RedisClusterClient *redis.Client
func InitCluster() {
RedisClusterClient = redis.NewClient(&redis.Options{
Addr: config.GetConfigRedis().REDIS_CLUSTER_HOST,
Password: config.GetConfigRedis().REDIS_CLUSTER_PASSWORD, // no password set
DB: 0, // use default DB
PoolSize: 20,
MinIdleConns: 20,
})
mylogrus.MyLog.Infoln(config.GetConfigRedis().REDIS_HOST)
mylogrus.MyLog.Infoln(config.GetConfigRedis().REDIS_PASSWORD)
pong, err := RedisClient.Ping(context.Background()).Result()
if err != nil {
mylogrus.MyLog.Warn(err)
mylogrus.MyLog.Fatal("redis cluster db0 connect fail")
} else {
mylogrus.MyLog.Info("redis cluster db0 connection success - ", pong)
}
}
func GetClusterRedis() *redis.Client {
return RedisClusterClient
}
......@@ -36,6 +36,25 @@ func Lock(key string, expiration time.Duration) bool {
return true
}
// 尝试获取锁
func TryLock(key string, expiration time.Duration) bool {
deadline := time.Now().Add(expiration)
for {
if time.Now().After(deadline) {
return false // 超时无法获取锁
}
if Lock(key, expiration) {
return true
}
time.Sleep(time.Millisecond)
}
}
// 删除锁
func DelLock(key string) {
RedisClient.Del(context.Background(), key)
}
func GetCacheInt64(key string) (int64, error) {
data, err := RedisClient.Get(context.Background(), key).Int64()
if err != nil && err != redis.Nil {
......@@ -106,3 +125,17 @@ func DecrNum(key string, num int64) (int64, error) {
}
return resNum, nil
}
func SetExpire(cli *redis.Client, key string, expiration time.Duration) error {
ttl, err := cli.TTL(context.Background(), key).Result()
if err != nil {
return err
}
if ttl == -1 {
err = cli.Expire(context.Background(), key, expiration).Err()
if err != nil {
return err
}
}
return nil
}
......@@ -2,12 +2,14 @@ package rpc
import (
"encoding/json"
"errors"
"fmt"
"git.hilo.cn/hilo-common/_const/enum/timezone_e"
"git.hilo.cn/hilo-common/domain"
"git.hilo.cn/hilo-common/mylogrus"
"git.hilo.cn/hilo-common/resource/consul"
"git.hilo.cn/hilo-common/resource/mysql"
"git.hilo.cn/hilo-common/utils"
"math/rand"
)
......@@ -190,3 +192,36 @@ func getGroupHost() string {
mylogrus.MyLog.Infof("getHostGroup:%v---%v", r, groupServerHost[r])
return groupServerHost[r]
}
// 上麦
func MicIn(model *domain.Model, groupId, token string) error {
defer utils.CheckGoPanic()
type MicInResp struct {
Code int `json:"code"`
Data struct {
MicIndex int `json:"micIndex"`
} `json:"data"`
}
_url := fmt.Sprintf("%v://%v/v1/imGroup/mic/in", defaultGroupServerScheme, getGroupHost())
header := map[string]string{
"token": token,
}
resp, err := HttpPostForm(model, _url, header, map[string]string{
"groupUuid": groupId,
"i": "", // 空则随意上一个空位置
})
if err != nil {
model.Log.Errorf("MicIn fail:%v", err)
return err
}
response := new(MicInResp)
if err = json.Unmarshal(resp, response); err != nil {
model.Log.Errorf("MicIn json fail:%v", err)
return err
}
if response.Code != 200 {
model.Log.Errorf(fmt.Sprintf("Mic In Not 200:%v,groupId:%v", response, groupId))
return errors.New(fmt.Sprintf("Mic In Not 200:%v", response))
}
return nil
}
......@@ -493,3 +493,46 @@ func GetUserCpEntryEffect(model *domain.Model, userId mysql.ID) (*CvCpEntryEffec
}
return nil, nil
}
//用户详细信息
type CvUserDetail struct {
CvUserBase
WealthUserGrade uint32 `json:"wealthUserGrade"` //财富等级
CharmUserGrade uint32 `json:"charmUserGrade"` //魅力等级
ActivityUserGrade uint32 `json:"activityUserGrade"` //活跃等级
CurrentRoom string `json:"currentRoom"` // 当前用户所在房间(产品叫“群组”)
// ...先省略其他字段
}
// 批量获取用户svip/noble/level等信息
func MGetUserSvipNobleLevel(model *domain.Model, userIds []mysql.ID) (map[mysql.ID]CvUserDetail, error) {
type Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data map[mysql.ID]CvUserDetail `json:"data"`
}
var res = make(map[mysql.ID]CvUserDetail)
if len(userIds) <= 0 {
return res, nil
}
var userIdsStr []string
for _, userId := range userIds {
userIdsStr = append(userIdsStr, fmt.Sprintf("%d", userId))
}
_url := fmt.Sprintf("%v://%v/inner/user/svipNobleLevel", defaultUserServerScheme, getUserHost())
resp, err := HttpGet(model, _url, nil, map[string][]string{
"ids": userIdsStr,
})
if err != nil {
model.Log.Errorf("MGetUserLevel fail:%v", err)
return res, err
}
response := new(Response)
if err = json.Unmarshal(resp, response); err != nil {
model.Log.Errorf("MGetUserLevel json fail:%v", err)
return res, err
} else if response != nil && len(response.Data) > 0 {
res = response.Data
}
return res, nil
}
......@@ -136,8 +136,12 @@ func init() {
}
}
func multicast(uids []uint64, msgType uint32, data []byte) ([]uint64, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
func multicast(uids []uint64, msgType uint32, data []byte, seconds ...time.Duration) ([]uint64, error) {
duration := time.Duration(3)
if len(seconds) > 0 {
duration = seconds[0]
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second*duration)
defer cancel()
rsp, err := userClient.Multicast(ctx, &userCenter.MulticastMessage{
Uids: uids,
......
......@@ -67,6 +67,10 @@ const (
MsgTypeCpUpgrade = 150 // cp升级
MsgTypeSvipUpgrade = 151 // svip升级
MsgTypeGroupMicChange = 155 // 麦位变化
MsgTypeLobbyMatchSuccess = 157 // 大厅匹配成功
MsgTypeH5GameMute = 158 // H5游戏静音
MsgTypeH5GameUnMute = 159 // H5游戏开音
MsgTypeQuitRoom = 160 // 通知客户端退房
)
const (
......
......@@ -35,6 +35,32 @@ func SendFruitMachine(date string, round uint32) error {
return nil
}
func SendFruitMachineToUser(date string, round uint32, userIds []uint64) error {
msg := &userProxy.FruitMachine{
Date: date,
Round: round,
}
if buffer, err := proto.Marshal(msg); err == nil {
rspUids, err := multicast(userIds, MsgFruitMachine, buffer, time.Duration(5))
//记录socket,注意闭包问题
go func(userId uint64, msg *userProxy.FruitMachine, rspUids []uint64, err error) {
buf, _ := json.Marshal(msg)
AddRpcLog(MsgFruitMachine, userId, string(buf[:]), rspUids, err)
}(uint64(len(userIds)), msg, rspUids, err)
if err != nil {
mylogrus.MyLog.Errorf("grpc SendFruitMachine send fail")
return err
} else {
mylogrus.MyLog.Info("grpc SendFruitMachine send success")
}
} else {
return err
}
return nil
}
func SendGlobalRocketNotice(groupId string, period string, round uint32, stage uint32, fromUserId uint64, topUserIcon string, nick string, code string, avatar string) error {
msg := &userProxy.GlobalRocketNotice{
GroupId: groupId,
......@@ -76,11 +102,14 @@ func SendDiamondChange(userId uint64, diamond, pinkDiamond uint32) error {
}
if buffer, err := proto.Marshal(msg); err == nil {
rspUids, err := multicast([]uint64{userId}, MsgDiamondChange, buffer)
//记录socket,注意闭包问题
// 记录socket
// 有err||uid不在线才入库
if err != nil || len(rspUids) > 0 {
go func(userId uint64, msg *userProxy.DiamondChange, rspUids []uint64, err error) {
buf, _ := json.Marshal(msg)
AddRpcLog(MsgDiamondChange, userId, string(buf[:]), rspUids, err)
}(userId, msg, rspUids, err)
}
if err != nil {
mylogrus.MyLog.Errorf("grpc SendDiamondChange send fail")
......@@ -99,6 +128,7 @@ func SendDiamondChange(userId uint64, diamond, pinkDiamond uint32) error {
// param gameType 0:slot 5:luckybox 6:fruit
// param gameId 7:slot 8:candy 5:luckybox 6:fruit
func SendGlobalGameBanner(winUserId uint64, diamond uint64, avatar string, gameId uint64, gameType uint32) error {
defer utils.CheckGoPanic()
bannerUrl := ""
switch gameType {
case 0:
......@@ -111,6 +141,9 @@ func SendGlobalGameBanner(winUserId uint64, diamond uint64, avatar string, gameI
if gameId == uint64(8) {
bannerUrl = "https://image.whoisamy.shop/hilo/resource/game/game_banner_candy.png"
}
if gameId == uint64(17) {
bannerUrl = "https://image.whoisamy.shop/hilo/resource/game/game_banner_race.png"
}
msg := &userProxy.GlobalGameBanner{
GameId: gameId,
GameType: gameType,
......@@ -225,6 +258,7 @@ func SendGroupChatNotice(fromUserId uint64, userIds []uint64, senderExtId string
}
// 羊羊匹配成功
// Deprecated: missing Params
func SendSheepMatchSuccess(matchId, myUserId, otherUserId uint64, nick1, nick2, avatar1, avatar2 string, gameIds ...uint64) error {
gameId := uint64(0)
if len(gameIds) > 0 {
......@@ -258,6 +292,41 @@ func SendSheepMatchSuccess(matchId, myUserId, otherUserId uint64, nick1, nick2,
return nil
}
// 羊羊匹配成功
func SendSheepMatchSuccessV2(matchId, myUserId, otherUserId uint64, nick1, nick2, avatar1, avatar2 string, gameId uint64, channelId, token string, agoraId, otherAgoraId uint32, provider int) error {
msg := &userProxy.SheepMatchSuccess{
MatchId: matchId,
User: &userProxy.User{Id: myUserId, Nick: nick1, Avatar: avatar1},
OtherUser: &userProxy.User{Id: otherUserId, Nick: nick2, Avatar: avatar2},
GameId: gameId,
ChannelId: channelId,
Token: token,
AgoraId: agoraId,
OtherAgoraId: otherAgoraId,
Provider: uint32(provider),
}
if buffer, err := proto.Marshal(msg); err == nil {
userIds := []uint64{myUserId}
rspUids, err := multicast(userIds, MsgTypeSheepGameMatchSuccess, buffer)
//记录socket,注意闭包问题
go func(userIds []uint64, msg *userProxy.SheepMatchSuccess, rspUids []uint64, err error) {
buf, _ := json.Marshal(msg)
AddRpcLogs(MsgTypeSheepGameMatchSuccess, userIds, string(buf[:]), rspUids, err)
}(userIds, msg, rspUids, err)
if err != nil {
mylogrus.MyLog.Errorf("grpc SendSheepMatchSuccess send fail")
return err
} else {
mylogrus.MyLog.Info("grpc SendSheepMatchSuccess send success")
}
} else {
return err
}
return nil
}
// 羊羊游戏结果
func SendSheepGameResult(matchId, winId, userId1, userId2 uint64, nick1, nick2, avatar1, avatar2 string, isAiMap map[uint64]bool, gameIds ...uint64) error {
if isAiMap == nil {
......@@ -413,31 +482,139 @@ func SendSocketMicChange(seqId string, userId uint64, micUserExternalId, txGroup
Timestamp: time.Now().UnixNano(),
User: micUserData,
}
n := 0
if buffer, err := proto.Marshal(msg); err == nil {
userIds := []uint64{userId}
var rspUids []uint64
n := 0
for {
n++
rspUids, err = multicast(userIds, MsgTypeGroupMicChange, buffer)
rspUids, err = multicast(userIds, MsgTypeGroupMicChange, buffer, time.Duration(10))
if n >= 3 || len(rspUids) <= 0 {
break
}
mylogrus.MyLog.Infof("grpc SendSocketMicChange send fail,seqId:%v,retry:%v,data:%v", seqId, n, *msg)
time.Sleep(time.Millisecond * 200)
}
// 记录socket
// 有err||uid不在线才入库
if err != nil || len(rspUids) > 0 {
go func(userId uint64, msg *userProxy.GroupMicChange, rspUids []uint64, err error) {
buf, _ := json.Marshal(msg)
AddRpcLog(MsgTypeGroupMicChange, userId, string(buf[:]), rspUids, err)
}(userId, msg, rspUids, err)
}
if err != nil {
mylogrus.MyLog.Errorf("grpc SendSocketMicChange send fail,seqId:%v,retry:%v,data:%v,err:%v", seqId, n, *msg, err)
return err
} else {
mylogrus.MyLog.Infof("grpc SendSocketMicChange send success,seqId:%v,retry:%v,data:%v", seqId, n, *msg)
}
} else {
return err
}
return nil
}
// 游戏大厅匹配成功
func SendLobbyMatchSuccess(myUserId, otherUserId uint64, nick1, nick2, avatar1, avatar2 string, gameId uint64, txGroupId string, mode int, gameCode string) error {
msg := &userProxy.LobbyMatchSuccess{
GameId: gameId,
GroupId: txGroupId,
Mode: uint64(mode),
User: &userProxy.User{Id: myUserId, Nick: nick1, Avatar: avatar1},
OtherUser: &userProxy.User{Id: otherUserId, Nick: nick2, Avatar: avatar2},
GameCode: gameCode,
}
if buffer, err := proto.Marshal(msg); err == nil {
userIds := []uint64{myUserId}
rspUids, err := multicast(userIds, MsgTypeLobbyMatchSuccess, buffer)
//记录socket,注意闭包问题
go func(userIds []uint64, msg *userProxy.GroupMicChange, rspUids []uint64, err error) {
go func(userIds []uint64, msg *userProxy.LobbyMatchSuccess, rspUids []uint64, err error) {
buf, _ := json.Marshal(msg)
AddRpcLogs(MsgTypeGroupMicChange, userIds, string(buf[:]), rspUids, err)
AddRpcLogs(MsgTypeLobbyMatchSuccess, userIds, string(buf[:]), rspUids, err)
}(userIds, msg, rspUids, err)
if err != nil {
mylogrus.MyLog.Errorf("grpc SendSocketMicChange send fail")
mylogrus.MyLog.Errorf("grpc LobbyMatchSuccess send fail")
return err
} else {
mylogrus.MyLog.Info("grpc LobbyMatchSuccess send success")
}
} else {
return err
}
return nil
}
// h5游戏静音
func SendH5GameMute(userId uint64) error {
msg := &userProxy.H5GameVoiceMute{}
if buffer, err := proto.Marshal(msg); err == nil {
rspUids, err := multicast([]uint64{userId}, MsgTypeH5GameMute, buffer)
//记录socket,注意闭包问题
go func(userId uint64, msg *userProxy.H5GameVoiceMute, rspUids []uint64, err error) {
buf, _ := json.Marshal(msg)
AddRpcLog(MsgTypeH5GameMute, userId, string(buf[:]), rspUids, err)
}(userId, msg, rspUids, err)
if err != nil {
mylogrus.MyLog.Errorf("grpc SendH5GameMute send fail")
return err
} else {
mylogrus.MyLog.Info("grpc SendH5GameMute send success")
}
} else {
return err
}
return nil
}
// h5游戏开音
func SendH5GameUnMute(userId uint64) error {
msg := &userProxy.H5GameVoiceUnMute{}
if buffer, err := proto.Marshal(msg); err == nil {
rspUids, err := multicast([]uint64{userId}, MsgTypeH5GameUnMute, buffer)
//记录socket,注意闭包问题
go func(userId uint64, msg *userProxy.H5GameVoiceUnMute, rspUids []uint64, err error) {
buf, _ := json.Marshal(msg)
AddRpcLog(MsgTypeH5GameUnMute, userId, string(buf[:]), rspUids, err)
}(userId, msg, rspUids, err)
if err != nil {
mylogrus.MyLog.Errorf("grpc SendH5GameUnMute send fail")
return err
} else {
mylogrus.MyLog.Info("grpc SendH5GameUnMute send success")
}
} else {
return err
}
return nil
}
// 发送退房通知 原因1.被拉黑;2.被踢出
func SendQuitRoom(userId uint64, reason uint32, txGroupId string) error {
msg := &userProxy.QuitRoom{Reason: reason, GroupId: txGroupId}
if buffer, err := proto.Marshal(msg); err == nil {
rspUids, err := multicast([]uint64{userId}, MsgTypeQuitRoom, buffer)
// 记录socket
// 有err||uid不在线才入库
if err != nil || len(rspUids) > 0 {
go func(userId uint64, msg *userProxy.QuitRoom, rspUids []uint64, err error) {
buf, _ := json.Marshal(msg)
AddRpcLog(MsgTypeQuitRoom, userId, string(buf[:]), rspUids, err)
}(userId, msg, rspUids, err)
}
if err != nil {
mylogrus.MyLog.Errorf("grpc SendQuitRoom send fail")
return err
} else {
mylogrus.MyLog.Info("grpc SendSocketMicChange send success")
mylogrus.MyLog.Info("grpc SendQuitRoom send success")
}
} else {
return err
......
......@@ -16,4 +16,33 @@ charge_month:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o charge_month charge_month.go
user_register_stat:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o user_register_stat user_register_stat.go
h5_game_yellow:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o h5_game_yellow h5_game_yellow.go
fruit_fix:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o fruit_fix fruit_fix.go
fruit_day_award:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o fruit_day_award fruit_day_award.go
race_day_award:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o race_day_award race_day_award.go
race_ksa_rank:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o race_ksa_rank race_ksa_rank.go
promotion_data:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o promotion_data promotion_data.go
group_room_visit500:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o group_room_visit500 group_room_visit500.go
svip_user_charge:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o svip_user_charge svip_user_charge.go
act_710_data:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o act_710_data act_710_data.go
clear_redis:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o clear_redis clear_redis.go
charge_history_sum:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o charge_history_sum charge_history_sum.go
svip_history_top:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o svip_history_top svip_history_top.go
user_wealth_high:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o user_wealth_high user_wealth_high.go
history_charge_with_agent:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o history_charge_with_agent history_charge_with_agent.go
analyze_hilo:
go build -o analyze_hilo.exe analyze_hilo.go
package main
import (
"fmt"
"git.hilo.cn/hilo-common/script/model"
"git.hilo.cn/hilo-common/script/mysql"
"github.com/tealeg/xlsx"
"strings"
)
type Act710Data struct {
Code string
SendUserId uint64
ActDiamond uint64
Levels []int `gorm:"-"`
RealDiamond uint64
}
func ats39(a interface{}) string {
return fmt.Sprintf("%v", a)
}
type ActUserAward struct {
Level int
}
func main() {
var data []Act710Data
if err := mysql.ProdReadOnlyDB.Table("act_gift_record").
Where("activity_id = 710").
Select("send_user_id,SUM(diamond) act_diamond").
Group("send_user_id").Find(&data).Error; err != nil {
panic(err)
}
for i, v := range data {
var user model.User
if err := mysql.ProdReadOnlyDB.Model(model.User{}).Where("id = ? ", v.SendUserId).First(&user).Error; err != nil {
panic(err)
}
var realDiamond uint64
if err := mysql.ProdReadOnlyDB.Table("gift_operate").
Where("send_user_id = ? AND res_gift_id in (4766,4767,4768,4769) AND created_time >= \"2024-01-01 05:00:00\" AND created_time <= \"2024-01-08 05:00:00\"", v.SendUserId).
Select("SUM(send_user_diamond) real_diamond").Scan(&realDiamond).Error; err != nil {
panic(err)
}
data[i].Code = user.Code
data[i].RealDiamond = realDiamond
var levels []ActUserAward
if err := mysql.ProdReadOnlyDB.Table("act_user_award").Where("activity_id = 710 AND user_id = ?", v.SendUserId).Select("level").Find(&levels).Error; err != nil {
panic(err)
}
var l []int
for _, v := range levels {
l = append(l, v.Level)
}
data[i].Levels = l
//break
}
excelFileName := fmt.Sprintf("./710数据.xlsx")
xlFile := xlsx.NewFile()
sheet, _ := xlFile.AddSheet("charge")
row := sheet.AddRow()
c1, c2, c3, c4 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
c1.Value, c2.Value, c3.Value, c4.Value = "用户", "实际送礼", "活动统计送礼", "已经领取的任务"
for _, d := range data {
row := sheet.AddRow()
c1, c2, c3, c4 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
var l []string
for _, v := range d.Levels {
l = append(l, fmt.Sprintf("%v", v))
}
levels := strings.Join(l, ",")
c1.Value, c2.Value, c3.Value, c4.Value = ats39(d.Code), ats39(d.RealDiamond), ats39(d.ActDiamond), ats39(levels)
}
_ = xlFile.Save(excelFileName)
}
This diff is collapsed.
package main
import (
"bufio"
"encoding/json"
"fmt"
"github.com/tealeg/xlsx"
"log"
"os"
"strings"
)
// LogEntry 表示每行日志记录的结构
type DataD struct {
File string `json:"file"`
Func string `json:"func"`
Level string `json:"level"`
Msg string `json:"msg"`
Time string `json:"time"`
}
// LogEntry 表示日志记录的结构
type LogEntry struct {
Content string `json:"__CONTENT__"`
}
type RealData struct {
Uid string
Ip string
Lang string
Timezone string
Country string
CountryCode string
Imei string
Device string
Version string
Carrier string
Vpn string
Time string
}
func main() {
// 打开文件
file, err := os.Open("log.json")
if err != nil {
log.Fatalf("无法打开文件: %v", err)
}
defer file.Close()
var res []RealData
scanner := bufio.NewScanner(file)
for scanner.Scan() {
// 读取每一行
line := scanner.Text()
// 解析JSON
var entry LogEntry
err := json.Unmarshal([]byte(line), &entry)
if err != nil {
log.Printf("解析JSON失败: %v", err)
continue
}
var data DataD
json.Unmarshal([]byte(strings.Replace(entry.Content, "\\", "", -1)), &data)
// 打印解析后的结构
realDatas := strings.Split(data.Msg, "--")
uid := strings.Split(realDatas[1], ":")
ip := strings.Split(realDatas[2], ":")
lang := strings.Split(realDatas[3], ":")
timezone := strings.Split(realDatas[4], ":")
country := strings.Split(realDatas[5], ":")
countryCode := strings.Split(realDatas[6], ":")
imei := strings.Split(realDatas[7], ":")
device := strings.Split(realDatas[8], ":")
version := strings.Split(realDatas[9], ":")
carrier := strings.Split(realDatas[10], ":")
vpn := strings.Split(realDatas[11], ":")
fmt.Printf("uid:%v,ip:%v,lang:%v,timezone:%v,country:%v,countryCode:%v,imei:%v,device:%v,version:%v,carrier:%v,vpn:%v,time:%v\n",
uid[1], ip[1], lang[1], timezone[1], country[1], countryCode[1], imei[1], device[1], version[1], carrier[1], vpn[1], data.Time)
res = append(res, RealData{
Uid: uid[1],
Ip: ip[1],
Lang: lang[1],
Timezone: timezone[1],
Country: country[1],
CountryCode: countryCode[1],
Imei: imei[1],
Device: device[1],
Version: version[1],
Carrier: carrier[1],
Vpn: vpn[1],
Time: data.Time,
})
}
if err := scanner.Err(); err != nil {
log.Fatalf("读取文件时出错: %v", err)
}
excelFileName := fmt.Sprintf("./用户地区分析.xlsx")
xlFile := xlsx.NewFile()
sheet, err := xlFile.AddSheet("wealth")
if err != nil {
panic(err)
}
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12 := row.AddCell(), row.AddCell(), row.AddCell(), 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, c10.Value, c11.Value, c12.Value =
"uid", "ip", "lang", "timezone", "country", "countryCode", "imei", "device", "version", "carrier", "vpn", "time"
for _, d := range res {
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12 := row.AddCell(), row.AddCell(), row.AddCell(), 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, c10.Value, c11.Value, c12.Value =
d.Uid, d.Ip, d.Lang, d.Timezone, d.Country, d.CountryCode, d.Imei, d.Device, d.Version, d.Carrier, d.Vpn, d.Time
}
_ = xlFile.Save(excelFileName)
}
package main
import (
"fmt"
"git.hilo.cn/hilo-common/script/mysql"
"github.com/tealeg/xlsx"
"gorm.io/gorm"
)
type ChargeHistoryData struct {
UserId uint64
Code string
Country string
Dollar float64 // 累充金额$
SvipLevel int
MoneyMaxDollar float64 // 最高当月充值金额$
Month string
}
func ats40(a interface{}) string {
return fmt.Sprintf("%v", a)
}
func main() {
var charges []ChargeHistoryData
if err := mysql.ProdReadOnlyDB.Raw("select id as user_id,code,SUM(dollar) as dollar,country FROM " +
"(select u.id,u.`code`,SUM(price) / 100 as dollar,u.country FROM pay_order p, `user` u where u.id = p.user_id AND p.`status` = 2 AND `type` = 0 group by user_id UNION ALL select u.id,u.code,SUM(dollar) / 100 as dollar,u.country FROM dealer_transfer_detail d, `user` u where u.id = d.receiver_id group by receiver_id UNION ALL " +
"select u.id,u.code,SUM(dollar) / 100 as dollar,u.country FROM dealer_transfer_detail_pink d, `user` u where u.id = d.receiver_id group by receiver_id) t " +
"where country in (SELECT name FROM res_country where area = 1) group by code order by dollar DESC").Find(&charges).Error; err != nil {
panic(err)
}
for i, uc := range charges {
md, month := GetUserMonthMaxCharge2(uc.UserId)
charges[i].Month = month
charges[i].MoneyMaxDollar = md
charges[i].SvipLevel = GetUserSvip(uc.UserId)
//break
}
excelFileName := fmt.Sprintf("./阿语历史充值.xlsx")
xlFile := xlsx.NewFile()
sheet, err := xlFile.AddSheet("charge")
if err != nil {
panic(err)
}
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
c1.Value, c2.Value, c3.Value, c4.Value, c5.Value, c6.Value = "用户ID", "累充金额$", "SVIP等级", "最高当月充值金额$", "充值月份", "国家"
for _, d := range charges {
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
c1.Value, c2.Value, c3.Value, c4.Value, c5.Value, c6.Value = d.Code, ats40(d.Dollar), ats40(d.SvipLevel), ats40(d.MoneyMaxDollar), d.Month, d.Country
}
_ = xlFile.Save(excelFileName)
}
func GetUserMonthMaxCharge2(uid uint64) (float64, string) {
type MD struct {
UserId uint64
D string
Dollar float64
}
var md []MD
if err := mysql.ProdReadOnlyDB.Raw("select user_id,d,SUM(dollar) / 100 dollar \nFROM (\nSELECT\n\tuser_id,\n\tDATE_FORMAT(created_time,\"%Y-%m\") as d,\n\tSUM(price) as dollar\nFROM\n\t`pay_order`\nWHERE\n\t`status` = '2' AND `type` = 0 AND user_id = ?\nGROUP BY d UNION ALL \nSELECT\n\treceiver_id user_id,\n\tDATE_FORMAT(created_time,\"%Y-%m\") as d,\n\tSUM(dollar) as dollar\nFROM\n\t`dealer_transfer_detail`\nWHERE receiver_id = ?\nGROUP BY d UNION ALL \nSELECT\n\treceiver_id user_id,\n\tDATE_FORMAT(created_time,\"%Y-%m\") as d,\n\tSUM(dollar) as dollar\nFROM\n\t`dealer_transfer_detail_pink`\nWHERE receiver_id = ?\nGROUP BY d\n) t GROUP BY d order by dollar desc ", uid, uid, uid).Find(&md).Error; err != nil {
panic(err)
}
if len(md) > 0 {
return md[0].Dollar, md[0].D
}
return 0, ""
}
func GetUserSvip(uid uint64) int {
type UserSvip struct {
UserId uint64
Level int
}
var res UserSvip
if err := mysql.ProdReadOnlyDB.Table("user_svip").Where("user_id = ?", uid).First(&res).Error; err != nil {
if err != gorm.ErrRecordNotFound {
panic(err)
}
}
return res.Level
}
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
"log"
)
const redisAddr = "172.28.16.47:6379" // 替换为你的Redis地址
func main() {
// 创建Redis客户端
client := redis.NewClient(&redis.Options{
Addr: redisAddr,
DB: 0, // 替换为你的数据库编号
//Password: "yPyZH1DYMJhrVQgr",
})
// 关闭连接
defer func() {
if err := client.Close(); err != nil {
log.Fatalf("Failed to close Redis connection: %v", err)
}
}()
// 获取所有以"user_qps_"为前缀的键
keys, err := getKeysWithPrefix(client, "game:level:points:")
if err != nil {
log.Fatalf("Failed to get keys with prefix: %v", err)
}
println(len(keys))
// 谨慎打开-删除所有匹配的键
//err = deleteKeys(client, keys)
//if err != nil {
// log.Fatalf("Failed to delete keys: %v", err)
//}
fmt.Println("Cleanup completed.")
}
// 获取所有以特定前缀开头的键
func getKeysWithPrefix(client *redis.Client, prefix string) ([]string, error) {
ctx := context.Background()
var cursor uint64
var keys []string
var err error
for {
var result []string
result, cursor, err = client.Scan(ctx, cursor, prefix+"*", 1000).Result()
if err != nil {
return nil, err
}
keys = append(keys, result...)
if cursor == 0 {
break
}
}
return keys, nil
}
// 删除指定的键
// 谨慎打开删除动作
func deleteKeys(client *redis.Client, keys []string) error {
ctx := context.Background()
for index, key := range keys {
// 打开del操作
err := client.Del(ctx, key).Err()
if err != nil {
return err
}
log.Printf("key:%v,index:%v\n", key, index)
}
return nil
}
package main
import (
"encoding/json"
"fmt"
"git.hilo.cn/hilo-common/script/mysql"
"github.com/tealeg/xlsx"
"io/ioutil"
"net/http"
)
type FruitDayAward struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
Total int `json:"total"`
Data []struct {
Rank int `json:"rank"`
UserCode string `json:"userCode"`
Country string `json:"country"`
Stake int `json:"stake"`
Award int `json:"award"`
ProfitLoss int `json:"profitLoss"`
ChargeMoney float64 `json:"chargeMoney"`
} `json:"data"`
} `json:"data"`
}
type ResCountry struct {
Name string
Area int
}
type UserSvip2 struct {
Code string
Level int
}
func ats32(a interface{}) string {
return fmt.Sprintf("%v", a)
}
func main() {
url := "https://apiv2.faceline.live/v1/fruitMachine/rank/award?lang=zh-cn&pageIndex=1&pageSize=5000&beginDate=2023-08-31&endDate=2023-08-31&userCode=&timezone=1"
method := "GET"
client := &http.Client{}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("nonce", "hilo")
req.Header.Add("token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjI1MSwiRXh0ZXJuYWxJZCI6IiIsImV4cCI6MTY5NTc5ODg5NX0.1EvN1YLCFuHpZtparqUu7VOX7saoa2sYrcMi6LhVb3w")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err)
}
var response = new(FruitDayAward)
err = json.Unmarshal(body, &response)
if err != nil {
panic(err)
}
var countryArea = make(map[string]string)
// get from db
var countries []ResCountry
if err := mysql.ProdReadOnlyDB.Model(ResCountry{}).Find(&countries).Error; err != nil {
panic(err)
}
for _, v := range countries {
area := "阿语"
if v.Area == 2 {
area = "非阿语"
}
countryArea[v.Name] = area
}
var svipMap = make(map[string]int)
var codes []string
for _, v := range response.Data.Data {
codes = append(codes, v.UserCode)
}
var svips []UserSvip2
if err := mysql.ProdReadOnlyDB.Table("user_svip s").Joins("INNER JOIN user u ON u.id = s.user_id").Select("u.code,s.level").Where("u.code in ?", codes).Find(&svips).Error; err != nil {
panic(err)
}
for _, v := range svips {
svipMap[v.Code] = v.Level
}
excelFileName := fmt.Sprintf("./0831水果机中奖榜.xlsx")
xlFile := xlsx.NewFile()
sheet, _ := xlFile.AddSheet("charge")
row := sheet.AddRow()
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 = "排名", "用户ID", "区域", "国家", "SVIP等级", "投注钻石数", "中奖钻石数", "盈亏(中奖-投注)", "充值金额$"
for _, d := range response.Data.Data {
row := sheet.AddRow()
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 =
ats32(d.Rank), ats32(d.UserCode), countryArea[d.Country], ats32(d.Country), ats32(svipMap[d.UserCode]), ats32(d.Stake), ats32(d.Award), ats32(d.ProfitLoss), ats32(d.ChargeMoney)
}
_ = xlFile.Save(excelFileName)
}
package main
import (
"encoding/json"
"fmt"
"github.com/tealeg/xlsx"
"io/ioutil"
"net/http"
)
type FruitDayDetailResp struct {
Code int `json:"code,omitempty"`
Message string `json:"message,omitempty"`
Data struct {
Total int `json:"total,omitempty"`
Data []struct {
Date string `json:"Date,omitempty"`
Round int `json:"Round,omitempty"`
Pool int `json:"Pool,omitempty"`
UserNum int `json:"UserNum,omitempty"`
Stake int `json:"Stake,omitempty"`
Total int `json:"Total,omitempty"`
AwardNum int `json:"AwardNum,omitempty"`
Award int `json:"Award,omitempty"`
Recycle int `json:"Recycle,omitempty"`
LeftOver int `json:"LeftOver,omitempty"`
FruitId uint64 `json:"FruitId"`
} `json:"data,omitempty"`
} `json:"data,omitempty"`
}
func ats48(a interface{}) string {
return fmt.Sprintf("%v", a)
}
func main() {
url := "http://43.135.4.137:8088/v1/fruitMachine/day/detail?lang=zh-cn&pageIndex=1&pageSize=10000&date=2025-11-11"
method := "GET"
client := &http.Client{}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("nonce", "hilo")
req.Header.Add("token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsIkV4dGVybmFsSWQiOiIiLCJleHAiOjE3MTk3NDMzNDd9.O9UCpSAR82xW_w9wKNXOP5jW3lfX5TPYkv8un8Gu1q8")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
var response = new(FruitDayDetailResp)
json.Unmarshal(body, &response)
excelFileName := fmt.Sprintf("./水果机每日明细.xlsx")
xlFile := xlsx.NewFile()
sheet, _ := xlFile.AddSheet("charge")
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6, c7 := 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 = "轮次", "开奖位置", "投注", "奖励", "奖池盈余", "系统回收", "本轮盈余"
for _, d := range response.Data.Data {
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6, c7 := 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 = ats48(d.Round), ats48(d.FruitId), ats48(d.Stake), ats48(d.Award), ats48(d.Pool), ats48(d.Recycle), ats48(d.LeftOver)
}
_ = xlFile.Save(excelFileName)
}
......@@ -36,7 +36,8 @@ func ats28(a interface{}) string {
}
func main() {
url := "https://apiv2.faceline.live/v1/fruitMachine/day/stats?lang=zh-cn&pageIndex=1&pageSize=100000&beginDate=2023-04-01&endDate=2023-06-31"
//url := "https://apiv2.faceline.live/v1/fruitMachine/day/stats?lang=zh-cn&pageIndex=1&pageSize=100000&beginDate=2024-04-01&endDate=2024-06-30"
url := "https://apiv2.faceline.live/v1/race/day/stats?lang=zh-cn&pageIndex=1&pageSize=100000&beginDate=2024-04-01&endDate=2024-06-30"
method := "GET"
client := &http.Client{}
......@@ -47,7 +48,7 @@ func main() {
return
}
req.Header.Add("nonce", "hilo")
req.Header.Add("token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjI1MSwiRXh0ZXJuYWxJZCI6IiIsImV4cCI6MTY5MDYwOTY4NX0.dVsFGjc1wLPxqhAMloXICs-xQcVxM5FkweLvFta3ncA")
req.Header.Add("token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjI1MSwiRXh0ZXJuYWxJZCI6IiIsImV4cCI6MTcyMjczNzEzMH0.LZDmjeRkUiYIQA7hVnbb6_xFQtyGf9yev-y6NQqVhRY")
res, err := client.Do(req)
if err != nil {
......@@ -63,7 +64,7 @@ func main() {
}
var response = new(AutoGenerated)
json.Unmarshal(body, &response)
excelFileName := fmt.Sprintf("./水果机每日统计.xlsx")
excelFileName := fmt.Sprintf("./赛车每日统计-4-6月.xlsx")
xlFile := xlsx.NewFile()
sheet, _ := xlFile.AddSheet("charge")
row := sheet.AddRow()
......
package main
import (
"fmt"
"git.hilo.cn/hilo-common/script/mysql"
"github.com/tealeg/xlsx"
"gorm.io/gorm"
)
var userIds = []uint64{3117191}
type FruitMachine struct {
Date string
Round int64
FruitId int
}
type FruitMachineStake2 struct {
Stake int64
}
func main() {
var Plus = make(map[int]int64) // fruitId->plush
Plus[1] = 5
Plus[2] = 5
Plus[3] = 5
Plus[4] = 5
Plus[5] = 10
Plus[6] = 15
Plus[7] = 25
Plus[8] = 45
var data = make(map[uint64]int64)
for round := 194; round <= 216; round++ {
var fm = new(FruitMachine)
if err := mysql.ProdReadOnlyDB.Model(FruitMachine{}).Where("`date` = '2023-08-09'").Where("round = ?", round).First(fm).Error; err != nil {
panic(err)
}
for _, userId := range userIds {
var fs = new(FruitMachineStake2)
if err := mysql.ProdReadOnlyDB.Table("fruit_machine_stake").
Where("`date` = '2023-08-09'").
Where("round = ?", round).
Where("fruit_id = ?", fm.FruitId).
Where("user_id = ?", userId).First(&fs).Error; err != nil {
if err != gorm.ErrRecordNotFound {
panic(err)
}
continue
}
data[userId] += fs.Stake * Plus[fm.FruitId]
}
}
excelFileName := fmt.Sprintf("./水果机.xlsx")
xlFile := xlsx.NewFile()
sheet, _ := xlFile.AddSheet("charge")
row := sheet.AddRow()
c1, c2 := row.AddCell(), row.AddCell()
c1.Value, c2.Value = "userId", "should"
for userId, award := range data {
row := sheet.AddRow()
c1, c2 := row.AddCell(), row.AddCell()
c1.Value, c2.Value = fmt.Sprintf("%d", userId), fmt.Sprintf("%d", award)
}
_ = xlFile.Save(excelFileName)
}
package main
import (
"fmt"
"git.hilo.cn/hilo-common/script/mysql"
"github.com/tealeg/xlsx"
)
type FruitSlotRaceChargeHistoryData struct {
UserId uint64
Code string
Area string
Country string
Bet uint64 // 5月份
Dollar float64 // 累充金额$
}
func ats42(a interface{}) string {
return fmt.Sprintf("%v", a)
}
var start, end = "2024-05-27 05:00:00", "2024-06-03 05:00:00" // 左闭右开,沙特时间
func main() {
var charges []FruitSlotRaceChargeHistoryData
if err := mysql.ProdReadOnlyDB.Raw("select id as user_id,code,SUM(dollar) as dollar,country FROM " +
"(select u.id,u.`code`,SUM(price) / 100 as dollar,u.country FROM pay_order p, `user` u where u.id = p.user_id AND p.`status` = 2 AND `type` = 0 AND p.created_time >= \"" + start + "\" AND p.created_time < \"" + end + "\" group by user_id" +
" UNION ALL " +
"select u.id,u.code,SUM(dollar) / 100 as dollar,u.country FROM dealer_transfer_detail d, `user` u where u.id = d.receiver_id AND d.created_time >= \"" + start + "\" AND d.created_time < \"" + end + "\" group by receiver_id " +
" UNION ALL " +
"select u.id,u.code,SUM(dollar) / 100 as dollar,u.country FROM dealer_transfer_detail_pink d, `user` u where u.id = d.receiver_id AND d.created_time >= \"" + start + "\" AND d.created_time < \"" + end + "\" group by receiver_id" +
") t group by code order by dollar DESC").Find(&charges).Error; err != nil {
panic(err)
}
type ResCountry struct {
Name string
Area int
}
var countries []ResCountry
if err := mysql.ProdReadOnlyDB.Model(ResCountry{}).Find(&countries).Error; err != nil {
panic(err)
}
countryMap := make(map[string]string)
for _, c := range countries {
countryMap[c.Name] = "阿语"
if c.Area == 2 {
countryMap[c.Name] = "非阿语"
}
}
var userIds []uint64
for _, v := range charges {
userIds = append(userIds, v.UserId)
}
bets := GetBets(userIds)
for i, uc := range charges {
charges[i].Area = countryMap[uc.Country]
charges[i].Bet = bets[uc.UserId]
}
excelFileName := fmt.Sprintf("./5月27日-6月02日水果机slot赛车数据.xlsx")
xlFile := xlsx.NewFile()
sheet, err := xlFile.AddSheet("data")
if err != nil {
panic(err)
}
row := sheet.AddRow()
c1, c2, c3, c4, c5 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
c1.Value, c2.Value, c3.Value, c4.Value, c5.Value = "用户ID", "区域", "国家", "5月水果机+Slot+赛车的总下注钻石额", "上周充值金额"
for _, d := range charges {
row := sheet.AddRow()
c1, c2, c3, c4, c5 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
c1.Value, c2.Value, c3.Value, c4.Value, c5.Value = d.Code, d.Area, d.Country, ats42(d.Bet), ats42(d.Dollar)
}
_ = xlFile.Save(excelFileName)
}
func GetBets(userIds []uint64) map[uint64]uint64 {
type Bet struct {
UserId uint64
Num uint64
}
var bets []Bet
res := make(map[uint64]uint64)
sql := "select user_id,SUM(num) num FROM diamond_account_detail_202405 where operate_type in (69,39,117) AND created_time >= \"" + start + "\" AND created_time < \"" + end + "\" and user_id in ? group by user_id"
if err := mysql.ProdReadOnlyDB.Raw(sql, userIds).Find(&bets).Error; err != nil {
panic(err)
}
for _, v := range bets {
res[v.UserId] = v.Num
}
return res
}
package main
import (
"fmt"
"git.hilo.cn/hilo-common/script/model"
"git.hilo.cn/hilo-common/script/mysql"
"github.com/tealeg/xlsx"
)
type GameRacePlayer struct {
Date string
Round int
Award int64
Stake int64
Code string
UserId uint64
}
func main() {
var rows []GameRacePlayer
if err := mysql.ProdReadOnlyDB.Table("game_race_player").Select("`date`,round,user_id,award,u.code").
Joins("JOIN user u ON u.id = user_id").Where("award >= 1000000 AND `date` = '2023-11-06'").Find(&rows).Error; err != nil {
panic(err)
}
for i, v := range rows {
var user model.User
if err := mysql.ProdReadOnlyDB.Table("user").Where("id = ?", v.UserId).First(&user).Error; err != nil {
panic(err)
}
rows[i].Code = user.Code
var stake int64
if err := mysql.ProdReadOnlyDB.Table("game_race_stake").Select("SUM(stake)").
Where("`date` = ? AND round = ? AND user_id = ?", v.Date, v.Round, v.UserId).Scan(&stake).Error; err != nil {
panic(err)
}
rows[i].Stake = stake
}
excelFileName := fmt.Sprintf("./赛车1M.xlsx")
xlFile := xlsx.NewFile()
sheet, _ := xlFile.AddSheet("race")
row := sheet.AddRow()
c1, c2, c3, c4 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
c1.Value, c2.Value, c3.Value, c4.Value = "用户ID", "轮次", "投注", "中奖"
for _, d := range rows {
row := sheet.AddRow()
c1, c2, c3, c4 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
c1.Value, c2.Value, c3.Value, c4.Value =
ats37(d.Code), ats37(d.Round), ats37(d.Stake), ats37(d.Award)
}
_ = xlFile.Save(excelFileName)
}
func ats37(d interface{}) string {
return fmt.Sprintf("%v", d)
}
package main
import (
"git.hilo.cn/hilo-common/mylogrus"
"git.hilo.cn/hilo-common/script/mysql"
"time"
)
type GiftOperate struct {
ResGiftId uint64
GiftN uint64
SendUserId uint64
ReceiveUserId uint64
SendUserDiamond uint64
ReceiveUserDiamond uint64
ReceiveUserBean uint64
SceneUid string
BagId uint64
ID uint64 `gorm:"primary_key"`
CreatedTime time.Time `gorm:"->"`
UpdatedTime time.Time `gorm:"->"`
}
func main() {
var gift GiftOperate
if err := mysql.ProdReadOnlyDB.Table("gift_operate_2").Order("id ASC").First(&gift).Error; err != nil {
mylogrus.MyLog.Errorf("GiftOperateTable fail:%v", err)
panic("e")
}
println(time.Now().Sub(gift.CreatedTime).Hours())
if !gift.CreatedTime.IsZero() && time.Now().Sub(gift.CreatedTime) >= time.Hour*24*90 && time.Now().Hour() == 10 { // newTable已经过去90天
println(true)
} else {
println(false)
}
}
......@@ -75,7 +75,7 @@ func main() {
pageIndex := 1
pageSize := 500
for {
url := fmt.Sprintf("https://apiv2.faceline.live/v1/groupPower/page?lang=zh-cn&ownerCode=&beginDate=2023-04-01&endDate=2023-04-30&pageIndex=%d&pageSize=%d&status=1", pageIndex, pageSize)
url := fmt.Sprintf("https://apiv2.faceline.live/v1/groupPower/page?lang=zh-cn&ownerCode=&beginDate=2023-01-01&endDate=2023-10-30&pageIndex=%d&pageSize=%d&status=1", pageIndex, pageSize)
method := "GET"
client := &http.Client{}
......@@ -86,7 +86,7 @@ func main() {
return
}
req.Header.Add("nonce", "hilo")
req.Header.Add("token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjI1MSwiRXh0ZXJuYWxJZCI6IiIsImV4cCI6MTY4ODU0MDUxOX0.VWJAIv0iWtOgnefrfE5Wbeqc1MvmGjaxuRc47M1PvH8")
req.Header.Add("token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjI1MSwiRXh0ZXJuYWxJZCI6IiIsImV4cCI6MTY5ODM5MjYzNH0.2zOdawVOI8G_4U1xeQJib_s9-JqUORgcTEx7EACj8Wo")
res, err := client.Do(req)
if err != nil {
......@@ -111,9 +111,9 @@ func main() {
data = append(data, resp.Data.Data...)
pageIndex++
}
excelFileName := fmt.Sprintf("./家族4月数据.xlsx")
excelFileName := fmt.Sprintf("./家族2023数据.xlsx")
xlFile := xlsx.NewFile()
sheet, err := xlFile.AddSheet("slot")
sheet, err := xlFile.AddSheet("family")
if err != nil {
panic(err)
}
......
package main
import (
"context"
"fmt"
"git.hilo.cn/hilo-common/mylogrus"
"git.hilo.cn/hilo-common/script/mysql"
"github.com/go-redis/redis/v8"
"github.com/spf13/cast"
"github.com/tealeg/xlsx"
)
var RedisClient *redis.Client
func init() {
RedisClient = redis.NewClient(&redis.Options{
Addr: "172.28.16.47:6379", // redis cluster
Password: "",
DB: 0, // use default DB
PoolSize: 20,
MinIdleConns: 20,
})
pong, err := RedisClient.Ping(context.Background()).Result()
if err != nil {
panic(err)
} else {
mylogrus.MyLog.Info("redis db0 connection success - ", pong)
}
}
type GroupRoomVisit struct {
GroupId string
GroupCode string
Country string
Visit string
Consume string
Area string
}
func getGroupCode(groupId string) string {
var code string
if err := mysql.ProdReadOnlyDB.Table("group_info").Where("im_group_id = ?", groupId).Select("code").Scan(&code).Error; err != nil {
panic(err)
}
return code
}
func getGroupCountry(groupId string) string {
var code string
if err := mysql.ProdReadOnlyDB.Table("group_info").Where("im_group_id = ?", groupId).Select("country").Scan(&code).Error; err != nil {
panic(err)
}
return code
}
func getArea(country string) string {
code := "非阿语区"
var area int
if err := mysql.ProdReadOnlyDB.Table("res_country").Where("name = ?", country).Select("area").Scan(&area).Error; err != nil {
panic(err)
}
if area == 1 {
code = "阿语区"
}
return code
}
func getConsume(groupId string) string {
var result int64
if err := mysql.ProdReadOnlyDB.Table("room_day_consume").Where("group_id = ?", groupId).Select("SUM(diamond)").Scan(&result).Error; err != nil {
//panic(err)
}
return cast.ToString(result)
}
func main() {
var data []GroupRoomVisit
zRes, err := RedisClient.ZRevRangeByScoreWithScores(context.Background(), "room_visit_count_zset", &redis.ZRangeBy{
Min: fmt.Sprintf("%d", 500),
Max: "+inf",
}).Result()
if err != nil {
panic(err)
}
for _, v := range zRes {
d := GroupRoomVisit{
GroupId: cast.ToString(v.Member),
GroupCode: "",
Country: "",
Visit: cast.ToString(v.Score),
Consume: "",
}
code := getGroupCode(d.GroupId)
country := getGroupCountry(d.GroupId)
area := getArea(country)
consume := getConsume(d.GroupId)
d.GroupCode = code
d.Country = country
d.Area = area
d.Consume = consume
data = append(data, d)
}
excelFileName := fmt.Sprintf("./房间500热度.xlsx")
xlFile := xlsx.NewFile()
sheet, err := xlFile.AddSheet("room")
if err != nil {
panic(err)
}
row := sheet.AddRow()
c1, c2, c3, c4, c5 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
c1.Value, c2.Value, c3.Value, c4.Value, c5.Value = "房间code", "国家", "访客热度", "房间奖杯", "区域"
for _, d := range data {
row := sheet.AddRow()
c1, c2, c3, c4, c5 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
c1.Value, c2.Value, c3.Value, c4.Value, c5.Value = d.GroupCode, d.Country, d.Visit, d.Consume, d.Area
}
_ = xlFile.Save(excelFileName)
}
package main
import (
"fmt"
"git.hilo.cn/hilo-common/script/model"
"git.hilo.cn/hilo-common/script/mysql"
"github.com/tealeg/xlsx"
)
type H5GameData struct {
Game string // 游戏名字
Date string // 日期
UserId uint64 // 用户原始id
Code string // 用户ID
Stake uint64 // 下注
Award uint64 // 奖励
GoldCharge uint64 // 当日金币充值
DiamondCharge uint64 // 当日钻石充值
}
func ats31(a interface{}) string {
return fmt.Sprintf("%v", a)
}
func main() {
wheel()
fruit()
}
func wheel() {
type GameListRank struct {
Date string
GameId uint64
UserId uint64
Stake uint64
Award uint64
}
var rows []GameListRank
// 摩天轮sql
if err := mysql.ProdReadOnlyDB.Model(GameListRank{}).Where("game_id = 11").Find(&rows).Error; err != nil {
panic(err)
}
var userIds []uint64
for _, v := range rows {
userIds = append(userIds, v.UserId)
}
var users []model.User
if err := mysql.ProdReadOnlyDB.Model(model.User{}).Where("id in ?", userIds).Find(&users).Error; err != nil {
panic(err)
}
var uM = make(map[uint64]model.User)
for i := range users {
uM[users[i].Id] = users[i]
}
var data []H5GameData
for _, row := range rows {
data = append(data, H5GameData{
Game: "摩天轮",
Date: row.Date,
UserId: row.UserId,
Stake: row.Stake,
Award: row.Award,
Code: uM[row.UserId].Code,
GoldCharge: getChargeGolds(row.UserId, row.Date),
DiamondCharge: getChargeDiamonds(row.UserId, row.Date),
})
}
excelFileName := fmt.Sprintf("./摩天轮.xlsx")
xlFile := xlsx.NewFile()
sheet, _ := xlFile.AddSheet("charge")
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6, c7, c8 := 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 = "游戏名字", "日期", "用户原始id", "用户ID", "下注", "奖励", "当日金币充值", "当日钻石充值"
for _, d := range data {
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6, c7, c8 := 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 = d.Game, d.Date, ats31(d.UserId), d.Code, ats31(d.Stake), ats31(d.Award), ats31(d.GoldCharge), ats31(d.DiamondCharge)
}
_ = xlFile.Save(excelFileName)
}
func fruit() {
type GameListRank struct {
Date string
GameId uint64
UserId uint64
Stake uint64
Award uint64
}
var rows []GameListRank
// 水果slot
if err := mysql.ProdReadOnlyDB.Model(GameListRank{}).Where("game_id = 12").Find(&rows).Error; err != nil {
panic(err)
}
var userIds []uint64
for _, v := range rows {
userIds = append(userIds, v.UserId)
}
var users []model.User
if err := mysql.ProdReadOnlyDB.Model(model.User{}).Where("id in ?", userIds).Find(&users).Error; err != nil {
panic(err)
}
var uM = make(map[uint64]model.User)
for i := range users {
uM[users[i].Id] = users[i]
}
var data []H5GameData
for _, row := range rows {
data = append(data, H5GameData{
Game: "水果slot",
Date: row.Date,
UserId: row.UserId,
Stake: row.Stake,
Award: row.Award,
Code: uM[row.UserId].Code,
GoldCharge: getChargeGolds(row.UserId, row.Date),
DiamondCharge: getChargeDiamonds(row.UserId, row.Date),
})
}
excelFileName := fmt.Sprintf("./水果slot.xlsx")
xlFile := xlsx.NewFile()
sheet, _ := xlFile.AddSheet("charge")
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6, c7, c8 := 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 = "游戏名字", "日期", "用户原始id", "用户ID", "下注", "奖励", "当日金币充值", "当日钻石充值"
for _, d := range data {
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6, c7, c8 := 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 = d.Game, d.Date, ats31(d.UserId), d.Code, ats31(d.Stake), ats31(d.Award), ats31(d.GoldCharge), ats31(d.DiamondCharge)
}
_ = xlFile.Save(excelFileName)
}
func getChargeDiamonds(userId uint64, date string) uint64 {
var res uint64
type R struct {
Money uint64
}
var money R
if err := mysql.ProdReadOnlyDB.Table("pay_order AS p").
Where("p.status = 2 AND p.`type` = 0 AND platform >= 1 AND platform <= 6"). // type=0 就是用户给自己充值,status=2成功
Where("p.user_id = ? AND DATE(p.created_time) BETWEEN ? AND ?",
userId, date, date).Select("SUM(price) as money").Scan(&money).Error; err != nil {
panic(err)
}
res += money.Money
var money2 R
if err := mysql.ProdReadOnlyDB.Table("dealer_transfer_detail AS t").
Where("t.receiver_id = ? AND DATE(t.created_time) BETWEEN ? AND ?",
userId, date, date).Select("SUM(t.dollar) as money").
Scan(&money2).Error; err != nil {
panic(err)
}
res += money2.Money
return res
}
func getChargeGolds(userId uint64, date string) uint64 {
var res uint64
type R struct {
Money uint64
}
var money R
if err := mysql.ProdReadOnlyDB.Table("pay_order AS p").
Where("p.status = 2 AND p.`type` = 0 AND platform >= 31"). // type=0 就是用户给自己充值,status=2成功
Where("p.user_id = ? AND DATE(p.created_time) BETWEEN ? AND ?",
userId, date, date).Select("SUM(price) as money").Scan(&money).Error; err != nil {
panic(err)
}
res += money.Money
var money2 R
if err := mysql.ProdReadOnlyDB.Table("dealer_transfer_detail_pink AS t").
Where("t.receiver_id = ? AND DATE(t.created_time) BETWEEN ? AND ?",
userId, date, date).Select("SUM(t.dollar) as money").
Scan(&money2).Error; err != nil {
panic(err)
}
res += money2.Money
return res
}
package main
import (
"fmt"
"git.hilo.cn/hilo-common/script/mysql"
"github.com/spf13/cast"
"github.com/tealeg/xlsx"
"gorm.io/gorm"
"time"
)
type ChargeWithAgent struct {
UserId uint64
Code string
Dollar int64
Country string
Area string
LastDealerCode string
}
func main() {
type ResCountry struct {
Name string
Area int
}
var area []ResCountry
if err := mysql.ProdReadOnlyDB.Table("res_country").Find(&area).Error; err != nil {
panic(err)
}
am := make(map[string]string)
for _, v := range area {
am[v.Name] = "非阿语"
if v.Area == 1 {
am[v.Name] = "阿语区"
}
}
sql := `
select id as user_id,code ,SUM(dollar) as dollar ,country FROM (
select u.id,u.code,SUM(price) as dollar,u.country FROM pay_order p, user u where u.id = p.user_id AND p.status = 2 AND type = 0 group by user_id UNION ALL
select u.id,u.code,SUM(dollar) as dollar,u.country FROM dealer_transfer_detail d, user u where u.id = d.receiver_id group by receiver_id UNION ALL
select u.id,u.code,SUM(dollar) as dollar,u.country FROM dealer_transfer_detail_pink d, user u where u.id = d.receiver_id group by receiver_id
) t
-- where country in (SELECT name FROM res_country where area = 1)
group by code order by dollar DESC;
`
var data []ChargeWithAgent
if err := mysql.ProdReadOnlyDB.Raw(sql).Scan(&data).Error; err != nil {
panic(err)
}
for i, d := range data {
data[i].LastDealerCode = getLastDealerCode(d.UserId)
data[i].Area = am[d.Country]
if len(data[i].LastDealerCode) > 0 {
}
println(i)
}
excelFileName := fmt.Sprintf("./历史累充带代理.xlsx")
xlFile := xlsx.NewFile()
sheet, err := xlFile.AddSheet("wealth")
if err != nil {
panic(err)
}
row := sheet.AddRow()
c1, c2, c3, c4, c5 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
c1.Value, c2.Value, c3.Value, c4.Value, c5.Value = "靓号", "充值美分", "国家", "区域", "最近代理"
for _, d := range data {
row := sheet.AddRow()
c1, c2, c3, c4, c5 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
c1.Value, c2.Value, c3.Value, c4.Value, c5.Value = d.Code, cast.ToString(d.Dollar), d.Country, d.Area, d.LastDealerCode
}
_ = xlFile.Save(excelFileName)
}
func getLastDealerCode(userId uint64) string {
type Result struct {
Code string
CreateTime time.Time
}
sql := "SELECT u.code,dealer_id,receiver_id,dealer_transfer_detail.created_time FROM dealer_transfer_detail,user u where u.id = dealer_transfer_detail.dealer_id AND receiver_id = ? order by dealer_transfer_detail.id DESC limit 1"
var res Result
if err := mysql.ProdReadOnlyDB.Raw(sql, userId).Scan(&res).Error; err != nil {
if err != gorm.ErrRecordNotFound {
panic(err)
}
}
sql2 := "SELECT u.code,dealer_id,receiver_id,dealer_transfer_detail_pink.created_time FROM dealer_transfer_detail_pink,user u where u.id = dealer_transfer_detail_pink.dealer_id AND receiver_id = ? order by dealer_transfer_detail_pink.id DESC limit 1"
var res2 Result
if err := mysql.ProdReadOnlyDB.Raw(sql2, userId).Scan(&res2).Error; err != nil {
if err != gorm.ErrRecordNotFound {
panic(err)
}
}
if len(res.Code) > 0 && len(res2.Code) > 0 {
if res.CreateTime.After(res2.CreateTime) {
return res.Code
} else {
return res2.Code
}
}
if len(res.Code) > 0 {
return res.Code
}
return res2.Code
}
......@@ -17,7 +17,7 @@ var TestDB *gorm.DB
func init() {
var err error
options := "?charset=utf8mb4&parseTime=True&loc=Local&time_zone=" + url.QueryEscape("'+8:00'")
dsn := "read_only:hilo1632@(rm-eb3w787dzn9c8g07vuo.mysql.dubai.rds.aliyuncs.com)/hilo" + options
dsn := "hilo_read:hilo_TX_readonly!@#$@(de-cynosdbmysql-grp-rv5zqms3.sql.tencentcdb.com:25642)/hilo" + options
ProdReadOnlyDB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
NamingStrategy: schema.NamingStrategy{SingularTable: true},
......@@ -32,7 +32,7 @@ func init() {
fmt.Printf("database error %v", ProdReadOnlyDB.Error)
}
dsn = "root:yX0jPAhO0I4s2zlA@(47.244.34.27:3306)/hilo" + options
dsn = "hilo_test:cPsTMSA9szQ6B9Y2zFXSvpDdduB8kZxC@(hk-cynosdbmysql-grp-a3wqck8p.sql.tencentcdb.com:22303)/hilo" + options
TestDB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
NamingStrategy: schema.NamingStrategy{SingularTable: true},
......@@ -47,7 +47,7 @@ func init() {
fmt.Printf("database error %v", TestDB.Error)
}
dsn = "nextvideo:ihlUwI4nhi9W88MI@(rm-eb3w787dzn9c8g07vuo.mysql.dubai.rds.aliyuncs.com)/hilo" + options
dsn = "hilo_master:o8NNd8F7e6On2RqIgOhsy1PsiSxROT3n@(de-cynosdbmysql-grp-rv5zqms3.sql.tencentcdb.com:25642)/hilo" + options
ProdWriteDB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
NamingStrategy: schema.NamingStrategy{SingularTable: true},
......
package main
import (
"encoding/json"
"fmt"
"github.com/tealeg/xlsx"
"io/ioutil"
"net/http"
)
type PromotionData struct {
ID int `json:"id"`
AgentCode string `json:"agentCode"` // 推广员id
Name string `json:"name"` // 团队名称
InviteeCode string `json:"inviteeCode"` // 被邀请人id
Platform string `json:"platform"` // 来自平台
PlatformId string `json:"platformId"` // 平台ID
Reason string `json:"reason"` // 邀请原因
GroupCode string `json:"groupCode"` // 群组ID
GroupMemberNum uint `json:"groupMemberNum"` // 群组人数
GroupTotalConsume uint64 `json:"groupTotalConsume"` // 群组奖杯
InviteDate string `json:"inviteDate"` // 邀请日期
MonthPaySum float64 `json:"monthPaySum"` // 30天内充值 $
TwoMonthPaySum float64 `json:"twoMonthPaySum"` // 60天内充值 $
MonthDealPaySum float64 `json:"monthDealPaySum"` // 30天内代理充值 $
}
type PromotionDataResp struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
Total int `json:"total"`
Items []PromotionData `json:"items"`
} `json:"data"`
}
func ats38(a interface{}) string {
return fmt.Sprintf("%v", a)
}
func main() {
var data []PromotionData
pageIndex := 1
pageSize := 1000
for {
url := fmt.Sprintf("https://apiv2.faceline.live/v1/mgr/promotion/invite/data?lang=zh-cn&pageIndex=%d&pageSize=%d&startTime=2024-01-01&endTime=2024-06-30&teamName=&agentCode=&inviteeCode=&platform=All",
pageIndex, pageSize)
method := "GET"
client := &http.Client{}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("nonce", "hilo")
req.Header.Add("token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjI1MSwiRXh0ZXJuYWxJZCI6IiIsImV4cCI6MTcyMjczNzEzMH0.LZDmjeRkUiYIQA7hVnbb6_xFQtyGf9yev-y6NQqVhRY")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
_ = res.Body.Close()
var resp PromotionDataResp
err = json.Unmarshal(body, &resp)
if err != nil {
panic(err)
}
if len(resp.Data.Items) <= 0 {
break
}
data = append(data, resp.Data.Items...)
pageIndex++
}
excelFileName := fmt.Sprintf("./推广员数据1月1日-6月30日.xlsx")
xlFile := xlsx.NewFile()
sheet, err := xlFile.AddSheet("promotion")
if err != nil {
panic(err)
}
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(),
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, c10.Value, c11.Value, c12.Value, c13.Value = "推广员id", "团队名称", "被邀请人id", "来自平台",
"平台ID", "邀请原因", "群组ID", "群组人数", "群组奖杯", "邀请日期", "30天内充值 $", "60天内充值 $", "30天内代理充值 $"
for _, d := range data {
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), 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, c10.Value, c11.Value, c12.Value, c13.Value =
ats38(d.AgentCode), ats38(d.Name), ats38(d.InviteeCode), ats38(d.Platform), ats38(d.PlatformId), ats38(d.Reason), ats38(d.GroupCode), ats38(d.GroupMemberNum), ats38(d.GroupTotalConsume), ats38(d.InviteDate),
ats38(d.MonthPaySum), ats38(d.TwoMonthPaySum), ats38(d.MonthDealPaySum)
}
_ = xlFile.Save(excelFileName)
}
package main
import (
"encoding/json"
"fmt"
"git.hilo.cn/hilo-common/script/mysql"
"github.com/tealeg/xlsx"
"io/ioutil"
"net/http"
)
type RaceDayAward struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
Total int `json:"total"`
Data []struct {
Rank int `json:"rank"`
UserCode string `json:"userCode"`
Country string `json:"country"`
Stake int `json:"stake"`
Award int `json:"award"`
ProfitLoss int `json:"profitLoss"`
ChargeMoney float64 `json:"chargeMoney"`
} `json:"data"`
} `json:"data"`
}
type ResCountry3 struct {
Name string
Area int
}
func (ResCountry3) TableName() string {
return "res_country"
}
type UserSvip3 struct {
Code string
Level int
}
func ats33(a interface{}) string {
return fmt.Sprintf("%v", a)
}
func main() {
url := "https://apiv2.faceline.live/v1/race/rank/award?lang=zh-cn&pageIndex=1&pageSize=50000&beginDate=2023-08-20&endDate=2023-08-20&userCode=&timezone=1"
method := "GET"
client := &http.Client{}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("nonce", "hilo")
req.Header.Add("token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjI1MSwiRXh0ZXJuYWxJZCI6IiIsImV4cCI6MTY5MzIwNjcxOH0.V-5CfVUGbQDtn04vy85rjb2TtrfntZCuv209tUKFcgU")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err)
}
var response = new(RaceDayAward)
err = json.Unmarshal(body, &response)
if err != nil {
panic(err)
}
var countryArea = make(map[string]string)
// get from db
var countries []ResCountry3
if err := mysql.ProdReadOnlyDB.Model(ResCountry3{}).Find(&countries).Error; err != nil {
panic(err)
}
for _, v := range countries {
area := "阿语"
if v.Area == 2 {
area = "非阿语"
}
countryArea[v.Name] = area
}
var svipMap = make(map[string]int)
var codes []string
for _, v := range response.Data.Data {
codes = append(codes, v.UserCode)
}
var svips []UserSvip3
if err := mysql.ProdReadOnlyDB.Table("user_svip s").Joins("INNER JOIN user u ON u.id = s.user_id").Select("u.code,s.level").Where("u.code in ?", codes).Find(&svips).Error; err != nil {
panic(err)
}
for _, v := range svips {
svipMap[v.Code] = v.Level
}
excelFileName := fmt.Sprintf("./0820赛车中奖榜.xlsx")
xlFile := xlsx.NewFile()
sheet, _ := xlFile.AddSheet("charge")
row := sheet.AddRow()
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 = "排名", "用户ID", "区域", "国家", "SVIP等级", "投注钻石数", "中奖钻石数", "盈亏(中奖-投注)", "充值金额$"
for _, d := range response.Data.Data {
row := sheet.AddRow()
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 =
ats33(d.Rank), ats33(d.UserCode), countryArea[d.Country], ats33(d.Country), ats33(svipMap[d.UserCode]), ats33(d.Stake), ats33(d.Award), ats33(d.ProfitLoss), ats33(d.ChargeMoney)
}
_ = xlFile.Save(excelFileName)
}
package main
import (
"git.hilo.cn/hilo-common/script/mysql"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
type RaceDayRankKsa struct {
Period string
UserId uint64
Stake uint64
Award uint64
}
type TmpRank struct {
D string
UserId uint64
Stake uint64
Award uint64
}
func main() {
stakeSql := `SELECT DATE_FORMAT(created_time,"%Y-%m-%d") d,user_id,SUM(stake) stake FROM game_race_stake GROUP BY d,user_id ;`
var stakeRanks []TmpRank
if err := mysql.ProdWriteDB.Raw(stakeSql).Scan(&stakeRanks).Error; err != nil {
panic(err)
}
for _, v := range stakeRanks {
if err := mysql.ProdWriteDB.Model(RaceDayRankKsa{}).Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "period"}, {Name: "user_id"}},
DoUpdates: clause.Assignments(map[string]interface{}{
"stake": gorm.Expr("stake+ ?", v.Stake),
}),
}).Create(&RaceDayRankKsa{
Period: v.D,
UserId: v.UserId,
Stake: v.Stake,
}).Error; err != nil {
panic(err)
}
}
awardSql := `SELECT DATE_FORMAT(created_time,"%Y-%m-%d") d,user_id,SUM(award) award FROM game_race_player GROUP BY d,user_id;`
var awardRanks []TmpRank
if err := mysql.ProdWriteDB.Raw(awardSql).Scan(&awardRanks).Error; err != nil {
panic(err)
}
for _, v := range awardRanks {
if err := mysql.ProdWriteDB.Model(RaceDayRankKsa{}).Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "period"}, {Name: "user_id"}},
DoUpdates: clause.Assignments(map[string]interface{}{
"award": gorm.Expr("award+ ?", v.Award),
}),
}).Create(&RaceDayRankKsa{
Period: v.D,
UserId: v.UserId,
Award: v.Award,
}).Error; err != nil {
panic(err)
}
}
}
package main
import (
"fmt"
"git.hilo.cn/hilo-common/script/mysql"
"github.com/tealeg/xlsx"
"gorm.io/gorm"
)
type SvipHistoryData struct {
UserId uint64
Code string
Area string
Country string
SvipTopLevel int
SvipLevel int
Dollar float64 // 累充金额$
}
func ats41(a interface{}) string {
return fmt.Sprintf("%v", a)
}
func main() {
var data []SvipHistoryData
if err := mysql.ProdReadOnlyDB.Raw("select t.*,CASE area WHEN 1 THEN '阿语' ELSE '非阿语' END as area FROM (SELECT user_id,replace(MAX(remark),\"Become SVIP\",\"\") svip_top_level,code,country FROM `user_svip_detail` d,user u where u.id = d.user_id AND remark like '%Become SVIP%' GROUP BY user_id) t,res_country r where t.country = r.name").Find(&data).Error; err != nil {
panic(err)
}
var userIds []uint64
for _, d := range data {
userIds = append(userIds, d.UserId)
}
type ChargeData struct {
UserId uint64
Code string
Dollar float64
Country string
}
var chargeDatas []ChargeData
chargeMap := make(map[uint64]ChargeData)
if err := mysql.ProdReadOnlyDB.Raw("select id as user_id,code,SUM(dollar) as dollar,country FROM "+
"(select u.id,u.`code`,SUM(price) / 100 as dollar,u.country FROM pay_order p, `user` u where u.id = p.user_id AND p.`status` = 2 AND `type` = 0 group by user_id UNION ALL select u.id,u.code,SUM(dollar) / 100 as dollar,u.country FROM dealer_transfer_detail d, `user` u where u.id = d.receiver_id group by receiver_id UNION ALL "+
"select u.id,u.code,SUM(dollar) / 100 as dollar,u.country FROM dealer_transfer_detail_pink d, `user` u where u.id = d.receiver_id group by receiver_id) t "+
"where t.id in ? group by code order by dollar DESC", userIds).Find(&chargeDatas).Error; err != nil {
panic(err)
}
for i, v := range chargeDatas {
chargeMap[v.UserId] = chargeDatas[i]
}
for i, uc := range data {
data[i].SvipLevel = GetUserSvip2(uc.UserId)
if d, ok := chargeMap[uc.UserId]; ok {
data[i].Dollar = d.Dollar
}
//break
}
excelFileName := fmt.Sprintf("./svip历史充值.xlsx")
xlFile := xlsx.NewFile()
sheet, err := xlFile.AddSheet("charge")
if err != nil {
panic(err)
}
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
c1.Value, c2.Value, c3.Value, c4.Value, c5.Value, c6.Value = "用户ID", "最高svip等级", "区域", "国家", "目前SVIP等级", "累计充值$"
for _, d := range data {
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
c1.Value, c2.Value, c3.Value, c4.Value, c5.Value, c6.Value = d.Code, ats41(d.SvipTopLevel), ats41(d.Area), ats41(d.Country), ats41(d.SvipLevel), ats41(d.Dollar)
}
_ = xlFile.Save(excelFileName)
}
func GetUserSvip2(uid uint64) int {
type UserSvip struct {
UserId uint64
Level int
}
var res UserSvip
if err := mysql.ProdReadOnlyDB.Table("user_svip").Where("user_id = ?", uid).First(&res).Error; err != nil {
if err != gorm.ErrRecordNotFound {
panic(err)
}
}
return res.Level
}
package main
import (
"encoding/json"
"fmt"
"git.hilo.cn/hilo-common/script/mysql"
"github.com/tealeg/xlsx"
"io/ioutil"
"net/http"
"time"
)
type AutoGenerated34 struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
Total int `json:"total"`
Data []AutoGenerated34Data `json:"data"`
} `json:"data"`
}
type AutoGenerated34Data struct {
UserID uint64 `json:"userId"`
Date string `json:"date"`
Country string `json:"country"`
UserCode string `json:"userCode"`
UserName string `json:"userName"`
ChargeMoney string `json:"chargeMoney"`
HaveFirst int `json:"haveFirst"`
RegisterAt string `json:"registerAt"`
SvipLevel int `json:"svipLevel"`
MaxDollar int `json:"maxDollar"` // 历史最高单笔
MaxDollarDuration int `json:"maxDollarDuration"` // 时段最高单笔
Phone string `json:"phone"`
Charm int `json:"charm"`
LastRequestTime string `json:"lastRequestTime"`
}
func ats34(a interface{}) string {
return fmt.Sprintf("%v", a)
}
func main() {
//url := "https://apiv2.faceline.live/v1/stats/charge/user?lang=zh-cn&diamondType=2&beginDate=2023-10-01&endDate=2023-10-31&pageIndex=1&pageSize=10000&country=All&code=&area=1&timezone=1"
//url := "https://apiv2.faceline.live/v1/stats/charge/user?lang=zh-cn&diamondType=1&beginDate=2022-06-01&endDate=2023-12-13&pageIndex=1&pageSize=4805&country=All&code=&area=1&timezone=0"
var data []AutoGenerated34Data
pageIndex := 1
pageSize := 1000
for {
url := fmt.Sprintf("https://apiv2.faceline.live/v1/stats/charge/user?lang=zh-cn&diamondType=1&beginDate=2020-01-01&endDate=2024-07-05&pageIndex=%d&pageSize=%d&country=All&code=&area=2&timezone=0",
pageIndex, pageSize)
method := "GET"
client := &http.Client{}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("nonce", "hilo")
req.Header.Add("token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjI1MSwiRXh0ZXJuYWxJZCI6IiIsImV4cCI6MTcyMjczNzEzMH0.LZDmjeRkUiYIQA7hVnbb6_xFQtyGf9yev-y6NQqVhRY")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err)
}
println(string(body))
var response = new(AutoGenerated34)
err = json.Unmarshal(body, &response)
if err != nil {
panic(err)
}
if len(response.Data.Data) <= 0 {
break
}
data = append(data, response.Data.Data...)
pageIndex++
}
var userIds []uint64
for _, v := range data {
userIds = append(userIds, v.UserID)
}
phones := GetPhones(userIds)
charms := GetUserCharmLevel(userIds)
requsets := GetRequestLast(userIds)
for i, v := range data {
data[i].Phone = phones[v.UserID]
data[i].Charm = charms[v.UserID]
data[i].LastRequestTime = requsets[v.UserID]
}
excelFileName := fmt.Sprintf("./非阿语区黄钻充值202001-至今.xlsx")
xlFile := xlsx.NewFile()
sheet, _ := xlFile.AddSheet("charge")
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), 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, c10.Value, c11.Value, c12.Value, c13.Value = "日期", "国家", "用户ID", "用户昵称", "充值金额", "注册时间", "是否举办首场活动", "svip等级", "时段最高单笔", "历史最高单笔", "手机号", "魅力等级", "最后登陆时间"
for _, d := range data {
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), 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 = ats34(d.Date), ats34(d.Country), ats34(d.UserCode), ats34(d.UserName), ats34(d.ChargeMoney), ats34(d.RegisterAt)
c7.Value, c8.Value, c9.Value, c10.Value, c11.Value, c12.Value, c13.Value = ats34(d.HaveFirst), ats34(d.SvipLevel), ats34(d.MaxDollarDuration), ats34(d.MaxDollar), d.Phone, ats34(d.Charm), d.LastRequestTime
}
_ = xlFile.Save(excelFileName)
}
type UserBindInfo struct {
UserId uint64 `gorm:"column:user_id"`
Phone string `gorm:"column:phone"` // 手机号码(包含区号)
AreaCode string `gorm:"column:area_code"` // 国家区号
}
func (UserBindInfo) TableName() string {
return "user_bind_info"
}
func GetPhones(userIds []uint64) map[uint64]string {
var rows []UserBindInfo
if err := mysql.ProdReadOnlyDB.Model(UserBindInfo{}).Where("user_id in ?", userIds).Find(&rows).Error; err != nil {
panic(err)
}
var res = make(map[uint64]string)
for _, v := range rows {
res[v.UserId] = v.AreaCode + v.Phone
}
return res
}
// MatchCharmUserScore 用户魅力分数
type MatchCharmUserScore struct {
UserId uint64 `gorm:"column:user_id"` // user_id
Score int64 `gorm:"column:score"` // 分数
Grade int `gorm:"column:grade"` // 等级
}
func (MatchCharmUserScore) TableName() string {
return "match_charm_user_score"
}
func GetUserCharmLevel(userIds []uint64) map[uint64]int {
var rows []MatchCharmUserScore
if err := mysql.ProdReadOnlyDB.Model(MatchCharmUserScore{}).Where("user_id in ?", userIds).Find(&rows).Error; err != nil {
panic(err)
}
res := make(map[uint64]int)
for _, v := range rows {
res[v.UserId] = v.Grade
}
return res
}
// UserRequestLast 用户请求最后时间
type UserRequestLast struct {
ID int64 `gorm:"column:id"` // id
UserId uint64 `gorm:"column:user_id"` // 用户id
TimeLast time.Time `gorm:"column:time_last"` // 最后的时间
}
func (UserRequestLast) TableName() string {
return "user_request_last"
}
func GetRequestLast(userIds []uint64) map[uint64]string {
var rows []UserRequestLast
if err := mysql.ProdReadOnlyDB.Model(UserRequestLast{}).Where("user_id in ?", userIds).Find(&rows).Error; err != nil {
panic(err)
}
res := make(map[uint64]string)
for _, v := range rows {
res[v.UserId] = v.TimeLast.Format("2006-01-02 15:04:05")
}
return res
}
......@@ -10,7 +10,8 @@ import (
"time"
)
var micCodes = []string{"1000653", "1000516", "1000675", "1000890", "1000755", "1000593", "1000629", "1000634", "1000765", "1000591", "1000633", "1000224", "1000611", "1000689", "1000467", "1000384", "1000367", "1000623"}
// var micCodes = []string{"1000653", "1000516", "1000675", "1000890", "1000755", "1000593", "1000629", "1000634", "1000765", "1000591", "1000633", "1000224", "1000611", "1000689", "1000467", "1000384", "1000367", "1000623"}
var micCodes = []string{"1110189", "1110188", "1110186", "1110183", "1110180", "1110175", "1110170", "1110160", "1110158", "1110154", "1110152", "1110150", "1110141", "1110139", "1110130", "199777", "1110124", "1110122", "1110120", "1110118"}
func main() {
var users []model.User
......@@ -21,7 +22,7 @@ func main() {
url := "https://test.apiv1.faceline.live/v1/imGroup/mic/in"
method := "POST"
payload := strings.NewReader("groupUuid=HTGS%23a56194639&i=")
payload := strings.NewReader("groupUuid=HTGS_3HIKK4QIV&i=")
client := &http.Client{}
req, err := http.NewRequest(method, url, payload)
......
......@@ -25,6 +25,8 @@ func main() {
if err := mysql.TestDB.Model(model.User{}).Where("code in ?", fruitUserCodes).Find(&users).Error; err != nil {
panic(err)
}
for i := 0; i < 10; i++ {
go func() {
for {
times := 20 + rand.Intn(30)
for i := 0; i < times; i++ {
......@@ -67,9 +69,12 @@ func main() {
fmt.Println(err)
return
}
fmt.Println(string(body))
fmt.Printf("body:%v,uid:%v\n", string(body), u.Id)
}
}
//time.Sleep(time.Second * 55)
}
}()
}
time.Sleep(time.Hour)
}
......@@ -5,6 +5,8 @@ import (
"git.hilo.cn/hilo-common/script/mysql"
)
// cat 146.json | grep 'gameId\\"\:17' | wc -l
// 如果mysql navicate中导出json,可以用上面的命令,是准确的。
type RpcLog struct {
Type int
Msg string
......@@ -12,18 +14,20 @@ type RpcLog struct {
type Msg struct {
GameType int `json:"gameType"`
GameId int `json:"gameId"`
}
var GameTypeMap = map[int]string{
0: "slot",
5: "幸运盒子",
6: "水果机",
//0: "slot",
//5: "幸运盒子",
//6: "水果机",
17: "赛车",
}
func main() {
var rpcLogs []RpcLog
if err := mysql.ProdReadOnlyDB.Table("rpc_log_202303 ").Where("`type` = 146").
Where("created_time >= ? and created_time < ?", "2023-03-09", "2023-03-13").Find(&rpcLogs).Error; err != nil {
if err := mysql.ProdReadOnlyDB.Table("rpc_log_202308").Where("`type` = 146").
Where("created_time >= ?", "2023-08-22 15:57:49").Find(&rpcLogs).Error; err != nil {
panic(err)
}
var data = make(map[int]int)
......@@ -32,9 +36,9 @@ func main() {
if err := json.Unmarshal([]byte(log.Msg), msg); err != nil {
panic(err)
}
data[msg.GameType]++
data[msg.GameId]++
}
for gameType, count := range data {
println(GameTypeMap[gameType], count)
for gameId, count := range data {
println(GameTypeMap[gameId], count)
}
}
package main
import (
"fmt"
"git.hilo.cn/hilo-common/script/model"
"git.hilo.cn/hilo-common/script/mysql"
"git.hilo.cn/hilo-common/script/utils/jwt"
"io/ioutil"
"math/rand"
"net/http"
"strings"
"time"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
var raceUserCodes = []string{"1000653", "1000516", "1000675", "1000890", "1000755", "1000593", "1000629", "1000634", "1000765",
"1000591", "1000633", "1000224", "1000611", "1000689", "1000467", "1000384", "1000367", "1000623"}
var raceAmounts = []int{10, 100, 1000, 5000}
func main() {
var users []model.User
if err := mysql.TestDB.Model(model.User{}).Where("code in ?", raceUserCodes).Find(&users).Error; err != nil {
panic(err)
}
for i := 0; i < 10; i++ {
go func() {
for {
times := 20 + rand.Intn(30)
for i := 0; i < times; i++ {
arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
rand.Shuffle(len(arr), func(i, j int) {
arr[i], arr[j] = arr[j], arr[i]
})
for _, id := range arr {
if rand.Intn(100) < 30 {
break
}
url := "https://test.apiv1.faceline.live/v1/race/"
method := "POST"
amount := raceAmounts[rand.Intn(len(raceAmounts))]
payload := strings.NewReader(fmt.Sprintf("raceId=%d&amount=%d", id, amount))
client := &http.Client{}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
u := users[rand.Intn(len(users))]
token, _ := jwt.GenerateToken(u.Id, u.ExternalId, "hiloApi")
req.Header.Add("nonce", "hilo")
req.Header.Add("token", token)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("body:%v,uid:%v\n", string(body), u.Id)
}
}
//time.Sleep(time.Second * 55)
}
}()
}
time.Sleep(time.Hour * 24)
}
package main
import (
"fmt"
"git.hilo.cn/hilo-common/script/model"
"git.hilo.cn/hilo-common/script/mysql"
"github.com/tealeg/xlsx"
"gorm.io/gorm"
)
type GroupPowerDataFix struct {
GroupPowerId uint64
Exp int64
Grade int
NotGrade int
GroupPowerOwnerCode string
Country string
Area string
Charge float64
}
var groupPowerIds = []uint64{24351, 19291, 12801, 14291, 19891, 23231, 23011, 25141, 12221, 19001, 24821, 23391, 9011, 13121, 22051, 25261, 4221, 10541, 24571, 3541, 18541, 15551, 15761, 17261, 21921, 4691, 24551, 19311, 2481, 23151, 6701, 11171, 8501, 14651, 25121, 8741, 1771, 23931, 21651, 23401, 14851, 24211, 2791, 19081, 4961, 14641, 5651, 26051, 4571, 25171, 4861, 25741, 20961, 9451, 20691, 25911, 2861, 14211, 24791, 19801, 19221, 8101, 3441, 921, 25661, 10041, 22831, 12601, 6811, 4501, 19031, 23961, 6721, 22491, 25431, 15261, 17721, 15941, 2411, 18611, 16611, 25071, 14361, 24701, 8281, 25371, 25081, 18691, 9421, 8131, 13421, 23421, 24801, 4241, 26581, 24921, 10421, 24961, 24391, 16591, 26001, 20241, 19161, 4801, 3351, 5801, 5581, 11181, 6211, 18991, 25411, 24341, 12671, 25811, 18891, 25181, 2251, 24601, 3001, 24991, 9391, 19911, 25481, 21481, 12101, 24141, 5871, 2441, 19371, 24191, 17371, 13151, 19261, 22961, 23911, 16231, 24851, 24811, 23211, 5511, 24251, 19551, 24201, 23751, 19831, 13541, 25471, 6131, 19461, 24901, 11401, 24831, 13881, 25041, 24061, 23351, 18821, 23981, 4751, 24611, 24001, 19571, 25051, 9741, 20191, 15521, 19901, 14101}
var Exps = []int64{13832068, 13403439, 13297842, 13294352, 13288374, 12674730, 11909217, 11511666, 11497642, 11462372, 11059096, 10661536, 10567574, 10480370, 10423501, 9946222, 9832519, 9532238, 9490327, 9194177, 9085226, 8891812, 8867650, 8715147, 8301794, 8203831, 8103674, 7246163, 7208835, 6715474, 6421177, 6212649, 6150580, 5934318, 5906318, 5837393, 5680884, 5560053, 5332538, 4019449, 3993994, 3826258, 2857571, 2621534, 2606725, 2499191, 2485685, 2444304, 2394223, 2362256, 2354537, 2340696, 2301961, 2277107, 2273430, 2262166, 2183237, 2181348, 2181102, 2173626, 2147152, 2118118, 2075115, 2060869, 1985529, 1948781, 1833511, 1832977, 1782934, 1780923, 1719446, 1667931, 1652100, 1619574, 1611277, 1590309, 1504380, 1497201, 1471447, 1465675, 1422977, 1417761, 1417492, 1409111, 1388859, 1352661, 1344402, 1338039, 1321998, 1253457, 1226655, 1212393, 1189305, 1114168, 1113801, 1096744, 1058926, 1058041, 1040023, 1028898, 1008527, 1007879, 1000988, 927809, 845653, 842572, 837581, 830823, 822889, 799687, 722092, 681294, 675063, 657535, 650551, 612469, 601754, 601384, 576578, 574690, 535670, 528766, 519261, 514781, 508661, 500272, 499544, 482028, 477736, 462447, 458211, 423348, 412066, 407211, 385878, 377427, 362139, 340853, 301622, 289717, 262355, 258988, 251724, 249314, 244429, 243399, 222771, 181332, 170380, 156802, 135650, 109984, 106263, 57110, 50076, 37711, 31048, 28970, 23765, 22617, 20407, 9401, 5600, 2430, 1606, 66, 50, 30}
func ats36(v interface{}) string {
return fmt.Sprintf("%v", v)
}
func main() {
var data []GroupPowerDataFix
for i, groupPowerId := range groupPowerIds {
ownerId, ownerCode, country, area := getGroupPowerOwner(groupPowerId)
charge := float64(getUserChange(ownerId)) / 100
areaStr := "阿语区"
if area == 2 {
areaStr = "非阿语区"
}
data = append(data, GroupPowerDataFix{
GroupPowerId: groupPowerId,
Exp: Exps[i],
Grade: getShouldGrade(Exps[i]) + 1,
NotGrade: 4,
GroupPowerOwnerCode: ownerCode,
Country: country,
Area: areaStr,
Charge: charge,
})
}
excelFileName := fmt.Sprintf("./家族bug.xlsx")
xlFile := xlsx.NewFile()
sheet, err := xlFile.AddSheet("family")
if err != nil {
panic(err)
}
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6, c7, c8 := 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 = "家族id", "清零前经验", "应该等级", "错误等级", "家族长id", "国家", "区域", "累计充值"
for _, d := range data {
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6, c7, c8 := 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 =
ats36(d.GroupPowerId), ats36(d.Exp), ats36(d.Grade), ats36(d.NotGrade), ats36(d.GroupPowerOwnerCode), ats36(d.Country), ats36(d.Area), ats36(d.Charge)
}
_ = xlFile.Save(excelFileName)
}
const (
g1 = 2500000
g2 = 15000000
g3 = 60000000
)
func getShouldGrade(exp int64) int {
var moreExp int64
if exp > g3 {
moreExp = exp - g3
}
if exp > g2 {
moreExp = exp - g2
}
if exp > g1 {
moreExp = exp - g1
}
if moreExp >= g3 {
return 3
}
if moreExp >= g2 {
return 2
}
if moreExp >= g1 {
return 1
}
return 0
}
func getGroupPowerOwner(groupPowerId uint64) (uint64, string, string, int) {
var userId uint64
if err := mysql.ProdReadOnlyDB.Table("group_power_user").Select("user_id").Where("group_power_id = ?", groupPowerId).Where("role = 2").Scan(&userId).Error; err != nil {
panic(err)
}
var user model.User
if err := mysql.ProdReadOnlyDB.Table("user").Where("id = ?", userId).First(&user).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return 0, "没有家族长", "没有家族长", 0
}
panic(err)
}
var area int
if err := mysql.ProdReadOnlyDB.Table("res_country").Select("area").Where("name = ?", user.Country).Scan(&area).Error; err != nil {
panic(err)
}
return userId, user.Code, user.Country, area
}
func getUserChange(userId uint64) int64 {
m1, err := getUserChargeMoneySumV2(userId)
if err != nil {
panic(err)
}
m2, _ := getUserDealerTransferMoneySumV2(userId)
if err != nil {
panic(err)
}
return m1 + m2
}
// 获取用户总充值金额
// 返回美分
func getUserChargeMoneySumV2(uid uint64) (int64, error) {
type R struct {
Money int64
}
var money R
if err := mysql.ProdReadOnlyDB.Table("pay_order AS p").
Where("p.status = 2 AND p.`type` = 0 AND platform >= 1 AND platform <= 6"). // type=0 就是用户给自己充值,status=2成功
Where("p.user_id = ?", uid).Select("SUM(p.price) as money").Scan(&money).Error; err != nil {
return 0, err
}
return money.Money, nil
}
// 获取代理总充值金额
// 返回美分
func getUserDealerTransferMoneySumV2(uid uint64) (int64, error) {
type Money struct {
Price int64
}
var money Money
if err := mysql.ProdReadOnlyDB.Table("dealer_transfer_detail AS t").
Where("t.receiver_id = ?", uid).Select("SUM(t.dollar) as price").
Scan(&money).Error; err != nil {
return 0, err
}
return money.Price, nil
}
package main
import (
"fmt"
"git.hilo.cn/hilo-common/script/mysql"
"github.com/spf13/cast"
"github.com/tealeg/xlsx"
)
type UserWealthHigh struct {
UserId uint64
Grade int
Code string
Country string
Area string
Charge int64
SvipLevel int64
}
type ResArea struct {
Name string
Area int
}
type UserSvip22 struct {
UserId uint64
Level int64
}
func main() {
var users []UserWealthHigh
if err := mysql.ProdReadOnlyDB.Table("match_wealth_user_score").Joins("INNER JOIN user ON user.id = match_wealth_user_score.user_id").Where("grade >= 20").
Select("user_id,grade,country,code").Find(&users).Error; err != nil {
panic(err)
}
var resAreas []ResArea
if err := mysql.ProdReadOnlyDB.Table("res_country").Find(&resAreas).Error; err != nil {
panic(err)
}
areaMap := make(map[string]string)
for _, v := range resAreas {
if v.Area == 1 {
areaMap[v.Name] = "阿语区"
} else {
areaMap[v.Name] = "非阿语"
}
}
var userIds []uint64
for _, v := range users {
userIds = append(userIds, v.UserId)
}
var svips []UserSvip22
if err := mysql.ProdReadOnlyDB.Table("user_svip").Where("user_id in ?", userIds).Find(&svips).Error; err != nil {
panic(err)
}
sm := make(map[uint64]int64)
for _, v := range svips {
sm[v.UserId] = v.Level
}
for i, u := range users {
users[i].Area = areaMap[u.Country]
users[i].SvipLevel = sm[u.UserId]
users[i].Charge = GetUserChargeMoneySum(u.UserId)
if i >= 2 {
//break
}
}
excelFileName := fmt.Sprintf("./财富等级用户.xlsx")
xlFile := xlsx.NewFile()
sheet, err := xlFile.AddSheet("wealth")
if err != nil {
panic(err)
}
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
c1.Value, c2.Value, c3.Value, c4.Value, c5.Value, c6.Value = "id", "财富等级", "区域", "国家", "累计充值金额(美分)", "svip等级"
for _, d := range users {
row := sheet.AddRow()
c1, c2, c3, c4, c5, c6 := row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell(), row.AddCell()
c1.Value, c2.Value, c3.Value, c4.Value, c5.Value, c6.Value =
cast.ToString(d.Code), cast.ToString(d.Grade), cast.ToString(d.Area), cast.ToString(d.Country), cast.ToString(d.Charge), cast.ToString(d.SvipLevel)
}
_ = xlFile.Save(excelFileName)
}
// 获取用户累计充值
func GetUserChargeMoneySum(userId uint64) int64 {
type R struct {
Money int64
}
var money R
var total int64
if err := mysql.ProdReadOnlyDB.Table("pay_order AS p").
Where("p.status = 2 AND p.`type` = 0"). // type=0 就是用户给自己充值,status=2成功
Where("p.user_id = ?", userId).
Select("SUM(p.price) as money").Scan(&money).Error; err != nil {
}
total += money.Money
var money2 R
if err := mysql.ProdReadOnlyDB.Table("dealer_transfer_detail AS t").
Where("t.receiver_id = ?", userId).
Select("SUM(t.dollar) as money").
Scan(&money2).Error; err != nil {
}
total += money2.Money
var money3 R
if err := mysql.ProdReadOnlyDB.Table("dealer_transfer_detail_pink AS t").
Where("t.receiver_id = ?", userId).
Select("SUM(t.dollar) as money").
Scan(&money3).Error; err != nil {
}
total += money3.Money
return total
}
......@@ -12,7 +12,7 @@ type Claims struct {
jwt.StandardClaims
}
//生成token
// 生成token
func GenerateToken(userId uint64, externalId string, issuer string) (string, error) {
duration, err := time.ParseDuration("240h")
if err != nil {
......@@ -37,7 +37,7 @@ func GetJWTSecret() []byte {
return []byte("hilo1632")
}
//解析token
// 解析token
func ParseToken(token string) (*Claims, error) {
tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
return GetJWTSecret(), nil
......
......@@ -15,6 +15,6 @@ func TestJwt(t *testing.T) {
}
func TestJwtParse(t *testing.T) {
c, err := jwt.ParseToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjQyNDAyNjEsIkV4dGVybmFsSWQiOiI0MTIwOWU5NTE0ZDI0ODQwYTliNTMxMDgyMWViNjRkNiIsImV4cCI6MTY5MjI2MTIxNiwiaXNzIjoiaGlsb0FwaSJ9.2ru292Z1q8p87Chzp5DWrR1hMHO3sQcD1X3QNwOio2U")
println(c, err)
c, _ := jwt.ParseToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjg4Nzc2OTEsIkV4dGVybmFsSWQiOiJkNmZlNmJhN2E3ZTI0NjRiYjhhNmU3OTFlNmQxY2E5ZCIsIlRva2VuVmVyc2lvbiI6NywiZXhwIjoxNzE5NTczOTkzLCJpc3MiOiJoaWxvQXBpIn0.EWSFvxzyPDRLWA5eNQ_MSrUDlAeoMhmn0RKw4vfvL6k")
println(c.UserId)
}
......@@ -1532,7 +1532,7 @@ func SendSystemMsg(logger *logrus.Entry, groupId string, members []string, conte
}
func SendSystemMsgBy(logger *logrus.Entry, txGroupId string, members []string, content string, reqUrl string, getAdminSig func() (string, error), appId int) error {
logger = logger.WithField("appId", appId).WithField("txGroupId", txGroupId)
logger.Infof("SendSystemMsg content: %s", content)
//logger.Infof("SendSystemMsg content: %s", content)
beginTime := time.Now()
type BodyStruct struct {
......
......@@ -6,8 +6,11 @@ import (
"git.hilo.cn/hilo-common/internal/enum/diamond_e"
"git.hilo.cn/hilo-common/internal/enum/msg_e"
"git.hilo.cn/hilo-common/internal/model/diamond_m"
"git.hilo.cn/hilo-common/myerr"
"git.hilo.cn/hilo-common/resource/mysql"
"git.hilo.cn/hilo-common/txop/msg"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
// 下发钻石
......@@ -51,3 +54,113 @@ func SendDiamondPink(model *domain.Model, userId mysql.ID, opt diamond_e.Operate
}
return nil
}
// 事务操作账号明细
// 注意:外层不能再加事务了
// 注意:DiamondOperateSet限流的不能用
// 账号冻结/账号余额:属于业务逻辑,不在事务做
// 函数步骤
// 1. 非事务前置判断: 获取账号信息,加减,封号等
// 事务
// 2. diamondAccount表原子操作, 判断更新条数
// 3. 更新明细表
// param extraTxFunc: 外部函数,可能会影响到事务回滚的函数
func TxAddReduceDiamondAccount(model *domain.Model, userId mysql.ID, operateType diamond_e.OperateType, diamondNum mysql.Num, originId mysql.ID, operateIds mysql.Str, extraTxFunc ...func() error) error {
var diamondOperateSet diamond_m.DiamondOperateSet
var err error
if err = model.DB().Where(&diamond_m.DiamondOperateSet{
Type: operateType,
Status: mysql.USER,
DiamondType: diamond_e.DiamondYellow,
}).First(&diamondOperateSet).Error; err != nil {
return err
}
// logs
model.Log = model.Log.WithFields(logrus.Fields{
"func": "TxAddReduceDiamondAccount",
"uid": userId,
"ot": operateType,
"num": diamondNum,
"oid": originId,
"oids": operateIds,
"ar": diamondOperateSet.AddReduce,
})
var diamondAccount = new(diamond_m.DiamondAccount)
if err := model.DB().Model(diamond_m.DiamondAccount{}).Where("user_id = ?", userId).First(diamondAccount).Error; err != nil {
model.Log.Errorf("TxAddReduceDiamondAccount fail :%v", err)
return err
}
if diamondOperateSet.AddReduce == mysql.REDUCE && diamondAccount.DiamondNum < diamondNum {
return fmt.Errorf("bizerr.DiamondAccountNotEnough")
}
if diamondAccount.Status == diamond_e.Frozen && diamondOperateSet.AddReduce == mysql.REDUCE {
return fmt.Errorf("bizerr.DiamondAccountFrozen")
}
return model.Transaction(func(model *domain.Model) error {
// 更新diamondAccount表
var db *gorm.DB
if diamondOperateSet.AddReduce == mysql.ADD {
//增加
db = model.DB().Model(diamond_m.DiamondAccount{}).Where("id = ?", diamondAccount.ID).UpdateColumn("diamond_num", gorm.Expr("diamond_num + ?", diamondNum))
} else if diamondOperateSet.AddReduce == mysql.REDUCE {
//减少,保证不能扣成负数
db = model.DB().Model(diamond_m.DiamondAccount{}).Where("id = ?", diamondAccount.ID).Where("diamond_num >= ?", diamondNum).UpdateColumn("diamond_num", gorm.Expr("diamond_num - ?", diamondNum))
} else {
return myerr.NewSysErrorF("addReduce 枚举错误 value:", diamondOperateSet.AddReduce)
}
// 错误判断
if db == nil {
model.Log.Errorf("db nil")
return myerr.NewSysError("db nil")
}
if err := db.Error; err != nil {
model.Log.Errorf("db err:%v", err)
return myerr.WrapErr(err)
}
if db.RowsAffected == 0 {
model.Log.Errorf("gorm condition update.RowsAffected = 0")
return myerr.NewWaring("gorm condition update.RowsAffected = 0")
}
// 写后读(写后缓存都会丢失,多读一次不影响)
//newAccount := new(diamond_m.DiamondAccount)
//if err := model.DB().Model(diamond_m.DiamondAccount{}).Where("id = ?", diamondAccount.ID).First(newAccount).Error; err != nil {
// model.Log.Errorf("newAccount err:%v", err)
// return err
//}
//if newAccount.DiamondNum < 0 {
// model.Log.Errorf("newAccount 0")
// return myerr.NewSysError("newAccount 0")
//}
//// 更新明细
//befNum := mysql.Num(0)
//if diamondOperateSet.AddReduce == mysql.ADD {
// befNum = newAccount.DiamondNum - diamondNum
//}
//if diamondOperateSet.AddReduce == mysql.REDUCE {
// befNum = newAccount.DiamondNum + diamondNum
//}
if err := model.DB().Table(diamond_m.DiamondAccountDetail{}.TableName()).Create(&diamond_m.DiamondAccountDetail{
UserId: userId,
DiamondAccountId: diamondAccount.ID,
OperateId: diamondOperateSet.ID,
OperateType: operateType,
OriginId: originId,
AddReduce: diamondOperateSet.AddReduce,
Num: diamondNum,
Remark: diamondOperateSet.Name,
BefNum: 0,
AftNum: 0,
}).Error; err != nil {
model.Log.Errorf("add detail fail:%v", err)
return err
}
for i, f := range extraTxFunc {
if err := f(); err != nil {
model.Log.Errorf("extraFunc i:%v fail:%v", i, err)
return err
}
}
return nil
})
}
......@@ -14,8 +14,12 @@ func SendMedal(model *domain.Model, userId, medalId mysql.ID, day int) error {
MedalId: uint32(medalId),
EndTime: &endTime,
}
if err := um.Create(model.Db, day); err != nil {
if err := um.Create(model.DB(), day); err != nil {
return err
}
return nil
}
func DelMedal(model *domain.Model, userId, medalId mysql.ID) error {
return model.DB().Model(user_m.UserMedal{}).Where("user_id = ? AND medal_id = ?", userId, medalId).Delete(&user_m.UserMedal{}).Error
}
......@@ -34,11 +34,14 @@ func SendLittleAssistantMsg(model *domain.Model, userId mysql.ID, t msg_e.MsgUse
return err
}
}
err = msg_m.SendEmasMsgAssistant(model, user.ExternalId, user.DeviceType)
// 异步emas提醒
go func() {
defer utils.CheckGoPanic()
err = msg_m.SendEmasMsgAssistant(domain.CreateModelContext(model.MyContext), user.ExternalId, user.DeviceType)
if err != nil {
model.Log.Errorf("SendLittleAssistantMsg SendEmasMsgAssistant userId:%v, err:%v", userId, err)
return err
}
}()
return nil
}
......
......@@ -21,7 +21,7 @@ func SendNoble(model *domain.Model, receiverUserId mysql.ID, level uint16, days
return fmt.Errorf("level is 0")
}
cfg, err := noble_m.GetConfigByLevel(model.Db, level)
cfg, err := noble_m.GetConfigByLevel(model.DB(), level)
if err != nil {
return err
}
......@@ -29,7 +29,7 @@ func SendNoble(model *domain.Model, receiverUserId mysql.ID, level uint16, days
return fmt.Errorf("level is 0")
}
n := noble_m.UserNoble{UserId: receiverUserId, Level: level}
records, err := n.FindAll(model.Db)
records, err := n.FindAll(model.DB())
if err != nil {
return err
}
......@@ -42,9 +42,13 @@ func SendNoble(model *domain.Model, receiverUserId mysql.ID, level uint16, days
// 新增贵族
endTime := time.Now().AddDate(0, 0, int(days))
n = noble_m.UserNoble{UserId: receiverUserId, Level: level, EndTime: endTime}
err = n.Create(model.Db)
err = n.Create(model.DB())
if err != nil {
if af2, err := n.ExtenedEndTime(model.DB(), int(days)); err != nil {
return err
} else if af2 <= 0 {
return fmt.Errorf("bizerr.TransactionFailed create rows 0")
}
}
nbl := noble_m.UserNobleLog{
......@@ -55,7 +59,7 @@ func SendNoble(model *domain.Model, receiverUserId mysql.ID, level uint16, days
SrcType: noble_m.SRC_APP,
NewEndTime: endTime,
}
err = nbl.Create(model.Db)
err = nbl.Create(model.DB())
if err != nil {
return err
}
......@@ -71,12 +75,16 @@ func SendNoble(model *domain.Model, receiverUserId mysql.ID, level uint16, days
Entity: mysql.Entity{ID: n.ID, UpdatedTime: n.UpdatedTime},
}
af, err := nn.UpdateEndTime(model.Db, endTime)
af, err := nn.UpdateEndTime(model.DB(), endTime)
if err != nil {
return err
}
if af <= 0 {
return fmt.Errorf("bizerr.TransactionFailed")
if af2, err := nn.ExtenedEndTime(model.DB(), days); err != nil {
return err
} else if af2 <= 0 {
return fmt.Errorf("bizerr.TransactionFailed rows 0")
}
}
nbl := noble_m.UserNobleLog{
......@@ -88,7 +96,7 @@ func SendNoble(model *domain.Model, receiverUserId mysql.ID, level uint16, days
OldEndTime: n.EndTime,
NewEndTime: endTime,
}
err = nbl.Create(model.Db)
err = nbl.Create(model.DB())
if err != nil {
return err
}
......
......@@ -5,6 +5,7 @@ import (
"fmt"
"git.hilo.cn/hilo-common/resource/config"
"git.hilo.cn/hilo-common/resource/mysql"
uuid "github.com/satori/go.uuid"
"strconv"
"strings"
"time"
......@@ -114,3 +115,7 @@ func Decimal(value float64) float64 {
}
return newValue
}
func GetUUID() string {
return strings.Replace(uuid.NewV4().String(), "-", "", -1)
}