package jobs import ( "context" "encoding/json" "fmt" "gadmin/config" "gadmin/internal/admin/service" "gadmin/internal/gorm/query" "gadmin/utility" "gadmin/utility/player" "github.com/jinzhu/now" "github.com/sirupsen/logrus" "os" "strings" "sync" "time" ) var ( HaveRoles = new(jHaveRoles) ) type jHaveRoles struct { ctx context.Context sync.RWMutex } type HaveRolesNums struct { RoleNums int64 `json:"role_nums"` Count int64 `json:"count"` } func (j *jHaveRoles) Run() { j.ctx = context.TODO() logrus.Info("jHaveRoles Run.....") if os.Getenv("GIN_MODE") == "release" || os.Getenv("ADMIN_IS_LOCAL") == "1" { yesterday := now.With(time.Now().AddDate(0, 0, -1)) for serverId, _ := range config.GDBGroup { j.haveRoles(serverId, yesterday) } } else { logrus.Warn("非正式环境无需进行,跳过..") } } func (j *jHaveRoles) RunWithDate(date *now.Now) { j.ctx = context.TODO() logrus.Info("jHaveRoles RunWithDate.....") if os.Getenv("GIN_MODE") == "release" || os.Getenv("ADMIN_IS_LOCAL") == "1" { for serverId, _ := range config.GDBGroup { j.haveRoles(serverId, date) } } else { logrus.Warn("非正式环境无需进行,跳过..") } } func (j *jHaveRoles) haveRoles(serverId int, yesterday *now.Now) { j.RLock() defer j.RUnlock() DB, err := player.GetDBByServerID(serverId) if err != nil { logrus.Warningf("haveRoles GetDBByServerID,err:%v", err) return } var ( allHaveRoles = make(map[string]map[int64]int64) date = utility.Format(yesterday.Time) endUnix = yesterday.EndOfDay().Unix() ) logrus.Infof("统计拥有角色数据,date:%v, Unix:%+v", date, endUnix) channelIds, err := service.Channel.Ids() if err != nil { logrus.Warningf("Channel.Ids,err:%v", err) return } allHaveRoles["-1"] = make(map[int64]int64) for _, channelId := range channelIds { if allHaveRoles[channelId] == nil { allHaveRoles[channelId] = make(map[int64]int64) } if channelId == "0" { continue } tmpIds := service.PlayerChannel.PlayerIds(j.ctx, channelId) pIds := utility.SpiltInt64BySizeFromInt64(tmpIds, 10000) for _, ids := range pIds { roleNums, err := j.GetRoleNums(DB, ids, endUnix) if err != nil { logrus.Warningf("GetRoleNums,err:%v", err) return } if len(roleNums) == 0 { continue } for _, roleNum := range roleNums { allHaveRoles[channelId][roleNum.RoleNums] += roleNum.Count allHaveRoles["-1"][roleNum.RoleNums] += roleNum.Count } } } allRoleNums, err := j.GetRoleNums(DB, []int64{}, endUnix) if err != nil { logrus.Warningf("GetRoleNums all,err:%v", err) return } if len(allRoleNums) == 0 { // 设置默认值 allHaveRoles["0"][1] = 0 } else { for _, roleNum := range allRoleNums { allHaveRoles["0"][roleNum.RoleNums] += roleNum.Count - allHaveRoles["-1"][roleNum.RoleNums] } } for channelId, haveRoles := range allHaveRoles { if channelId == "-1" { continue } str, err := json.Marshal(haveRoles) if err != nil { logrus.Errorf("ReportDayHaveRole Save Marshal err:%+v", err) return } reportDao := query.Use(config.DB).ReportDayHaveRole // 统计表 arl, _ := reportDao.Where(reportDao.Date.Eq(date), reportDao.ChannelID.Eq(channelId), reportDao.ServerID.Eq(int32(serverId))).FirstOrInit() arl.Date = date arl.ChannelID = channelId arl.ServerID = int32(serverId) arl.Data = string(str) if err = reportDao.Save(arl); err != nil { logrus.Errorf("ReportDayHaveRole Save err:%+v", err) return } } logrus.Info("统计拥有角色数据完成..") } func (j *jHaveRoles) GetRoleNums(DB int, ids []int64, endStamp int64) (result []*HaveRolesNums, err error) { if endStamp <= 0 { endStamp = now.With(time.Now().AddDate(0, 0, -1)).EndOfDay().Unix() } endStr := time.Unix(endStamp, 0).Format("2006-01-02 15:04:05") // 存在条件 if len(ids) > 0 { idStr := strings.Trim(strings.Replace(fmt.Sprint(ids), " ", ",", -1), "[]") tx := config.GDBGroup[DB]. Raw(fmt.Sprintf("select b.role_nums, count(1) as count from (SELECT ua.playerid, floor(length(pm.roles)/27) as role_nums FROM player_attr ua left join player_material pm on ua.playerid = pm.playerid where ua.playerid in (%v) and ua.create_time <= '%v' and pm.roles is not null) b group by b.role_nums", idStr, endStr)) if err = tx.Scan(&result).Error; err != nil { return nil, err } return } tx := config.GDBGroup[DB]. Raw(fmt.Sprintf("select b.role_nums, count(1) as count from (SELECT ua.playerid, floor(length(pm.roles)/27) as role_nums FROM player_attr ua left join player_material pm on ua.playerid = pm.playerid where ua.create_time <= '%v' and pm.roles is not null) b group by b.role_nums", endStr)) if err = tx.Scan(&result).Error; err != nil { return nil, err } return }