Files
zt-closet-manage-backend/internal/redisdao/notification.go
T
2026-09-11 01:47:20 +08:00

45 lines
1.5 KiB
Go

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
}