| | package model |
| |
|
| | import ( |
| | "encoding/json" |
| | "fmt" |
| | "github.com/gin-gonic/gin" |
| | "one-api/common" |
| | "one-api/constant" |
| | "time" |
| |
|
| | "github.com/bytedance/gopkg/util/gopool" |
| | ) |
| |
|
| | |
| | type UserBase struct { |
| | Id int `json:"id"` |
| | Group string `json:"group"` |
| | Email string `json:"email"` |
| | Quota int `json:"quota"` |
| | Status int `json:"status"` |
| | Username string `json:"username"` |
| | Setting string `json:"setting"` |
| | } |
| |
|
| | func (user *UserBase) WriteContext(c *gin.Context) { |
| | c.Set(constant.ContextKeyUserGroup, user.Group) |
| | c.Set(constant.ContextKeyUserQuota, user.Quota) |
| | c.Set(constant.ContextKeyUserStatus, user.Status) |
| | c.Set(constant.ContextKeyUserEmail, user.Email) |
| | c.Set("username", user.Username) |
| | c.Set(constant.ContextKeyUserSetting, user.GetSetting()) |
| | } |
| |
|
| | func (user *UserBase) GetSetting() map[string]interface{} { |
| | if user.Setting == "" { |
| | return nil |
| | } |
| | return common.StrToMap(user.Setting) |
| | } |
| |
|
| | func (user *UserBase) SetSetting(setting map[string]interface{}) { |
| | settingBytes, err := json.Marshal(setting) |
| | if err != nil { |
| | common.SysError("failed to marshal setting: " + err.Error()) |
| | return |
| | } |
| | user.Setting = string(settingBytes) |
| | } |
| |
|
| | |
| | func getUserCacheKey(userId int) string { |
| | return fmt.Sprintf("user:%d", userId) |
| | } |
| |
|
| | |
| | func invalidateUserCache(userId int) error { |
| | if !common.RedisEnabled { |
| | return nil |
| | } |
| | return common.RedisHDelObj(getUserCacheKey(userId)) |
| | } |
| |
|
| | |
| | func updateUserCache(user User) error { |
| | if !common.RedisEnabled { |
| | return nil |
| | } |
| |
|
| | return common.RedisHSetObj( |
| | getUserCacheKey(user.Id), |
| | user.ToBaseUser(), |
| | time.Duration(constant.UserId2QuotaCacheSeconds)*time.Second, |
| | ) |
| | } |
| |
|
| | |
| | func GetUserCache(userId int) (userCache *UserBase, err error) { |
| | var user *User |
| | var fromDB bool |
| | defer func() { |
| | |
| | if shouldUpdateRedis(fromDB, err) && user != nil { |
| | gopool.Go(func() { |
| | if err := updateUserCache(*user); err != nil { |
| | common.SysError("failed to update user status cache: " + err.Error()) |
| | } |
| | }) |
| | } |
| | }() |
| |
|
| | |
| | userCache, err = cacheGetUserBase(userId) |
| | if err == nil { |
| | return userCache, nil |
| | } |
| |
|
| | |
| | fromDB = true |
| | user, err = GetUserById(userId, false) |
| | if err != nil { |
| | return nil, err |
| | } |
| |
|
| | |
| | userCache = &UserBase{ |
| | Id: user.Id, |
| | Group: user.Group, |
| | Quota: user.Quota, |
| | Status: user.Status, |
| | Username: user.Username, |
| | Setting: user.Setting, |
| | Email: user.Email, |
| | } |
| |
|
| | return userCache, nil |
| | } |
| |
|
| | func cacheGetUserBase(userId int) (*UserBase, error) { |
| | if !common.RedisEnabled { |
| | return nil, fmt.Errorf("redis is not enabled") |
| | } |
| | var userCache UserBase |
| | |
| | err := common.RedisHGetObj(getUserCacheKey(userId), &userCache) |
| | if err != nil { |
| | return nil, err |
| | } |
| | return &userCache, nil |
| | } |
| |
|
| | |
| | func cacheIncrUserQuota(userId int, delta int64) error { |
| | if !common.RedisEnabled { |
| | return nil |
| | } |
| | return common.RedisHIncrBy(getUserCacheKey(userId), "Quota", delta) |
| | } |
| |
|
| | func cacheDecrUserQuota(userId int, delta int64) error { |
| | return cacheIncrUserQuota(userId, -delta) |
| | } |
| |
|
| | |
| | func getUserGroupCache(userId int) (string, error) { |
| | cache, err := GetUserCache(userId) |
| | if err != nil { |
| | return "", err |
| | } |
| | return cache.Group, nil |
| | } |
| |
|
| | func getUserQuotaCache(userId int) (int, error) { |
| | cache, err := GetUserCache(userId) |
| | if err != nil { |
| | return 0, err |
| | } |
| | return cache.Quota, nil |
| | } |
| |
|
| | func getUserStatusCache(userId int) (int, error) { |
| | cache, err := GetUserCache(userId) |
| | if err != nil { |
| | return 0, err |
| | } |
| | return cache.Status, nil |
| | } |
| |
|
| | func getUserNameCache(userId int) (string, error) { |
| | cache, err := GetUserCache(userId) |
| | if err != nil { |
| | return "", err |
| | } |
| | return cache.Username, nil |
| | } |
| |
|
| | func getUserSettingCache(userId int) (map[string]interface{}, error) { |
| | setting := make(map[string]interface{}) |
| | cache, err := GetUserCache(userId) |
| | if err != nil { |
| | return setting, err |
| | } |
| | return cache.GetSetting(), nil |
| | } |
| |
|
| | |
| | func updateUserStatusCache(userId int, status bool) error { |
| | if !common.RedisEnabled { |
| | return nil |
| | } |
| | statusInt := common.UserStatusEnabled |
| | if !status { |
| | statusInt = common.UserStatusDisabled |
| | } |
| | return common.RedisHSetField(getUserCacheKey(userId), "Status", fmt.Sprintf("%d", statusInt)) |
| | } |
| |
|
| | func updateUserQuotaCache(userId int, quota int) error { |
| | if !common.RedisEnabled { |
| | return nil |
| | } |
| | return common.RedisHSetField(getUserCacheKey(userId), "Quota", fmt.Sprintf("%d", quota)) |
| | } |
| |
|
| | func updateUserGroupCache(userId int, group string) error { |
| | if !common.RedisEnabled { |
| | return nil |
| | } |
| | return common.RedisHSetField(getUserCacheKey(userId), "Group", group) |
| | } |
| |
|
| | func updateUserNameCache(userId int, username string) error { |
| | if !common.RedisEnabled { |
| | return nil |
| | } |
| | return common.RedisHSetField(getUserCacheKey(userId), "Username", username) |
| | } |
| |
|
| | func updateUserSettingCache(userId int, setting string) error { |
| | if !common.RedisEnabled { |
| | return nil |
| | } |
| | return common.RedisHSetField(getUserCacheKey(userId), "Setting", setting) |
| | } |
| |
|