package biz import ( "context" "fmt" "time" err2 "voucher/api/err" v1 "voucher/api/v1" "voucher/internal/biz/bo" "voucher/internal/biz/vo" "voucher/internal/pkg/helper" "voucher/internal/pkg/lock" ) func (v *VoucherBiz) CmbOrder(ctx context.Context, req *bo.OrderCreateReqBo) (orderNo string, err error) { bizCtx := helper.CopyValueCtx(ctx) c := vo.CmbOrderLockKey.BuildCache([]string{req.OutBizNo, req.Type.String()}) err = lock.NewMutex(v.rdb.Rdb, c.TTL).Lock(bizCtx, c.Key, func(bizCtx context.Context) error { // 压测商品直接过 if req.ProductNo != "001" { order, err := v.OrderRepo.GetByOutBizNo(bizCtx, vo.OrderTypeCmb, req.OutBizNo) if err != nil && !err2.IsDbNotFound(err) { return err } if order != nil { if order.Status.IsFail() { if err = v.orderRetry(bizCtx, order); err != nil { return err } } orderNo = order.OrderNo return nil } } product, err := v.ProductRepo.GetByProductNo(bizCtx, req.ProductNo) if err != nil { return err } order, err := v.order(bizCtx, req, product) if err != nil { return err } orderNo = order.OrderNo return nil }) return } func (v *VoucherBiz) CmbQuery(ctx context.Context, orderNo string) (resp *v1.CmbQueryReply, err error) { c := vo.CmbQueryLockKey.BuildCache([]string{orderNo}) err = lock.NewMutex(v.rdb.Rdb, c.TTL).Lock(ctx, c.Key, func(ctx context.Context) error { order, err := v.OrderRepo.GetByOrderNo(ctx, orderNo) if err != nil { return err } if err = v.Query(ctx, order); err != nil { return err } status, err := order.Status.GetCmbStatusText() if err != nil { return err } resp = &v1.CmbQueryReply{ Ticket: order.OrderNo, Status: status.GetValue(), TransDate: time.Now().Format("20060102150405"), OrgNo: v.bc.Cmb.OrgNo, Ext: "", } return nil }) return } func (v *VoucherBiz) CmbProductQuery(ctx context.Context, productNo string) (reps *v1.CmbQueryProductReply, err error) { c := vo.CmbProductQueryLockKey.BuildCache([]string{productNo}) err = lock.NewMutex(v.rdb.Rdb, c.TTL).Lock(ctx, c.Key, func(ctx context.Context) error { product, err := v.ProductRepo.GetByProductNo(ctx, productNo) if err != nil { return err } if !product.Channel.IsWeChat() { return fmt.Errorf("只支持微信") } wechatResp, err := v.WechatCpnRepo.QueryProduct(ctx, product.MchId, product.BatchNo) if err != nil { return err } reps = &v1.CmbQueryProductReply{ RespCode: vo.CmbResponseStatusSuccess.GetValue(), RespMsg: "成功", ActivityName: product.Name, ActivityId: product.ProductNo, Amount: "", MinAmount: "", AvailableType: "", AvailableDays: "", // 动态有效期天数 StartTime: "", EndTime: "", AvailableStock: "", Detail: *wechatResp.Description, } inputFormat := time.RFC3339 if wechatResp.AvailableBeginTime != nil { availableBeginTime, _ := time.Parse(inputFormat, *wechatResp.AvailableBeginTime) reps.StartTime = availableBeginTime.Format(time.DateTime) reps.SaleStartTime = reps.StartTime reps.SaleStartTime = reps.StartTime } if wechatResp.AvailableEndTime != nil { availableEndTime, _ := time.Parse(inputFormat, *wechatResp.AvailableEndTime) reps.EndTime = availableEndTime.Format(time.DateTime) reps.SaleEndTime = reps.EndTime reps.SaleEndTime = reps.EndTime } reps.Amount = fmt.Sprintf("%d", *wechatResp.StockUseRule.FixedNormalCoupon.CouponAmount) reps.MinAmount = fmt.Sprintf("%d", *wechatResp.StockUseRule.FixedNormalCoupon.TransactionMinimum) availableStock := *wechatResp.StockUseRule.MaxCoupons - *wechatResp.DistributedCoupons reps.AvailableStock = fmt.Sprintf("%d", availableStock) availableType, err := product.AvailableType.GetCmbAvailableType() if err != nil { return err } reps.AvailableType = availableType.GetValue() reps.AvailableDays = fmt.Sprintf("%d", product.AvailableDays) return nil }) return }