package service import ( "context" "encoding/json" "errors" "fmt" "strings" "time" "github.com/redis/go-redis/v9" ) // SummaryCache 封装 summary 接口的 Redis 缓存。 type SummaryCache struct { rc *redis.Client keyPrefix string ttl time.Duration } func NewSummaryCache(rc *redis.Client, keyPrefix string, ttl time.Duration) *SummaryCache { if ttl <= 0 { ttl = 5 * time.Minute } return &SummaryCache{ rc: rc, keyPrefix: keyPrefix, ttl: ttl, } } func (c *SummaryCache) Get(ctx context.Context, userID uint) (*SummaryResponse, bool, error) { if c == nil || c.rc == nil || userID == 0 { return nil, false, nil } val, err := c.rc.Get(ctx, c.summaryKey(userID)).Bytes() if err != nil { if errors.Is(err, redis.Nil) { return nil, false, nil } return nil, false, fmt.Errorf("redis get summary: %w", err) } var summary SummaryResponse if err := json.Unmarshal(val, &summary); err != nil { _ = c.rc.Del(ctx, c.summaryKey(userID)).Err() return nil, false, nil } return &summary, true, nil } func (c *SummaryCache) Set(ctx context.Context, userID uint, summary *SummaryResponse) error { if c == nil || c.rc == nil || userID == 0 || summary == nil { return nil } body, err := json.Marshal(summary) if err != nil { return fmt.Errorf("marshal summary: %w", err) } if err := c.rc.Set(ctx, c.summaryKey(userID), body, c.ttl).Err(); err != nil { return fmt.Errorf("redis set summary: %w", err) } return nil } func (c *SummaryCache) Delete(ctx context.Context, userID uint) error { if c == nil || c.rc == nil || userID == 0 { return nil } if err := c.rc.Del(ctx, c.summaryKey(userID)).Err(); err != nil { return fmt.Errorf("redis del summary: %w", err) } return nil } func (c *SummaryCache) summaryKey(userID uint) string { prefix := c.keyPrefix if prefix != "" && !strings.HasSuffix(prefix, ":") { prefix += ":" } return fmt.Sprintf("%sexpiry_summary:%d", prefix, userID) }