From af6580c8ecb4e617195f692ab91afba155e10b0c Mon Sep 17 00:00:00 2001 From: chenweijian <820961417@qq.com> Date: Wed, 23 Aug 2023 11:27:05 +0800 Subject: [PATCH] group support --- cron/cron.go | 1 + cron/group_cron/group_power_month_act.go | 4 + cron/group_cron/group_support.go | 87 +++++++++++++++ domain/service/event_s/event_init.go | 43 ++++++++ domain/service/group_s/group_support.go | 133 +++++++++++++++++++++++ main.go | 2 + 6 files changed, 270 insertions(+) create mode 100644 cron/group_cron/group_support.go diff --git a/cron/cron.go b/cron/cron.go index d10deb0..4685ff4 100644 --- a/cron/cron.go +++ b/cron/cron.go @@ -19,4 +19,5 @@ func Init() { group_cron.GroupInEventInit() // 进房事件 group_cron.GroupPowerGradeExp() // 家族升级 group_cron.CreateGroup() // + group_cron.CalcGroupSupport() // 群组扶持计算 } diff --git a/cron/group_cron/group_power_month_act.go b/cron/group_cron/group_power_month_act.go index 1f6f86e..412b2ab 100644 --- a/cron/group_cron/group_power_month_act.go +++ b/cron/group_cron/group_power_month_act.go @@ -2,12 +2,16 @@ package group_cron import ( "git.hilo.cn/hilo-common/domain" + "git.hilo.cn/hilo-common/resource/config" "github.com/robfig/cron" "hilo-group/domain/service/group_power_s" ) // 家族贡献月度排行榜发奖 func GroupPowerMonthRankAct() { + if !config.IsMaster() { + return + } c := cron.New() // 每月1号0:01结算发奖 spec := "0 1 0 1 * ?" diff --git a/cron/group_cron/group_support.go b/cron/group_cron/group_support.go new file mode 100644 index 0000000..17f2aab --- /dev/null +++ b/cron/group_cron/group_support.go @@ -0,0 +1,87 @@ +package group_cron + +import ( + "encoding/json" + "git.hilo.cn/hilo-common/domain" + "git.hilo.cn/hilo-common/resource/config" + "git.hilo.cn/hilo-common/sdk/tencentyun" + "git.hilo.cn/hilo-common/utils" + "github.com/robfig/cron" + "hilo-group/_const/enum/group_e" + "hilo-group/domain/model/group_m" + "hilo-group/domain/service/group_s" + "time" +) + +// 群组扶持计算 +func CalcGroupSupport() { + if !config.IsMaster() { + return + } + c := cron.New() + //北京时间周一0点,过了一秒后, + spec := "1 0 0 * * 1" + _ = c.AddFunc(spec, func() { + defer utils.CheckGoPanic() + var model = domain.CreateModelNil() + //开始 + model.Log.Infof("cron CalcGroupSupport start") + + calcTime := time.Now().AddDate(0, 0, -1) + if err := group_s.NewGroupService(model.MyContext).GroupSupportResult(calcTime); err != nil { + model.Log.Errorf("cron CalcGroupSupport faild calcTime:%v, err:%v", calcTime, err) + return + } + model.Log.Infof("cron CalcGroupSupport after GroupSupportResult") + + //全服发送H5 + if err := sendGroupSupportH5(domain.CreateModelContext(model.MyContext)); err != nil { + model.Log.Errorf("cron CalcGroupSupport err:%v", err) + } else { + model.Log.Infof("cron CalcGroupSupport success") + } + }) + + c.Start() +} + +func sendGroupSupportH5(model *domain.Model) error { + groupIds, err := group_m.GetAllGroupsSorted(model) + if err != nil { + return err + } + + model.Log.Infof("SendGroupSupportH5 groupIds:%v", groupIds) + + groupSupportH5 := group_m.GroupSupportH5{ + CommonPublicMsg: group_m.CommonPublicMsg{ + Type: group_e.GroupSupportH5, + }, + H5: config.GetH5Config().GROUP_SUPPORT, + } + buffer, err := json.Marshal(groupSupportH5) + if err != nil { + model.Log.Errorf("publicScreenMsg AddSendGiftAsync json.Marshal(giftContent) err:%v", err) + return err + } + content := string(buffer) + + //策略1:for循环,没有开启协程,100个停一下 + for i, _ := range groupIds { + func(groupId string, content string) { + defer utils.CheckGoPanic() + model.Log.Infof("SendGroupSupportH5 groupId:%v", groupId) + txGroupId, err := group_m.ToTxGroupId(model, groupId) + // 公屏消息 + if err == nil { + tencentyun.SendCustomMsg(model.Log, txGroupId, nil, content, "") + } + }(groupIds[i], content) + + if i != 0 && i%100 == 0 { + //躺平1秒 + time.Sleep(1 * time.Second) + } + } + return nil +} diff --git a/domain/service/event_s/event_init.go b/domain/service/event_s/event_init.go index d64f653..2f7c345 100644 --- a/domain/service/event_s/event_init.go +++ b/domain/service/event_s/event_init.go @@ -1,11 +1,15 @@ package event_s import ( + "context" "encoding/json" + "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" "git.hilo.cn/hilo-common/rpc" "git.hilo.cn/hilo-common/sdk/tencentyun" + "hilo-group/_const/enum/gift_e" "hilo-group/_const/enum/groupPower_e" "hilo-group/_const/enum/group_e" "hilo-group/_const/enum/msg_e" @@ -537,6 +541,45 @@ func SendGift() { } return nil }) + // 送礼事件-群组扶持数据累加 + gift_ev.AddSendGiftEventAsync(func(model *domain.Model, event interface{}) error { + if time.Now().Unix() < 1692964800 { // cwj---- + return nil + } + sendGiftEvent, ok := event.(*gift_ev.SendGiftEvent) + if !ok { + model.Log.Errorf("AddSendGiftEventAsync event type err 群组扶持") + return nil + } + if sendGiftEvent.SceneType != gift_e.GroupSceneType || sendGiftEvent.SceneUid == "" { + return nil + } + _, _, period := group_m.GetSupportLevelTime(time.Now()) + // 钻石数 + diamond := sendGiftEvent.GiftN * sendGiftEvent.ResGift.DiamondNum + keyDiamond := rediskey.GetGroupSupportConsumeSummary(period) + _, err := model.RedisCluster.ZIncrBy(context.Background(), keyDiamond, float64(diamond), sendGiftEvent.SceneUid).Result() + if err != nil { + model.Log.Errorf("AddSendGiftEventAsync groupSupport key:%s, val:%d, member:%s, err:%v", + keyDiamond, diamond, sendGiftEvent.SceneUid, err) + } + err = redisCli.SetExpire(model.RedisCluster, keyDiamond, time.Hour*24*14) // 保留两周 + if err != nil { + model.Log.Errorf("AddSendGiftEventAsync groupSupport key:%s, val:%d, member:%s, err:%v", + keyDiamond, diamond, sendGiftEvent.SceneUid, err) + } + // 支持者数量 + keySupportNum := rediskey.GetGroupSupportCountSupporter(period, sendGiftEvent.SceneUid) + err = model.RedisCluster.SAdd(context.Background(), keySupportNum, sendGiftEvent.SendUserId).Err() + if err != nil { + model.Log.Errorf("AddSendGiftEventAsync groupSupport key:%s, UserId:%d, err:%v", keySupportNum, sendGiftEvent.SendUserId, err) + } + err = redisCli.SetExpire(model.RedisCluster, keySupportNum, time.Hour*24*14) // 保留两周 + if err != nil { + model.Log.Errorf("AddSendGiftEventAsync groupSupport key:%s, UserId:%d, err:%v", keySupportNum, sendGiftEvent.SendUserId, err) + } + return nil + }) } func OnMic() { diff --git a/domain/service/group_s/group_support.go b/domain/service/group_s/group_support.go index fe63bd1..c3202c7 100644 --- a/domain/service/group_s/group_support.go +++ b/domain/service/group_s/group_support.go @@ -1,14 +1,22 @@ 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" ) @@ -173,3 +181,128 @@ func (s *GroupService) RenewGroupSupporter(groupId string, userIds []uint64) 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() +} diff --git a/main.go b/main.go index 629b87e..055e546 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main import ( "fmt" "git.hilo.cn/hilo-common/resource/consul" + "git.hilo.cn/hilo-common/resource/redisCli" "hilo-group/cron" "hilo-group/domain/service/event_s" "hilo-group/route" @@ -17,6 +18,7 @@ const ( func main() { cron.Init() // 开启定时任务 event_s.EventInit() // 注册事件(内部事件+mysql拟kafka) + redisCli.InitCluster() // redis集群 r := route.InitRouter() // 注册路由 consul.RegisterToConsul(PORT, RegisterName, RegisterTag) // 服务注册 r.Run(fmt.Sprintf(":%d", PORT)) // 启动服务 -- 2.22.0