You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
9.2 KiB
243 lines
9.2 KiB
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 |
|
}
|
|
|