Files
workspace/code/allapp/allapp-go/utils/redisx/helper.go
T
2026-01-27 17:33:32 +08:00

141 lines
3.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package redisx
import (
"context"
"errors"
"fmt"
"strconv"
"time"
"github.com/redis/go-redis/v9"
)
// ---------------- 基础方法 ----------------
// Set 设置任意 key
func Set(key string, value interface{}, expire time.Duration) error {
return Client().Set(context.Background(), key, value, expire).Err()
}
// Get 获取任意 key 的值,返回 string
func Get(key string) (string, error) {
val, err := Client().Get(context.Background(), key).Result()
if errors.Is(err, redis.Nil) {
return "", nil
}
return val, err
}
// Delete 删除任意 key
func Delete(key string) error {
return Client().Del(context.Background(), key).Err()
}
// Exists 判断 key 是否存在
func Exists(key string) (bool, error) {
cnt, err := Client().Exists(context.Background(), key).Result()
if err != nil {
return false, err
}
return cnt > 0, nil
}
// SetUserSpaces 初始化用户空间列表(spaceID -> role)
func SetUserSpaces(ctx context.Context, userID int64, spaces map[int64]int32) error {
key := fmt.Sprintf("user:%d:spaces", userID)
pipe := Client().TxPipeline()
// 1. 先清空旧数据
pipe.Del(ctx, key)
// 2. 再写入新数据(如果有)
if len(spaces) > 0 {
data := make(map[string]interface{}, len(spaces))
for spaceID, role := range spaces {
data[strconv.FormatInt(spaceID, 10)] = role
}
pipe.HSet(ctx, key, data)
}
// 3. 执行
_, err := pipe.Exec(ctx)
return err
}
// AddOrUpdateUserSpace 添加或更新单个空间的角色(增量更新)
func AddOrUpdateUserSpace(ctx context.Context, userID, spaceID int64, role int32) error {
key := fmt.Sprintf("user:%d:spaces", userID)
return Client().HSet(ctx, key, strconv.FormatInt(spaceID, 10), role).Err()
}
// GetUserSpaces 获取用户所有空间列表和角色
func GetUserSpaces(ctx context.Context, userID int64) (map[int64]int, error) {
key := fmt.Sprintf("user:%d:spaces", userID)
result, err := Client().HGetAll(ctx, key).Result()
if err != nil {
return nil, err
}
spaces := make(map[int64]int, len(result))
for k, v := range result {
spaceID, err1 := strconv.ParseInt(k, 10, 64)
role, err2 := strconv.Atoi(v)
if err1 != nil || err2 != nil {
continue
}
spaces[spaceID] = role
}
return spaces, nil
}
// GetUserSpaceRole 获取用户在指定空间的角色
func GetUserSpaceRole(ctx context.Context, userID int64, spaceID int64) (role int, exists bool, err error) {
key := fmt.Sprintf("user:%d:spaces", userID)
val, err := Client().HGet(ctx, key, strconv.FormatInt(spaceID, 10)).Result()
if err != nil {
if errors.Is(err, redis.Nil) {
return 0, false, nil // 用户不在空间
}
return 0, false, err
}
role, err = strconv.Atoi(val)
if err != nil {
return 0, false, err
}
return role, true, nil
}
// RemoveUserSpace 从用户缓存中删除一个空间(用户退出或被踢)
func RemoveUserSpace(ctx context.Context, userID int64, spaceID int64) error {
key := fmt.Sprintf("user:%d:spaces", userID)
return Client().HDel(ctx, key, strconv.FormatInt(spaceID, 10)).Err()
}
// ClearUserSpaces 删除用户的所有空间列表
func ClearUserSpaces(ctx context.Context, userID int64) error {
key := fmt.Sprintf("user:%d:spaces", userID)
return Client().Del(ctx, key).Err()
}
func InSpace(ctx context.Context, userID, spaceID int64) (bool, error) {
key := fmt.Sprintf("user:%d:spaces", userID)
return Client().HExists(ctx, key, strconv.FormatInt(spaceID, 10)).Result()
}
// HasUserSpaces 判断用户是否在 Redis 中有空间缓存
func HasUserSpaces(ctx context.Context, userID int64) (bool, error) {
key := fmt.Sprintf("user:%d:spaces", userID)
// HLen 返回 hash 的字段数量
cnt, err := Client().HLen(ctx, key).Result()
if err != nil {
return false, err
}
return cnt > 0, nil
}