game_sync/statistics/task/task/bankruptcy.go

190 lines
5.9 KiB
Go

package task
import (
"context"
"errors"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"mongo.games.com/goserver/core/logger"
mymongo "mongo.games.com/goserver/core/mongox"
mymysql "mongo.games.com/goserver/core/mysqlx"
"mongo.games.com/game/common"
mongomodel "mongo.games.com/game/statistics/modelmongo"
)
// 新用户id
func GetNewPayerIds(plt string, startTime, endTime string) ([]int, error) {
s, e := common.StrRFC3339TimeToTime(startTime), common.StrRFC3339TimeToTime(endTime)
c, err := mymongo.GetUserCollection(plt, mongomodel.UserAccount)
if err != nil {
return nil, err
}
var res []struct{ Snid int }
dd, err := c.Find(context.TODO(), bson.M{"registetime": bson.M{"$gte": s, "$lt": e}}, options.Find().SetProjection(bson.M{"snid": 1}))
if err != nil {
if errors.Is(err, mongo.ErrNoDocuments) {
return nil, nil
}
logger.Logger.Errorf("find new player snid get err: %v", err)
return nil, err
}
if err := dd.All(context.TODO(), &res); err != nil {
logger.Logger.Errorf("find new player snid decode err: %v", err)
return nil, err
}
var ret []int
for _, v := range res {
ret = append(ret, v.Snid)
}
logger.Logger.Tracef("find new player snid: %v", ret)
return ret, nil
}
// 场次破产总人数
func GameFreeIdBankruptPlayerCount(plt string, ids []int, startTime, endTime string, gamefreeid int) (int, error) {
s, e := common.StrRFC3339TimeToTime(startTime), common.StrRFC3339TimeToTime(endTime)
db, err := mymysql.GetDatabase("count")
if err != nil {
return 0, err
}
var ret int
for _, v := range ids {
var n int64
if err = db.Table("bankrupt_log").Where("snid = ? AND bankrupt_time >= ? AND bankrupt_time < ? AND game_free_id = ?",
v, s.Unix(), e.Unix(), gamefreeid).Count(&n).Error; err != nil {
logger.Logger.Errorf("find bankrupt player count get err: %v", err)
return 0, err
}
if n > 0 {
ret++
}
}
return ret, nil
}
// 场次参与总人数
func PlayingGameCount(plt string, ids []int, startTime, endTime string, gamefreeid int) (int, error) {
s, e := common.StrRFC3339TimeToTime(startTime), common.StrRFC3339TimeToTime(endTime)
c, err := mymongo.GetLogCollection(plt, mongomodel.LogGamePlayerListLog)
if err != nil {
return 0, err
}
var ret int
for _, v := range ids {
// 参与过游戏
n, err := c.CountDocuments(context.TODO(), bson.M{"snid": v, "time": bson.M{"$gte": s, "$lt": e}, "gamefreeid": gamefreeid})
if err != nil {
logger.Logger.Errorf("find playing game count get err: %v", err)
return 0, err
}
if n > 0 {
ret++
}
}
return ret, nil
}
// NewPlayerBankruptRate 新用户破产率
// 新用户游戏破产率 = 新用户游戏破产玩家数量/新用户游戏参与总人数;破产数量,每个玩家每个游戏破产只统计一次;参与人数,每个玩家每个游戏只统计一次;
// 返回 新用户数量,破产人数,参与人数
func NewPlayerBankruptRate(plt string, startTime, endTime string, gamefreeid int) (n, a, b int, err error) {
s, e := common.StrRFC3339TimeToTime(startTime), common.StrRFC3339TimeToTime(endTime)
if s.IsZero() || e.IsZero() {
return 0, 0, 0, fmt.Errorf("time format error")
}
ids, err := GetNewPayerIds(plt, startTime, endTime)
if err != nil {
return 0, 0, 0, err
}
a, err = GameFreeIdBankruptPlayerCount(plt, ids, startTime, endTime, gamefreeid)
if err != nil {
return 0, 0, 0, err
}
b, err = PlayingGameCount(plt, ids, startTime, endTime, gamefreeid)
if err != nil {
return 0, 0, 0, err
}
if b == 0 {
return 0, 0, 0, nil
}
return
}
// ActivePlayerCount 活跃玩家游戏总人数
func ActivePlayerCount(plt string, startTime, endTime string, gamefreeid int) (int, error) {
s, e := common.StrRFC3339TimeToTime(startTime), common.StrRFC3339TimeToTime(endTime)
c, err := mymongo.GetLogCollection(plt, mongomodel.LogGamePlayerListLog)
if err != nil {
return 0, err
}
var count []struct {
Count int
}
cur, err := c.Aggregate(context.TODO(), bson.A{
bson.M{"$match": bson.M{"time": bson.M{"$gte": s, "$lt": e}, "gamefreeid": gamefreeid}},
bson.M{"$group": bson.M{"_id": "$snid"}},
bson.M{"$count": "count"},
})
if err != nil {
logger.Logger.Errorf("find active player count get err: %v", err)
return 0, err
}
if err := cur.All(context.TODO(), &count); err != nil {
logger.Logger.Errorf("find active player count decode err: %v", err)
return 0, err
}
if len(count) == 0 {
return 0, nil
}
return count[0].Count, nil
}
// ActivePlayerBankruptCount 活跃玩家破产总人数
func ActivePlayerBankruptCount(plt string, startTime, endTime string, gamefreeid int) (int, error) {
s, e := common.StrRFC3339TimeToTime(startTime), common.StrRFC3339TimeToTime(endTime)
db, err := mymysql.GetDatabase("count")
if err != nil {
return 0, err
}
var n int64
if err = db.Table("bankrupt_log").Where("bankrupt_time >= ? AND bankrupt_time < ? AND game_free_id = ?",
s.Unix(), e.Unix(), gamefreeid).Group("snid").Count(&n).Error; err != nil {
logger.Logger.Errorf("find bankrupt count get err: %v", err)
return 0, err
}
return int(n), nil
}
// ActivePlayerBankruptRate 活跃玩家破产率
// 活跃玩家游戏破产率 = 活跃玩家游戏破产玩家数量/活跃玩家游戏总人数;破产数量,每个玩家每个游戏破产只统计一次;参与人数,每个玩家每个游戏只统计一次;
// 返回 破产人数,参与人数
func ActivePlayerBankruptRate(plt string, startTime, endTime string, gamefreeid int) (a, b int, err error) {
s, e := common.StrRFC3339TimeToTime(startTime), common.StrRFC3339TimeToTime(endTime)
if s.IsZero() || e.IsZero() {
return 0, 0, fmt.Errorf("time format error")
}
a, err = ActivePlayerBankruptCount(plt, startTime, endTime, gamefreeid)
if err != nil {
return 0, 0, err
}
b, err = ActivePlayerCount(plt, startTime, endTime, gamefreeid)
if err != nil {
return 0, 0, err
}
if b == 0 {
return 0, 0, nil
}
return
}