This commit is contained in:
parent
3e9bb2b762
commit
d091564610
|
|
@ -62,7 +62,7 @@ func (v *VoucherBiz) alarmText(_ context.Context, order *bo.OrderBo, errMsg stri
|
|||
"</font> \n" +
|
||||
"<font color='black'>" +
|
||||
"不好了,订单发放发生异常了" +
|
||||
"[<font color='red'>%s</font>]请尽快处理@相关人员。" +
|
||||
"[<font color='red'>%s</font>]" +
|
||||
"</font>"
|
||||
|
||||
return fmt.Sprintf(msg, remarks)
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ func (v *VoucherBiz) timeSliceQuery(ctx context.Context, startTime, endTime time
|
|||
duration := 2 * time.Hour
|
||||
|
||||
eg := new(errgroup.Group)
|
||||
eg.SetLimit(8)
|
||||
eg.SetLimit(10)
|
||||
|
||||
for start := startTime; start.Before(endTime); start = start.Add(duration) {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package do
|
||||
|
||||
import "time"
|
||||
|
||||
type WarningBudget struct {
|
||||
StockName string // 券名称
|
||||
StockId string // 券ID
|
||||
|
|
@ -12,3 +14,9 @@ type WarningBudget struct {
|
|||
AvailableStock int64 // 可用库存
|
||||
RemainingBudget int64 // 剩余预算
|
||||
}
|
||||
|
||||
type WarningBudgetLog struct {
|
||||
WarningBudget *WarningBudget
|
||||
Num int
|
||||
LastTime time.Time
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ const (
|
|||
ProductQueryLockKey CacheKey = "product_query_lock"
|
||||
)
|
||||
|
||||
var (
|
||||
WarningBudgetSendIncr CacheKey = "warning_budget_send_incr"
|
||||
)
|
||||
|
||||
var CacheKeyMap = map[CacheKey]time.Duration{
|
||||
CmbOrderLockKey: 30 * time.Second,
|
||||
CmbQueryLockKey: 30 * time.Second,
|
||||
|
|
@ -43,6 +47,8 @@ var CacheKeyMap = map[CacheKey]time.Duration{
|
|||
|
||||
ProductQueryKey: 30 * 86400 * time.Second, // 30天
|
||||
ProductQueryLockKey: 30 * time.Second,
|
||||
|
||||
WarningBudgetSendIncr: 1 * time.Hour,
|
||||
}
|
||||
|
||||
type Cache struct {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package biz
|
|||
import (
|
||||
"sync"
|
||||
"voucher/internal/biz/cmb"
|
||||
"voucher/internal/biz/do"
|
||||
"voucher/internal/biz/mixrepos"
|
||||
"voucher/internal/biz/repo"
|
||||
"voucher/internal/biz/wechatrepo"
|
||||
|
|
@ -26,6 +27,7 @@ type VoucherBiz struct {
|
|||
|
||||
mu sync.RWMutex
|
||||
queryMap map[string]bool
|
||||
warningBudgeMap map[string]*do.WarningBudgetLog
|
||||
}
|
||||
|
||||
func NewVoucherBiz(
|
||||
|
|
@ -57,6 +59,7 @@ func NewVoucherBiz(
|
|||
CmbMixRepo: CmbMixRepo,
|
||||
|
||||
queryMap: make(map[string]bool),
|
||||
warningBudgeMap: make(map[string]*do.WarningBudgetLog),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,10 +9,93 @@ import (
|
|||
"time"
|
||||
"voucher/internal/biz/bo"
|
||||
"voucher/internal/biz/do"
|
||||
"voucher/internal/biz/vo"
|
||||
)
|
||||
|
||||
func (s *VoucherBiz) WarningBudgetIncr(ctx context.Context, uid string) (int64, error) {
|
||||
|
||||
v := vo.WarningBudgetSendIncr.BuildCache([]string{uid})
|
||||
|
||||
// 增加发送计数
|
||||
count, err := s.rdb.Rdb.IncrBy(ctx, v.Key, 1).Result()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 如果是第一次发送,设置 过期时间
|
||||
if count == 1 {
|
||||
if err = s.rdb.Rdb.Expire(ctx, v.Key, v.TTL).Err(); err != nil {
|
||||
return 0, fmt.Errorf("设置过期时间失败: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 如果发送次数超过 6 条,限制发送
|
||||
if count > 6 {
|
||||
if _, err = s.rdb.Rdb.Del(ctx, v.Key).Result(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (this *VoucherBiz) WarningBudgetGet(uid string) *do.WarningBudgetLog {
|
||||
|
||||
if w, ok := this.warningBudgeMap[uid]; ok {
|
||||
return w
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *VoucherBiz) WarningBudgetSet(req *do.WarningBudget) {
|
||||
|
||||
this.warningBudgeMap[req.StockId] = &do.WarningBudgetLog{
|
||||
WarningBudget: req,
|
||||
Num: 1, // 默认1
|
||||
LastTime: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
func (this *VoucherBiz) WarningBudgetAdd(req *do.WarningBudget) *do.WarningBudgetLog {
|
||||
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
|
||||
w := this.WarningBudgetGet(req.StockId)
|
||||
if w == nil {
|
||||
this.WarningBudgetSet(req)
|
||||
} else {
|
||||
w.LastTime = time.Now()
|
||||
w.Num += 1
|
||||
w.WarningBudget = req
|
||||
}
|
||||
|
||||
return w
|
||||
}
|
||||
|
||||
func (this *VoucherBiz) WarningBudgetRemove(uid string) {
|
||||
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
|
||||
if _, ok := this.warningBudgeMap[uid]; ok {
|
||||
delete(this.warningBudgeMap, uid)
|
||||
}
|
||||
}
|
||||
|
||||
func (v *VoucherBiz) WarningBudget(ctx context.Context) {
|
||||
|
||||
uid := "warningBudget"
|
||||
|
||||
if b := v.Get(uid); b {
|
||||
log.Warn("预警查询,上波还未执行完毕,此次暂不执行")
|
||||
return
|
||||
}
|
||||
|
||||
v.Add(uid)
|
||||
defer v.Remove(uid)
|
||||
|
||||
start := time.Now()
|
||||
log.Warnf("预警查询,执行开始: %s", start.Format(time.DateTime))
|
||||
|
||||
|
|
@ -80,24 +163,40 @@ func (v *VoucherBiz) Calculate(ctx context.Context, product *bo.ProductBo, wxRes
|
|||
log.Warnf("预警查询,券预算明细,%s", str)
|
||||
|
||||
if product.WarningBudget >= remainingBudget {
|
||||
|
||||
count, err := v.WarningBudgetIncr(ctx, req.StockId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if count == 1 {
|
||||
return v.WarningSend(ctx, str)
|
||||
} else {
|
||||
log.Warnf("预警查询,当前达到预警第[%d]次,暂不做通知", count)
|
||||
}
|
||||
|
||||
//w := v.WarningBudgetAdd(req)
|
||||
//if w.Num == 1 {
|
||||
// return v.WarningSend(ctx, str)
|
||||
//} else if w.Num > 5 {
|
||||
// v.WarningBudgetRemove(req.StockId)
|
||||
//}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *VoucherBiz) WarningSend(ctx context.Context, str string) error {
|
||||
|
||||
return v.DingMixRepo.SendMarkdownMessage(ctx, "券预算不足", str)
|
||||
}
|
||||
|
||||
func formatAsCard(req *do.WarningBudget) string {
|
||||
var card strings.Builder
|
||||
|
||||
card.WriteString("### 🎫 " + req.StockName + "\n\n")
|
||||
card.WriteString("### " + req.StockName + "\n\n")
|
||||
|
||||
// 基本信息
|
||||
card.WriteString("#### 💰 基本信息\n")
|
||||
card.WriteString("#### 🎫 基本信息\n")
|
||||
card.WriteString(fmt.Sprintf("- **批次号**: %s\n", req.StockId))
|
||||
card.WriteString(fmt.Sprintf("- **活动号**: %s\n", req.StockNo))
|
||||
card.WriteString(fmt.Sprintf("- **面额**: %d元\n", req.Amount))
|
||||
|
|
|
|||
|
|
@ -117,11 +117,14 @@ func (c *TalkClient) SendLinkMessage(title, text, messageURL, picURL string, atM
|
|||
|
||||
// SendMarkdownMessage 发送 Markdown 消息并可 @ 人员
|
||||
func (c *TalkClient) SendMarkdownMessage(title, text string, atMobiles []string, isAtAll bool) error {
|
||||
|
||||
if len(atMobiles) > 0 {
|
||||
var atStr string
|
||||
for _, mobile := range atMobiles {
|
||||
atStr += fmt.Sprintf("<font color='#003BFF'>@%s</font>", mobile)
|
||||
atStr += fmt.Sprintf("<font color='#00008B'>@%s</font>", mobile)
|
||||
}
|
||||
text += fmt.Sprintf("\n请尽快处理@相关人员%s", atStr)
|
||||
}
|
||||
text += atStr
|
||||
|
||||
message := map[string]interface{}{
|
||||
"msgtype": "markdown",
|
||||
|
|
|
|||
|
|
@ -142,14 +142,14 @@ func TestWarningBudgetText(t *testing.T) {
|
|||
|
||||
markdownTitle := "批次预算预警"
|
||||
|
||||
//atMobiles := []string{"18666173766"}
|
||||
atMobiles := []string{"18666173766"}
|
||||
|
||||
webhookURL := "https://oapi.dingtalk.com/robot/send?access_token=5f10c2213cbf8168985cb2d061ebb1a5f70bd1dd47ec7cef58fa6fe545d52588"
|
||||
secret := "SEC77b63d70a9e22317144e712b4538ce1e0013db885c65f7f9bae283e8958b39eb"
|
||||
|
||||
client := NewDingTalkClient(webhookURL, secret)
|
||||
|
||||
if err := client.SendMarkdownMessage(markdownTitle, str, nil, false); err != nil {
|
||||
if err := client.SendMarkdownMessage(markdownTitle, str, atMobiles, false); err != nil {
|
||||
fmt.Println("Markdown 消息发送失败:", err)
|
||||
} else {
|
||||
fmt.Println("Markdown 消息发送成功")
|
||||
|
|
@ -159,10 +159,10 @@ func TestWarningBudgetText(t *testing.T) {
|
|||
func formatAsCard(req do.WarningBudget) string {
|
||||
var card strings.Builder
|
||||
|
||||
card.WriteString("### 🎫 " + req.StockName + "\n\n")
|
||||
card.WriteString("### " + req.StockName + "\n\n")
|
||||
|
||||
// 基本信息
|
||||
card.WriteString("#### 💰 基本信息\n")
|
||||
card.WriteString("#### 🎫 基本信息\n")
|
||||
card.WriteString(fmt.Sprintf("- **批次号**: %s\n", req.StockId))
|
||||
card.WriteString(fmt.Sprintf("- **活动号**: %s\n", req.StockNo))
|
||||
card.WriteString(fmt.Sprintf("- **面额**: %d元\n", req.Amount))
|
||||
|
|
|
|||
Loading…
Reference in New Issue