207 lines
4.9 KiB
Go
207 lines
4.9 KiB
Go
package model
|
|
|
|
import (
|
|
"fmt"
|
|
"one-api/common"
|
|
"one-api/constant"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
// Change UserCache struct to userCache
|
|
type userCache struct {
|
|
Id int `json:"id"`
|
|
Group string `json:"group"`
|
|
Quota int `json:"quota"`
|
|
Status int `json:"status"`
|
|
Role int `json:"role"`
|
|
Username string `json:"username"`
|
|
}
|
|
|
|
// Rename all exported functions to private ones
|
|
// invalidateUserCache clears all user related cache
|
|
func invalidateUserCache(userId int) error {
|
|
if !common.RedisEnabled {
|
|
return nil
|
|
}
|
|
|
|
keys := []string{
|
|
fmt.Sprintf(constant.UserGroupKeyFmt, userId),
|
|
fmt.Sprintf(constant.UserQuotaKeyFmt, userId),
|
|
fmt.Sprintf(constant.UserEnabledKeyFmt, userId),
|
|
fmt.Sprintf(constant.UserUsernameKeyFmt, userId),
|
|
}
|
|
|
|
for _, key := range keys {
|
|
if err := common.RedisDel(key); err != nil {
|
|
return fmt.Errorf("failed to delete cache key %s: %w", key, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// updateUserGroupCache updates user group cache
|
|
func updateUserGroupCache(userId int, group string) error {
|
|
if !common.RedisEnabled {
|
|
return nil
|
|
}
|
|
return common.RedisSet(
|
|
fmt.Sprintf(constant.UserGroupKeyFmt, userId),
|
|
group,
|
|
time.Duration(constant.UserId2QuotaCacheSeconds)*time.Second,
|
|
)
|
|
}
|
|
|
|
// updateUserQuotaCache updates user quota cache
|
|
func updateUserQuotaCache(userId int, quota int) error {
|
|
if !common.RedisEnabled {
|
|
return nil
|
|
}
|
|
return common.RedisSet(
|
|
fmt.Sprintf(constant.UserQuotaKeyFmt, userId),
|
|
fmt.Sprintf("%d", quota),
|
|
time.Duration(constant.UserId2QuotaCacheSeconds)*time.Second,
|
|
)
|
|
}
|
|
|
|
// updateUserStatusCache updates user status cache
|
|
func updateUserStatusCache(userId int, userEnabled bool) error {
|
|
if !common.RedisEnabled {
|
|
return nil
|
|
}
|
|
enabled := "0"
|
|
if userEnabled {
|
|
enabled = "1"
|
|
}
|
|
return common.RedisSet(
|
|
fmt.Sprintf(constant.UserEnabledKeyFmt, userId),
|
|
enabled,
|
|
time.Duration(constant.UserId2StatusCacheSeconds)*time.Second,
|
|
)
|
|
}
|
|
|
|
// updateUserNameCache updates username cache
|
|
func updateUserNameCache(userId int, username string) error {
|
|
if !common.RedisEnabled {
|
|
return nil
|
|
}
|
|
return common.RedisSet(
|
|
fmt.Sprintf(constant.UserUsernameKeyFmt, userId),
|
|
username,
|
|
time.Duration(constant.UserId2QuotaCacheSeconds)*time.Second,
|
|
)
|
|
}
|
|
|
|
// updateUserCache updates all user cache fields
|
|
func updateUserCache(userId int, username string, userGroup string, quota int, status int) error {
|
|
if !common.RedisEnabled {
|
|
return nil
|
|
}
|
|
|
|
if err := updateUserGroupCache(userId, userGroup); err != nil {
|
|
return fmt.Errorf("update group cache: %w", err)
|
|
}
|
|
|
|
if err := updateUserQuotaCache(userId, quota); err != nil {
|
|
return fmt.Errorf("update quota cache: %w", err)
|
|
}
|
|
|
|
if err := updateUserStatusCache(userId, status == common.UserStatusEnabled); err != nil {
|
|
return fmt.Errorf("update status cache: %w", err)
|
|
}
|
|
|
|
if err := updateUserNameCache(userId, username); err != nil {
|
|
return fmt.Errorf("update username cache: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// getUserGroupCache gets user group from cache
|
|
func getUserGroupCache(userId int) (string, error) {
|
|
if !common.RedisEnabled {
|
|
return "", nil
|
|
}
|
|
return common.RedisGet(fmt.Sprintf(constant.UserGroupKeyFmt, userId))
|
|
}
|
|
|
|
// getUserQuotaCache gets user quota from cache
|
|
func getUserQuotaCache(userId int) (int, error) {
|
|
if !common.RedisEnabled {
|
|
return 0, nil
|
|
}
|
|
quotaStr, err := common.RedisGet(fmt.Sprintf(constant.UserQuotaKeyFmt, userId))
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return strconv.Atoi(quotaStr)
|
|
}
|
|
|
|
// getUserStatusCache gets user status from cache
|
|
func getUserStatusCache(userId int) (int, error) {
|
|
if !common.RedisEnabled {
|
|
return 0, nil
|
|
}
|
|
statusStr, err := common.RedisGet(fmt.Sprintf(constant.UserEnabledKeyFmt, userId))
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return strconv.Atoi(statusStr)
|
|
}
|
|
|
|
// getUserNameCache gets username from cache
|
|
func getUserNameCache(userId int) (string, error) {
|
|
if !common.RedisEnabled {
|
|
return "", nil
|
|
}
|
|
return common.RedisGet(fmt.Sprintf(constant.UserUsernameKeyFmt, userId))
|
|
}
|
|
|
|
// getUserCache gets complete user cache
|
|
func getUserCache(userId int) (*userCache, error) {
|
|
if !common.RedisEnabled {
|
|
return nil, nil
|
|
}
|
|
|
|
group, err := getUserGroupCache(userId)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("get group cache: %w", err)
|
|
}
|
|
|
|
quota, err := getUserQuotaCache(userId)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("get quota cache: %w", err)
|
|
}
|
|
|
|
status, err := getUserStatusCache(userId)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("get status cache: %w", err)
|
|
}
|
|
|
|
username, err := getUserNameCache(userId)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("get username cache: %w", err)
|
|
}
|
|
|
|
return &userCache{
|
|
Id: userId,
|
|
Group: group,
|
|
Quota: quota,
|
|
Status: status,
|
|
Username: username,
|
|
}, nil
|
|
}
|
|
|
|
// Add atomic quota operations
|
|
func cacheIncrUserQuota(userId int, delta int64) error {
|
|
if !common.RedisEnabled {
|
|
return nil
|
|
}
|
|
key := fmt.Sprintf(constant.UserQuotaKeyFmt, userId)
|
|
return common.RedisIncr(key, delta)
|
|
}
|
|
|
|
func cacheDecrUserQuota(userId int, delta int64) error {
|
|
return cacheIncrUserQuota(userId, -delta)
|
|
}
|