80 lines
2.4 KiB
Go
80 lines
2.4 KiB
Go
package biz
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"github.com/redis/go-redis/v9"
|
|
"strings"
|
|
"voucher/internal/biz/bo"
|
|
"voucher/internal/biz/vo"
|
|
"voucher/internal/pkg/lock"
|
|
)
|
|
|
|
func (this *VoucherBiz) alarm(ctx context.Context, order *bo.OrderBo, errMsg string) error {
|
|
|
|
// 1小时 内 指定的批次号 发放 发生错误 预警
|
|
c := vo.OrderConsumeFailAlarmKey.BuildCache([]string{order.ProductNo})
|
|
|
|
_, err := this.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(this.rdb.Rdb, cl.TTL).Lock(ctx, cl.Key, func(ctx context.Context) error {
|
|
// 二次获取,判定处理,以免获取锁后又执行了一次
|
|
|
|
cacheValue, err3 := this.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 // 有直接返回
|
|
}
|
|
|
|
// 通知
|
|
title := fmt.Sprintf("券发放异常")
|
|
if err = this.DingMixRepo.SendMarkdownMessage(ctx, title, alarmText(order, errMsg)); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err = this.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 alarmText(order *bo.OrderBo, errMsg string) string {
|
|
var card strings.Builder
|
|
|
|
// 警示信息(简化版)
|
|
card.WriteString("⚠️ **券发放异常** ⚠️\n\n")
|
|
|
|
// 订单信息(通过引用和代码块模拟小字体)
|
|
card.WriteString("> **订单信息:**\n\n")
|
|
card.WriteString(fmt.Sprintf("> AppID: `%s`\n\n", order.AppID))
|
|
card.WriteString(fmt.Sprintf("> OpenID: `%s`\n\n", order.Account))
|
|
card.WriteString(fmt.Sprintf("> 批次号: `%s`\n\n", order.BatchNo))
|
|
card.WriteString(fmt.Sprintf("> 活动号: `%s`\n\n", order.ProductNo))
|
|
card.WriteString(fmt.Sprintf("> 订单号: `%s`\n\n", order.OrderNo))
|
|
card.WriteString(fmt.Sprintf("> 招行订单号: `%s`\n", order.OutBizNo))
|
|
card.WriteString("\n")
|
|
|
|
// 报警原因(通过引用和代码块模拟小字体)
|
|
card.WriteString("> **❗ 报警原因:**\n\n")
|
|
card.WriteString(fmt.Sprintf("> `%s`\n", errMsg))
|
|
|
|
return card.String()
|
|
}
|