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 }