package tim_m import ( "context" "encoding/json" "git.hilo.cn/hilo-common/domain" "git.hilo.cn/hilo-common/mylogrus" "git.hilo.cn/hilo-common/resource/redisCli" "git.hilo.cn/hilo-common/sdk/tencentyun" "hilo-group/_const/enum/msg_e" "hilo-group/_const/enum/online_e" "hilo-group/_const/enum/tim_e" "hilo-group/_const/redis_key" "hilo-group/domain/model/groupPower_m" "hilo-group/domain/model/res_m" "hilo-group/domain/model/user_m" "runtime/debug" "strconv" "time" ) func FlushGrades(userExtId string, wealthGrade uint32, charmGrade uint32) error { level := (charmGrade & 0x000000FF << 8) | wealthGrade&0x000000FF return tencentyun.SetUserLevel(userExtId, level) } func SyncWealthGrade(userExtId string, wealthGrade uint32) error { level, err := tencentyun.GetUserLevel(userExtId) if err != nil { return err } mylogrus.MyLog.Infof("SyncWealthGrade, user %s, level before = %x, wealthGrade = %d", userExtId, level, wealthGrade) level = level&0xFFFFFF00 | wealthGrade&0x000000FF return tencentyun.SetUserLevel(userExtId, level) } func SyncCharmGrade(userExtId string, charmGrade uint32) error { level, err := tencentyun.GetUserLevel(userExtId) if err != nil { return err } mylogrus.MyLog.Infof("SyncCharmGrade, user %s, level before = %x, charmGrade = %d", userExtId, level, charmGrade) level = level&0xFFFF00FF | (charmGrade & 0x000000FF << 8) return tencentyun.SetUserLevel(userExtId, level) } type TimHiloInfo struct { IsVip bool `json:"isVip"` IsPretty bool `json:"isPretty"` Medals []uint32 `json:"medals"` PowerName string `json:"powerName"` // 用户加入的国家势力的绑定群组的名称 NobleLevel uint16 `json:"nobleLevel"` } func GetHiloInfo(extId string) (string, error) { result, err := tencentyun.GetUserHiloInfo(extId) if err != nil { return "", err } return result, nil } func ResetHiloInfo(extId string) error { info := TimHiloInfo{} buf, err := json.Marshal(info) if err != nil { return err } return tencentyun.SetUserHiloInfo(extId, string(buf)) } func SyncIsVip(model *domain.Model, userId uint64, externalId string) error { //detail, err := cv.GetUserVip(model, userId) //if err != nil { // return err //} isVip, _, err := user_m.IsVip(userId) if err != nil { return err } //isVip := false //if detail != nil { // isVip = true //} if err = SaveIsVip(externalId, isVip); err != nil { model.Log.Info("Sync TIM hilo info failed: ", err) } return nil } func SaveIsVip(extId string, isVip bool) error { value, err := tencentyun.GetUserHiloInfo(extId) if err != nil { return err } mylogrus.MyLog.Info("TIM hilo info: ", value) info := TimHiloInfo{} if len(value) > 0 { if err = json.Unmarshal([]byte(value), &info); err != nil { return err } } info.IsVip = isVip buf, err := json.Marshal(info) if err != nil { return err } if err = tencentyun.SetUserHiloInfo(extId, string(buf)); err != nil { return err } return nil } func SyncIsPretty(extId string, isPretty bool) error { value, err := tencentyun.GetUserHiloInfo(extId) if err != nil { return err } mylogrus.MyLog.Info("TIM hilo info: ", value) info := TimHiloInfo{} if len(value) > 0 { if err = json.Unmarshal([]byte(value), &info); err != nil { return err } } info.IsPretty = isPretty buf, err := json.Marshal(info) if err != nil { return err } if err = tencentyun.SetUserHiloInfo(extId, string(buf)); err != nil { return err } return nil } func SyncMedals(model *domain.Model, userId uint64, externalId string) error { // 同步勋章 medals, err := user_m.GetUserMedalMerge(model.Log, model.Db, userId) if err != nil { return nil } if err = SaveMedals(externalId, medals); err != nil { mylogrus.MyLog.Info("Sync TIM hilo info failed: ", err) } return nil } // fixme:同步贵族信息,购买、续费贵族时需要 func SyncNobleLevel(extId string, nobleLevel uint16) error { value, err := tencentyun.GetUserHiloInfo(extId) if err != nil { return err } mylogrus.MyLog.Info("TIM hilo info: ", value) info := TimHiloInfo{} if len(value) > 0 { if err = json.Unmarshal([]byte(value), &info); err != nil { return err } } info.NobleLevel = nobleLevel buf, err := json.Marshal(info) if err != nil { return err } if err = tencentyun.SetUserHiloInfo(extId, string(buf)); err != nil { return err } return nil } func SaveMedals(extId string, medals []uint32) error { value, err := tencentyun.GetUserHiloInfo(extId) if err != nil { return err } mylogrus.MyLog.Info("TIM hilo info: ", value) info := TimHiloInfo{} if len(value) > 0 { if err = json.Unmarshal([]byte(value), &info); err != nil { return err } } info.Medals = medals buf, err := json.Marshal(info) if err != nil { return err } if err = tencentyun.SetUserHiloInfo(extId, string(buf)); err != nil { return err } return nil } // fixme: 以下时机要同步:用户加入/退出势力;势力被取消;势力改绑定群组;群组改名称,欢迎补充 func SyncPowerName(model *domain.Model, userId uint64, externalId string) error { _, powerName, err := groupPower_m.GetUserGroupPower(model, userId) if err != nil { return err } if err = SavePowerName(externalId, powerName); err != nil { mylogrus.MyLog.Info("Sync TIM hilo info failed: ", err) } return nil } func SavePowerName(extId string, powerName string) error { value, err := tencentyun.GetUserHiloInfo(extId) if err != nil { return err } mylogrus.MyLog.Info("TIM hilo info: ", value) info := TimHiloInfo{} if len(value) > 0 { if err = json.Unmarshal([]byte(value), &info); err != nil { return err } } info.PowerName = powerName buf, err := json.Marshal(info) if err != nil { return err } if err = tencentyun.SetUserHiloInfo(extId, string(buf)); err != nil { return err } return nil } func SaveNobleLevel(extId string, nobleLevel uint16) error { value, err := tencentyun.GetUserHiloInfo(extId) if err != nil { return err } mylogrus.MyLog.Info("TIM hilo info: ", value) info := TimHiloInfo{} if len(value) > 0 { if err = json.Unmarshal([]byte(value), &info); err != nil { return err } } info.NobleLevel = nobleLevel buf, err := json.Marshal(info) if err != nil { return err } if err = tencentyun.SetUserHiloInfo(extId, string(buf)); err != nil { return err } return nil } func FlushHiloInfo(extId string, isVip bool, isPrettyCode bool, medals []uint32, groupPowerName string, nobleLevel uint16) error { info := TimHiloInfo{IsVip: isVip, IsPretty: isPrettyCode, Medals: medals, PowerName: groupPowerName, NobleLevel: nobleLevel} buf, err := json.Marshal(info) if err != nil { return err } if err = tencentyun.SetUserHiloInfo(extId, string(buf)); err != nil { return err } return nil } func SendGroupInvitationShare(model *domain.Model, fromAccount string, toAccounts []string, txGroupId, faceUrl string, lang string) error { type TIMInviteEnterRoomMessage struct { Identifier string `json:"identifier"` GroupFaceUrl string `json:"groupFaceUrl"` GroupId string `json:"groupId"` } msg := TIMInviteEnterRoomMessage{ Identifier: "TIMGroupInviteMessage", GroupFaceUrl: faceUrl, GroupId: txGroupId, } buf, err := json.Marshal(msg) if err != nil { return err } msgBody := string(buf) /* mt := res_m.ResMultiText{MsgId: common.MSG_ID_GROUP_INVITE, Language: lang} if err = mt.Get(model.Db); err != nil { return err }*/ mt, err := res_m.GetResMultiTextBy(model.Db, msg_e.MSG_ID_GROUP_INVITE, lang) if err != nil { return err } return tencentyun.BatchSendCustomMsg(model, tim_e.SYNC_TO_SENDER, fromAccount, toAccounts, msgBody, mt.Content) } func GetOnlineStatus(model *domain.Model, extIds []string) (map[string]uint, error) { left := make([]string, 0) result := make(map[string]uint, 0) r, err := getOnlineStatus(extIds) if err != nil { model.Log.Warnf("getOnlineStatus redis failed") left = extIds } else { model.Log.Infof("getOnlineStatus redis return size = %d: %v", len(r), r) if len(r) >= len(extIds) { for i, e := range extIds { if r[i] == nil { left = append(left, e) } else { switch r[i].(type) { case string: s, err := strconv.Atoi(r[i].(string)) if err == nil { result[e] = uint(s) } else { left = append(left, e) } default: model.Log.Infof("getOnlineStatus return unknown type %v for %s", r[i], e) left = append(left, e) } } } } else { left = extIds } } model.Log.Debug("getOnlineStatus cache: ", result) if len(left) > 0 { for _, i := range left { result[i] = online_e.IM_STATUS_OFF_LINE } // 异步去取TIM取数据及更新。查不到的就当离线! go func(userIds []string) { defer func() { if r := recover(); r != nil { mylogrus.MyLog.Errorf("SetOnlineStatus SYSTEM ACTION PANIC: %v, stack: %v", r, string(debug.Stack())) } }() st, err := tencentyun.BatchQueryState(model, userIds) if err != nil { return } mylogrus.MyLog.Info("getOnlineStatus db: ", st) for k, v := range st { if err := setOnlineStatus(k, v, time.Hour*12); err != nil { model.Log.Warn("SetOnlineStatus failed for ", k) } else { model.Log.Infof("SetOnlineStatus done %s - %d", k, v) } } }(left) } return result, nil } func getOnlineStatus(extIds []string) ([]interface{}, error) { keys := make([]string, 0) for _, e := range extIds { keys = append(keys, redis_key.GetOnLineStatusKey(e)) } return redisCli.RedisClient.MGet(context.Background(), keys...).Result() } func setOnlineStatus(extId string, status uint, ttl time.Duration) error { key := redis_key.GetOnLineStatusKey(extId) return redisCli.RedisClient.Set(context.Background(), key, status, ttl).Err() }