package guser import ( "fmt" "server/common" "server/db" "server/modules/backend/models" utils "server/modules/backend/util" "server/modules/backend/values" "server/modules/customer/app" "time" "github.com/gin-gonic/gin" "github.com/liangdas/mqant/log" ) // 流失玩家数据 func LostUserData(c *gin.Context) { a := app.NewApp(c) defer func() { a.Response() }() req := new(values.LostUserDataReq) if !a.S(req) { return } resp := values.LostUserDataResp{} su, eu := utils.GetQueryUnix(req.Start, req.End) switch req.Sort { case 1: resp.Count, resp.List = getAllLostUser(su, eu, req.Page, req.Num, req.Channel) case 2: resp.Count, resp.List = getPayLostUser(su, eu, req.Page, req.Num, req.Channel) case 3: resp.Count, resp.List = getActiveLostUser(su, eu, req.Page, req.Num, req.Channel) case 4: resp.Count, resp.List = getNewLostUser(su, eu, req.Page, req.Num, req.Channel) default: resp.Count, resp.List = getAllLostUser(su, eu, req.Page, req.Num, req.Channel) } a.Data = resp } // 获取所有流失用户 func getAllLostUser(su, eu int64, page, num int, channel *int) (int64, []values.LostUserData) { var oneDay = 24 * 60 * 60 now := time.Now().Unix() queryUser := " SELECT u.id, u.nick, u.bind_cash, u.cash, u.birth FROM users u LEFT JOIN (SELECT a.* FROM login_record a INNER JOIN ( SELECT uid, MAX( created_at ) created_at FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON a.uid = b.uid AND a.created_at = b.created_at WHERE a.uid = b.uid AND a.created_at = b.created_at AND UNIX_TIMESTAMP(a.date) >= %d) r ON u.id = r.uid WHERE " queryCount := " SELECT COUNT(DISTINCT(u.id)) FROM users u LEFT JOIN (SELECT a.* FROM login_record a INNER JOIN ( SELECT uid, MAX( created_at ) created_at FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON a.uid = b.uid AND a.created_at = b.created_at WHERE a.uid = b.uid AND a.created_at = b.created_at AND UNIX_TIMESTAMP(a.date) >= %d) r ON u.id = r.uid WHERE " str := fmt.Sprintf(" u.birth >= %d AND u.birth < %d ", su, eu) if channel != nil { str += fmt.Sprintf(" AND u.channel_id = %d AND r.channel_id = %d", *channel, *channel) } // 七天未登录的用户 UNIX_TIMESTAMP('20210816') str += fmt.Sprintf(" AND (%d - UNIX_TIMESTAMP(r.date) > %d ) ", now, 7*oneDay) var count int64 err := db.Mysql().QueryBySql(fmt.Sprintf(queryCount+str, su, su), &count) if err != nil { log.Error(err.Error()) return 0, nil } str += " GROUP BY u.id " str += fmt.Sprintf(" LIMIT %d, %d ", (page-1)*num, num) var users []common.PlayerDBInfo err = db.Mysql().QueryBySql(fmt.Sprintf(queryUser+str, su, su), &users) if err != nil { log.Error(err.Error()) return 0, nil } return count, getLostUserInfo(users) } // 获取付费流失用户 func getPayLostUser(su, eu int64, page, num int, channel *int) (int64, []values.LostUserData) { var oneDay = 24 * 60 * 60 now := time.Now().Unix() queryUser := " SELECT u.id, u.nick, u.bind_cash, u.cash, u.birth FROM users u LEFT JOIN (SELECT a.* FROM login_record a INNER JOIN ( SELECT uid, MAX( created_at ) created_at FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON a.uid = b.uid AND a.created_at = b.created_at WHERE a.uid = b.uid AND a.created_at = b.created_at AND UNIX_TIMESTAMP(a.date) >= %d) r ON u.id = r.uid LEFT JOIN (SELECT * FROM recharge_order WHERE `event` = %d AND `status` = %d AND callback_time > %d) re ON u.id = re.uid WHERE u.id = re.uid AND " queryCount := " SELECT COUNT(DISTINCT(u.id)) FROM users u LEFT JOIN (SELECT a.* FROM login_record a INNER JOIN ( SELECT uid, MAX( created_at ) created_at FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON a.uid = b.uid AND a.created_at = b.created_at WHERE a.uid = b.uid AND a.created_at = b.created_at AND UNIX_TIMESTAMP(a.date) >= %d) r ON u.id = r.uid LEFT JOIN (SELECT * FROM recharge_order WHERE `event` = %d AND `status` = %d AND callback_time > %d) re ON u.id = re.uid WHERE u.id = re.uid AND " str := fmt.Sprintf(" u.birth >= %d AND u.birth < %d ", su, eu) if channel != nil { str += fmt.Sprintf(" AND u.channel_id = %d AND r.channel_id = %d", *channel, *channel) } // 三天未登录的用户 UNIX_TIMESTAMP('20210816') str += fmt.Sprintf(" AND (%d - UNIX_TIMESTAMP(r.date) > %d ) ", now, 7*oneDay) var count int64 err := db.Mysql().QueryBySql(fmt.Sprintf(queryCount+str, su, su, common.CurrencyEventReCharge, common.StatusROrderPay, su), &count) if err != nil { log.Error(err.Error()) return 0, nil } str += " GROUP BY u.id " str += fmt.Sprintf(" LIMIT %d, %d ", (page-1)*num, num) var users []common.PlayerDBInfo err = db.Mysql().QueryBySql(fmt.Sprintf(queryUser+str, su, su, common.CurrencyEventReCharge, common.StatusROrderPay, su), &users) if err != nil { log.Error(err.Error()) return 0, nil } return count, getLostUserInfo(users) } // 获取活跃流失用户 func getActiveLostUser(su, eu int64, page, num int, channel *int) (int64, []values.LostUserData) { var oneDay = 24 * 60 * 60 now := time.Now().Unix() queryUser := fmt.Sprintf(" SELECT u.id, u.nick, u.bind_cash, u.cash, u.birth FROM users u LEFT JOIN ( SELECT uid, MAX(date) date, MAX( created_at ) created_at FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON u.id = b.uid WHERE u.id = b.uid AND ", su) + " FROM_UNIXTIME(u.birth,'%Y%m%d') != b.date AND " queryCount := fmt.Sprintf(" SELECT COUNT(DISTINCT(u.id)) FROM users u LEFT JOIN ( SELECT uid, MAX(date) date, MAX( created_at ) created_at FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON u.id = b.uid WHERE u.id = b.uid AND ", su) + " FROM_UNIXTIME(u.birth,'%Y%m%d') != b.date AND " str := fmt.Sprintf(" u.birth >= %d AND u.birth < %d ", su, eu) if channel != nil { str += fmt.Sprintf(" AND u.channel_id = %d AND b.channel_id = %d", *channel, *channel) } // 七天未登录的用户 UNIX_TIMESTAMP('20210816') str += fmt.Sprintf(" AND (%d - UNIX_TIMESTAMP(b.date) > %d ) ", now, 7*oneDay) var count int64 err := db.Mysql().QueryBySql(queryCount+str, &count) if err != nil { log.Error(err.Error()) return 0, nil } str += " GROUP BY u.id " str += fmt.Sprintf(" LIMIT %d, %d ", (page-1)*num, num) var users []common.PlayerDBInfo err = db.Mysql().QueryBySql(queryUser+str, &users) if err != nil { log.Error(err.Error()) return 0, nil } return count, getLostUserInfo(users) } // 获取新用户流失 func getNewLostUser(su, eu int64, page, num int, channel *int) (int64, []values.LostUserData) { queryUser := fmt.Sprintf(" SELECT u.id, u.nick, u.bind_cash, u.cash, u.birth FROM users u LEFT JOIN ( SELECT uid, MAX( created_at ) created_at, MAX(date) date FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON u.id = b.uid WHERE u.id = b.uid ", su) + "AND FROM_UNIXTIME(u.birth,'%Y%m%d') = b.date AND" queryCount := fmt.Sprintf(" SELECT COUNT(DISTINCT(u.id)) FROM users u LEFT JOIN ( SELECT uid, MAX( created_at )created_at, MAX(date) date FROM login_record WHERE UNIX_TIMESTAMP(date) >= %d GROUP BY uid ) b ON u.id = b.uid WHERE u.id = b.uid ", su) + "AND FROM_UNIXTIME(u.birth,'%Y%m%d') = b.date AND" str := fmt.Sprintf(" u.birth >= %d AND u.birth < %d ", su, eu) if channel != nil { str += fmt.Sprintf(" AND u.channel_id = %d ", *channel) str += fmt.Sprintf(" AND u.channel_id = %d ", *channel) } // 7天未登录的用户 UNIX_TIMESTAMP('20210816') str += fmt.Sprintf(" AND (%d - UNIX_TIMESTAMP(b.date) > %d ) ", time.Now().Unix(), 7*24*60*60) var count int64 err := db.Mysql().QueryBySql(queryCount+str, &count) if err != nil { log.Error(err.Error()) return 0, nil } str += fmt.Sprintf(" LIMIT %d, %d ", (page-1)*num, num) var users []common.PlayerDBInfo err = db.Mysql().QueryBySql(queryUser+str, &users) if err != nil { log.Error(err.Error()) return 0, nil } return count, getLostUserInfo(users) } func getLostUserInfo(users []common.PlayerDBInfo) []values.LostUserData { var res []values.LostUserData for i := 0; i < len(users); i++ { var data values.LostUserData // 用户昵称 data.Nick = users[i].Nick // 用户uid data.Uid = users[i].Id // 用户生日 data.Birth = users[i].Birth var record common.LoginRecord err := db.Mysql().C().Model(&common.LoginRecord{}).Where(" uid = ?", users[i].Id).Last(&record).Error if err != nil { log.Error(err.Error()) } // 最后登录时间 data.LastLogin = record.Time // 玩家游戏局数 data.GameCount = models.GetGameCountByBalance(nil, nil, &users[i].Id, nil, nil, nil) // 玩家剩余账户金额 data.Amount = users[i].BindCash + users[i].Cash // 玩家账户可提现金额 data.Cash = users[i].Cash // 玩家总提现金额 data.WithDrawAmount = getPlayerAmountBySql(users[i].Id, int(common.CurrencyEventWithDraw), common.StatusROrderFinish) // 玩家总充值金额 data.RechargeAmount = getPlayerAmountBySql(users[i].Id, int(common.CurrencyEventReCharge), common.StatusROrderPay) res = append(res, data) } return res } // 获取玩家充值金额 func getPlayerAmountBySql(uid, event, status int) int64 { var amount int64 amountTotal := "SELECT IFNULL(SUM(amount),0) as Amount FROM recharge_order WHERE uid = %d AND event = %v AND status = %v " err := db.Mysql().QueryBySql(fmt.Sprintf(amountTotal, uid, event, status), &amount) if err != nil { log.Error(err.Error()) } return amount }