From 832827bee2a70c4b1844962dffa68f5072821e23 Mon Sep 17 00:00:00 2001 From: ziming Date: Wed, 28 May 2025 19:38:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/biz/cmb.go | 158 ---------------------------------- internal/biz/order.go | 56 ++++++------ internal/biz/product.go | 80 +++++++++++++++++ internal/biz/query.go | 38 ++++++++ internal/biz/retry.go | 45 ++++++++++ internal/service/cmb_order.go | 70 +++++++-------- 6 files changed, 229 insertions(+), 218 deletions(-) create mode 100644 internal/biz/product.go create mode 100644 internal/biz/retry.go diff --git a/internal/biz/cmb.go b/internal/biz/cmb.go index 53acbf3..26ded5e 100644 --- a/internal/biz/cmb.go +++ b/internal/biz/cmb.go @@ -1,159 +1 @@ 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/lock" -) - -func (v *VoucherBiz) GetByOutBizNo(ctx context.Context, req *bo.OrderCreateReqBo) (*bo.OrderBo, error) { - - order, err := v.OrderRepo.GetByOutBizNo(ctx, vo.OrderTypeCmb, req.OutBizNo) - - if err != nil && !err2.IsDbNotFound(err) { - return nil, err - } - - return order, nil -} - -func (v *VoucherBiz) CmbOrder(ctx context.Context, req *bo.OrderCreateReqBo) (orderNo string, err error) { - - order, err3 := v.GetByOutBizNo(ctx, req) - if err3 != nil { - return orderNo, err3 - } - - if order != nil { - - if order.Status.IsFail() || order.Status.IsIng() { - - if err4 := v.orderRetry(ctx, order); err4 != nil { - return orderNo, err4 - } - } - - return order.OrderNo, err - } - - product, err3 := v.ProductRepo.GetByProductNo(ctx, req.ProductNo) - if err3 != nil { - return orderNo, err3 - } - - order, err3 = v.order(ctx, req, product) - if err3 != nil { - return orderNo, err3 - } - - return order.OrderNo, nil -} - -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, err3 := v.OrderRepo.GetByOrderNo(ctx, orderNo) - if err3 != nil { - return err3 - } - - if err = v.Query(ctx, order); err != nil { - return err - } - - status, err3 := order.Status.GetCmbStatusText() - if err3 != nil { - return err3 - } - - 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, err3 := v.ProductRepo.GetByProductNo(ctx, productNo) - if err3 != nil { - return err3 - } - - if !product.Channel.IsWeChat() { - return fmt.Errorf("只支持微信") - } - - wechatResp, err4 := v.WechatCpnRepo.QueryProduct(ctx, product.MchId, product.BatchNo) - if err4 != nil { - return err4 - } - - 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("2006-01-02 15:04:05.000") - reps.SaleStartTime = reps.StartTime - } - - if wechatResp.AvailableEndTime != nil { - availableEndTime, _ := time.Parse(inputFormat, *wechatResp.AvailableEndTime) - reps.EndTime = availableEndTime.Format("2006-01-02 15:04:05.000") - 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, err3 := product.AvailableType.GetCmbAvailableType() - if err3 != nil { - return err3 - } - - reps.AvailableType = availableType.GetValue() - reps.AvailableDays = fmt.Sprintf("%d", product.AvailableDays) - - return nil - }) - - return -} diff --git a/internal/biz/order.go b/internal/biz/order.go index 29db30e..5cd6a61 100644 --- a/internal/biz/order.go +++ b/internal/biz/order.go @@ -8,41 +8,36 @@ import ( "voucher/internal/biz/vo" ) -func (v *VoucherBiz) OrderRetry(ctx context.Context, outBizNos []string) error { +func (v *VoucherBiz) CmbOrder(ctx context.Context, req *bo.OrderCreateReqBo) (orderNo string, err error) { - if len(outBizNos) > 0 { - - for _, outBizNo := range outBizNos { - - order, err := v.OrderRepo.GetByOutBizNo(ctx, vo.OrderTypeCmb, outBizNo) - if err != nil { - return fmt.Errorf(fmt.Sprintf("获取订单%s异常:%v", outBizNo, err)) - } - - if !order.Status.IsIng() { - return fmt.Errorf(fmt.Sprintf("订单%s状态异常:%s", order.OrderNo, order.Status)) - } - - if err4 := v.orderRetry(ctx, order); err4 != nil { - return err4 - } - } - - return nil + order, err3 := v.GetByOutBizNo(ctx, req) + if err3 != nil { + return orderNo, err3 } - return v.OrderRepo.FindIngInBatches(ctx, func(ctx context.Context, rows []*bo.OrderBo) error { + if order != nil { - for _, order := range rows { + if order.Status.IsFail() || order.Status.IsIng() { if err4 := v.orderRetry(ctx, order); err4 != nil { - return err4 + return orderNo, err4 } } - return nil - }) + return order.OrderNo, err + } + product, err3 := v.ProductRepo.GetByProductNo(ctx, req.ProductNo) + if err3 != nil { + return orderNo, err3 + } + + order, err3 = v.order(ctx, req, product) + if err3 != nil { + return orderNo, err3 + } + + return order.OrderNo, nil } func (v *VoucherBiz) order(ctx context.Context, req *bo.OrderCreateReqBo, product *bo.ProductBo) (*bo.OrderBo, error) { @@ -126,6 +121,17 @@ func (v *VoucherBiz) fail(ctx context.Context, order *bo.OrderBo, errReq error) return v.alarm(ctx, order, errReq.Error()) } +func (v *VoucherBiz) GetByOutBizNo(ctx context.Context, req *bo.OrderCreateReqBo) (*bo.OrderBo, error) { + + order, err := v.OrderRepo.GetByOutBizNo(ctx, vo.OrderTypeCmb, req.OutBizNo) + + if err != nil && !err2.IsDbNotFound(err) { + return nil, err + } + + return order, nil +} + func (v *VoucherBiz) UpdateOrderStatus(ctx context.Context, orderId uint64, status vo.OrderStatus) error { if status.IsSuccess() { diff --git a/internal/biz/product.go b/internal/biz/product.go new file mode 100644 index 0000000..9d62b66 --- /dev/null +++ b/internal/biz/product.go @@ -0,0 +1,80 @@ +package biz + +import ( + "context" + "fmt" + "time" + v1 "voucher/api/v1" + "voucher/internal/biz/vo" + "voucher/internal/pkg/lock" +) + +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, err3 := v.ProductRepo.GetByProductNo(ctx, productNo) + if err3 != nil { + return err3 + } + + if !product.Channel.IsWeChat() { + return fmt.Errorf("只支持微信") + } + + wechatResp, err4 := v.WechatCpnRepo.QueryProduct(ctx, product.MchId, product.BatchNo) + if err4 != nil { + return err4 + } + + 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("2006-01-02 15:04:05.000") + reps.SaleStartTime = reps.StartTime + } + + if wechatResp.AvailableEndTime != nil { + availableEndTime, _ := time.Parse(inputFormat, *wechatResp.AvailableEndTime) + reps.EndTime = availableEndTime.Format("2006-01-02 15:04:05.000") + 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, err3 := product.AvailableType.GetCmbAvailableType() + if err3 != nil { + return err3 + } + + reps.AvailableType = availableType.GetValue() + reps.AvailableDays = fmt.Sprintf("%d", product.AvailableDays) + + return nil + }) + + return +} diff --git a/internal/biz/query.go b/internal/biz/query.go index 5bdc0af..5d8515c 100644 --- a/internal/biz/query.go +++ b/internal/biz/query.go @@ -4,9 +4,47 @@ import ( "context" "fmt" "github.com/go-kratos/kratos/v2/log" + "time" + v1 "voucher/api/v1" "voucher/internal/biz/bo" + "voucher/internal/biz/vo" + "voucher/internal/pkg/lock" ) +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, err3 := v.OrderRepo.GetByOrderNo(ctx, orderNo) + if err3 != nil { + return err3 + } + + if err = v.Query(ctx, order); err != nil { + return err + } + + status, err3 := order.Status.GetCmbStatusText() + if err3 != nil { + return err3 + } + + 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) Query(ctx context.Context, order *bo.OrderBo) error { status, err := v.WechatCpnRepo.Query(ctx, order) diff --git a/internal/biz/retry.go b/internal/biz/retry.go new file mode 100644 index 0000000..2816fdf --- /dev/null +++ b/internal/biz/retry.go @@ -0,0 +1,45 @@ +package biz + +import ( + "context" + "fmt" + "voucher/internal/biz/bo" + "voucher/internal/biz/vo" +) + +func (v *VoucherBiz) OrderRetry(ctx context.Context, outBizNos []string) error { + + if len(outBizNos) > 0 { + + for _, outBizNo := range outBizNos { + + order, err := v.OrderRepo.GetByOutBizNo(ctx, vo.OrderTypeCmb, outBizNo) + if err != nil { + return fmt.Errorf(fmt.Sprintf("获取订单%s异常:%v", outBizNo, err)) + } + + if !order.Status.IsIng() { + return fmt.Errorf(fmt.Sprintf("订单%s状态异常:%s", order.OrderNo, order.Status)) + } + + if err4 := v.orderRetry(ctx, order); err4 != nil { + return err4 + } + } + + return nil + } + + return v.OrderRepo.FindIngInBatches(ctx, func(ctx context.Context, rows []*bo.OrderBo) error { + + for _, order := range rows { + + if err4 := v.orderRetry(ctx, order); err4 != nil { + return err4 + } + } + + return nil + }) + +} diff --git a/internal/service/cmb_order.go b/internal/service/cmb_order.go index 3351c1f..fa9e6fb 100644 --- a/internal/service/cmb_order.go +++ b/internal/service/cmb_order.go @@ -11,41 +11,6 @@ import ( "voucher/internal/biz/vo" ) -func (c *CmbService) OrderSuccess(ctx context.Context, orderNo string) (*v1.CmbReply, error) { - - bizReply := &v1.CmbOrderReply{ - RespCode: vo.CmbResponseStatusSuccess.GetValue(), - RespMsg: "成功", - CodeNo: orderNo, - } - - replyBizContent, _ := json.Marshal(bizReply) - - return c.GetResponse(ctx, replyBizContent) -} - -func (c *CmbService) OrderFail(ctx context.Context, err error) (*v1.CmbReply, error) { - - se := errors.FromError(err) - - if len(se.Reason) == 0 { - se.Reason = err2.CmbErr_CMB_UNKNOWN.String() - } - - log.Errorf("order fail: %v", se) - - bizReply := &v1.CmbOrderReply{ - RespCode: vo.CmbResponseStatusFail.GetValue(), - RespMsg: se.Message, - CodeNo: "", - ThirdErrCode: se.Reason, - } - - replyBizContent, _ := json.Marshal(bizReply) - - return c.GetResponse(ctx, replyBizContent) -} - func (c *CmbService) Order(ctx context.Context, request *v1.CmbRequest) (*v1.CmbReply, error) { orderNo, err := c.order(ctx, request) @@ -84,3 +49,38 @@ func (c *CmbService) order(ctx context.Context, request *v1.CmbRequest) (string, return orderNo, nil } + +func (c *CmbService) OrderSuccess(ctx context.Context, orderNo string) (*v1.CmbReply, error) { + + bizReply := &v1.CmbOrderReply{ + RespCode: vo.CmbResponseStatusSuccess.GetValue(), + RespMsg: "成功", + CodeNo: orderNo, + } + + replyBizContent, _ := json.Marshal(bizReply) + + return c.GetResponse(ctx, replyBizContent) +} + +func (c *CmbService) OrderFail(ctx context.Context, err error) (*v1.CmbReply, error) { + + se := errors.FromError(err) + + if len(se.Reason) == 0 { + se.Reason = err2.CmbErr_CMB_UNKNOWN.String() + } + + log.Errorf("order fail: %v", se) + + bizReply := &v1.CmbOrderReply{ + RespCode: vo.CmbResponseStatusFail.GetValue(), + RespMsg: se.Message, + CodeNo: "", + ThirdErrCode: se.Reason, + } + + replyBizContent, _ := json.Marshal(bizReply) + + return c.GetResponse(ctx, replyBizContent) +}