This commit is contained in:
oneao committed 2026-02-08 22:23:30 +08:00
1 parent dc46d8034d
commit 949cfa113b
1 file changed
+102 -32
+102 -32
View File
@@ -40,7 +40,14 @@ func Exists(key string) (bool, error) {
return cnt > 0, nil return cnt > 0, nil
} }
// ================== Space User / Role ================== /*
Key design:
space:user:{spaceId}:{userId} -> role (string/int)
space:users:{spaceId} -> Set(userId)
*/
// ================== Role ==================
const ( const (
RoleMember int32 = 1 RoleMember int32 = 1
@@ -50,32 +57,78 @@ const (
SpaceUserTTL = 10 * time.Minute SpaceUserTTL = 10 * time.Minute
) )
// space:user:{spaceId}:{userId} // ================== Key helpers ==================
func SpaceUserKey(spaceId int64, userId int64) string {
func spaceUserKey(spaceId, userId int64) string {
return fmt.Sprintf("space:user:%d:%d", spaceId, userId) return fmt.Sprintf("space:user:%d:%d", spaceId, userId)
} }
// Set / Create space user role func spaceUsersKey(spaceId int64) string {
func SetSpaceUserRole(spaceId int64, userId int64, role int32) error { return fmt.Sprintf("space:users:%d", spaceId)
key := SpaceUserKey(spaceId, userId)
return Set(key, role, SpaceUserTTL)
} }
// Update space user role (same as set, semantic clarity) // ================== Domain APIs ==================
func UpdateSpaceUserRole(spaceId int64, userId int64, role int32) error {
return SetSpaceUserRole(spaceId, userId, role)
}
// Get space user role // JoinSpace
// return 0 means not exists // - add user to space users set
func GetSpaceUserRole(spaceId int64, userId int64) (int32, error) { // - set user role
key := SpaceUserKey(spaceId, userId) func JoinSpace(spaceId, userId int64, role int32) error {
val, err := Get(key) ctx := context.Background()
if err != nil {
return 0, err // 1. add to space users
if err := Client().SAdd(ctx, spaceUsersKey(spaceId), userId).Err(); err != nil {
return err
} }
if val == "" {
return 0, nil // 2. set role
if err := Set(spaceUserKey(spaceId, userId), role, SpaceUserTTL); err != nil {
// rollback
_ = Client().SRem(ctx, spaceUsersKey(spaceId), userId).Err()
return err
}
return nil
}
// LeaveSpace
// - remove user from space
// - delete role cache
func LeaveSpace(spaceId, userId int64) error {
ctx := context.Background()
if err := Client().SRem(ctx, spaceUsersKey(spaceId), userId).Err(); err != nil {
return err
}
return Delete(spaceUserKey(spaceId, userId))
}
// KickSpaceUser = LeaveSpace
func KickSpaceUser(spaceId, userId int64) error {
return LeaveSpace(spaceId, userId)
}
// ChangeSpaceUserRole
func ChangeSpaceUserRole(spaceId, userId int64, role int32) error {
ok, err := IsUserInSpace(spaceId, userId)
if err != nil {
return err
}
if !ok {
return fmt.Errorf("user not in space")
}
return Set(spaceUserKey(spaceId, userId), role, SpaceUserTTL)
}
// ================== Query APIs ==================
// GetSpaceUserRole
// return 0 means not exists
func GetSpaceUserRole(spaceId, userId int64) (int32, error) {
val, err := Get(spaceUserKey(spaceId, userId))
if err != nil || val == "" {
return 0, err
} }
r, err := strconv.ParseInt(val, 10, 32) r, err := strconv.ParseInt(val, 10, 32)
@@ -85,20 +138,37 @@ func GetSpaceUserRole(spaceId int64, userId int64) (int32, error) {
return int32(r), nil return int32(r), nil
} }
// Delete space user (kick / dissolve) func IsUserInSpace(spaceId, userId int64) (bool, error) {
func DeleteSpaceUser(spaceId int64, userId int64) error { return Client().
key := SpaceUserKey(spaceId, userId) SIsMember(context.Background(), spaceUsersKey(spaceId), userId).
return Delete(key) Result()
} }
// Exists space user func GetSpaceUsers(spaceId int64) ([]int64, error) {
func ExistsSpaceUser(spaceId int64, userId int64) (bool, error) { members, err := Client().
key := SpaceUserKey(spaceId, userId) SMembers(context.Background(), spaceUsersKey(spaceId)).
return Exists(key) Result()
if err != nil {
return nil, err
}
users := make([]int64, 0, len(members))
for _, m := range members {
uid, err := strconv.ParseInt(m, 10, 64)
if err == nil {
users = append(users, uid)
}
}
return users, nil
} }
// Permission check // CheckRole
// owner > admin > member // check whether user's role in space >= needRole
func HasPermission(userRole int32, needRole int32) bool { func CheckRole(spaceId, userId int64, needRole int32) (bool, error) {
return userRole >= needRole userRole, err := GetSpaceUserRole(spaceId, userId)
if err != nil {
return false, err
}
return userRole == needRole, nil
} }