package group_s import ( "context" "git.hilo.cn/hilo-common/_const/rediskey" "git.hilo.cn/hilo-common/domain" "git.hilo.cn/hilo-common/resource/redisCli" "github.com/go-redis/redis/v8" "hilo-group/_const/enum/gift_e" "hilo-group/cv/gift_cv" "hilo-group/domain/cache/room_c" "hilo-group/domain/model/group_m" "hilo-group/domain/model/res_m" "sort" "strconv" "time" ) func SortGroupCommonCountryList(model *domain.Model) { // 常用的国家 countryMap := map[string]struct{}{"India": {}, "Indonesia": {}, "Iraq": {}, "KSA": {}, "Kuwait": {}, "Pakistan": {}, "Turkey": {}} for country, _ := range countryMap { sortGroupList, err := GetGroupSortList(model, country) if err != nil { model.Log.Errorf("SortGroupCommonCountryList err:%v", err) return } // 写入redis err = setToRedis(model, country, sortGroupList) if err != nil { model.Log.Errorf("SortGroupCommonCountryList country:%v, len(sortGroupList):%v, err:%v", country, len(sortGroupList), err) return } time.Sleep(time.Second * 3) } } func SortGroupNotCommonCountryList(model *domain.Model) { // 常用的国家 countryMap := map[string]struct{}{"India": {}, "Indonesia": {}, "Iraq": {}, "KSA": {}, "Kuwait": {}, "Pakistan": {}, "Turkey": {}} // 取所有的国家名字 allCountryList, err := res_m.GetCountryNameList(model) if err != nil { model.Log.Errorf("SortGroupNotCommonCountryList err:%v", err) return } for _, country := range allCountryList { if _, ok := countryMap[country]; ok { continue } // 计算非常用国家 sortGroupList, err := GetGroupSortList(model, country) if err != nil { model.Log.Errorf("SortGroupNotCommonCountryList err:%v", err) return } // 写入redis err = setToRedis(model, country, sortGroupList) if err != nil { model.Log.Errorf("SortGroupNotCommonCountryList country:%v, len(sortGroupList):%v, err:%v", country, len(sortGroupList), err) return } time.Sleep(time.Second * 5) } } func setToRedis(model *domain.Model, country string, groupList []string) error { // 写入redis key := rediskey.GetGroupCountrySortList(country) for idx, group := range groupList { err := redisCli.GetRedis().ZRemRangeByRank(context.Background(), key, int64(idx), int64(idx)).Err() // 先删除旧的 if err != nil { model.Log.Errorf("setToRedis SortGroup key:%v, idx:%v, err:%v", key, idx, err) return err } // 插入 err = redisCli.GetRedis().ZAdd(context.Background(), key, &redis.Z{Score: float64(idx), Member: group}).Err() if err != nil { model.Log.Errorf("setToRedis SortGroup key:%v, idx:%v, group:%s, err:%v", key, idx, group, err) return err } if idx%1000 == 0 { time.Sleep(time.Millisecond * 50) } } return nil } // 计算国家群组列表排序 func GetGroupSortList(model *domain.Model, country string) ([]string, error) { bannedGroups, err := group_m.GetBannedGroupsMap(model) if err != nil { return nil, err } beginTime := time.Now() groups, banCount, visitCount, err := GetCandidatesByCountry(model, bannedGroups, country) if err != nil { return nil, err } endTime := time.Now() model.Log.Infof("GroupCountryListSort: candidates size = %d, takes %d ms banned = %d, visitCount size = %d", len(groups), endTime.Sub(beginTime).Milliseconds(), banCount, len(visitCount)) // 获取麦上有人的所有群组及麦上人数 micGroupNum, err := group_m.GetMicHasInGroupNum(model) if err != nil { return nil, err } model.Log.Infof("GroupCountryListSort, micGroupNum : %v", micGroupNum) model.Log.Infof("GroupCountryListSort cost2:%v", time.Now().Sub(beginTime)) sortedGroupIds := make([]string, 0) diamondGroupIds := make([]string, 0) for i, _ := range groups { // 麦上没人也放出来 sortedGroupIds = append(sortedGroupIds, i) // 麦上有人才计算流水 if micGroupNum[i] > 0 { diamondGroupIds = append(diamondGroupIds, i) } } now := time.Now() bTime := now.Add(-time.Minute * 30) g := gift_cv.GiftOperate{SceneType: gift_e.GroupSceneType} diamonds, err := g.GetRangeConsumeSummaryV2(bTime, now, diamondGroupIds) if err != nil { return nil, err } model.Log.Infof("GroupCountryListSort, diamonds in 30 mins: %v", diamonds) model.Log.Infof("GroupCountryListSort cost3:%v", time.Now().Sub(beginTime)) supportLevels, err := NewGroupService(model.MyContext).GetWeekMaxSupportLevelMap() if err != nil { return nil, err } model.Log.Infof("GroupCountryListSort, supportLevels : %v", supportLevels) model.Log.Infof("GroupCountryListSort cost4:%v", time.Now().Sub(beginTime)) // 排序优先级2022-07-25 sort.Slice(sortedGroupIds, func(i, j int) bool { gi := sortedGroupIds[i] gj := sortedGroupIds[j] // 1、按麦上人数多少排序 if micGroupNum[gi] > micGroupNum[gj] { return true } else if micGroupNum[gi] < micGroupNum[gj] { return false } // 2、麦上人数相同,按30分钟内送礼钻石数排序 if diamonds[gi] > diamonds[gj] { return true } else if diamonds[gi] < diamonds[gj] { return false } // 3. 根据热度排序groupInUserDuration if visitCount[gi] > visitCount[gj] { return true } else if visitCount[gi] < visitCount[gj] { return false } // * Final resort: 群组CODE,短号优先,然后按字母序 return len(groups[gi].Code) < len(groups[gj].Code) || len(groups[gi].Code) == len(groups[gj].Code) && groups[gi].Code < groups[gj].Code }) model.Log.Infof("GroupCountryListSort cost5:%v", time.Now().Sub(beginTime)) return sortedGroupIds, nil } // 国家群候选:没有密码且没被封禁的群, 有国家 func GetCandidatesByCountry(model *domain.Model, bannedGroups map[string]uint64, country string) (map[string]*group_m.GroupInfo, int, map[string]int64, error) { noPwdGroups, err := group_m.FindOwnerCountryGroups(model, country) if err != nil { return nil, 0, nil, err } var groupIds []string for _, v := range noPwdGroups { groupIds = append(groupIds, v.ImGroupId) // imGroupId } //roomVisitCount, err := room_c.GetAllRoomVisitCount() roomVisitCount, err := room_c.MGetRoomVisitCount(groupIds) if err != nil { return nil, 0, nil, err } gameRoom := group_m.GetGameGroupsMap(model) banCount := 0 groups := make(map[string]*group_m.GroupInfo, 0) visitCount := make(map[string]int64) for i, v := range noPwdGroups { // 过滤掉被封禁的群 if bannedGroups[v.ImGroupId] != 0 { banCount++ continue } // 过滤游戏房 if gameRoom[v.ImGroupId] { continue } // 先从二级缓存中找 if c, ok := roomVisitCount[v.ImGroupId]; ok { if vc, err := strconv.ParseInt(c, 10, 64); err == nil && vc > 0 { //model.Log.Debugf("getPopularCandidates, from roomVisitCount %s(%s) - %d", v.ImGroupId, v.Code, vc) groups[v.ImGroupId] = &noPwdGroups[i] visitCount[v.ImGroupId] = vc } } else { // 如果没有,就从roomVisit中取 if vc, err := room_c.GetSetRoomVisitCount(v.ImGroupId); err == nil && vc > 0 { model.Log.Infof("getPopularCandidates, from roomVisit %s(%s) - %d", v.ImGroupId, v.Code, vc) groups[v.ImGroupId] = &noPwdGroups[i] visitCount[v.ImGroupId] = vc } } } return groups, banCount, visitCount, nil } func GetVisitCount(groupIds []string) (map[string]int64, error) { roomVisitCount, err := room_c.MGetRoomVisitCount(groupIds) if err != nil { return nil, err } visitCount := make(map[string]int64) for _, v := range groupIds { // 先从二级缓存中找 if c, ok := roomVisitCount[v]; ok { if vc, err := strconv.ParseInt(c, 10, 64); err == nil && vc > 0 { visitCount[v] = vc } } else { // 如果没有,就从roomVisit中取 if vc, err := room_c.GetSetRoomVisitCount(v); err == nil && vc > 0 { visitCount[v] = vc } } } return visitCount, nil }