This commit is contained in:
oneao committed 2026-02-08 22:01:35 +08:00
1 parent bce259f165
commit dc46d8034d
8 files changed
+430 -259

No files matched your search

+43 -79
View File
@@ -40,101 +40,65 @@ func Exists(key string) (bool, error) {
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)
// ================== Space User / Role ==================
pipe := Client().TxPipeline()
const (
RoleMember int32 = 1
RoleAdmin int32 = 5
RoleOwner int32 = 9
// 1. 先清空旧数据
pipe.Del(ctx, key)
SpaceUserTTL = 10 * time.Minute
)
// 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
// space:user:{spaceId}:{userId}
func SpaceUserKey(spaceId int64, userId int64) string {
return fmt.Sprintf("space:user:%d:%d", spaceId, userId)
}
// 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()
// Set / Create space user role
func SetSpaceUserRole(spaceId int64, userId int64, role int32) error {
key := SpaceUserKey(spaceId, userId)
return Set(key, role, SpaceUserTTL)
}
// 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()
// Update space user role (same as set, semantic clarity)
func UpdateSpaceUserRole(spaceId int64, userId int64, role int32) error {
return SetSpaceUserRole(spaceId, userId, role)
}
// Get space user role
// return 0 means not exists
func GetSpaceUserRole(spaceId int64, userId int64) (int32, error) {
key := SpaceUserKey(spaceId, userId)
val, err := Get(key)
if err != nil {
return nil, err
return 0, err
}
if val == "" {
return 0, nil
}
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()
r, err := strconv.ParseInt(val, 10, 32)
if err != nil {
if errors.Is(err, redis.Nil) {
return 0, false, nil // 用户不在空间
}
return 0, false, err
return 0, err
}
role, err = strconv.Atoi(val)
if err != nil {
return 0, false, err
}
return role, true, nil
return int32(r), 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()
// Delete space user (kick / dissolve)
func DeleteSpaceUser(spaceId int64, userId int64) error {
key := SpaceUserKey(spaceId, userId)
return Delete(key)
}
// ClearUserSpaces 删除用户的所有空间列表
func ClearUserSpaces(ctx context.Context, userID int64) error {
key := fmt.Sprintf("user:%d:spaces", userID)
return Client().Del(ctx, key).Err()
// Exists space user
func ExistsSpaceUser(spaceId int64, userId int64) (bool, error) {
key := SpaceUserKey(spaceId, userId)
return Exists(key)
}
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
// Permission check
// owner > admin > member
func HasPermission(userRole int32, needRole int32) bool {
return userRole >= needRole
}