u
This commit is contained in:
1 parent
bce259f165
commit
dc46d8034d
8 files changed
+430
-259
No files matched your search
@@ -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
|
||||
}
|
||||
Reference in new issue
Block a user