预警4
This commit is contained in:
parent
b7c52ce699
commit
8c5396729e
|
|
@ -17,6 +17,8 @@ type ProductBo struct {
|
||||||
AvailableType vo.AvailableType
|
AvailableType vo.AvailableType
|
||||||
AvailableDays uint32
|
AvailableDays uint32
|
||||||
Amount int64
|
Amount int64
|
||||||
|
AllBudget int64
|
||||||
|
AvailableBudget int64
|
||||||
WarningBudget int64
|
WarningBudget int64
|
||||||
StartTime *time.Time
|
StartTime *time.Time
|
||||||
EndTime *time.Time
|
EndTime *time.Time
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ type WxResp struct {
|
||||||
UsedStock int64 // 已使用库存
|
UsedStock int64 // 已使用库存
|
||||||
UsedBudget int64 // 已使用预算
|
UsedBudget int64 // 已使用预算
|
||||||
AvailableStock int64 // 可用库存
|
AvailableStock int64 // 可用库存
|
||||||
RemainingBudget int64 // 剩余预算
|
AvailableBudget int64 // 可用预算
|
||||||
|
StockUsageRate float64 // 券使用率
|
||||||
StartTime *time.Time
|
StartTime *time.Time
|
||||||
EndTime *time.Time
|
EndTime *time.Time
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,8 @@ func (v *VoucherBiz) WxResp(wxResp *cashcoupons.Stock) (reps *do.WxResp) {
|
||||||
|
|
||||||
remainingBudget := availableStock * couponAmount
|
remainingBudget := availableStock * couponAmount
|
||||||
|
|
||||||
|
stockUsageRate := float64(*wxResp.DistributedCoupons) / float64(*wxResp.StockUseRule.MaxCoupons) * 100
|
||||||
|
|
||||||
req := &do.WxResp{
|
req := &do.WxResp{
|
||||||
Amount: couponAmount,
|
Amount: couponAmount,
|
||||||
AllBudget: *wxResp.StockUseRule.MaxAmount / 100,
|
AllBudget: *wxResp.StockUseRule.MaxAmount / 100,
|
||||||
|
|
@ -95,7 +97,8 @@ func (v *VoucherBiz) WxResp(wxResp *cashcoupons.Stock) (reps *do.WxResp) {
|
||||||
UsedStock: *wxResp.DistributedCoupons,
|
UsedStock: *wxResp.DistributedCoupons,
|
||||||
UsedBudget: *wxResp.DistributedCoupons * couponAmount,
|
UsedBudget: *wxResp.DistributedCoupons * couponAmount,
|
||||||
AvailableStock: availableStock,
|
AvailableStock: availableStock,
|
||||||
RemainingBudget: remainingBudget,
|
AvailableBudget: remainingBudget,
|
||||||
|
StockUsageRate: stockUsageRate,
|
||||||
}
|
}
|
||||||
|
|
||||||
inputFormat := time.RFC3339
|
inputFormat := time.RFC3339
|
||||||
|
|
|
||||||
|
|
@ -138,53 +138,24 @@ func (v *VoucherBiz) warningBudget(ctx context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *VoucherBiz) GetWarningBudget(product *bo.ProductBo, wxResp *cashcoupons.Stock) (*do.WarningBudget, error) {
|
|
||||||
|
|
||||||
availableStock := *wxResp.StockUseRule.MaxCoupons - *wxResp.DistributedCoupons
|
|
||||||
couponAmount := *wxResp.StockUseRule.FixedNormalCoupon.CouponAmount / 100
|
|
||||||
|
|
||||||
remainingBudget := availableStock * couponAmount
|
|
||||||
|
|
||||||
stockUsageRate := float64(*wxResp.DistributedCoupons) / float64(*wxResp.StockUseRule.MaxCoupons) * 100
|
|
||||||
|
|
||||||
req := &do.WarningBudget{
|
|
||||||
StockName: product.Name,
|
|
||||||
StockId: product.BatchNo,
|
|
||||||
StockNo: product.ProductNo,
|
|
||||||
Amount: couponAmount,
|
|
||||||
AllBudget: *wxResp.StockUseRule.MaxAmount / 100,
|
|
||||||
AllStock: *wxResp.StockUseRule.MaxCoupons,
|
|
||||||
UsedStock: *wxResp.DistributedCoupons,
|
|
||||||
UsedBudget: *wxResp.DistributedCoupons * couponAmount,
|
|
||||||
AvailableStock: availableStock,
|
|
||||||
RemainingBudget: remainingBudget,
|
|
||||||
StockUsageRate: stockUsageRate,
|
|
||||||
}
|
|
||||||
|
|
||||||
return req, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *VoucherBiz) Calculate(ctx context.Context, product *bo.ProductBo, wxResp *cashcoupons.Stock) error {
|
func (v *VoucherBiz) Calculate(ctx context.Context, product *bo.ProductBo, wxResp *cashcoupons.Stock) error {
|
||||||
|
|
||||||
req, err := v.GetWarningBudget(product, wxResp)
|
w := v.WxResp(wxResp)
|
||||||
|
|
||||||
|
err := v.ProductRepo.UpdateWarningBudget(ctx, product.ID, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = v.ProductRepo.UpdateWarningBudget(ctx, product.ID, v.WxResp(wxResp))
|
if product.WarningBudget >= w.AvailableBudget {
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if product.WarningBudget >= req.RemainingBudget {
|
count, err2 := v.WarningBudgetIncr(ctx, product.BatchNo)
|
||||||
|
|
||||||
count, err2 := v.WarningBudgetIncr(ctx, req.StockId)
|
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
return err2
|
return err2
|
||||||
}
|
}
|
||||||
|
|
||||||
if count == 1 {
|
if count == 1 {
|
||||||
return v.WarningSend(ctx, formatAsCard(req))
|
return v.WarningSend(ctx, formatAsCard(product, w))
|
||||||
} else {
|
} else {
|
||||||
log.Warnf("预警查询,当前达到预警第[%d]次,暂不做通知", count)
|
log.Warnf("预警查询,当前达到预警第[%d]次,暂不做通知", count)
|
||||||
}
|
}
|
||||||
|
|
@ -198,15 +169,15 @@ func (v *VoucherBiz) WarningSend(ctx context.Context, str string) error {
|
||||||
return v.DingMixRepo.SendMarkdownMessage(ctx, "券预算不足", str)
|
return v.DingMixRepo.SendMarkdownMessage(ctx, "券预算不足", str)
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatAsCard(req *do.WarningBudget) string {
|
func formatAsCard(product *bo.ProductBo, req *do.WxResp) string {
|
||||||
var card strings.Builder
|
var card strings.Builder
|
||||||
|
|
||||||
card.WriteString("### " + req.StockName + "\n\n")
|
card.WriteString("### " + product.BatchName + "\n\n")
|
||||||
|
|
||||||
// 基本信息
|
// 基本信息
|
||||||
card.WriteString("#### 🎫 基本信息\n")
|
card.WriteString("#### 🎫 基本信息\n")
|
||||||
card.WriteString(fmt.Sprintf("- **批次号**: %s\n", req.StockId))
|
card.WriteString(fmt.Sprintf("- **批次号**: %s\n", product.BatchNo))
|
||||||
card.WriteString(fmt.Sprintf("- **活动号**: %s\n", req.StockNo))
|
card.WriteString(fmt.Sprintf("- **活动号**: %s\n", product.ProductNo))
|
||||||
card.WriteString(fmt.Sprintf("- **面额**: %d元\n", req.Amount))
|
card.WriteString(fmt.Sprintf("- **面额**: %d元\n", req.Amount))
|
||||||
card.WriteString(fmt.Sprintf("- **总预算**: %d元\n", req.AllBudget))
|
card.WriteString(fmt.Sprintf("- **总预算**: %d元\n", req.AllBudget))
|
||||||
card.WriteString(fmt.Sprintf("- **总库存**: %d张\n", req.AllStock))
|
card.WriteString(fmt.Sprintf("- **总库存**: %d张\n", req.AllStock))
|
||||||
|
|
@ -217,7 +188,7 @@ func formatAsCard(req *do.WarningBudget) string {
|
||||||
card.WriteString(fmt.Sprintf("- **已发券数**: %d张\n", req.UsedStock))
|
card.WriteString(fmt.Sprintf("- **已发券数**: %d张\n", req.UsedStock))
|
||||||
card.WriteString(fmt.Sprintf("- **已发券金额**: %d元\n", req.UsedBudget))
|
card.WriteString(fmt.Sprintf("- **已发券金额**: %d元\n", req.UsedBudget))
|
||||||
card.WriteString(fmt.Sprintf("- **剩余库存**: %d张\n", req.AvailableStock))
|
card.WriteString(fmt.Sprintf("- **剩余库存**: %d张\n", req.AvailableStock))
|
||||||
card.WriteString(fmt.Sprintf("- **剩余预算**: %d元\n", req.RemainingBudget))
|
card.WriteString(fmt.Sprintf("- **剩余预算**: %d元\n", req.AvailableBudget))
|
||||||
card.WriteString("\n")
|
card.WriteString("\n")
|
||||||
|
|
||||||
card.WriteString("#### 📈 使用率\n")
|
card.WriteString("#### 📈 使用率\n")
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ type Product struct {
|
||||||
AvailableDays uint32 `gorm:"column:available_days;not null;comment:领取后多少天内" json:"available_days"`
|
AvailableDays uint32 `gorm:"column:available_days;not null;comment:领取后多少天内" json:"available_days"`
|
||||||
Amount int64 `gorm:"column:amount;not null;default:0" json:"amount"`
|
Amount int64 `gorm:"column:amount;not null;default:0" json:"amount"`
|
||||||
AllBudget int64 `gorm:"column:all_budget;not null;default:0" json:"all_budget"`
|
AllBudget int64 `gorm:"column:all_budget;not null;default:0" json:"all_budget"`
|
||||||
RemainingBudget int64 `gorm:"column:remaining_budget;not null;default:0" json:"remaining_budget"`
|
AvailableBudget int64 `gorm:"column:available_budget;not null;default:0" json:"available_budget"`
|
||||||
WarningBudget int64 `gorm:"column:warning_budget;not null;default:0" json:"warning_budget"` // 预警预算=0不做预警
|
WarningBudget int64 `gorm:"column:warning_budget;not null;default:0" json:"warning_budget"` // 预警预算=0不做预警
|
||||||
WarningPerson string `gorm:"column:warning_person" json:"warning_person"`
|
WarningPerson string `gorm:"column:warning_person" json:"warning_person"`
|
||||||
StartTime *time.Time `gorm:"column:start_time;not null" json:"start_time"`
|
StartTime *time.Time `gorm:"column:start_time;not null" json:"start_time"`
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ func (r *ProductRepoImpl) UpdateWarningBudget(ctx context.Context, id int32, req
|
||||||
|
|
||||||
u := model.Product{
|
u := model.Product{
|
||||||
AllBudget: req.AllBudget,
|
AllBudget: req.AllBudget,
|
||||||
RemainingBudget: req.RemainingBudget,
|
AvailableBudget: req.AvailableBudget,
|
||||||
UpdateTime: &now,
|
UpdateTime: &now,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ func TestWarningSend(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = smsService.SendSMS(context.Background(), []string{"18666173766"}, "", params)
|
err = smsService.SendSMS(context.Background(), []string{"18666173766"}, "SMS_489705720", params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("发送短信失败: %v", err)
|
t.Errorf("发送短信失败: %v", err)
|
||||||
return
|
return
|
||||||
|
|
@ -84,8 +84,8 @@ func buildTemplateParams(req *do.WarningBudget) map[string]string {
|
||||||
"all_stock": strconv.Itoa(int(req.AllStock)),
|
"all_stock": strconv.Itoa(int(req.AllStock)),
|
||||||
"used_stock": strconv.Itoa(int(req.UsedStock)),
|
"used_stock": strconv.Itoa(int(req.UsedStock)),
|
||||||
"used_budget": strconv.Itoa(int(req.UsedBudget)),
|
"used_budget": strconv.Itoa(int(req.UsedBudget)),
|
||||||
"remaining_budget": strconv.Itoa(int(req.RemainingBudget)),
|
"available_budget": strconv.Itoa(int(req.RemainingBudget)),
|
||||||
"remaining_stock": strconv.Itoa(int(req.AvailableStock)),
|
"available_stock": strconv.Itoa(int(req.AvailableStock)),
|
||||||
"budget_usage_rate": fmt.Sprintf("%.1f", req.StockUsageRate),
|
"budget_usage_rate": fmt.Sprintf("%.1f", req.StockUsageRate),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue