|
|
package model |
|
|
|
|
|
import ( |
|
|
"fmt" |
|
|
"time" |
|
|
|
|
|
"github.com/QuantumNous/new-api/common" |
|
|
"github.com/QuantumNous/new-api/constant" |
|
|
"github.com/QuantumNous/new-api/dto" |
|
|
|
|
|
"github.com/gin-gonic/gin" |
|
|
|
|
|
"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) { |
|
|
common.SetContextKey(c, constant.ContextKeyUserGroup, user.Group) |
|
|
common.SetContextKey(c, constant.ContextKeyUserQuota, user.Quota) |
|
|
common.SetContextKey(c, constant.ContextKeyUserStatus, user.Status) |
|
|
common.SetContextKey(c, constant.ContextKeyUserEmail, user.Email) |
|
|
common.SetContextKey(c, constant.ContextKeyUserName, user.Username) |
|
|
common.SetContextKey(c, constant.ContextKeyUserSetting, user.GetSetting()) |
|
|
} |
|
|
|
|
|
func (user *UserBase) GetSetting() dto.UserSetting { |
|
|
setting := dto.UserSetting{} |
|
|
if user.Setting != "" { |
|
|
err := common.Unmarshal([]byte(user.Setting), &setting) |
|
|
if err != nil { |
|
|
common.SysLog("failed to unmarshal setting: " + err.Error()) |
|
|
} |
|
|
} |
|
|
return setting |
|
|
} |
|
|
|
|
|
|
|
|
func getUserCacheKey(userId int) string { |
|
|
return fmt.Sprintf("user:%d", userId) |
|
|
} |
|
|
|
|
|
|
|
|
func invalidateUserCache(userId int) error { |
|
|
if !common.RedisEnabled { |
|
|
return nil |
|
|
} |
|
|
return common.RedisDelKey(getUserCacheKey(userId)) |
|
|
} |
|
|
|
|
|
|
|
|
func updateUserCache(user User) error { |
|
|
if !common.RedisEnabled { |
|
|
return nil |
|
|
} |
|
|
|
|
|
return common.RedisHSetObj( |
|
|
getUserCacheKey(user.Id), |
|
|
user.ToBaseUser(), |
|
|
time.Duration(common.RedisKeyCacheSeconds())*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.SysLog("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) (dto.UserSetting, error) { |
|
|
cache, err := GetUserCache(userId) |
|
|
if err != nil { |
|
|
return dto.UserSetting{}, 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) |
|
|
} |
|
|
|