diff --git a/api/v1/cmb_cpn.proto b/api/v1/cmb_cpn.proto index a3cd78e..ae03540 100644 --- a/api/v1/cmb_cpn.proto +++ b/api/v1/cmb_cpn.proto @@ -62,12 +62,6 @@ service Cmb { }; } - rpc Test (Empty) returns (Empty) { - option (google.api.http) = { - post: "/voucher/cmb/v1/test", - body: "*" - }; - } } message OrderRetryRequest { diff --git a/internal/biz/notify_tag.go b/internal/biz/notify_tag.go deleted file mode 100644 index b50daf8..0000000 --- a/internal/biz/notify_tag.go +++ /dev/null @@ -1,101 +0,0 @@ -package biz - -import ( - "context" - "fmt" - "github.com/redis/go-redis/v9" - err2 "voucher/api/err" - "voucher/internal/biz/bo" - "voucher/internal/biz/vo" - "voucher/internal/pkg/lock" -) - -func (v *VoucherBiz) RegisterTag(ctx context.Context, productNo string) error { - - product, err := v.ProductRepo.GetByProductNo(ctx, productNo) - if err != nil { - return err - } - - return v.registerNotifyTag(ctx, product.MchId, product.BatchNo) -} - -func (v *VoucherBiz) registerNotifyTag(ctx context.Context, stockCreatorMchID, stockID string) error { - - c := vo.WechatNotifyRegisterTagCacheKey.BuildCache([]string{v.bc.WechatNotifyMQ.Tag, stockCreatorMchID, stockID}) - - _, err := v.rdb.Rdb.Get(ctx, c.Key).Result() - - if err == nil { - // 缓存存在,直接返回 - return nil - } - - if err != redis.Nil { - return fmt.Errorf(fmt.Sprintf("获取redis缓存%s异常:%v", c.Key, err)) - } - - cl := vo.WechatNotifyRegisterTagCacheLockKey.BuildCache([]string{v.bc.WechatNotifyMQ.Tag, stockCreatorMchID, stockID}) - - return lock.NewMutex(v.rdb.Rdb, cl.TTL).Lock(ctx, cl.Key, func(ctx context.Context) error { - // 二次获取,判定处理,以免获取锁后又执行了一次 - - cacheValue, err3 := v.rdb.Rdb.Get(ctx, c.Key).Result() - - if err3 != nil && err3 != redis.Nil { - return fmt.Errorf(fmt.Sprintf("二次获取redis缓存%s异常:%v", c.Key, err)) - } - - if cacheValue != "" { - return nil // 有直接返回 - } - - wechatNotifyTag, err3 := v.WechatNotifyRegisterTagRepo.GetByStockIdAndMchId(ctx, stockCreatorMchID, stockID) - if err3 != nil && !err2.IsDbNotFound(err3) { - return err3 - } - - if wechatNotifyTag != nil { - if wechatNotifyTag.Tag != v.bc.WechatNotifyMQ.Tag { - return fmt.Errorf("tag不一致,请检查tag配置:%s", wechatNotifyTag.Tag) - } - - if wechatNotifyTag.Status.IsSuccess() { - return v.setCache(ctx, c, wechatNotifyTag) - } - } else { - wechatNotifyTag, err3 = v.createWechatNotifyRegisterTag(ctx, stockCreatorMchID, stockID) - if err3 != nil { - return err3 - } - } - - if err = v.WechatCpnRepo.RegisterNotifyTag(ctx, stockID); err != nil { - - return v.WechatNotifyRegisterTagRepo.Fail(ctx, wechatNotifyTag.ID, err.Error()) - } - - if err = v.WechatNotifyRegisterTagRepo.Success(ctx, wechatNotifyTag.ID); err != nil { - return err - } - - return v.setCache(ctx, c, wechatNotifyTag) - }) -} - -func (v *VoucherBiz) createWechatNotifyRegisterTag(ctx context.Context, stockCreatorMchID, stockID string) (*bo.WechatNotifyRegisterTagBo, error) { - return v.WechatNotifyRegisterTagRepo.Create(ctx, &bo.WechatNotifyRegisterTagBo{ - StockID: stockID, - StockCreatorMchID: stockCreatorMchID, - Tag: v.bc.WechatNotifyMQ.Tag, - }) -} - -func (v *VoucherBiz) setCache(ctx context.Context, c *vo.Cache, wechatNotifyTag *bo.WechatNotifyRegisterTagBo) error { - - if err := v.rdb.Rdb.Set(ctx, c.Key, wechatNotifyTag.Tag, c.TTL).Err(); err != nil { - return fmt.Errorf(fmt.Sprintf("设置redis缓存%s异常:%v", c.Key, err)) - } - - return nil -} diff --git a/internal/biz/order.go b/internal/biz/order.go index a7b5b40..d2dfaa4 100644 --- a/internal/biz/order.go +++ b/internal/biz/order.go @@ -2,17 +2,62 @@ package biz import ( "context" + "encoding/json" "fmt" + "github.com/go-kratos/kratos/v2/errors" + "time" err2 "voucher/api/err" + v1 "voucher/api/v1" "voucher/internal/biz/bo" "voucher/internal/biz/vo" ) -func (v *VoucherBiz) CmbOrder(ctx context.Context, req *bo.OrderCreateReqBo) (orderNo string, err error) { +func (v *VoucherBiz) CmbOrder(ctx context.Context, request *v1.CmbRequest) (*v1.CmbReply, error) { - order, err3 := v.GetByOutBizNo(ctx, req) + order, err := v.cmbOrder(ctx, request) + + if err != nil { + return v.OrderFail(ctx, err) + } + + reply, err := v.OrderSuccess(ctx, order.OrderNo) + if err != nil { + return nil, err + } + + _ = v.bbToWx(ctx, order, reply) + + return reply, nil +} + +func (v *VoucherBiz) cmbOrder(ctx context.Context, request *v1.CmbRequest) (*bo.OrderBo, error) { + + bizContent, err := v.CmbMixRepo.OrderVerify(ctx, request) + if err != nil { + return nil, err + } + + product, err3 := v.ProductRepo.GetByProductNo(ctx, bizContent.ActivityId) if err3 != nil { - return "", err3 + return nil, err + } + + order, err := v.Order(ctx, product, bizContent) + if err != nil { + return nil, err + } + + order.MiniMum = product.MiniMum + order.CouponValue = product.Amount + + return order, nil +} + +func (v *VoucherBiz) Order(ctx context.Context, product *bo.ProductBo, bizContent *v1.CmbOrderRequest) (order *bo.OrderBo, err error) { + + order, err = v.OrderRepo.GetByOutBizNo(ctx, vo.OrderTypeCmb, bizContent.TransactionId) + if err != nil && !err2.IsDbNotFound(err) { + return order, err } if order != nil { @@ -20,60 +65,74 @@ func (v *VoucherBiz) CmbOrder(ctx context.Context, req *bo.OrderCreateReqBo) (or if order.Status.IsFail() || order.Status.IsIng() { if err4 := v.orderRetry(ctx, order); err4 != nil { - return "", err4 + return order, err4 } } - return order.OrderNo, err + return order, err } - product, err3 := v.ProductRepo.GetByProductNo(ctx, req.ProductNo) - if err3 != nil { - return "", err3 + order, err = v.order(ctx, product, bizContent) + if err != nil { + return nil, err } - order, err3 = v.order(ctx, req, product) - if err3 != nil { - return "", err3 - } - - return order.OrderNo, nil + return order, nil } -func (v *VoucherBiz) order(ctx context.Context, req *bo.OrderCreateReqBo, product *bo.ProductBo) (*bo.OrderBo, error) { +func (v *VoucherBiz) order(ctx context.Context, product *bo.ProductBo, bizContent *v1.CmbOrderRequest) (*bo.OrderBo, error) { + + req := &bo.OrderCreateReqBo{ + OutBizNo: bizContent.TransactionId, + ProductNo: bizContent.ActivityId, + Account: bizContent.CmbUid, + AppID: bizContent.AppId, + Attach: bizContent.Attach, + AccountType: vo.OrderAccountTypeOpenId, + Type: vo.OrderTypeCmb, + NotifyUrl: v.bc.Cmb.NotifyUrl, + } order, err := v.create(ctx, req, product) if err != nil { return nil, err } - voucherNo, err := v.WechatCpnRepo.Order(ctx, order) - if err != nil { - if err3 := v.fail(ctx, order, err); err3 != nil { - return nil, err3 - } - return nil, err - } + _ = v.cmbToBB(ctx, bizContent) + + //voucherNo, err := v.WechatCpnRepo.Order(ctx, order) + //if err != nil { + // if err3 := v.fail(ctx, order, err); err3 != nil { + // return nil, err3 + // } + // return nil, err + //} + + //休眠100微妙 + time.Sleep(time.Millisecond * 100) + //mock发券成功,测试使用 + voucherNo := order.OrderNo if err = v.success(ctx, order, voucherNo); err != nil { - return nil, err + return order, err } - //_ = v.bbToWx(ctx, order, reply) - return order, nil } func (v *VoucherBiz) orderRetry(ctx context.Context, order *bo.OrderBo) error { - voucherNo, err := v.WechatCpnRepo.Order(ctx, order) + // mock发券成功,测试使用 + voucherNo := order.OrderNo - if err != nil { - if err3 := v.fail(ctx, order, err); err3 != nil { - return err3 - } - return err - } + //voucherNo, err := v.WechatCpnRepo.Order(ctx, order) + + //if err != nil { + // if err3 := v.fail(ctx, order, err); err3 != nil { + // return err3 + // } + // return err + //} return v.success(ctx, order, voucherNo) } @@ -122,17 +181,6 @@ 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() { @@ -150,3 +198,36 @@ func (v *VoucherBiz) UpdateOrderStatus(ctx context.Context, orderId uint64, stat return fmt.Errorf("notice 未知券状态,orderId:%d,statuText:%s", orderId, status.GetText()) } + +func (c *VoucherBiz) 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 *VoucherBiz) 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() + } + + bizReply := &v1.CmbOrderReply{ + RespCode: vo.CmbResponseStatusFail.GetValue(), + RespMsg: se.Message, + CodeNo: "", + ThirdErrCode: se.Reason, + } + + replyBizContent, _ := json.Marshal(bizReply) + + return c.GetResponse(ctx, replyBizContent) +} diff --git a/internal/biz/register_tag.go b/internal/biz/register_tag.go index cb8314d..bebafc7 100644 --- a/internal/biz/register_tag.go +++ b/internal/biz/register_tag.go @@ -3,7 +3,6 @@ package biz import ( "context" "fmt" - "github.com/redis/go-redis/v9" err2 "voucher/api/err" "voucher/internal/biz/bo" "voucher/internal/biz/vo" @@ -23,33 +22,9 @@ func (this *VoucherBiz) RegisterTag(ctx context.Context, productNo string) error func (v *VoucherBiz) registerNotifyTag(ctx context.Context, stockCreatorMchID, stockID string) error { - c := vo.WechatNotifyRegisterTagCacheKey.BuildCache([]string{v.bc.WechatNotifyMQ.Tag, stockCreatorMchID, stockID}) - - _, err := v.rdb.Rdb.Get(ctx, c.Key).Result() - - if err == nil { - // 缓存存在,直接返回 - return nil - } - - if err != redis.Nil { - return fmt.Errorf(fmt.Sprintf("获取redis缓存%s异常:%v", c.Key, err)) - } - cl := vo.WechatNotifyRegisterTagCacheLockKey.BuildCache([]string{v.bc.WechatNotifyMQ.Tag, stockCreatorMchID, stockID}) return lock.NewMutex(v.rdb.Rdb, cl.TTL).Lock(ctx, cl.Key, func(ctx context.Context) error { - // 二次获取,判定处理,以免获取锁后又执行了一次 - - cacheValue, err3 := v.rdb.Rdb.Get(ctx, c.Key).Result() - - if err3 != nil && err3 != redis.Nil { - return fmt.Errorf(fmt.Sprintf("二次获取redis缓存%s异常:%v", c.Key, err)) - } - - if cacheValue != "" { - return nil // 有直接返回 - } wechatNotifyTag, err3 := v.WechatNotifyRegisterTagRepo.GetByStockIdAndMchId(ctx, stockCreatorMchID, stockID) if err3 != nil && !err2.IsDbNotFound(err3) { @@ -57,33 +32,36 @@ func (v *VoucherBiz) registerNotifyTag(ctx context.Context, stockCreatorMchID, s } if wechatNotifyTag != nil { + if wechatNotifyTag.Tag != v.bc.WechatNotifyMQ.Tag { return fmt.Errorf("tag不一致,请检查tag配置:%s", wechatNotifyTag.Tag) } if wechatNotifyTag.Status.IsSuccess() { - return v.setCache(ctx, c, wechatNotifyTag) + return nil } + } else { + wechatNotifyTag, err3 = v.createWechatNotifyRegisterTag(ctx, stockCreatorMchID, stockID) if err3 != nil { return err3 } } - if err = v.WechatCpnRepo.RegisterNotifyTag(ctx, stockID); err != nil { - - return v.WechatNotifyRegisterTagRepo.Fail(ctx, wechatNotifyTag.ID, err.Error()) - } - - if err = v.WechatNotifyRegisterTagRepo.Success(ctx, wechatNotifyTag.ID); err != nil { - return err - } - - return v.setCache(ctx, c, wechatNotifyTag) + return v.registerTag(ctx, wechatNotifyTag) }) } +func (v *VoucherBiz) registerTag(ctx context.Context, wechatNotifyTa *bo.WechatNotifyRegisterTagBo) error { + if err := v.WechatCpnRepo.RegisterNotifyTag(ctx, wechatNotifyTa.Tag); err != nil { + + return v.WechatNotifyRegisterTagRepo.Fail(ctx, wechatNotifyTa.ID, err.Error()) + } + + return v.WechatNotifyRegisterTagRepo.Success(ctx, wechatNotifyTa.ID) +} + func (v *VoucherBiz) createWechatNotifyRegisterTag(ctx context.Context, stockCreatorMchID, stockID string) (*bo.WechatNotifyRegisterTagBo, error) { return v.WechatNotifyRegisterTagRepo.Create(ctx, &bo.WechatNotifyRegisterTagBo{ StockID: stockID, @@ -91,12 +69,3 @@ func (v *VoucherBiz) createWechatNotifyRegisterTag(ctx context.Context, stockCre Tag: v.bc.WechatNotifyMQ.Tag, }) } - -func (v *VoucherBiz) setCache(ctx context.Context, c *vo.Cache, wechatNotifyTag *bo.WechatNotifyRegisterTagBo) error { - - if err := v.rdb.Rdb.Set(ctx, c.Key, wechatNotifyTag.Tag, c.TTL).Err(); err != nil { - return fmt.Errorf(fmt.Sprintf("设置redis缓存%s异常:%v", c.Key, err)) - } - - return nil -} diff --git a/internal/biz/repo/order.go b/internal/biz/repo/order.go index 9c43d90..a1c583a 100644 --- a/internal/biz/repo/order.go +++ b/internal/biz/repo/order.go @@ -2,7 +2,6 @@ package repo import ( "context" - "time" "voucher/internal/biz/bo" "voucher/internal/biz/vo" ) @@ -18,7 +17,7 @@ type OrderRepo interface { Ing(ctx context.Context, id uint64) error Success(ctx context.Context, id uint64, voucherNo string) error Fail(ctx context.Context, id uint64, remark string) error - Used(ctx context.Context, id uint64, usedTime time.Time) error + Used(ctx context.Context, id uint64) error Available(ctx context.Context, id uint64) error Expired(ctx context.Context, id uint64) error } diff --git a/internal/biz/wechat_notify.go b/internal/biz/wechat_notify.go index 88bb49b..6065136 100644 --- a/internal/biz/wechat_notify.go +++ b/internal/biz/wechat_notify.go @@ -86,19 +86,24 @@ func (v *VoucherBiz) createUseLog(ctx context.Context, order *bo.OrderBo, req *b func (v *VoucherBiz) used(ctx context.Context, order *bo.OrderBo, req *bo.WechatVoucherNotifyBo) error { - var usedTime time.Time - if req.PlainText.ConsumeInformation.ConsumeTime != "" { - usedTime, _ = time.Parse(time.RFC3339, req.PlainText.ConsumeInformation.ConsumeTime) - } else { - usedTime = time.Now() - } + //var usedTime time.Time + //if req.PlainText.ConsumeInformation.ConsumeTime != "" { + // usedTime, _ = time.Parse(time.RFC3339, req.PlainText.ConsumeInformation.ConsumeTime) + //} else { + // usedTime = time.Now() + //} - if order.Status.IsUse() && usedTime == *order.LastUseTime { + //if order.Status.IsUse() && usedTime == *order.LastUseTime { + // log.Warnf("券状态已是可使用,忽略不处理,orderNo:%s", order.OrderNo) + // return nil + //} + + if order.Status.IsUse() { log.Warnf("券状态已是可使用,忽略不处理,orderNo:%s", order.OrderNo) return nil } - if err := v.OrderRepo.Used(ctx, order.ID, usedTime); err != nil { + if err := v.OrderRepo.Used(ctx, order.ID); err != nil { return err } diff --git a/internal/data/repoimpl/order.go b/internal/data/repoimpl/order.go index fd1d49c..d7780b0 100644 --- a/internal/data/repoimpl/order.go +++ b/internal/data/repoimpl/order.go @@ -271,7 +271,7 @@ func (p *OrderRepoImpl) Fail(ctx context.Context, id uint64, remark string) erro return nil } -func (p *OrderRepoImpl) Used(ctx context.Context, id uint64, usedTime time.Time) error { +func (p *OrderRepoImpl) Used(ctx context.Context, id uint64) error { now := time.Now() tx := p.DB(ctx). @@ -280,7 +280,7 @@ func (p *OrderRepoImpl) Used(ctx context.Context, id uint64, usedTime time.Time) }). Updates(model.Order{ Status: vo.OrderStatusUse.GetValue(), - LastUseTime: &usedTime, + LastUseTime: &now, UpdateTime: &now, }) diff --git a/internal/service/notice.go b/internal/service/notice.go deleted file mode 100644 index c855bde..0000000 --- a/internal/service/notice.go +++ /dev/null @@ -1,41 +0,0 @@ -package service - -import ( - "context" - "fmt" - v1 "voucher/api/v1" - "voucher/internal/biz/bo" - "voucher/internal/biz/vo" - "voucher/internal/pkg/helper" -) - -func (s *CmbService) BatchQuery(ctx context.Context, request *v1.BatchQueryRequest) (*v1.Empty, error) { - - req := &bo.FindInBatchesUseBo{ - Type: vo.OrderTypeCmb, - } - - if len(request.BeginTime) > 0 { - beginTime, err := helper.Parse(request.BeginTime) - if err != nil { - return nil, err - } - req.StartTime = &beginTime - } - - if len(request.EndTime) > 0 { - endTime, err := helper.Parse(request.EndTime) - if err != nil { - return nil, err - } - req.EndTime = &endTime - } - - if req.StartTime == nil || req.EndTime == nil { - return nil, fmt.Errorf("时间范围错误") - } - - ctx = context.Background() - - return nil, s.VoucherBiz.ExecuteNotice(ctx, req) -} diff --git a/internal/service/order.go b/internal/service/order.go index 398076b..33bc3a0 100644 --- a/internal/service/order.go +++ b/internal/service/order.go @@ -2,80 +2,10 @@ package service import ( "context" - "encoding/json" - "github.com/go-kratos/kratos/v2/errors" - err2 "voucher/api/err" v1 "voucher/api/v1" - "voucher/internal/biz/bo" - "voucher/internal/biz/vo" ) func (c *CmbService) Order(ctx context.Context, request *v1.CmbRequest) (*v1.CmbReply, error) { - orderNo, err := c.order(ctx, request) - - if err != nil { - return c.OrderFail(ctx, err) - } - - return c.OrderSuccess(ctx, orderNo) -} - -func (c *CmbService) order(ctx context.Context, request *v1.CmbRequest) (string, error) { - - bizContent, err := c.CmbMixRepo.OrderVerify(ctx, request) - if err != nil { - return "", err - } - - boReq := &bo.OrderCreateReqBo{ - OutBizNo: bizContent.TransactionId, - ProductNo: bizContent.ActivityId, - Account: bizContent.CmbUid, - AppID: bizContent.AppId, - Attach: bizContent.Attach, - AccountType: vo.OrderAccountTypeOpenId, - Type: vo.OrderTypeCmb, - NotifyUrl: c.bc.Cmb.NotifyUrl, - } - - orderNo, err := c.VoucherBiz.CmbOrder(ctx, boReq) - if err != nil { - return "", err - } - - 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() - } - - bizReply := &v1.CmbOrderReply{ - RespCode: vo.CmbResponseStatusFail.GetValue(), - RespMsg: se.Message, - CodeNo: "", - ThirdErrCode: se.Reason, - } - - replyBizContent, _ := json.Marshal(bizReply) - - return c.GetResponse(ctx, replyBizContent) + return c.VoucherBiz.CmbOrder(ctx, request) } diff --git a/third_party/swagger_ui/openapi.yaml b/third_party/swagger_ui/openapi.yaml index 2136ec6..368aa0c 100644 --- a/third_party/swagger_ui/openapi.yaml +++ b/third_party/swagger_ui/openapi.yaml @@ -150,37 +150,8 @@ paths: application/json: schema: $ref: '#/components/schemas/api.v1.CmbRequest' - /voucher/cmb/v1/test: - post: - tags: - - Cmb - operationId: Cmb_BatchQuery - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/api.v1.BatchQueryRequest' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/api.v1.Empty' components: schemas: - api.v1.BatchQueryRequest: - type: object - properties: - order_ids: - type: array - items: - type: string - begin_time: - type: string - end_time: - type: string api.v1.CmbOrderRequest: type: object properties: