Files
hi-server/internal/logic/admin/user/session.go
T
2026-06-16 06:28:47 -07:00

82 lines
2.0 KiB
Go

package user
import (
"context"
"fmt"
"strconv"
"strings"
"github.com/perfect-panel/server/internal/config"
"github.com/perfect-panel/server/internal/svc"
)
func clearAllSessions(ctx context.Context, svcCtx *svc.ServiceContext, userID int64) error {
userIDText := strconv.FormatInt(userID, 10)
sessionSet := make(map[string]struct{})
pattern := fmt.Sprintf("%s:*", config.SessionIdKey)
var cursor uint64
for {
keys, nextCursor, err := svcCtx.Redis.Scan(ctx, cursor, pattern, 200).Result()
if err != nil {
return err
}
for _, sessionKey := range keys {
value, err := svcCtx.Redis.Get(ctx, sessionKey).Result()
if err != nil || value != userIDText {
continue
}
sessionID := strings.TrimPrefix(sessionKey, config.SessionIdKey+":")
if sessionID == "" || strings.HasPrefix(sessionID, "detail:") {
continue
}
sessionSet[sessionID] = struct{}{}
}
cursor = nextCursor
if cursor == 0 {
break
}
}
if len(sessionSet) == 0 {
return nil
}
deviceKeySet := make(map[string]struct{})
devicePattern := fmt.Sprintf("%s:*", config.DeviceCacheKeyKey)
cursor = 0
for {
keys, nextCursor, err := svcCtx.Redis.Scan(ctx, cursor, devicePattern, 200).Result()
if err != nil {
return err
}
for _, deviceKey := range keys {
sessionID, err := svcCtx.Redis.Get(ctx, deviceKey).Result()
if err != nil {
continue
}
if _, exists := sessionSet[sessionID]; exists {
deviceKeySet[deviceKey] = struct{}{}
}
}
cursor = nextCursor
if cursor == 0 {
break
}
}
sessionsKey := fmt.Sprintf("%s%v", config.UserSessionsKeyPrefix, userID)
pipe := svcCtx.Redis.TxPipeline()
for sessionID := range sessionSet {
pipe.Del(ctx, fmt.Sprintf("%v:%v", config.SessionIdKey, sessionID))
pipe.Del(ctx, fmt.Sprintf("%s:detail:%s", config.SessionIdKey, sessionID))
pipe.ZRem(ctx, sessionsKey, sessionID)
}
pipe.Del(ctx, sessionsKey)
for deviceKey := range deviceKeySet {
pipe.Del(ctx, deviceKey)
}
_, err := pipe.Exec(ctx)
return err
}