package user_c import ( "git.hilo.cn/hilo-common/_const/common" "git.hilo.cn/hilo-common/domain" "git.hilo.cn/hilo-common/resource/mysql" "git.hilo.cn/hilo-common/utils" redisV8 "github.com/go-redis/redis/v8" "github.com/jinzhu/copier" "hilo-user/_const/redis_key/user_k" "hilo-user/domain/cache" "hilo-user/domain/model/user_m" "hilo-user/myerr" "hilo-user/myerr/bizerr" "time" ) // 获取用户简要信息 // param userId 用户id func GetUserTinyById(model *domain.Model, userId mysql.ID) (*user_m.UserTiny, error) { userTiny := new(user_m.UserTiny) key := user_k.GetUserTinyKey(userId) err := cache.GetJSON(model, key, userTiny) if err != nil && err != redisV8.Nil { return nil, err } if err == redisV8.Nil { // cache miss,get from mysql if user, err := user_m.GetUser(model, userId); err != nil { return nil, err } else { copier.Copy(userTiny, user) err = cacheUserTiny(model, user) if err != nil { return nil, err } } } return userTiny, nil } // 获取用户简要信息By ExternalId func GetUserByExternalId(model *domain.Model, externalId mysql.Str) (*user_m.UserTiny, error) { userId, err := ToUserId(model, externalId) if err != nil { return nil, err } return GetUserTinyById(model, userId) } // externalId 到 userId func ToUserId(model *domain.Model, externalId mysql.Str) (mysql.ID, error) { if externalId == "" { return 0, myerr.NewSysError("externalId 不能为空") } userId, err := model.Redis.Get(model.Context, user_k.GetExternalIdToUidKey(externalId)).Int64() if err != nil && err != redisV8.Nil { return 0, err } // cache miss,sync from db if err == redisV8.Nil { if user, err := user_m.GetUserByExtId(model, externalId); err != nil { return 0, bizerr.ExternalIdNoExist } else { if err = cacheUserTiny(model, user); err != nil { return 0, err } userId = int64(user.ID) } } return mysql.ID(userId), nil } // code 到 userId func ToUserIdByCode(model *domain.Model, code mysql.Str) (mysql.ID, error) { if code == "" { return 0, myerr.NewSysError("code 不能为空") } userId, err := model.Redis.Get(model.Context, user_k.GetCodeToUidKey(code)).Int64() if err != nil && err != redisV8.Nil { return 0, err } // cache miss,sync from db if err == redisV8.Nil { if user, err := user_m.GetUserByCode(model, code); err != nil { return 0, bizerr.CodeNoExist } else { if err = cacheUserTiny(model, user); err != nil { return 0, err } userId = int64(user.ID) } } return mysql.ID(userId), nil } // 缓存userTiny // 顺手缓存externalId->userId // 顺手缓存code->userId // param user: 已经在上层获取的db User结构 func cacheUserTiny(model *domain.Model, user *user_m.User) error { userTiny := new(user_m.UserTiny) if err := copier.Copy(userTiny, user); err != nil { return err } // cache externalId->userId if err := model.Redis.SetEX(model.Context, user_k.GetExternalIdToUidKey(user.ExternalId), user.ID, cache.GetDefaultTTL()).Err(); err != nil { return err } // cache code->userId if err := model.Redis.SetEX(model.Context, user_k.GetCodeToUidKey(user.Code), user.ID, cache.GetDefaultTTL()).Err(); err != nil { return err } if err := cache.SetJSON(model, user_k.GetUserTinyKey(user.ID), userTiny); err != nil { return err } return nil } // 获取用户简要信息 // param userIds 用户id列表 func GetUserTinyMap(model *domain.Model, userIds []mysql.ID, isDefAvatar bool) (map[mysql.ID]*user_m.UserTiny, error) { redisNoIds := make([]mysql.ID, 0) res := make(map[mysql.ID]*user_m.UserTiny) for _, id := range userIds { userTiny := new(user_m.UserTiny) key := user_k.GetUserTinyKey(id) err := cache.GetJSON(model, key, userTiny) if err != nil && err != redisV8.Nil { return nil, err } if err == redisV8.Nil { redisNoIds = append(redisNoIds, id) } else if userTiny.ID > 0 { res[id] = userTiny } } // 从db中读 users, err := user_m.GetUsers(model, redisNoIds) if err != nil { return nil, err } for _, u := range users { userTiny := ToUserTinyBy(u) err = cacheUserTiny(model, u) if err != nil { return nil, err } res[userTiny.ID] = userTiny } if isDefAvatar { for _, v := range res { if len(v.Avatar) <= 0 { if v.Sex == mysql.MAN { v.Avatar = utils.MakeFullUrl(common.DefaultAvatarMan) } else if v.Sex == mysql.WOMAN { v.Avatar = utils.MakeFullUrl(common.DefaultAvatarWoman) } } } } return res, nil } func ToUserTinyBy(user *user_m.User) *user_m.UserTiny { return &user_m.UserTiny{ ID: user.ID, Avatar: IfLogoutStr(IfLogout(user.LogoutTime), "", user.Avatar), ExternalId: user.ExternalId, Nick: IfLogoutNick(IfLogout(user.LogoutTime), user.Code, user.Nick), Sex: user.Sex, Code: user.Code, Country: user.Country, CountryIcon: user.CountryIcon, IsPrettyCode: user.IsPrettyCode(), IsLogout: IfLogout(user.LogoutTime), Birthday: BirthdayToUint64(&user.Birthday), } } func IfLogout(logoutTime int64) bool { return logoutTime > 0 && time.Now().Unix() > logoutTime } func BirthdayToUint64(birthday *mysql.Timestamp) *uint64 { if *birthday == 0 { return nil } return (*uint64)(birthday) } func IfLogoutStr(condition bool, trueVal, falseVal string) string { if condition { return trueVal } return falseVal } func IfLogoutNick(condition bool, code string, nick string) string { if condition { return "Hilo No." + code } return nick }