voucher/internal/biz/cron_notice.go

163 lines
4.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package biz
import (
"context"
"errors"
"fmt"
"github.com/go-kratos/kratos/v2/log"
"github.com/redis/go-redis/v9"
"time"
"voucher/internal/biz/bo"
"voucher/internal/biz/vo"
"voucher/internal/pkg/lock"
)
func (v *VoucherBiz) Notice(ctx context.Context) error {
if err := v.isCanNotice(ctx); err != nil {
return err
}
return v.ExecuteNotice(ctx)
}
func (v *VoucherBiz) ExecuteNotice(ctx context.Context) error {
now := time.Now()
// 获取七天前的日期
noticeStartDay := now.AddDate(0, 0, int(-v.bc.Cmb.NoticeStartDays))
// 获取七天前 00:00:00 的时间
startTime := time.Date(noticeStartDay.Year(), noticeStartDay.Month(), noticeStartDay.Day(), 0, 0, 0, 0, noticeStartDay.Location())
noticeEndDay := now.AddDate(0, 0, int(-v.bc.Cmb.NoticeEndDays))
// 获取昨天 23:59:59 的时间
endTime := time.Date(noticeEndDay.Year(), noticeEndDay.Month(), noticeEndDay.Day(), 23, 59, 59, 0, noticeEndDay.Location())
req := &bo.FindInBatchesUseBo{
Type: vo.OrderTypeCmb,
StartTime: &startTime,
EndTime: &endTime,
}
return v.OrderRepo.FindInBatches(ctx, req, func(ctx context.Context, rows []*bo.OrderBo) error {
for _, order := range rows {
if err := v.notice(ctx, order); err != nil {
log.Errorf("招行查询券订单状态发生错误,orderNo:%s,err:%v", order.OrderNo, err)
}
}
time.Sleep(1 * time.Second)
return nil
})
}
func (v *VoucherBiz) isCanNotice(ctx context.Context) error {
if v.bc.Cmb.NoticeStartDays == 0 {
return errors.New("noticeStartDays eq 0")
}
if v.bc.Cmb.NoticeEndDays == 0 {
return errors.New("noticeEndDays eq 0")
}
cache := vo.CmbBatchNoticeCacheKey.BuildCache([]string{""})
_, err := v.rdb.Rdb.Get(ctx, cache.Key).Result()
if err == nil {
return fmt.Errorf("notice 获取redis缓存存在已被执行,本台服务不做执行")
}
if err != redis.Nil {
return fmt.Errorf(fmt.Sprintf("notice 获取redis缓存%s异常:%v", cache.Key, err))
}
c := vo.CmbBatchNoticeLockKey.BuildCache([]string{""})
return lock.NewMutex(v.rdb.Rdb, c.TTL).Lock(ctx, c.Key, func(ctx context.Context) error {
// 二次获取,判定处理,以免获取锁后又执行了一次
cacheValue, err := v.rdb.Rdb.Get(ctx, cache.Key).Result()
if err != nil && err != redis.Nil {
return fmt.Errorf(fmt.Sprintf("notice 二次获取redis缓存%s异常:%v", cache.Key, err))
}
if len(cacheValue) > 0 {
return fmt.Errorf("notice 二次获取redis缓存存在已被执行,本台服务不做执行")
}
if err = v.rdb.Rdb.Set(ctx, cache.Key, fmt.Sprintf("%d_%d", v.bc.Cmb.NoticeStartDays, v.bc.Cmb.NoticeEndDays), c.TTL).Err(); err != nil {
return fmt.Errorf(fmt.Sprintf("notice 设置redis缓存%s异常:%v", cache.Key, err))
}
log.Warnf("notice 获取redis缓存,不存在,开始处理")
return nil
})
}
func (v *VoucherBiz) notice(ctx context.Context, order *bo.OrderBo) error {
// 批量通知不做数据存储,量会很大
status, err := v.WechatCpnRepo.Query(ctx, order)
if err != nil {
return err
}
if order.Status == status {
log.Warnf("notice 券状态未改变:%s忽略不处理,orderNo:%s", order.Status.GetText(), order.OrderNo)
return nil
}
event, err := status.GetOrderNotifyEvent()
if err != nil {
return err
}
orderNotify := &bo.OrderNotifyBo{
OrderNo: order.OrderNo,
NotifyUrl: order.NotifyUrl,
Channel: order.Channel,
Event: event,
Type: order.Type,
}
if err = v.cmbNotice(ctx, order, orderNotify); err != nil {
return err
}
return v.UpdateOrderStatus(ctx, order.ID, status)
}
func (v *VoucherBiz) cmbNotice(ctx context.Context, order *bo.OrderBo, orderNotify *bo.OrderNotifyBo) error {
if !orderNotify.Event.CanNotify() {
log.Warnf("notice 券状态:%s忽略不通知,orderNo:%s", orderNotify.Event.GetText(), order.OrderNo)
return nil
}
request, err := v.Cmb.NotifyRequest(ctx, order, orderNotify)
if err != nil {
return err
}
reply, err := v.CmbMixRepo.Request(ctx, request, order.NotifyUrl)
if err != nil {
return err
}
if reply.RespCode != vo.CmbResponseStatusSuccess.GetValue() {
return errors.New(reply.RespMsg)
}
return nil
}