This commit is contained in:
李子铭 2025-03-03 18:03:19 +08:00
parent 505d744bf5
commit b62bf1c793
22 changed files with 282 additions and 172 deletions

View File

@ -1,47 +0,0 @@
syntax = "proto3";
package api.v1;
option go_package = "voucher/api/v1;v1";
//
message Empty {}
//
message ReqEmpty {}
//
message RespEmpty {}
//
message RespOption {
//
string label = 1;
//
string value = 2;
//
bool select = 3;
//
bool disable = 4;
//
repeated RespOption children = 5;
}
//
message RespOptions {
//
repeated RespOption list = 1;
}
// ReqPage
message RespPage {
//
int32 page = 1;
//
int32 limit = 2;
//
int32 total = 3;
}

View File

@ -3,38 +3,34 @@ syntax = "proto3";
package api.v1; package api.v1;
option go_package = "voucher/api/v1;v1"; option go_package = "voucher/api/v1;v1";
import "google/api/annotations.proto";
import "validate/validate.proto"; import "validate/validate.proto";
import "v1/common.proto";
service Order {
rpc Order (OrderRequest) returns (OrderReply) {
option (google.api.http) = {
post: "/openapi/v1/voucher/order",
body:"*"
};
}
rpc Query (QueryRequest) returns (QueryReply) {
option (google.api.http) = {
post: "/openapi/v1/voucher/query",
body:"*"
};
}
message OrderCmbRequest {
// 14
string transactionId = 1 [json_name = "transactionId", (validate.rules).string = {min_len: 1,max_len: 50}];
//
string activityId = 2 [json_name = "activityId", (validate.rules).string = {min_len: 1,max_len: 32}];
// openId
string cmbUid = 3 [json_name = "cmbUid", (validate.rules).string = {min_len: 1,max_len: 100}];
// 0-1-openId
string cmbUidType = 4 [json_name = "cmbUidType", (validate.rules).string = {min_len: 1,max_len: 10}];
// 13
string timestamp = 5 [json_name = "timestamp", (validate.rules).string = {min_len: 1,max_len: 20}];
} }
message OrderCmbReply {
message OrderRequest { // 1000 1001
string respCode = 1 [json_name = "respCode"];
} //
message OrderReply { string respMsg = 2 [json_name = "respMsg"];
// 50
string codeNo = 3 [json_name = "codeNo"];
} }
message QueryRequest { message QueryCmbRequest {
} }
message QueryReply { message QueryCmbReply {
} }

View File

@ -13,7 +13,7 @@ import (
"voucher/internal/conf" "voucher/internal/conf"
"voucher/internal/data" "voucher/internal/data"
"voucher/internal/data/repositoryimpl" "voucher/internal/data/repositoryimpl"
"voucher/internal/data/thirdrepositoryimpl" "voucher/internal/data/thirdrepoimpl"
log2 "voucher/internal/pkg/log" log2 "voucher/internal/pkg/log"
"voucher/internal/server" "voucher/internal/server"
"voucher/internal/service" "voucher/internal/service"
@ -26,7 +26,7 @@ func wireApp(*conf.Bootstrap, log.Logger, *log2.AccessLogger) (*kratos.App, func
service.ProviderSetService, service.ProviderSetService,
biz.ProviderSetBiz, biz.ProviderSetBiz,
repositoryimpl.ProviderRepoImplSet, repositoryimpl.ProviderRepoImplSet,
thirdrepositoryimpl.ProviderThirdRepositoryImplSet, thirdrepoimpl.ProviderThirdRepositoryImplSet,
data.ProviderDataSet, data.ProviderDataSet,
log2.NewLogHelper, log2.NewLogHelper,
newApp, newApp,

View File

@ -13,7 +13,7 @@ import (
"voucher/internal/conf" "voucher/internal/conf"
"voucher/internal/data" "voucher/internal/data"
"voucher/internal/data/repositoryimpl" "voucher/internal/data/repositoryimpl"
"voucher/internal/data/thirdrepositoryimpl" "voucher/internal/data/thirdrepoimpl"
log2 "voucher/internal/pkg/log" log2 "voucher/internal/pkg/log"
"voucher/internal/server" "voucher/internal/server"
"voucher/internal/service" "voucher/internal/service"
@ -36,7 +36,7 @@ func wireApp(bootstrap *conf.Bootstrap, logger log.Logger, accessLogger *log2.Ac
cleanup() cleanup()
return nil, nil, err return nil, nil, err
} }
thirdMQSend := thirdrepositoryimpl.NewMQSendImpl(rocketMQ) thirdMQSend := thirdrepoimpl.NewMQSendImpl(rocketMQ)
voucherBiz := biz.NewVoucherBiz(orderRepo, thirdMQSend) voucherBiz := biz.NewVoucherBiz(orderRepo, thirdMQSend)
voucherService := service.NewVoucherService(voucherBiz) voucherService := service.NewVoucherService(voucherBiz)
httpServer := server.NewHTTPServer(bootstrap, helper, accessLogger, voucherService) httpServer := server.NewHTTPServer(bootstrap, helper, accessLogger, voucherService)

View File

@ -1,18 +1,34 @@
package bo package bo
import "time" import (
"time"
"voucher/internal/biz/vo"
)
// OrderBo 领域实体Bo结构字段和模型字段保持一致 // OrderBo 领域实体Bo结构字段和模型字段保持一致
type OrderBo struct { type OrderBo struct {
ID int32 ID uint64
OrderNo string OrderNo string
OutBizNo string OutBizNo string
ProductNo string ProductNo string
Account string Account string
AccountType bool AccountType vo.OrderAccountType
Status bool Status vo.OrderStatus
AppID string AppID string
MerchantNo string MerchantNo string
Channel bool Channel vo.OrderChannel
CreateTime time.Time CreateTime *time.Time
UpdateTime *time.Time
}
type OrderCreateReqBo struct {
OutBizNo string
ProductNo string
Account string
AccountType vo.OrderAccountType
Channel vo.OrderChannel
}
type OrderCreateRepBo struct {
OrderNo string
} }

19
internal/biz/cmb.go Normal file
View File

@ -0,0 +1,19 @@
package biz
import (
"context"
"fmt"
"time"
"voucher/internal/biz/bo"
"voucher/internal/pkg/lock"
)
func (v *VoucherBiz) CmbOrder(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 {
return nil
})
return
}

View File

@ -6,8 +6,8 @@ import (
) )
type OrderRepo interface { type OrderRepo interface {
// Create 创建 Order // Create 创建 CmbOrder
Create(ctx context.Context, req *bo.OrderBo) (*bo.OrderBo, error) Create(ctx context.Context, req *bo.OrderBo) (*bo.OrderBo, error)
// GetByID 根据 ID 获取 Order // GetByID 根据 ID 获取 CmbOrder
GetByID(ctx context.Context, id int32) (*bo.OrderBo, error) GetByID(ctx context.Context, id int32) (*bo.OrderBo, error)
} }

View File

@ -1,4 +0,0 @@
package repository
type OrderRepo interface {
}

View File

@ -1,4 +1,4 @@
package thirdrepository package thirdrepo
import ( import (
"context" "context"

View File

@ -0,0 +1,32 @@
package vo
type OrderAccountType uint8
const (
OrderAccountTypeOpenId OrderAccountType = iota + 1
OrderAccountTypePhone
)
var OrderAccountTypeMap = map[OrderAccountType]string{
OrderAccountTypeOpenId: "openid/userid",
OrderAccountTypePhone: "手机号",
}
func (s OrderAccountType) GetText() string {
if t, ok := OrderAccountTypeMap[s]; ok {
return t
}
return ""
}
func (s OrderAccountType) GetValue() uint8 {
return uint8(s)
}
func (s OrderAccountType) IsOpenId() bool {
return s == OrderAccountTypeOpenId
}
func (s OrderAccountType) IsPhone() bool {
return s == OrderAccountTypePhone
}

View File

@ -0,0 +1,32 @@
package vo
type OrderChannel uint8
const (
OrderChannelWechat OrderChannel = iota + 1
OrderChannelAlipay
)
var OrderChannelMap = map[OrderChannel]string{
OrderChannelWechat: "微信",
OrderChannelAlipay: "支付宝",
}
func (s OrderChannel) GetText() string {
if t, ok := OrderChannelMap[s]; ok {
return t
}
return ""
}
func (s OrderChannel) GetValue() uint8 {
return uint8(s)
}
func (s OrderChannel) IsWeChat() bool {
return s == OrderChannelWechat
}
func (s OrderChannel) IsAlipay() bool {
return s == OrderChannelAlipay
}

View File

@ -1 +1,44 @@
package vo package vo
type OrderStatus uint8
const (
OrderStatusWait OrderStatus = iota + 1
OrderStatusIng
OrderStatusSuccess
OrderStatusFail
)
var OrderStatusMap = map[OrderStatus]string{
OrderStatusWait: "待发放",
OrderStatusIng: "发放中",
OrderStatusSuccess: "发放成功",
OrderStatusFail: "发放失败",
}
func (s OrderStatus) GetText() string {
if t, ok := OrderStatusMap[s]; ok {
return t
}
return ""
}
func (s OrderStatus) GetValue() uint8 {
return uint8(s)
}
func (s OrderStatus) IsWait() bool {
return s == OrderStatusWait
}
func (s OrderStatus) IsIng() bool {
return s == OrderStatusIng
}
func (s OrderStatus) IsSuccess() bool {
return s == OrderStatusSuccess
}
func (s OrderStatus) IsFail() bool {
return s == OrderStatusFail
}

View File

@ -1,17 +1,17 @@
package biz package biz
import ( import (
"voucher/internal/biz/repository" "voucher/internal/biz/repo"
"voucher/internal/biz/thirdrepository" "voucher/internal/biz/thirdrepo"
"voucher/internal/data"
) )
type VoucherBiz struct { type VoucherBiz struct {
OrderRepo repository.OrderRepo rdb *data.Rdb
ThirdMQSend thirdrepository.ThirdMQSend OrderRepo repo.OrderRepo
ThirdMQSend thirdrepo.ThirdMQSend
} }
func NewVoucherBiz(orderRepo repository.OrderRepo, thirdMQSend thirdrepository.ThirdMQSend) *VoucherBiz { func NewVoucherBiz(rdb *data.Rdb, orderRepo repo.OrderRepo, thirdMQSend thirdrepo.ThirdMQSend) *VoucherBiz {
return &VoucherBiz{OrderRepo: orderRepo, ThirdMQSend: thirdMQSend} return &VoucherBiz{rdb: rdb, OrderRepo: orderRepo, ThirdMQSend: thirdMQSend}
} }
// 1:收单

View File

@ -12,7 +12,7 @@ const TableNameOrder = "order"
// Order mapped from table <order> // Order mapped from table <order>
type Order struct { type Order struct {
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` ID uint64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"`
OrderNo string `gorm:"column:order_no;not null" json:"order_no"` OrderNo string `gorm:"column:order_no;not null" json:"order_no"`
OutBizNo string `gorm:"column:out_biz_no;not null;comment:外部交易号" json:"out_biz_no"` // 外部交易号 OutBizNo string `gorm:"column:out_biz_no;not null;comment:外部交易号" json:"out_biz_no"` // 外部交易号
ProductNo string `gorm:"column:product_no;not null;comment:商品编号" json:"product_no"` // 商品编号 ProductNo string `gorm:"column:product_no;not null;comment:商品编号" json:"product_no"` // 商品编号
@ -23,6 +23,7 @@ type Order struct {
MerchantNo string `gorm:"column:merchant_no;not null;comment:创建批次号的商户号" json:"merchant_no"` // 创建批次号的商户号 MerchantNo string `gorm:"column:merchant_no;not null;comment:创建批次号的商户号" json:"merchant_no"` // 创建批次号的商户号
Channel uint8 `gorm:"column:channel;not null;comment:1:微信 2:支付宝" json:"channel"` // 1:微信 2:支付宝 Channel uint8 `gorm:"column:channel;not null;comment:1:微信 2:支付宝" json:"channel"` // 1:微信 2:支付宝
CreateTime *time.Time `gorm:"column:create_time" json:"create_time"` CreateTime *time.Time `gorm:"column:create_time" json:"create_time"`
UpdateTime *time.Time `gorm:"column:update_time" json:"update_time"`
} }
// TableName Order's table name // TableName Order's table name

View File

@ -7,7 +7,7 @@ import (
"voucher/internal/data/model" "voucher/internal/data/model"
) )
// OrderRepoImpl 定义了针对 Order 表的 CRUD 操作 // OrderRepoImpl 定义了针对 CmbOrder 表的 CRUD 操作
type OrderRepoImpl struct { type OrderRepoImpl struct {
Base[model.Order, bo.OrderBo] Base[model.Order, bo.OrderBo]
} }
@ -22,7 +22,7 @@ func (r *OrderRepoImpl) Create(ctx context.Context, req *bo.OrderBo) (*bo.OrderB
return nil, nil return nil, nil
} }
// GetByID 根据 ID 获取 Order // GetByID 根据 ID 获取 CmbOrder
func (r *OrderRepoImpl) GetByID(ctx context.Context, id int32) (*bo.OrderBo, error) { func (r *OrderRepoImpl) GetByID(ctx context.Context, id int32) (*bo.OrderBo, error) {
var item model.Order var item model.Order
// todo 待实现 // todo 待实现

View File

@ -1,9 +1,9 @@
package thirdrepositoryimpl package thirdrepoimpl
import ( import (
"context" "context"
"github.com/go-kratos/kratos/v2/log" "github.com/go-kratos/kratos/v2/log"
"voucher/internal/biz/thirdrepository" "voucher/internal/biz/thirdrepo"
"voucher/internal/data" "voucher/internal/data"
"voucher/internal/pkg/mq" "voucher/internal/pkg/mq"
) )
@ -12,7 +12,7 @@ type ThirdMQSendImpl struct {
mq *data.RocketMQ mq *data.RocketMQ
} }
func NewMQSendImpl(mq *data.RocketMQ) thirdrepository.ThirdMQSend { func NewMQSendImpl(mq *data.RocketMQ) thirdrepo.ThirdMQSend {
return &ThirdMQSendImpl{ return &ThirdMQSendImpl{
mq: mq, mq: mq,
} }

View File

@ -1,4 +1,4 @@
package thirdrepositoryimpl package thirdrepoimpl
import ( import (
"github.com/google/wire" "github.com/google/wire"

View File

@ -32,8 +32,11 @@ func NewHTTPServer(
return ctx.String(http2.StatusOK, "pong") return ctx.String(http2.StatusOK, "pong")
}) })
//v1 := srv.Route("/v1") v1 := srv.Route("/voucher")
//v1.POST("/order", pluginService.Upload)
cmb := v1.Group("/cmb")
cmb.POST("/v1/order", voucherService.CmbOrder)
cmb.POST("/v1/product_query", voucherService.CmbProductQuery)
return srv return srv
} }

34
internal/service/base.go Normal file
View File

@ -0,0 +1,34 @@
package service
import (
"github.com/go-kratos/kratos/v2/transport/http"
http2 "net/http"
)
// BaseService order 公共方法
type BaseService struct {
}
type BaseResponse struct {
Code int `json:"code"`
Data interface{} `json:"data"`
Message string `json:"message"`
}
// ResponseOK 返回 json 成功
func (b *BaseService) ResponseOK(ctx http.Context, data interface{}) error {
return ctx.JSON(http2.StatusOK, &BaseResponse{
Code: http2.StatusOK,
Data: data,
Message: "",
})
}
// ResponseError 返回 json 错误
func (b *BaseService) ResponseError(ctx http.Context, error string) error {
return ctx.JSON(http2.StatusOK, &BaseResponse{
Code: 4001,
Data: nil,
Message: error,
})
}

49
internal/service/cmb.go Normal file
View File

@ -0,0 +1,49 @@
package service
import (
"github.com/go-kratos/kratos/v2/transport/http"
v1 "voucher/api/v1"
"voucher/internal/biz/bo"
"voucher/internal/biz/vo"
)
func (s *VoucherService) CmbOrder(ctx http.Context) error {
var req v1.OrderCmbRequest
if err := ctx.BindForm(&req); err != nil {
return err
}
boReq := &bo.OrderCreateReqBo{
OutBizNo: req.TransactionId,
ProductNo: req.ActivityId,
Account: req.CmbUid,
AccountType: vo.OrderAccountTypeOpenId,
Channel: vo.OrderChannelWechat,
}
boRep, err := s.VoucherBiz.CmbOrder(ctx, boReq)
if err != nil {
return err
}
rep := &v1.OrderCmbReply{
RespCode: "",
RespMsg: "",
CodeNo: boRep.OrderNo,
}
return ctx.JSON(200, rep)
}
func (s *VoucherService) CmbProductQuery(ctx http.Context) error {
var req v1.QueryCmbRequest
if err := ctx.BindForm(&req); err != nil {
return err
}
rep := &v1.QueryCmbReply{}
return ctx.JSON(200, rep)
}

View File

@ -1,13 +1,9 @@
package service package service
import ( import (
"context"
v1 "voucher/api/v1"
"voucher/internal/biz" "voucher/internal/biz"
) )
var _ v1.OrderHTTPServer = (*VoucherService)(nil)
type VoucherService struct { type VoucherService struct {
VoucherBiz *biz.VoucherBiz VoucherBiz *biz.VoucherBiz
} }
@ -15,13 +11,3 @@ type VoucherService struct {
func NewVoucherService(VoucherBiz *biz.VoucherBiz) *VoucherService { func NewVoucherService(VoucherBiz *biz.VoucherBiz) *VoucherService {
return &VoucherService{VoucherBiz: VoucherBiz} return &VoucherService{VoucherBiz: VoucherBiz}
} }
func (v VoucherService) Order(ctx context.Context, request *v1.OrderRequest) (*v1.OrderReply, error) {
//TODO implement me
panic("implement me")
}
func (v VoucherService) Query(ctx context.Context, request *v1.QueryRequest) (*v1.QueryReply, error) {
//TODO implement me
panic("implement me")
}

View File

@ -3,58 +3,8 @@
openapi: 3.0.3 openapi: 3.0.3
info: info:
title: Order API title: ""
version: 0.0.1 version: 0.0.1
paths: paths: {}
/openapi/v1/voucher/order:
post:
tags:
- Order
operationId: Order_Order
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/api.v1.OrderRequest'
required: true
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/api.v1.OrderReply'
/openapi/v1/voucher/query:
post:
tags:
- Order
operationId: Order_Query
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/api.v1.QueryRequest'
required: true
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/api.v1.QueryReply'
components: components:
schemas: schemas: {}
api.v1.OrderReply:
type: object
properties: {}
api.v1.OrderRequest:
type: object
properties: {}
api.v1.QueryReply:
type: object
properties: {}
api.v1.QueryRequest:
type: object
properties: {}
tags:
- name: Order