package cache import ( "context" "encoding/json" "errors" "fmt" "strings" "time" "github.com/redis/go-redis/v9" "wx_service/internal/model" ) type SessionUserCache struct { rc *redis.Client keyPrefix string ttl time.Duration } func NewSessionUserCache(rc *redis.Client, keyPrefix string, ttl time.Duration) *SessionUserCache { return &SessionUserCache{ rc: rc, keyPrefix: keyPrefix, ttl: ttl, } } func (c *SessionUserCache) Get(ctx context.Context, token string) (*model.User, bool, error) { if c == nil || c.rc == nil || token == "" { return nil, false, nil } key := c.sessionKey(token) val, err := c.rc.Get(ctx, key).Bytes() if err != nil { if errors.Is(err, redis.Nil) { return nil, false, nil } return nil, false, fmt.Errorf("redis get: %w", err) } var user model.User if err := json.Unmarshal(val, &user); err != nil { _ = c.rc.Del(ctx, key).Err() return nil, false, nil } return &user, true, nil } func (c *SessionUserCache) Set(ctx context.Context, token string, user *model.User) error { if c == nil || c.rc == nil || token == "" || user == nil { return nil } key := c.sessionKey(token) body, err := json.Marshal(user) if err != nil { return fmt.Errorf("marshal user: %w", err) } if err := c.rc.Set(ctx, key, body, c.ttl).Err(); err != nil { return fmt.Errorf("redis set: %w", err) } return nil } func (c *SessionUserCache) sessionKey(token string) string { prefix := c.keyPrefix if prefix != "" && !strings.HasSuffix(prefix, ":") { prefix += ":" } return prefix + "session_user:" + token }