From ec182fabadda6d54b8cb20f143c45edc6686dbee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=AD=90=E9=93=AD?= Date: Tue, 4 Mar 2025 15:42:06 +0800 Subject: [PATCH] cmb --- api/v1/cmb_cpn.proto | 32 +++---- cmd/server/wire.go | 2 - cmd/server/wire_gen.go | 10 ++- internal/biz/cmb/cmb.go | 5 +- internal/biz/cmb/provider_set.go | 2 +- internal/biz/cmb/voucher.go | 89 +++++++++++-------- internal/biz/{thirdrepo => mixrepos}/send.go | 4 +- .../data/{thirdrepoimpl => mixrepoimpl}/mq.go | 16 ++-- internal/data/mixrepoimpl/provider_set.go | 5 +- internal/data/repoimpl/provider_set.go | 1 + internal/data/thirdrepoimpl/provider_set.go | 10 --- internal/service/cmb.go | 60 ++++++++++--- 12 files changed, 139 insertions(+), 97 deletions(-) rename internal/biz/{thirdrepo => mixrepos}/send.go (93%) rename internal/data/{thirdrepoimpl => mixrepoimpl}/mq.go (55%) delete mode 100644 internal/data/thirdrepoimpl/provider_set.go diff --git a/api/v1/cmb_cpn.proto b/api/v1/cmb_cpn.proto index 6ef6bfe..e2c91bf 100644 --- a/api/v1/cmb_cpn.proto +++ b/api/v1/cmb_cpn.proto @@ -9,21 +9,21 @@ import "validate/validate.proto"; message CmbOrderRequest { // 公共参数 // 合作方唯一ID,32位定长 - string mid = 1 [json_name = "mid"]; + string mid = 1 [json_name = "mid", (validate.rules).string = {min_len: 1,max_len: 32}]; // 应用唯一ID,32位定长 - string aid = 2 [json_name = "aid"]; + string aid = 2 [json_name = "aid", (validate.rules).string = {min_len: 1,max_len: 32}]; // 时间戳 yyyyMMddHHmmss - string date = 3 [json_name = "date"]; + string date = 3 [json_name = "date", (validate.rules).string = {min_len: 14}]; // 随机字符串,保证签名不可预测,不长于32位 - string random = 4 [json_name = "random"]; + string random = 4 [json_name = "random", (validate.rules).string = {min_len: 1,max_len: 32}]; // 合作方密钥对别名 - string keyAlias = 5 [json_name = "keyAlias"]; + string keyAlias = 5 [json_name = "keyAlias", (validate.rules).string = {min_len: 2}]; // 掌上生活密钥对别名 - string cmbKeyAlias = 6 [json_name = "cmbKeyAlias"]; + string cmbKeyAlias = 6 [json_name = "cmbKeyAlias", (validate.rules).string = {min_len: 2}]; // 加密报文,是否需要加密,请查看各API的说明文档 - string encryptBody = 7 [json_name = "encryptBody"]; + string encryptBody = 7 [json_name = "encryptBody", (validate.rules).string = {min_len: 10}]; // 签名,具体详见签名规范 - string sign = 8 [json_name = "sign"]; + string sign = 8 [json_name = "sign", (validate.rules).string = {min_len: 10}]; // 业务参数 // 唯一流水号,需支持14天内幂等 @@ -63,21 +63,21 @@ message CmbOrderReply { message CmbQueryProductRequest { // 公共参数 // 合作方唯一ID,32位定长 - string mid = 1 [json_name = "mid"]; + string mid = 1 [json_name = "mid", (validate.rules).string = {min_len: 1,max_len: 32}]; // 应用唯一ID,32位定长 - string aid = 2 [json_name = "aid"]; + string aid = 2 [json_name = "aid", (validate.rules).string = {min_len: 1,max_len: 32}]; // 时间戳 yyyyMMddHHmmss - string date = 3 [json_name = "date"]; + string date = 3 [json_name = "date", (validate.rules).string = {min_len: 14}]; // 随机字符串,保证签名不可预测,不长于32位 - string random = 4 [json_name = "random"]; + string random = 4 [json_name = "random", (validate.rules).string = {min_len: 1,max_len: 32}]; // 合作方密钥对别名 - string keyAlias = 5 [json_name = "keyAlias"]; + string keyAlias = 5 [json_name = "keyAlias", (validate.rules).string = {min_len: 2}]; // 掌上生活密钥对别名 - string cmbKeyAlias = 6 [json_name = "cmbKeyAlias"]; + string cmbKeyAlias = 6 [json_name = "cmbKeyAlias", (validate.rules).string = {min_len: 2}]; // 加密报文,是否需要加密,请查看各API的说明文档 - string encryptBody = 7 [json_name = "encryptBody"]; + string encryptBody = 7 [json_name = "encryptBody", (validate.rules).string = {min_len: 10}]; // 签名,具体详见签名规范 - string sign = 8 [json_name = "sign"]; + string sign = 8 [json_name = "sign", (validate.rules).string = {min_len: 10}]; // 业务参数 // 外部合作方权益批次号 diff --git a/cmd/server/wire.go b/cmd/server/wire.go index 5c592b1..98acf4a 100644 --- a/cmd/server/wire.go +++ b/cmd/server/wire.go @@ -15,7 +15,6 @@ import ( "voucher/internal/data" "voucher/internal/data/mixrepoimpl" "voucher/internal/data/repoimpl" - "voucher/internal/data/thirdrepoimpl" "voucher/internal/data/wechatrepoimpl" log2 "voucher/internal/pkg/log" "voucher/internal/server" @@ -31,7 +30,6 @@ func wireApp(*conf.Bootstrap, log.Logger, *log2.AccessLogger) (*kratos.App, func biz.ProviderSetBiz, data.ProviderDataSet, repoimpl.ProviderRepoImplSet, - thirdrepoimpl.ProviderThirdRepositoryImplSet, wechatrepoimpl.ProviderWechatReposImplSet, mixrepoimpl.ProviderMixRepoImplSet, log2.NewLogHelper, diff --git a/cmd/server/wire_gen.go b/cmd/server/wire_gen.go index 44d2ed9..8752948 100644 --- a/cmd/server/wire_gen.go +++ b/cmd/server/wire_gen.go @@ -9,12 +9,12 @@ package main import ( "github.com/go-kratos/kratos/v2" "github.com/go-kratos/kratos/v2/log" + "voucher/internal/biz" "voucher/internal/biz/cmb" "voucher/internal/conf" "voucher/internal/data" "voucher/internal/data/mixrepoimpl" "voucher/internal/data/repoimpl" - "voucher/internal/data/thirdrepoimpl" "voucher/internal/data/wechatrepoimpl" log2 "voucher/internal/pkg/log" "voucher/internal/server" @@ -35,12 +35,13 @@ func wireApp(bootstrap *conf.Bootstrap, logger log.Logger, accessLogger *log2.Ac return nil, nil, err } orderRepo := repoimpl.NewOrderRepoImpl() + productRepo := repoimpl.NewProductRepoImpl() rocketMQ, cleanup2, err := data.NewRocketMQ(bootstrap) if err != nil { cleanup() return nil, nil, err } - thirdMQSend := thirdrepoimpl.NewMQSendImpl(rocketMQ) + mqSendMixRepo := mixrepoimpl.NewMQSendMixRepoImpl(rocketMQ) wechatCpnRepo, err := wechatrepoimpl.NewCpnRepoImpl(bootstrap) if err != nil { cleanup2() @@ -48,8 +49,9 @@ func wireApp(bootstrap *conf.Bootstrap, logger log.Logger, accessLogger *log2.Ac return nil, nil, err } generateMixRepo := mixrepoimpl.NewGenerateMixRepoImpl(rdb) - voucherBiz := cmb.NewCmb(rdb, orderRepo, thirdMQSend, wechatCpnRepo, generateMixRepo) - voucherService := service.NewVoucherService(bootstrap, voucherBiz) + cmbCmb := cmb.NewCmb(rdb, orderRepo, productRepo, mqSendMixRepo, wechatCpnRepo, generateMixRepo) + voucherBiz := biz.NewVoucherBiz(rdb, cmbCmb, orderRepo) + voucherService := service.NewVoucherService(bootstrap, voucherBiz, cmbCmb) httpServer := server.NewHTTPServer(bootstrap, helper, accessLogger, voucherService) consumer := server.NewConsumer(helper, bootstrap, voucherService) app := newApp(logger, httpServer, consumer) diff --git a/internal/biz/cmb/cmb.go b/internal/biz/cmb/cmb.go index f6a30e1..ef1738b 100644 --- a/internal/biz/cmb/cmb.go +++ b/internal/biz/cmb/cmb.go @@ -3,7 +3,6 @@ package cmb import ( "voucher/internal/biz/mixrepos" "voucher/internal/biz/repo" - "voucher/internal/biz/thirdrepo" "voucher/internal/biz/wechatrepo" "voucher/internal/data" ) @@ -12,7 +11,7 @@ type Cmb struct { rdb *data.Rdb OrderRepo repo.OrderRepo ProductRepo repo.ProductRepo - ThirdMQSend thirdrepo.ThirdMQSend + ThirdMQSend mixrepos.MQSendMixRepo WechatCpnRepo wechatrepo.WechatCpnRepo GenerateMixRepo mixrepos.GenerateMixRepo } @@ -21,7 +20,7 @@ func NewCmb( rdb *data.Rdb, orderRepo repo.OrderRepo, ProductRepo repo.ProductRepo, - thirdMQSend thirdrepo.ThirdMQSend, + thirdMQSend mixrepos.MQSendMixRepo, WechatCpnRepo wechatrepo.WechatCpnRepo, GenerateMixRepo mixrepos.GenerateMixRepo, ) *Cmb { diff --git a/internal/biz/cmb/provider_set.go b/internal/biz/cmb/provider_set.go index e22c1d4..d6b41fe 100644 --- a/internal/biz/cmb/provider_set.go +++ b/internal/biz/cmb/provider_set.go @@ -4,5 +4,5 @@ import ( "github.com/google/wire" ) -// ProviderSetCmb is biz providers. +// ProviderSetCmb ProviderSetCmb is biz providers. var ProviderSetCmb = wire.NewSet(NewCmb) diff --git a/internal/biz/cmb/voucher.go b/internal/biz/cmb/voucher.go index 767de95..43aba03 100644 --- a/internal/biz/cmb/voucher.go +++ b/internal/biz/cmb/voucher.go @@ -12,48 +12,11 @@ import ( "voucher/internal/pkg/uid" ) -func (v *Cmb) Order(ctx context.Context, req *bo.OrderCreateReqBo) (reps *bo.OrderCreateRepBo, err error) { +func (v *Cmb) Order(ctx context.Context, req *bo.OrderCreateReqBo) (orderNo string, err error) { err = lock.NewMutex(v.rdb.Rdb, time.Second*30).Lock(ctx, fmt.Sprintf("cmb_order_%s", req.OutBizNo), func(ctx context.Context) error { - order, err := v.OrderRepo.GetByOutBizNo(ctx, req.OutBizNo) - if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { - return err - } - - if order != nil { - // todo - return nil - } - - product, err := v.ProductRepo.GetByPNO(ctx, req.ProductNo) - if err != nil { - return err - } - - orderNo, err := v.GenerateMixRepo.GeneratorString(ctx, uid.Order) - if err != nil { - return err - } - - o := &bo.OrderBo{ - OrderNo: orderNo, - - OutBizNo: req.OutBizNo, - ProductNo: req.ProductNo, - Account: req.Account, - - AppID: product.AppID, - MerchantNo: product.MerchantNo, - Channel: product.Channel, - - AccountType: vo.OrderAccountTypeOpenId, - Type: vo.OrderTypeCmb, - Status: vo.OrderStatusWait, - } - - order, err = v.OrderRepo.Create(ctx, o) - if err != nil { + if orderNo, err = v.order(ctx, req); err != nil { return err } @@ -63,6 +26,54 @@ func (v *Cmb) Order(ctx context.Context, req *bo.OrderCreateReqBo) (reps *bo.Ord return } +func (v *Cmb) order(ctx context.Context, req *bo.OrderCreateReqBo) (orderNo string, err error) { + + order, err := v.OrderRepo.GetByOutBizNo(ctx, req.OutBizNo) + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + return + } + + if order != nil { + orderNo = order.OrderNo + return + } + + product, err := v.ProductRepo.GetByPNO(ctx, req.ProductNo) + if err != nil { + return + } + + orderNo, err = v.GenerateMixRepo.GeneratorString(ctx, uid.Order) + if err != nil { + return + } + + o := &bo.OrderBo{ + OrderNo: orderNo, + + OutBizNo: req.OutBizNo, + ProductNo: req.ProductNo, + Account: req.Account, + + AppID: product.AppID, + MerchantNo: product.MerchantNo, + Channel: product.Channel, + + AccountType: vo.OrderAccountTypeOpenId, + Type: vo.OrderTypeCmb, + Status: vo.OrderStatusWait, + } + + order, err = v.OrderRepo.Create(ctx, o) + if err != nil { + return + } + + //v.ThirdMQSend + + return +} + func (v *Cmb) Query(ctx context.Context, req *bo.OrderCreateReqBo) (reps *bo.OrderCreateRepBo, err error) { err = lock.NewMutex(v.rdb.Rdb, time.Second*30).Lock(ctx, fmt.Sprintf("cmb_order_%s", req.OutBizNo), func(ctx context.Context) error { diff --git a/internal/biz/thirdrepo/send.go b/internal/biz/mixrepos/send.go similarity index 93% rename from internal/biz/thirdrepo/send.go rename to internal/biz/mixrepos/send.go index 1570b86..764f7c7 100644 --- a/internal/biz/thirdrepo/send.go +++ b/internal/biz/mixrepos/send.go @@ -1,11 +1,11 @@ -package thirdrepo +package mixrepos import ( "context" "voucher/internal/pkg/mq" ) -type ThirdMQSend interface { +type MQSendMixRepo interface { // SendASync 异步发送消息,出错会自动写日志,errFn 中可以不用再写失败日志,可以处理一些数据纠正的操作等 SendASync(ctx context.Context, topicName string, body []byte, errFn func(error), sendOptions ...mq.SendOption) error diff --git a/internal/data/thirdrepoimpl/mq.go b/internal/data/mixrepoimpl/mq.go similarity index 55% rename from internal/data/thirdrepoimpl/mq.go rename to internal/data/mixrepoimpl/mq.go index e40b1a0..69c1675 100644 --- a/internal/data/thirdrepoimpl/mq.go +++ b/internal/data/mixrepoimpl/mq.go @@ -1,28 +1,28 @@ -package thirdrepoimpl +package mixrepoimpl import ( "context" "github.com/go-kratos/kratos/v2/log" - "voucher/internal/biz/thirdrepo" + "voucher/internal/biz/mixrepos" "voucher/internal/data" "voucher/internal/pkg/mq" ) -type ThirdMQSendImpl struct { +type MQSendMixRepoImpl struct { mq *data.RocketMQ } -func NewMQSendImpl(mq *data.RocketMQ) thirdrepo.ThirdMQSend { - return &ThirdMQSendImpl{ +func NewMQSendMixRepoImpl(mq *data.RocketMQ) mixrepos.MQSendMixRepo { + return &MQSendMixRepoImpl{ mq: mq, } } -func (s *ThirdMQSendImpl) SendSync(ctx context.Context, topicName string, body []byte, sendOptions ...mq.SendOption) error { +func (s *MQSendMixRepoImpl) SendSync(ctx context.Context, topicName string, body []byte, sendOptions ...mq.SendOption) error { return s.mq.MqProducer.SendSync(ctx, topicName, body, sendOptions...) } -func (s *ThirdMQSendImpl) SendASync(ctx context.Context, topicName string, body []byte, errFn func(error), sendOptions ...mq.SendOption) error { +func (s *MQSendMixRepoImpl) SendASync(ctx context.Context, topicName string, body []byte, errFn func(error), sendOptions ...mq.SendOption) error { err := s.mq.MqProducer.SendAsync(ctx, topicName, body, func(err error) { if err == nil { return @@ -33,7 +33,7 @@ func (s *ThirdMQSendImpl) SendASync(ctx context.Context, topicName string, body return err } -func (s *ThirdMQSendImpl) SendAsyncNotFn(ctx context.Context, topic string, body []byte, sendOptions ...mq.SendOption) error { +func (s *MQSendMixRepoImpl) SendAsyncNotFn(ctx context.Context, topic string, body []byte, sendOptions ...mq.SendOption) error { err := s.mq.MqProducer.SendAsync(ctx, topic, body, func(err error) { if err == nil { return diff --git a/internal/data/mixrepoimpl/provider_set.go b/internal/data/mixrepoimpl/provider_set.go index dde83eb..15bb377 100644 --- a/internal/data/mixrepoimpl/provider_set.go +++ b/internal/data/mixrepoimpl/provider_set.go @@ -5,4 +5,7 @@ import ( ) // ProviderMixRepoImplSet is providers. -var ProviderMixRepoImplSet = wire.NewSet(NewGenerateMixRepoImpl) +var ProviderMixRepoImplSet = wire.NewSet( + NewGenerateMixRepoImpl, + NewMQSendMixRepoImpl, +) diff --git a/internal/data/repoimpl/provider_set.go b/internal/data/repoimpl/provider_set.go index 9d6e95c..32a7c2b 100644 --- a/internal/data/repoimpl/provider_set.go +++ b/internal/data/repoimpl/provider_set.go @@ -7,4 +7,5 @@ import ( // ProviderRepoImplSet is providers. var ProviderRepoImplSet = wire.NewSet( NewOrderRepoImpl, + NewProductRepoImpl, ) diff --git a/internal/data/thirdrepoimpl/provider_set.go b/internal/data/thirdrepoimpl/provider_set.go deleted file mode 100644 index 356f26a..0000000 --- a/internal/data/thirdrepoimpl/provider_set.go +++ /dev/null @@ -1,10 +0,0 @@ -package thirdrepoimpl - -import ( - "github.com/google/wire" -) - -// ProviderThirdRepositoryImplSet is providers. -var ProviderThirdRepositoryImplSet = wire.NewSet( - NewMQSendImpl, -) diff --git a/internal/service/cmb.go b/internal/service/cmb.go index 83c6041..9b013cf 100644 --- a/internal/service/cmb.go +++ b/internal/service/cmb.go @@ -9,13 +9,42 @@ import ( func (s *VoucherService) CmbOrder(ctx http.Context) error { + reply := &v1.CmbOrderReply{ + RespCode: "", + RespMsg: "", + Date: "", + KeyAlias: "", + CmbKeyAlias: "", + EncryptBody: "", + Sign: "", + CodeNo: "", + } + + orderNo, err := s.cmbOrder(ctx) + if err != nil { + reply.RespCode = "1001" + reply.RespMsg = err.Error() + } else { + reply.RespCode = "1000" + reply.RespMsg = "成功" + reply.CodeNo = orderNo + } + + // todo 签名 + reply.Sign = "" + + return ctx.JSON(200, reply) +} + +func (s *VoucherService) cmbOrder(ctx http.Context) (string, error) { + var req v1.CmbOrderRequest if err := ctx.BindForm(&req); err != nil { - return err + return "", err } if err := req.Validate(); err != nil { - return err + return "", err } // todo 签名验证 @@ -27,22 +56,29 @@ func (s *VoucherService) CmbOrder(ctx http.Context) error { AccountType: vo.OrderAccountTypeOpenId, } - boRep, err := s.Cmb.Order(ctx, boReq) + orderNo, err := s.Cmb.Order(ctx, boReq) if err != nil { - return err + return "", err } - rep := &v1.CmbOrderReply{ - RespCode: "", - RespMsg: "", - CodeNo: boRep.OrderNo, - } - - return ctx.JSON(200, rep) + return orderNo, nil } func (s *VoucherService) CmbProductQuery(ctx http.Context) error { + err := s.cmbProductQuery(ctx) + if err != nil { + return ctx.JSON(200, &v1.CmbOrderReply{ + RespCode: "1001", + RespMsg: err.Error(), + }) + } + + return ctx.JSON(200, nil) +} + +func (s *VoucherService) cmbProductQuery(ctx http.Context) error { + var req v1.CmbQueryProductRequest if err := ctx.BindForm(&req); err != nil { return err @@ -52,6 +88,8 @@ func (s *VoucherService) CmbProductQuery(ctx http.Context) error { return err } + // todo 签名验证 + rep := &v1.CmbQueryProductReply{} return ctx.JSON(200, rep)