package biz import ( "context" "fmt" "github.com/redis/go-redis/v9" "voucher/internal/biz/bo" "voucher/internal/biz/vo" "voucher/internal/pkg/lock" ) func (v *VoucherBiz) alarm(ctx context.Context, order *bo.OrderBo, errMsg string) error { // 1小时 内 指定的批次号 发放 发生错误 预警 c := vo.OrderConsumeFailAlarmKey.BuildCache([]string{order.ProductNo}) _, err := v.rdb.Rdb.Get(ctx, c.Key).Result() if err == nil { // 缓存存在,直接返回 return nil } if err != redis.Nil { return fmt.Errorf(fmt.Sprintf("alarm 获取redis缓存%s异常:%v", c.Key, err)) } cl := vo.OrderConsumeFailAlarmLockKey.BuildCache([]string{order.ProductNo}) return lock.NewMutex(v.rdb.Rdb, cl.TTL).Lock(ctx, cl.Key, func(ctx context.Context) error { // 二次获取,判定处理,以免获取锁后又执行了一次 cacheValue, err3 := v.rdb.Rdb.Get(ctx, c.Key).Result() if err3 != nil && err3 != redis.Nil { return fmt.Errorf(fmt.Sprintf("alarm 二次获取redis缓存%s异常:%v", c.Key, err)) } if len(cacheValue) > 0 { return nil // 有直接返回 } // 通知 if err = v.DingMixRepo.SendMarkdownMessage(ctx, "异常通知", v.alarmText(ctx, order, errMsg)); err != nil { return err } if err = v.rdb.Rdb.Set(ctx, c.Key, order.ProductNo, c.TTL).Err(); err != nil { return fmt.Errorf(fmt.Sprintf("设置redis缓存%s异常:%v", c.Key, err)) } return nil }) } func (v *VoucherBiz) alarmText(_ context.Context, order *bo.OrderBo, errMsg string) string { remarks := fmt.Sprintf("订单号:%s,商品编号:%s,原因:%s", order.OrderNo, order.ProductNo, errMsg) msg := "# " + "

立减金发放报警通知

" + "
\n" + "" + "不好了,订单发放发生异常了" + "[%s]" + "" return fmt.Sprintf(msg, remarks) }