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.
244 lines
9.2 KiB
244 lines
9.2 KiB
|
1 year ago
|
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
|
||
|
|
}
|