代码调整
This commit is contained in:
parent
4f71228ff1
commit
7abaf972a4
|
|
@ -3,6 +3,59 @@ syntax = "proto3";
|
|||
package api.v1;
|
||||
option go_package = "voucher/api/v1;v1";
|
||||
import "validate/validate.proto";
|
||||
import "google/api/annotations.proto";
|
||||
|
||||
service Cmb {
|
||||
|
||||
rpc Order (CmbRequest) returns (CmbReply) {
|
||||
option (google.api.http) = {
|
||||
post: "/voucher/cmb/v1/order",
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
rpc Query (CmbRequest) returns (CmbReply) {
|
||||
option (google.api.http) = {
|
||||
post: "/voucher/cmb/v1/query",
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
rpc QueryProduct (CmbRequest) returns (CmbReply) {
|
||||
option (google.api.http) = {
|
||||
post: "/voucher/cmb/v1/product/query",
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
rpc OrderMock (CmbOrderRequest) returns (CmbRequest) {
|
||||
option (google.api.http) = {
|
||||
post: "/voucher/cmb/v1/orderMock",
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
rpc QueryMock (CmbQueryRequest) returns (CmbRequest) {
|
||||
option (google.api.http) = {
|
||||
post: "/voucher/cmb/v1/queryMock",
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
rpc QueryProductMock (CmbQueryProductRequest) returns (CmbRequest) {
|
||||
option (google.api.http) = {
|
||||
post: "/voucher/cmb/v1/product/queryMock",
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
rpc DecryptBody (EncryptBodyRequest) returns (DecryptBodyReply) {
|
||||
option (google.api.http) = {
|
||||
post: "/voucher/cmb/v1/decryptBody",
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
message CmbRequest {
|
||||
// 请求公共参数
|
||||
|
|
@ -94,7 +147,7 @@ message CmbQueryReply {
|
|||
message CmbQueryProductRequest {
|
||||
// 业务参数
|
||||
// 外部合作方权益批次号
|
||||
string activityId = 9 [json_name = "activityId", (validate.rules).string = {min_len: 1,max_len: 32}];
|
||||
string activityId = 9 [json_name = "activityId"];
|
||||
}
|
||||
message CmbQueryProductReply {
|
||||
// 接口调用返回码,1000 成功,1001 失败
|
||||
|
|
@ -156,29 +209,9 @@ message CmbNotifyReply {
|
|||
}
|
||||
|
||||
|
||||
message EncryptBody {
|
||||
message EncryptBodyRequest {
|
||||
string encryptBody = 1 [json_name = "encryptBody"];
|
||||
}
|
||||
message DecryptBody {
|
||||
message DecryptBodyReply {
|
||||
string decryptBody = 1 [json_name = "decryptBody"];
|
||||
}
|
||||
|
||||
|
||||
message QueryWechatVoucherNotifyUrlRequest {
|
||||
string mch_id = 1 [json_name = "mch_id"];
|
||||
string mch_cert_no = 2 [json_name = "mch_cert_no"];
|
||||
}
|
||||
message QueryWechatVoucherNotifyUrlReply {
|
||||
string url = 1 [json_name = "url"];
|
||||
}
|
||||
|
||||
message SetWechatVoucherNotifyUrlRequest {
|
||||
string mch_id = 1 [json_name = "mch_id"];
|
||||
string mch_cert_no = 2 [json_name = "mch_cert_no"];
|
||||
string url = 3 [json_name = "url"];
|
||||
}
|
||||
message SetWechatVoucherNotifyUrlReply {
|
||||
string mch_id = 1 [json_name = "mch_id"];
|
||||
string url = 2 [json_name = "url"];
|
||||
string mch_cert_no = 3 [json_name = "mch_cert_no"];
|
||||
}
|
||||
4
go.mod
4
go.mod
|
|
@ -28,6 +28,8 @@ require (
|
|||
go.opentelemetry.io/otel/sdk v1.28.0
|
||||
go.opentelemetry.io/otel/trace v1.28.0
|
||||
go.uber.org/automaxprocs v1.5.1
|
||||
golang.org/x/time v0.5.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917
|
||||
google.golang.org/protobuf v1.34.2
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gorm.io/driver/mysql v1.5.7
|
||||
|
|
@ -86,7 +88,7 @@ require (
|
|||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/term v0.29.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 // indirect
|
||||
google.golang.org/grpc v1.61.1 // indirect
|
||||
gopkg.in/ini.v1 v1.42.0 // indirect
|
||||
|
|
|
|||
1
go.sum
1
go.sum
|
|
@ -129,7 +129,6 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
|
|||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE=
|
||||
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"github.com/go-kratos/kratos/v2/log"
|
||||
http2 "github.com/go-kratos/kratos/v2/transport/http"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
|
@ -28,6 +30,23 @@ func NewCmbMixRepoImpl(bc *conf.Bootstrap) mixrepos.CmbMixRepo {
|
|||
return &CmbMixRepoImpl{bc: bc}
|
||||
}
|
||||
|
||||
func (c *CmbMixRepoImpl) recordBody(ctx context.Context) {
|
||||
|
||||
httpRequest, ok := http2.RequestFromServerContext(ctx)
|
||||
if !ok {
|
||||
log.Errorf("read body not ok")
|
||||
return
|
||||
}
|
||||
|
||||
bodyBytes, err := io.ReadAll(httpRequest.Body)
|
||||
if err != nil {
|
||||
log.Errorf("read body not ok, %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Errorf("body %v", string(bodyBytes))
|
||||
}
|
||||
|
||||
func (s *CmbMixRepoImpl) OrderVerify(ctx context.Context, req *v1.CmbRequest) (*v1.CmbOrderRequest, error) {
|
||||
|
||||
bizStr, err := s.Verify(ctx, req)
|
||||
|
|
@ -36,6 +55,7 @@ func (s *CmbMixRepoImpl) OrderVerify(ctx context.Context, req *v1.CmbRequest) (*
|
|||
}
|
||||
|
||||
if len(bizStr) == 0 {
|
||||
s.recordBody(ctx)
|
||||
return nil, err2.ErrorCmbBizContentFail("业务参数获取异常,请检查参数是否正确传递")
|
||||
}
|
||||
|
||||
|
|
@ -59,6 +79,7 @@ func (s *CmbMixRepoImpl) QueryVerify(ctx context.Context, req *v1.CmbRequest) (*
|
|||
}
|
||||
|
||||
if len(bizStr) == 0 {
|
||||
s.recordBody(ctx)
|
||||
return nil, err2.ErrorCmbBizContentFail("业务参数获取异常,请检查参数是否正确传递")
|
||||
}
|
||||
|
||||
|
|
@ -82,6 +103,7 @@ func (s *CmbMixRepoImpl) ProductQueryVerify(ctx context.Context, req *v1.CmbRequ
|
|||
}
|
||||
|
||||
if len(bizStr) == 0 {
|
||||
s.recordBody(ctx)
|
||||
return nil, err2.ErrorCmbBizContentFail("业务参数获取异常,请检查参数是否正确传递")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/go-kratos/kratos/v2/transport/http"
|
||||
"github.com/gorilla/handlers"
|
||||
http2 "net/http"
|
||||
v1 "voucher/api/v1"
|
||||
"voucher/internal/conf"
|
||||
log2 "voucher/internal/pkg/log"
|
||||
"voucher/internal/service"
|
||||
|
|
@ -23,34 +24,21 @@ func NewHTTPServer(
|
|||
c *conf.Bootstrap,
|
||||
log *log.Helper,
|
||||
accessLogger *log2.AccessLogger,
|
||||
voucherService *service.VoucherService,
|
||||
cmb *service.CmbService,
|
||||
) *http.Server {
|
||||
//构建 server
|
||||
srv := buildHTTPServer(c, accessLogger, log)
|
||||
|
||||
r := srv.Route("/voucher")
|
||||
|
||||
r.GET("/ping", func(ctx http.Context) error {
|
||||
srv.Route("/").GET("ping", func(ctx http.Context) error {
|
||||
return ctx.String(http2.StatusOK, "pong")
|
||||
})
|
||||
|
||||
cmb := r.Group("/cmb")
|
||||
v1.RegisterCmbHTTPServer(srv, cmb)
|
||||
|
||||
v1 := cmb.Group("/v1")
|
||||
|
||||
v1.POST("/orderMock", voucherService.CmbOrderMock)
|
||||
v1.POST("/order", voucherService.CmbOrder)
|
||||
|
||||
v1.POST("/queryMock", voucherService.CmbQueryMock)
|
||||
v1.POST("/query", voucherService.CmbQuery)
|
||||
|
||||
v1.POST("/product/queryMock", voucherService.CmbProductQueryMock)
|
||||
v1.POST("/product/query", voucherService.CmbProductQuery)
|
||||
|
||||
v1.POST("/decryptBody", voucherService.DecryptBody)
|
||||
v1.POST("/queryWechatVoucherNotifyUrl", voucherService.QueryWechatVoucherNotifyUrl)
|
||||
v1.POST("/setWechatVoucherNotifyUrl", voucherService.SetWechatVoucherNotifyUrl)
|
||||
v1.POST("/test", voucherService.Test)
|
||||
//v1.POST("/decryptBody", voucherService.DecryptBody)
|
||||
//v1.POST("/queryWechatVoucherNotifyUrl", voucherService.QueryWechatVoucherNotifyUrl)
|
||||
//v1.POST("/setWechatVoucherNotifyUrl", voucherService.SetWechatVoucherNotifyUrl)
|
||||
//v1.POST("/test", voucherService.Test)
|
||||
|
||||
return srv
|
||||
}
|
||||
|
|
@ -135,6 +123,7 @@ func responseEncoder(w http.ResponseWriter, r *http.Request, data interface{}) e
|
|||
if data == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
codec, _ := http.CodecForRequest(r, "Accept")
|
||||
dataByte, err := codec.Marshal(data)
|
||||
if err != nil {
|
||||
|
|
@ -142,7 +131,7 @@ func responseEncoder(w http.ResponseWriter, r *http.Request, data interface{}) e
|
|||
}
|
||||
|
||||
w.Header().Set("Content-Type", fmt.Sprintf("application/%s", codec.Name()))
|
||||
_, err = w.Write([]byte(fmt.Sprintf(`{"code":%d,"data":%s,"message":"%s"}`, http2.StatusOK, string(dataByte), "成功")))
|
||||
_, err = w.Write(dataByte)
|
||||
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,229 +1,57 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/go-kratos/kratos/v2/errors"
|
||||
"context"
|
||||
"github.com/go-kratos/kratos/v2/log"
|
||||
"github.com/go-kratos/kratos/v2/transport/http"
|
||||
"io"
|
||||
err2 "voucher/api/err"
|
||||
"github.com/robfig/cron"
|
||||
v1 "voucher/api/v1"
|
||||
"voucher/internal/biz"
|
||||
"voucher/internal/biz/bo"
|
||||
"voucher/internal/biz/mixrepos"
|
||||
"voucher/internal/biz/vo"
|
||||
"voucher/internal/biz/wechatrepo"
|
||||
"voucher/internal/conf"
|
||||
)
|
||||
|
||||
func (s *VoucherService) buildCmbRequest(bodyBytes []byte) (*v1.CmbRequest, error) {
|
||||
var _ v1.CmbHTTPServer = (*CmbService)(nil)
|
||||
|
||||
var req *v1.CmbRequest
|
||||
if err := json.Unmarshal(bodyBytes, &req); err != nil {
|
||||
return nil, err2.ErrorCmbParamFail(err.Error())
|
||||
}
|
||||
|
||||
if err := req.Validate(); err != nil {
|
||||
return nil, err2.ErrorCmbParamFail(err.Error())
|
||||
}
|
||||
|
||||
return req, nil
|
||||
type CmbService struct {
|
||||
bc *conf.Bootstrap
|
||||
cron *cron.Cron
|
||||
VoucherBiz *biz.VoucherBiz
|
||||
CmbMixRepo mixrepos.CmbMixRepo
|
||||
WechatCpnRepo wechatrepo.WechatCpnRepo
|
||||
}
|
||||
|
||||
func (s *VoucherService) CmbOrder(ctx http.Context) error {
|
||||
|
||||
var (
|
||||
reply *v1.CmbReply
|
||||
|
||||
bizReply *v1.CmbOrderReply
|
||||
)
|
||||
|
||||
orderNo, err := s.cmbOrder(ctx)
|
||||
|
||||
if err != nil {
|
||||
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,
|
||||
}
|
||||
|
||||
log.Errorf("cmbOrder: %v", err)
|
||||
} else {
|
||||
bizReply = &v1.CmbOrderReply{
|
||||
RespCode: vo.CmbResponseStatusSuccess.GetValue(),
|
||||
RespMsg: "成功",
|
||||
CodeNo: orderNo,
|
||||
}
|
||||
func NewCmbService(
|
||||
bc *conf.Bootstrap,
|
||||
cron *cron.Cron,
|
||||
VoucherBiz *biz.VoucherBiz,
|
||||
CmbMixRepo mixrepos.CmbMixRepo,
|
||||
WechatCpnRepo wechatrepo.WechatCpnRepo,
|
||||
) *CmbService {
|
||||
return &CmbService{
|
||||
bc: bc,
|
||||
cron: cron,
|
||||
VoucherBiz: VoucherBiz,
|
||||
CmbMixRepo: CmbMixRepo,
|
||||
WechatCpnRepo: WechatCpnRepo,
|
||||
}
|
||||
}
|
||||
|
||||
replyBizContent, _ := json.Marshal(bizReply)
|
||||
xx := &bo.CmbResponseBo{
|
||||
func (c *CmbService) GetResponse(ctx context.Context, replyBizContent []byte) (*v1.CmbReply, error) {
|
||||
|
||||
req := &bo.CmbResponseBo{
|
||||
RespCode: vo.CmbResponseStatusSuccess.GetValue(),
|
||||
RespMsg: "成功",
|
||||
BizContent: string(replyBizContent),
|
||||
}
|
||||
|
||||
reply, err = s.CmbMixRepo.GetResponse(ctx, xx)
|
||||
if err != nil {
|
||||
log.Errorf("CmbOrder GetResponse: %v", err)
|
||||
return ctx.JSON(400, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(200, reply)
|
||||
}
|
||||
|
||||
func (v *VoucherService) cmbOrder(ctx http.Context) (string, error) {
|
||||
|
||||
bodyBytes, err := io.ReadAll(ctx.Request().Body)
|
||||
if err != nil {
|
||||
return "", err2.ErrorCmbParamFail(err.Error())
|
||||
}
|
||||
|
||||
req, err := v.buildCmbRequest(bodyBytes)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
bizContent, err := v.CmbMixRepo.OrderVerify(ctx, req)
|
||||
if err != nil {
|
||||
log.Errorf("cmbOrder body: %s", string(bodyBytes))
|
||||
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: v.bc.Cmb.NotifyUrl,
|
||||
}
|
||||
|
||||
orderNo, err := v.VoucherBiz.CmbOrder(ctx, boReq)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return orderNo, nil
|
||||
}
|
||||
|
||||
func (s *VoucherService) CmbProductQuery(ctx http.Context) error {
|
||||
|
||||
var (
|
||||
reply *v1.CmbReply
|
||||
|
||||
bizReply *v1.CmbQueryProductReply
|
||||
)
|
||||
|
||||
bizReply, err := s.cmbProductQuery(ctx)
|
||||
if err != nil {
|
||||
se := errors.FromError(err)
|
||||
|
||||
if len(se.Reason) == 0 {
|
||||
se.Reason = err2.CmbErr_CMB_UNKNOWN.String()
|
||||
}
|
||||
|
||||
bizReply = &v1.CmbQueryProductReply{
|
||||
RespCode: vo.CmbResponseStatusFail.GetValue(),
|
||||
RespMsg: se.Message,
|
||||
ThirdErrCode: se.Reason,
|
||||
}
|
||||
|
||||
log.Errorf("cmbProductQuery: %v", err)
|
||||
}
|
||||
|
||||
replyBizContent, _ := json.Marshal(bizReply)
|
||||
xx := &bo.CmbResponseBo{
|
||||
RespCode: vo.CmbResponseStatusSuccess.GetValue(),
|
||||
RespMsg: "成功",
|
||||
BizContent: string(replyBizContent),
|
||||
}
|
||||
|
||||
reply, err = s.CmbMixRepo.GetResponse(ctx, xx)
|
||||
if err != nil {
|
||||
log.Errorf("cmbProductQuery GetResponse: %v", err)
|
||||
return ctx.JSON(400, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(200, reply)
|
||||
}
|
||||
|
||||
func (v *VoucherService) cmbProductQuery(ctx http.Context) (*v1.CmbQueryProductReply, error) {
|
||||
|
||||
bodyBytes, err := io.ReadAll(ctx.Request().Body)
|
||||
if err != nil {
|
||||
return nil, err2.ErrorCmbParamFail(err.Error())
|
||||
}
|
||||
|
||||
req, err := v.buildCmbRequest(bodyBytes)
|
||||
reply, err := c.CmbMixRepo.GetResponse(ctx, req)
|
||||
if err != nil {
|
||||
log.Errorf("build cmb response fail: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bizContent, err := v.CmbMixRepo.ProductQueryVerify(ctx, req)
|
||||
if err != nil {
|
||||
log.Errorf("cmbProductQuery body: %s", string(bodyBytes))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return v.VoucherBiz.CmbProductQuery(ctx, bizContent.ActivityId)
|
||||
}
|
||||
|
||||
func (s *VoucherService) CmbQuery(ctx http.Context) error {
|
||||
|
||||
var (
|
||||
reply *v1.CmbReply
|
||||
|
||||
req = &bo.CmbResponseBo{}
|
||||
)
|
||||
|
||||
bizReply, err := s.cmbQuery(ctx)
|
||||
if err != nil {
|
||||
|
||||
req.RespCode = vo.CmbResponseStatusFail.GetValue()
|
||||
req.RespMsg = err.Error()
|
||||
req.BizContent = ""
|
||||
|
||||
log.Errorf("CmbQuery: %v", err)
|
||||
} else {
|
||||
|
||||
replyBizContentBytes, _ := json.Marshal(bizReply)
|
||||
|
||||
req.RespCode = vo.CmbResponseStatusSuccess.GetValue()
|
||||
req.RespMsg = "成功"
|
||||
req.BizContent = string(replyBizContentBytes)
|
||||
}
|
||||
|
||||
reply, err = s.CmbMixRepo.GetResponse(ctx, req)
|
||||
if err != nil {
|
||||
log.Errorf("cmbProductQuery GetResponse: %v", err)
|
||||
return ctx.JSON(400, err)
|
||||
}
|
||||
|
||||
return ctx.JSON(200, reply)
|
||||
}
|
||||
|
||||
func (v *VoucherService) cmbQuery(ctx http.Context) (*v1.CmbQueryReply, error) {
|
||||
|
||||
bodyBytes, err := io.ReadAll(ctx.Request().Body)
|
||||
if err != nil {
|
||||
return nil, err2.ErrorCmbParamFail(err.Error())
|
||||
}
|
||||
|
||||
req, err := v.buildCmbRequest(bodyBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bizContent, err := v.CmbMixRepo.QueryVerify(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return v.VoucherBiz.CmbQuery(ctx, bizContent.CodeNo)
|
||||
return reply, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,162 +1,64 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/go-kratos/kratos/v2/transport/http"
|
||||
"io"
|
||||
v1 "voucher/api/v1"
|
||||
)
|
||||
|
||||
func (s *VoucherService) CmbOrderMock(ctx http.Context) error {
|
||||
func (s *CmbService) OrderMock(ctx context.Context, request *v1.CmbOrderRequest) (*v1.CmbRequest, error) {
|
||||
|
||||
bodyBytes, err := io.ReadAll(ctx.Request().Body)
|
||||
bizJsonBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req *v1.CmbOrderRequest
|
||||
|
||||
if err = json.Unmarshal(bodyBytes, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bizJsonBytes, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reply, err := s.CmbMixRepo.GetMockRequest(ctx, string(bizJsonBytes))
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ctx.JSON(200, reply)
|
||||
return reply, nil
|
||||
}
|
||||
|
||||
func (s *VoucherService) CmbQueryMock(ctx http.Context) error {
|
||||
func (s *CmbService) QueryMock(ctx context.Context, request *v1.CmbQueryRequest) (*v1.CmbRequest, error) {
|
||||
|
||||
bodyBytes, err := io.ReadAll(ctx.Request().Body)
|
||||
bizJsonBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req *v1.CmbQueryRequest
|
||||
if err = json.Unmarshal(bodyBytes, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bizJsonBytes, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reply, err := s.CmbMixRepo.GetMockRequest(ctx, string(bizJsonBytes))
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ctx.JSON(200, reply)
|
||||
return reply, nil
|
||||
}
|
||||
|
||||
func (s *VoucherService) CmbProductQueryMock(ctx http.Context) error {
|
||||
func (s *CmbService) QueryProductMock(ctx context.Context, request *v1.CmbQueryProductRequest) (*v1.CmbRequest, error) {
|
||||
|
||||
bodyBytes, err := io.ReadAll(ctx.Request().Body)
|
||||
bizJsonBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req *v1.CmbQueryProductRequest
|
||||
if err = json.Unmarshal(bodyBytes, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bizJsonBytes, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reply, err := s.CmbMixRepo.GetMockRequest(ctx, string(bizJsonBytes))
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ctx.JSON(200, reply)
|
||||
return reply, nil
|
||||
}
|
||||
|
||||
func (s *VoucherService) DecryptBody(ctx http.Context) error {
|
||||
func (s *CmbService) DecryptBody(ctx context.Context, request *v1.EncryptBodyRequest) (*v1.DecryptBodyReply, error) {
|
||||
|
||||
bodyBytes, err := io.ReadAll(ctx.Request().Body)
|
||||
decryptBody, err := s.CmbMixRepo.Decrypt(ctx, request.EncryptBody)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var req *v1.EncryptBody
|
||||
if err = json.Unmarshal(bodyBytes, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
decryptBody, err := s.CmbMixRepo.Decrypt(ctx, req.EncryptBody)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ctx.JSON(200, &v1.DecryptBody{
|
||||
return &v1.DecryptBodyReply{
|
||||
DecryptBody: decryptBody,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *VoucherService) QueryWechatVoucherNotifyUrl(ctx http.Context) error {
|
||||
|
||||
bodyBytes, err := io.ReadAll(ctx.Request().Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req *v1.QueryWechatVoucherNotifyUrlRequest
|
||||
if err = json.Unmarshal(bodyBytes, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rep, err := s.VoucherBiz.WechatCpnRepo.QueryCallback(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ctx.JSON(200, &v1.QueryWechatVoucherNotifyUrlReply{
|
||||
Url: *rep.NotifyUrl,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *VoucherService) SetWechatVoucherNotifyUrl(ctx http.Context) error {
|
||||
|
||||
//bodyBytes, err := io.ReadAll(ctx.Request().Body)
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
//var req *v1.SetWechatVoucherNotifyUrlRequest
|
||||
//if err = json.Unmarshal(bodyBytes, &req); err != nil {
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
//rep, err := s.VoucherBiz.WechatCpnRepo.SetCallback(ctx, req.MchId, req.MchCertNo, req.Url)
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
//return ctx.JSON(200, &v1.SetWechatVoucherNotifyUrlReply{
|
||||
// MchId: req.MchId,
|
||||
// Url: *rep.NotifyUrl,
|
||||
//})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *VoucherService) Test(ctx http.Context) error {
|
||||
|
||||
if err := s.VoucherBiz.ExecuteNotice(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
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) 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)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/go-kratos/kratos/v2/errors"
|
||||
err2 "voucher/api/err"
|
||||
v1 "voucher/api/v1"
|
||||
"voucher/internal/biz/vo"
|
||||
)
|
||||
|
||||
func (c *CmbService) QueryProductsuccess(ctx context.Context, bizReply *v1.CmbQueryProductReply) (*v1.CmbReply, error) {
|
||||
|
||||
replyBizContent, _ := json.Marshal(bizReply)
|
||||
|
||||
return c.GetResponse(ctx, replyBizContent)
|
||||
}
|
||||
|
||||
func (c *CmbService) QueryProductFail(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.CmbQueryProductReply{
|
||||
RespCode: vo.CmbResponseStatusFail.GetValue(),
|
||||
RespMsg: se.Message,
|
||||
ThirdErrCode: se.Reason,
|
||||
}
|
||||
|
||||
replyBizContent, _ := json.Marshal(bizReply)
|
||||
|
||||
return c.GetResponse(ctx, replyBizContent)
|
||||
}
|
||||
|
||||
func (c *CmbService) QueryProduct(ctx context.Context, request *v1.CmbRequest) (*v1.CmbReply, error) {
|
||||
|
||||
bizReply, err := c.qaueryProduct(ctx, request)
|
||||
if err != nil {
|
||||
return c.QueryProductFail(ctx, err)
|
||||
}
|
||||
|
||||
return c.QueryProductsuccess(ctx, bizReply)
|
||||
}
|
||||
|
||||
func (c *CmbService) qaueryProduct(ctx context.Context, request *v1.CmbRequest) (*v1.CmbQueryProductReply, error) {
|
||||
|
||||
bizContent, err := c.CmbMixRepo.ProductQueryVerify(ctx, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c.VoucherBiz.CmbProductQuery(ctx, bizContent.ActivityId)
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/go-kratos/kratos/v2/errors"
|
||||
err2 "voucher/api/err"
|
||||
v1 "voucher/api/v1"
|
||||
)
|
||||
|
||||
func (c *CmbService) QuerySuccess(ctx context.Context, bizReply *v1.CmbQueryReply) (*v1.CmbReply, error) {
|
||||
|
||||
replyBizContent, _ := json.Marshal(bizReply)
|
||||
|
||||
return c.GetResponse(ctx, replyBizContent)
|
||||
}
|
||||
|
||||
func (c *CmbService) QueryFail(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.CmbQueryReply{}
|
||||
|
||||
replyBizContent, _ := json.Marshal(bizReply)
|
||||
|
||||
return c.GetResponse(ctx, replyBizContent)
|
||||
}
|
||||
|
||||
func (c *CmbService) Query(ctx context.Context, request *v1.CmbRequest) (*v1.CmbReply, error) {
|
||||
|
||||
orderNo, err := c.query(ctx, request)
|
||||
|
||||
if err != nil {
|
||||
return c.QueryFail(ctx, err)
|
||||
}
|
||||
|
||||
return c.QuerySuccess(ctx, orderNo)
|
||||
}
|
||||
|
||||
func (c *CmbService) query(ctx context.Context, request *v1.CmbRequest) (*v1.CmbQueryReply, error) {
|
||||
|
||||
bizContent, err := c.CmbMixRepo.QueryVerify(ctx, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c.VoucherBiz.CmbQuery(ctx, bizContent.CodeNo)
|
||||
}
|
||||
|
|
@ -7,4 +7,5 @@ import (
|
|||
// ProviderSetService is service providers.
|
||||
var ProviderSetService = wire.NewSet(
|
||||
NewVoucherService,
|
||||
NewCmbService,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,33 +1,35 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"github.com/go-kratos/kratos/v2/transport/http"
|
||||
"github.com/robfig/cron"
|
||||
"voucher/internal/biz"
|
||||
"voucher/internal/biz/mixrepos"
|
||||
"voucher/internal/biz/wechatrepo"
|
||||
"voucher/internal/conf"
|
||||
)
|
||||
|
||||
type VoucherService struct {
|
||||
bc *conf.Bootstrap
|
||||
cron *cron.Cron
|
||||
VoucherBiz *biz.VoucherBiz
|
||||
CmbMixRepo mixrepos.CmbMixRepo
|
||||
WechatCpnRepo wechatrepo.WechatCpnRepo
|
||||
bc *conf.Bootstrap
|
||||
cron *cron.Cron
|
||||
VoucherBiz *biz.VoucherBiz
|
||||
}
|
||||
|
||||
func NewVoucherService(
|
||||
bc *conf.Bootstrap,
|
||||
cron *cron.Cron,
|
||||
VoucherBiz *biz.VoucherBiz,
|
||||
CmbMixRepo mixrepos.CmbMixRepo,
|
||||
WechatCpnRepo wechatrepo.WechatCpnRepo,
|
||||
) *VoucherService {
|
||||
return &VoucherService{
|
||||
bc: bc,
|
||||
cron: cron,
|
||||
VoucherBiz: VoucherBiz,
|
||||
CmbMixRepo: CmbMixRepo,
|
||||
WechatCpnRepo: WechatCpnRepo,
|
||||
bc: bc,
|
||||
cron: cron,
|
||||
VoucherBiz: VoucherBiz,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *VoucherService) Test(ctx http.Context) error {
|
||||
|
||||
if err := s.VoucherBiz.ExecuteNotice(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,243 @@
|
|||
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: ""
|
||||
title: Cmb API
|
||||
version: 0.0.1
|
||||
paths: {}
|
||||
paths:
|
||||
/voucher/cmb/v1/decryptBody:
|
||||
post:
|
||||
tags:
|
||||
- Cmb
|
||||
operationId: Cmb_DecryptBody
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/api.v1.EncryptBodyRequest'
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/api.v1.DecryptBodyReply'
|
||||
/voucher/cmb/v1/order:
|
||||
post:
|
||||
tags:
|
||||
- Cmb
|
||||
operationId: Cmb_Order
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/api.v1.CmbRequest'
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/api.v1.CmbReply'
|
||||
/voucher/cmb/v1/orderMock:
|
||||
post:
|
||||
tags:
|
||||
- Cmb
|
||||
operationId: Cmb_OrderMock
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/api.v1.CmbOrderRequest'
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/api.v1.CmbRequest'
|
||||
/voucher/cmb/v1/product/query:
|
||||
post:
|
||||
tags:
|
||||
- Cmb
|
||||
operationId: Cmb_QueryProduct
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/api.v1.CmbRequest'
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/api.v1.CmbReply'
|
||||
/voucher/cmb/v1/product/queryMock:
|
||||
post:
|
||||
tags:
|
||||
- Cmb
|
||||
operationId: Cmb_QueryProductMock
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/api.v1.CmbQueryProductRequest'
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/api.v1.CmbRequest'
|
||||
/voucher/cmb/v1/query:
|
||||
post:
|
||||
tags:
|
||||
- Cmb
|
||||
operationId: Cmb_Query
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/api.v1.CmbRequest'
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/api.v1.CmbReply'
|
||||
/voucher/cmb/v1/queryMock:
|
||||
post:
|
||||
tags:
|
||||
- Cmb
|
||||
operationId: Cmb_QueryMock
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/api.v1.CmbQueryRequest'
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/api.v1.CmbRequest'
|
||||
components:
|
||||
schemas: {}
|
||||
schemas:
|
||||
api.v1.CmbOrderRequest:
|
||||
type: object
|
||||
properties:
|
||||
transactionId:
|
||||
type: string
|
||||
description: |-
|
||||
业务参数
|
||||
唯一流水号,需支持14天内幂等
|
||||
activityId:
|
||||
type: string
|
||||
description: 外部合作方权益批次号
|
||||
cmbUid:
|
||||
type: string
|
||||
description: 招商银行用户号 用户标识,比如手机号、支付宝openId
|
||||
appId:
|
||||
type: string
|
||||
description: 应用id
|
||||
cmbUidType:
|
||||
type: string
|
||||
description: 用户标识类型,0-手机号,1-支付宝openId
|
||||
timestamp:
|
||||
type: string
|
||||
description: 时间戳,长度为13位,精度为毫秒
|
||||
attach:
|
||||
type: string
|
||||
description: 拓展参数
|
||||
api.v1.CmbQueryProductRequest:
|
||||
type: object
|
||||
properties:
|
||||
activityId:
|
||||
type: string
|
||||
description: |-
|
||||
业务参数
|
||||
外部合作方权益批次号
|
||||
api.v1.CmbQueryRequest:
|
||||
type: object
|
||||
properties:
|
||||
codeNo:
|
||||
type: string
|
||||
description: |-
|
||||
业务参数
|
||||
外部合作方权益批次号
|
||||
api.v1.CmbReply:
|
||||
type: object
|
||||
properties:
|
||||
respCode:
|
||||
type: string
|
||||
description: |-
|
||||
响应公共参数
|
||||
接口调用返回码,1000 成功,1001 失败
|
||||
respMsg:
|
||||
type: string
|
||||
description: 返回话术,失败信息落此字段
|
||||
date:
|
||||
type: string
|
||||
description: 时间戳 yyyyMMddHHmmss
|
||||
keyAlias:
|
||||
type: string
|
||||
description: 合作方密钥对别名
|
||||
cmbKeyAlias:
|
||||
type: string
|
||||
description: 掌上生活密钥对别名
|
||||
encryptBody:
|
||||
type: string
|
||||
description: 加密报文,是否需要加密,请查看各API的说明文档
|
||||
sign:
|
||||
type: string
|
||||
description: 签名,具体详见签名规范
|
||||
api.v1.CmbRequest:
|
||||
type: object
|
||||
properties:
|
||||
mid:
|
||||
type: string
|
||||
description: |-
|
||||
请求公共参数
|
||||
合作方唯一ID,32位定长
|
||||
aid:
|
||||
type: string
|
||||
description: 应用唯一ID,32位定长
|
||||
date:
|
||||
type: string
|
||||
description: 时间戳 yyyyMMddHHmmss
|
||||
random:
|
||||
type: string
|
||||
description: 随机字符串,保证签名不可预测,不长于32位
|
||||
keyAlias:
|
||||
type: string
|
||||
description: 合作方密钥对别名
|
||||
cmbKeyAlias:
|
||||
type: string
|
||||
description: 掌上生活密钥对别名
|
||||
encryptBody:
|
||||
type: string
|
||||
description: 加密报文,是否需要加密,请查看各API的说明文档
|
||||
sign:
|
||||
type: string
|
||||
description: 签名,具体详见签名规范
|
||||
api.v1.DecryptBodyReply:
|
||||
type: object
|
||||
properties:
|
||||
decryptBody:
|
||||
type: string
|
||||
api.v1.EncryptBodyRequest:
|
||||
type: object
|
||||
properties:
|
||||
encryptBody:
|
||||
type: string
|
||||
tags:
|
||||
- name: Cmb
|
||||
|
|
|
|||
Loading…
Reference in New Issue