package redisdao import ( "context" "fmt" "time" "git.lzcwy.cn/zhengchiliu/zt-closet-manage-backend/global" "github.com/redis/go-redis/v9" ) // businessRedisPrefix 业务服务(zt-closet-backend)的 Redis key 前缀。 // 管理后台推送通知时,必须自增业务服务所读的同一未读计数 key, // 保证小程序端未读角标实时一致。要求管理后台与业务服务共用同一 Redis 库(config.yaml 的 Redis.DB)。 const businessRedisPrefix = "ztcloset:" // KeyNotificationUnread 业务服务的用户未读通知计数 key(格式保持一致)。 var KeyNotificationUnread = businessRedisPrefix + "notification:unread:%d" // notificationUnreadTTL 未读数 key 的过期时间,与业务服务保持一致。 const notificationUnreadTTL = 7 * 24 * time.Hour // notificationUnreadIncrScript 首次自增时设置过期时间,保证 INCR 与 EXPIRE 原子执行。 var notificationUnreadIncrScript = redis.NewScript(` local v = redis.call('INCR', KEYS[1]) if v == 1 then redis.call('EXPIRE', KEYS[1], ARGV[1]) end return v `) // NotificationUnreadIncr 用户未读消息数 +1,返回最新值 func NotificationUnreadIncr(ctx context.Context, userID int64) (int64, error) { ctx, span := global.Tracer.Start(ctx, "redisdao.NotificationUnreadIncr") defer span.End() key := fmt.Sprintf(KeyNotificationUnread, userID) val, err := notificationUnreadIncrScript.Run(ctx, global.RedisEngine, []string{key}, int(notificationUnreadTTL.Seconds())).Int64() if err != nil { span.RecordError(err) return 0, err } return val, nil }