package biz import ( "context" "fmt" err2 "voucher/api/err" "voucher/internal/biz/bo" "voucher/internal/biz/vo" ) func (this *VoucherBiz) CmbOrder(ctx context.Context, req *bo.OrderCreateReqBo) (orderNo string, err error) { order, err3 := this.GetByOutBizNo(ctx, req) if err3 != nil { return "", err3 } if order != nil { if order.Status.IsFail() || order.Status.IsIng() { if err4 := this.orderRetry(ctx, order); err4 != nil { return "", err4 } } return order.OrderNo, err } product, err3 := this.ProductRepo.GetByProductNo(ctx, req.ProductNo) if err3 != nil { return "", err3 } order, err3 = this.order(ctx, req, product) if err3 != nil { return "", err3 } return order.OrderNo, nil } func (this *VoucherBiz) order(ctx context.Context, req *bo.OrderCreateReqBo, product *bo.ProductBo) (*bo.OrderBo, error) { order, err := this.create(ctx, req, product) if err != nil { return nil, err } voucherNo, err := this.send(ctx, order) if err != nil { if err3 := this.fail(ctx, order, err); err3 != nil { return nil, err3 } return nil, err } if err = this.success(ctx, order, voucherNo); err != nil { return nil, err } return order, nil } func (this *VoucherBiz) send(ctx context.Context, order *bo.OrderBo) (string, error) { if order.ActivityId == "" { return this.WechatCpnRepo.Order(ctx, order) } return this.BankMultiActivityRepo.Order(order) } func (this *VoucherBiz) orderRetry(ctx context.Context, order *bo.OrderBo) error { voucherNo, err := this.send(ctx, order) if err != nil { if err3 := this.fail(ctx, order, err); err3 != nil { return err3 } return err } return this.success(ctx, order, voucherNo) } func (this *VoucherBiz) create(ctx context.Context, req *bo.OrderCreateReqBo, product *bo.ProductBo) (*bo.OrderBo, error) { o := &bo.OrderBo{ OrderNo: this.GenerateMixRepo.GeneratorString(ctx, fmt.Sprintf("%d%s", req.Type, req.OutBizNo)), OutBizNo: req.OutBizNo, ProductNo: req.ProductNo, Account: req.Account, AppID: req.AppID, MerchantNo: product.MchId, Channel: product.Channel, BatchNo: product.BatchNo, NotifyUrl: req.NotifyUrl, AccountType: vo.OrderAccountTypeOpenId, Type: req.Type, Status: vo.OrderStatusIng, // 同步发放,状态至为发放中 Attach: req.Attach, ActivityId: product.ActivityId, // 多笔立减活动 } return this.OrderRepo.Create(ctx, o) } func (this *VoucherBiz) ing(ctx context.Context, id uint64) error { return this.OrderRepo.Ing(ctx, id) } func (this *VoucherBiz) success(ctx context.Context, order *bo.OrderBo, voucherNo string) error { return this.OrderRepo.Success(ctx, order.ID, voucherNo) } func (this *VoucherBiz) fail(ctx context.Context, order *bo.OrderBo, errReq error) error { errMsg := errReq.Error() if err := this.OrderRepo.Fail(ctx, order.ID, errMsg); err != nil { return err } if errMsg == `Post "https://api.mch.weixin.qq.com/v3/marketing/favor/users/oW97fjrv_ntYBPjMsaaEMRSj6TPA/coupons": EOF` { // 微信:不同微信号,领取了很多次,自然人限领,发放频率限制,微信研发排期,后续这个错误信息应该会更新,近期没那么快同步上去 return nil } if err2.IsWechatAccountFail(errReq) || err2.IsWechatUserMaxCoupons(errReq) { return nil // 过滤调该类型错误通知 } return this.alarm(ctx, order, errReq.Error()) } func (this *VoucherBiz) GetByOutBizNo(ctx context.Context, req *bo.OrderCreateReqBo) (*bo.OrderBo, error) { order, err := this.OrderRepo.GetByOutBizNo(ctx, vo.OrderTypeCmb, req.OutBizNo) if err != nil && !err2.IsDbNotFound(err) { return nil, err } return order, nil } func (this *VoucherBiz) UpdateOrderStatus(ctx context.Context, orderId uint64, status vo.OrderStatus) error { if status.IsSuccess() { return this.OrderRepo.Available(ctx, orderId) } else if status.IsUse() { return this.OrderRepo.Used(ctx, orderId) } else if status.IsExpired() { return this.OrderRepo.Expired(ctx, orderId) } return fmt.Errorf("notice 未知券状态,orderId:%d,statuText:%s", orderId, status.GetText()) }