package group_s import ( "context" "git.hilo.cn/hilo-common/_const/enum/msg_e" "git.hilo.cn/hilo-common/_const/rediskey" "git.hilo.cn/hilo-common/domain" "git.hilo.cn/hilo-common/resource/mysql" "git.hilo.cn/hilo-common/resource/redisCli" "github.com/go-redis/redis/v8" "hilo-group/_const/enum/gift_e" "hilo-group/domain/event/group_ev" "hilo-group/domain/model/gift_m" "hilo-group/domain/model/group_m" "hilo-group/domain/model/msg_m" "hilo-group/domain/model/res_m" "hilo-group/domain/model/user_m" "hilo-group/myerr/bizerr" "strconv" "time" ) // 群组支持名单过滤 func (s *GroupService) GroupSupportList(groupId string, uids []uint64) ([]uint64, []uint64, error) { if len(uids) <= 0 { return uids, nil, nil } result := make([]uint64, 0) out := make([]uint64, 0) err := s.svc.Transactional(func() error { model := domain.CreateModel(s.svc.CtxAndDb) // 1. 去掉非群管理者 roles, _, err := group_m.GetRolesInGroup(model, groupId) if err != nil { return err } userIds := make([]uint64, 0) for _, i := range uids { if _, ok := roles[i]; ok { userIds = append(userIds, i) } else { out = append(out, i) model.Log.Infof("GroupSupportList: rule out %d, no role", i) } } // TODO: 去掉非群成员 //(4)1个账户只能做1个群组的管理员(5)1个设备下只允许领取1个管理奖励 _, _, period := group_m.GetLastSupportPeriod(time.Now()) gsa := group_m.GroupSupportAwardMgr{Period: period} rows, err := gsa.Get(model.Db) if err != nil { return err } awards := make(map[uint64]struct{}, 0) for _, i := range rows { awards[i.UserId] = struct{}{} } uids = userIds userIds = make([]uint64, 0) m := make(map[uint64]uint64) for _, u := range uids { m, err := user_m.GetSameImeiMap(model, u) if err != nil { return err } passed := true for _, i := range m { if _, ok := awards[i]; ok { if i == u { passed = false model.Log.Infof("GroupSupportList: rule out %d, already awarded", i) } else { passed = false model.Log.Infof("GroupSupportList: rule out %d, imei awarded", i) } } } if passed == true { userIds = append(userIds, u) } else { out = append(out, u) } } model.Log.Infof("GroupSupportList: uids %v, map %v", uids, m) _, supportLevel, err := s.GetSupportLevel(groupId) if err != nil { return err } if uint32(len(userIds)) > supportLevel { model.Log.Infof("GroupSupportList: rule out %v, limit exeeded", userIds[supportLevel:]) out = append(out, userIds[supportLevel:]...) userIds = userIds[0:supportLevel] } result = userIds return nil }) if err == nil { return result, out, nil } else { return nil, nil, err } } func (s *GroupService) GetSupportLevel(groupId string) (uint64, uint32, error) { model := domain.CreateModel(s.svc.CtxAndDb) beginTime, endTime, _ := group_m.GetLastSupportPeriod(time.Now()) g := gift_m.GiftOperate{SceneType: gift_e.GroupSceneType, SceneUid: groupId, Model: model} count, consume, err := g.GetConsumeByRange(beginTime, endTime) if err != nil { return 0, 0, err } rec, err := res_m.GetResGroupSupportBy(model, count, consume) if err != nil { return 0, 0, err } if rec != nil { return rec.ID, rec.MgrNum, nil } return 0, 0, nil } //群组支持奖励 func (s *GroupService) GroupSupportAward(groupId string, profitAllocator uint64, userIds []uint64, resId uint64, period string) error { return s.svc.Transactional(func() error { model := domain.CreateModel(s.svc.CtxAndDb) // groupInfo, err := group_m.GetGroupInfo(model, groupId) if groupInfo == nil { return bizerr.GroupNotFound } //发放奖励 groupSupportAwardAdmin, groupSupportAwardMgrs, err := group_m.AddGroupSupportAward(model, groupId, profitAllocator, resId, userIds, period) if err != nil { return err } if err := groupSupportAwardAdmin.Persistent(); err != nil { return err } groupSupportEvent := group_ev.InitGroupSupportEvent(len(groupSupportAwardMgrs), groupInfo.Code) //数据持久化 groupSupportEvent.AddAdmin(groupSupportAwardAdmin.ID, groupSupportAwardAdmin.UserId, groupSupportAwardAdmin.DiamondNum) for i, _ := range groupSupportAwardMgrs { if err := groupSupportAwardMgrs[i].Persistent(); err != nil { return err } groupSupportEvent.AddMgr(groupSupportAwardMgrs[i].ID, groupSupportAwardMgrs[i].UserId, groupSupportAwardMgrs[i].DiamondNum) } return group_ev.PublishGroupSupport(model, groupSupportEvent) }) } func (s *GroupService) RenewGroupSupporter(groupId string, userIds []uint64) error { return s.svc.Transactional(func() error { model := domain.CreateModel(s.svc.CtxAndDb) gs := group_m.GroupSupporter{GroupId: groupId} if err := gs.Delete(model.Db); err != nil { return err } if len(userIds) > 0 { gs = group_m.GroupSupporter{GroupId: groupId} if err := gs.BatchSave(model.Db, userIds); err != nil { return err } } return nil }) } func (s *GroupService) GroupSupportResult(time time.Time) error { model := domain.CreateModelContext(s.svc.MyContext) _, _, period := group_m.GetSupportLevelTime(time) // 群组扶持数值 groupGradeMap, err := getGroupGradeMap(model, period) if err != nil { model.Log.Errorf("GroupSupportResult time:%v, err:%v", time, err) return err } model.Log.Infof("GroupSupportResult period:%s, len:%d, groupUidGadeMap:%v", period, len(groupGradeMap), groupGradeMap) // 房间访问人数 roomVisitCount, err := GetAllRoomNonZeroVisitCount() if err != nil { model.Log.Errorf("GroupSupportResult err:%v", err) return err } // 入库群组扶持结果 for g, grade := range groupGradeMap { r := group_m.InitGroupSupportResult(model, g, grade, period, roomVisitCount[g]) r.SetOnDuplicateKeyIGNORE() if err = r.Persistent(); err != nil { model.Log.Errorf("GroupSupportResult InitGroupSupportResult r:%+v, err:%v", r, err) } } // 小助手通知 AssistantNotification(model, groupGradeMap) return nil } func getGroupGradeMap(model *domain.Model, period string) (map[string]uint8, error) { // 配置 gsConfig, err := res_m.GetResGroupSupportByValid(model) if err != nil { model.Log.Errorf("GroupSupportResult err:%v", err) return nil, err } // 群组扶持数值 groupGradeMap := make(map[string]uint8, 0) //userNum := make(map[string]uint32, 0) // 流水 keyDiamond := rediskey.GetGroupSupportConsumeSummary(period) var start int64 count := int64(999) var zList []redis.Z // 一次取1000个处理 for start == 0 || len(zList) > 0 { stop := start + count zList, err = model.RedisCluster.ZRangeWithScores(context.Background(), keyDiamond, start, stop).Result() if err != nil { model.Log.Errorf("GroupSupportResult err:%v", err) return nil, err } if len(zList) == 0 { break } for _, v := range zList { imGroupId := v.Member.(string) consume := mysql.Num(v.Score) // 支持者数量 keySupportNum := rediskey.GetGroupSupportCountSupporter(period, imGroupId) supportNum, err := model.RedisCluster.SCard(context.Background(), keySupportNum).Result() if err != nil { model.Log.Errorf("GroupSupportResult key:%s, err:%v", keySupportNum, err) return nil, err } for j := len(gsConfig) - 1; j >= 0; j-- { if mysql.Num(supportNum) >= gsConfig[j].ContributeUserNum && consume >= gsConfig[j].ContributeDiamondNum { groupGradeMap[imGroupId] = gsConfig[j].Grade //userNum[imGroupId] = uint32(supportNum) break } } } start = stop + 1 } return groupGradeMap, nil } func AssistantNotification(model *domain.Model, groupGradeMap map[string]uint8) { // 小助手通知 for g, _ := range groupGradeMap { userId, err := group_m.GetProfitAllocator(model, g) if err != nil { model.Log.Errorf("GroupSupportResult msg GetProfitAllocator err:%v, groupUid:%v", err, g) continue } //推送 user, err := user_m.GetUser(model, userId) if err != nil { model.Log.Infof("GroupSupportResult msg GetUser userId:=%v, err:=%v", userId, err) continue } record := msg_m.NewUserRecord(model, user.ID, msg_e.GroupSupportResult, "", 0, "", "", "", "", "") if err := record.Persistent(); err != nil { model.Log.Infof("GroupSupportResult msg record.Persistent() err:%v", err) continue } msg_m.SendEmasMsgAssistant(model, user.ExternalId, user.DeviceType) } } func GetAllRoomNonZeroVisitCount() (map[string]uint, error) { m, err := GetAllRoomVisitCount() if err != nil { return nil, err } result := make(map[string]uint, 0) for g, s := range m { if c, err := strconv.Atoi(s); err == nil && c > 0 { result[g] = uint(c) } } return result, nil } func GetAllRoomVisitCount() (map[string]string, error) { key := rediskey.GetPrefixRoomVisitCount() return redisCli.GetRedis().HGetAll(context.Background(), key).Result() }