修复产品修改、删除
This commit is contained in:
@@ -191,6 +191,7 @@ service gateway-api {
|
||||
@handler getUserProductList
|
||||
get /userProductList (GetUserProductListReq) returns (GetUserProductListResp)
|
||||
}
|
||||
|
||||
@server (
|
||||
group: userProduct
|
||||
prefix: /api/console/user-product
|
||||
@@ -202,8 +203,8 @@ service gateway-api {
|
||||
|
||||
@handler deleteUserProduct
|
||||
delete /userProductDel/:id (DeleteUserProductReq)
|
||||
|
||||
}
|
||||
|
||||
type (
|
||||
AddWhitelistReq {
|
||||
Ip string `json:"ip"`
|
||||
@@ -250,3 +251,25 @@ service gateway-api {
|
||||
delete /delWhitelist (DeleteWhitelistReq)
|
||||
}
|
||||
|
||||
type (
|
||||
AliTopUpRequest {
|
||||
amount int64 `json:"amount"`
|
||||
}
|
||||
AliTopUpResponse {
|
||||
payUrl string `json:"payUrl"`
|
||||
}
|
||||
)
|
||||
|
||||
@server (
|
||||
group: topup
|
||||
prefix: /api/console/topupfmghnjx
|
||||
middleware: AuthInterceptor,EntAuthInterceptor
|
||||
)
|
||||
service gateway-api {
|
||||
@handler aliTopUp
|
||||
post /aliTopUp (AliTopUpRequest) returns (AliTopUpResponse)
|
||||
|
||||
@handler aliTopUpCallback
|
||||
post /aliTopUpCallback
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
auth "tianyuan-api/apps/gateway/internal/handler/auth"
|
||||
base "tianyuan-api/apps/gateway/internal/handler/base"
|
||||
product "tianyuan-api/apps/gateway/internal/handler/product"
|
||||
topup "tianyuan-api/apps/gateway/internal/handler/topup"
|
||||
user "tianyuan-api/apps/gateway/internal/handler/user"
|
||||
userProduct "tianyuan-api/apps/gateway/internal/handler/userProduct"
|
||||
whitelistr "tianyuan-api/apps/gateway/internal/handler/whitelistr"
|
||||
@@ -79,6 +80,25 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
rest.WithPrefix("/api/console/product"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.AuthInterceptor, serverCtx.EntAuthInterceptor},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/aliTopUp",
|
||||
Handler: topup.AliTopUpHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/aliTopUpCallback",
|
||||
Handler: topup.AliTopUpCallbackHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithPrefix("/api/console/topupfmghnjx"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.AuthInterceptor},
|
||||
@@ -111,6 +131,20 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.AuthInterceptor},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/userProductList",
|
||||
Handler: userProduct.GetUserProductListHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithPrefix("/api/console/user-product"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.AuthInterceptor, serverCtx.EntAuthInterceptor},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
@@ -122,11 +156,6 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
Path: "/userProductDel/:id",
|
||||
Handler: userProduct.DeleteUserProductHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/userProductList",
|
||||
Handler: userProduct.GetUserProductListHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithPrefix("/api/console/user-product"),
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package topup
|
||||
|
||||
import (
|
||||
"github.com/smartwalle/alipay/v3"
|
||||
"net/http"
|
||||
|
||||
"tianyuan-api/apps/gateway/internal/logic/topup"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
)
|
||||
|
||||
func AliTopUpCallbackHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := topup.NewAliTopUpCallbackLogic(r.Context(), svcCtx)
|
||||
err := l.AliTopUpCallback(r)
|
||||
if err != nil {
|
||||
alipay.ACKNotification(w)
|
||||
}
|
||||
}
|
||||
}
|
||||
30
apps/gateway/internal/handler/topup/alitopuphandler.go
Normal file
30
apps/gateway/internal/handler/topup/alitopuphandler.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package topup
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tianyuan-api/apps/gateway/internal/logic/topup"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
)
|
||||
|
||||
func AliTopUpHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.AliTopUpRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := topup.NewAliTopUpLogic(r.Context(), svcCtx)
|
||||
resp, err := l.AliTopUp(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
34
apps/gateway/internal/logic/topup/alitopupcallbacklogic.go
Normal file
34
apps/gateway/internal/logic/topup/alitopupcallbacklogic.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package topup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"tianyuan-api/apps/sentinel/sentinel"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
)
|
||||
|
||||
type AliTopUpCallbackLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewAliTopUpCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AliTopUpCallbackLogic {
|
||||
return &AliTopUpCallbackLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *AliTopUpCallbackLogic) AliTopUpCallback(r *http.Request) error {
|
||||
_, err := l.svcCtx.TopUpRpc.AliTopUpNotify(l.ctx, &sentinel.AliTopUpNotifyRequest{
|
||||
RawForm: r.Form.Encode(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
40
apps/gateway/internal/logic/topup/alitopuplogic.go
Normal file
40
apps/gateway/internal/logic/topup/alitopuplogic.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package topup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"tianyuan-api/apps/sentinel/sentinel"
|
||||
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type AliTopUpLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewAliTopUpLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AliTopUpLogic {
|
||||
return &AliTopUpLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *AliTopUpLogic) AliTopUp(req *types.AliTopUpRequest) (resp *types.AliTopUpResponse, err error) {
|
||||
userId, ok := l.ctx.Value("userId").(int64)
|
||||
if !ok {
|
||||
return nil, errors.New("无法获取 userId")
|
||||
}
|
||||
up, err := l.svcCtx.TopUpRpc.AliTopUp(l.ctx, &sentinel.AliTopUpRequest{UserId: userId, Amount: req.Amount})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &types.AliTopUpResponse{
|
||||
PayUrl: up.PayUrl,
|
||||
}, nil
|
||||
}
|
||||
@@ -22,6 +22,7 @@ type ServiceContext struct {
|
||||
UserProductRpc sentinel.UserProductClient
|
||||
WhitelistRpc sentinel.WhitelistClient
|
||||
SecretRpc sentinel.SecretClient
|
||||
TopUpRpc sentinel.TopUpClient
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
@@ -40,7 +41,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
userProductRpc := sentinel.NewUserProductClient(zrpc.MustNewClient(c.SentinelRpc).Conn())
|
||||
whitelistRpc := sentinel.NewWhitelistClient(zrpc.MustNewClient(c.SentinelRpc).Conn())
|
||||
secretRpc := sentinel.NewSecretClient(zrpc.MustNewClient(c.SentinelRpc).Conn())
|
||||
|
||||
topUpRpc := sentinel.NewTopUpClient(zrpc.MustNewClient(c.SentinelRpc).Conn())
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
AuthInterceptor: middleware.NewAuthInterceptorMiddleware(c).Handle,
|
||||
@@ -53,5 +54,6 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
UserProductRpc: userProductRpc,
|
||||
WhitelistRpc: whitelistRpc,
|
||||
SecretRpc: secretRpc,
|
||||
TopUpRpc: topUpRpc,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,14 @@ type AddWhitelistReq struct {
|
||||
Ip string `json:"ip"`
|
||||
}
|
||||
|
||||
type AliTopUpRequest struct {
|
||||
Amount int64 `json:"amount"`
|
||||
}
|
||||
|
||||
type AliTopUpResponse struct {
|
||||
PayUrl string `json:"payUrl"`
|
||||
}
|
||||
|
||||
type DeleteUserProductReq struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
|
||||
@@ -14,6 +14,10 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
AliTopUpNotifyRequest = sentinel.AliTopUpNotifyRequest
|
||||
AliTopUpNotifyResponse = sentinel.AliTopUpNotifyResponse
|
||||
AliTopUpRequest = sentinel.AliTopUpRequest
|
||||
AliTopUpResponse = sentinel.AliTopUpResponse
|
||||
CreateProductRequest = sentinel.CreateProductRequest
|
||||
CreateSecretRequest = sentinel.CreateSecretRequest
|
||||
CreateUserProductRequest = sentinel.CreateUserProductRequest
|
||||
|
||||
@@ -14,6 +14,10 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
AliTopUpNotifyRequest = sentinel.AliTopUpNotifyRequest
|
||||
AliTopUpNotifyResponse = sentinel.AliTopUpNotifyResponse
|
||||
AliTopUpRequest = sentinel.AliTopUpRequest
|
||||
AliTopUpResponse = sentinel.AliTopUpResponse
|
||||
CreateProductRequest = sentinel.CreateProductRequest
|
||||
CreateSecretRequest = sentinel.CreateSecretRequest
|
||||
CreateUserProductRequest = sentinel.CreateUserProductRequest
|
||||
|
||||
76
apps/sentinel/client/topup/topup.go
Normal file
76
apps/sentinel/client/topup/topup.go
Normal file
@@ -0,0 +1,76 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.7.2
|
||||
// Source: sentinel.proto
|
||||
|
||||
package topup
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"tianyuan-api/apps/sentinel/sentinel"
|
||||
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type (
|
||||
AliTopUpNotifyRequest = sentinel.AliTopUpNotifyRequest
|
||||
AliTopUpNotifyResponse = sentinel.AliTopUpNotifyResponse
|
||||
AliTopUpRequest = sentinel.AliTopUpRequest
|
||||
AliTopUpResponse = sentinel.AliTopUpResponse
|
||||
CreateProductRequest = sentinel.CreateProductRequest
|
||||
CreateSecretRequest = sentinel.CreateSecretRequest
|
||||
CreateUserProductRequest = sentinel.CreateUserProductRequest
|
||||
CreateWhitelistRequest = sentinel.CreateWhitelistRequest
|
||||
DeleteProductRequest = sentinel.DeleteProductRequest
|
||||
DeleteSecretRequest = sentinel.DeleteSecretRequest
|
||||
DeleteUserProductRequest = sentinel.DeleteUserProductRequest
|
||||
DeleteWhitelistRequest = sentinel.DeleteWhitelistRequest
|
||||
GetRecordByCodeRequest = sentinel.GetRecordByCodeRequest
|
||||
GetRecordByIdRequest = sentinel.GetRecordByIdRequest
|
||||
GetSecretBySecretIdRequest = sentinel.GetSecretBySecretIdRequest
|
||||
MatchResponse = sentinel.MatchResponse
|
||||
MatchWhitelistByIpRequest = sentinel.MatchWhitelistByIpRequest
|
||||
MatchingUserIdProductCodeRequest = sentinel.MatchingUserIdProductCodeRequest
|
||||
PageListRequest = sentinel.PageListRequest
|
||||
Product = sentinel.Product
|
||||
ProductResponse = sentinel.ProductResponse
|
||||
Secret = sentinel.Secret
|
||||
SecretResponse = sentinel.SecretResponse
|
||||
UpdateProductRequest = sentinel.UpdateProductRequest
|
||||
UpdateSecretRequest = sentinel.UpdateSecretRequest
|
||||
UpdateUserProductRequest = sentinel.UpdateUserProductRequest
|
||||
UpdateWhitelistRequest = sentinel.UpdateWhitelistRequest
|
||||
UserProductEmptyResponse = sentinel.UserProductEmptyResponse
|
||||
UserProductItem = sentinel.UserProductItem
|
||||
UserProductResponse = sentinel.UserProductResponse
|
||||
UserProuctPageListRequest = sentinel.UserProuctPageListRequest
|
||||
WhitePageListRequest = sentinel.WhitePageListRequest
|
||||
Whitelist = sentinel.Whitelist
|
||||
WhitelistResponse = sentinel.WhitelistResponse
|
||||
|
||||
TopUp interface {
|
||||
AliTopUp(ctx context.Context, in *AliTopUpRequest, opts ...grpc.CallOption) (*AliTopUpResponse, error)
|
||||
AliTopUpNotify(ctx context.Context, in *AliTopUpNotifyRequest, opts ...grpc.CallOption) (*AliTopUpNotifyResponse, error)
|
||||
}
|
||||
|
||||
defaultTopUp struct {
|
||||
cli zrpc.Client
|
||||
}
|
||||
)
|
||||
|
||||
func NewTopUp(cli zrpc.Client) TopUp {
|
||||
return &defaultTopUp{
|
||||
cli: cli,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultTopUp) AliTopUp(ctx context.Context, in *AliTopUpRequest, opts ...grpc.CallOption) (*AliTopUpResponse, error) {
|
||||
client := sentinel.NewTopUpClient(m.cli.Conn())
|
||||
return client.AliTopUp(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (m *defaultTopUp) AliTopUpNotify(ctx context.Context, in *AliTopUpNotifyRequest, opts ...grpc.CallOption) (*AliTopUpNotifyResponse, error) {
|
||||
client := sentinel.NewTopUpClient(m.cli.Conn())
|
||||
return client.AliTopUpNotify(ctx, in, opts...)
|
||||
}
|
||||
@@ -14,6 +14,10 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
AliTopUpNotifyRequest = sentinel.AliTopUpNotifyRequest
|
||||
AliTopUpNotifyResponse = sentinel.AliTopUpNotifyResponse
|
||||
AliTopUpRequest = sentinel.AliTopUpRequest
|
||||
AliTopUpResponse = sentinel.AliTopUpResponse
|
||||
CreateProductRequest = sentinel.CreateProductRequest
|
||||
CreateSecretRequest = sentinel.CreateSecretRequest
|
||||
CreateUserProductRequest = sentinel.CreateUserProductRequest
|
||||
|
||||
@@ -14,6 +14,10 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
AliTopUpNotifyRequest = sentinel.AliTopUpNotifyRequest
|
||||
AliTopUpNotifyResponse = sentinel.AliTopUpNotifyResponse
|
||||
AliTopUpRequest = sentinel.AliTopUpRequest
|
||||
AliTopUpResponse = sentinel.AliTopUpResponse
|
||||
CreateProductRequest = sentinel.CreateProductRequest
|
||||
CreateSecretRequest = sentinel.CreateSecretRequest
|
||||
CreateUserProductRequest = sentinel.CreateUserProductRequest
|
||||
|
||||
@@ -8,4 +8,16 @@ DataSource: "tianyuanapi:g3h98u0291j@tcp(127.0.0.1:3307)/tianyuanapi?charset=utf
|
||||
CacheRedis:
|
||||
- Host: "127.0.0.1:6379"
|
||||
Pass: "" # Redis 密码,如果未设置则留空
|
||||
Type: "node" # 单节点模式
|
||||
Type: "node" # 单节点模式
|
||||
Alipay:
|
||||
AppID: "2021004181633376"
|
||||
PrivateKey: "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCC2GNEWrQUg6FVHBdlDcgL1SA1KmRI8IHgSJGvXEsgfo3g62aa5usFXHVz5bMzpIcDu0N+jGtZQIBuuq7TxGwhDvWBygEDXN17p00uwqik/3TsyFvJ4FfbkaS7pRIGfeO/cBTzjqznanPUdHJZ9L39QmTqTefIQQvGOCvgntKxPa/LdS24+ZLA2RNh3TsRzbSxOOJPmUrwvCX8U13F9jH250hvf+Tewz4hyG8CkiMM4d1UpGMndQNr8oTY0vwFbWAG0ZDGgkxjg0iRJ02fgxwShQS1TgY5NxPhpKBiN5C/WG15qCqEw0F3GlpfWZwzUhv1uMiy+xbZ2bGLo1YCtwUtAgMBAAECggEAQ8uk25T3u61cWYH9qTGT1nWug32ciqJ7WN+hBLCYiJSqJMEz380INzXp8Ywx5u83ubo8xYQyVwNxyG3YCge7UwGyOXaWQczLQbe06SaZRSzLw6gozxf7zdvP9B4akdyGtfl4EZ56fkmNDKbtXSjPjDrrmO+Wyg7R7/nI2lDQsF6dXTKD0YiHtTKz40amKgbIYX+qc3yVS0slkVjcfnRczr+PKM5RMsV3Jk2pr6IYeq3E24LnbuVtV76priTqJN3hVSy2Y6JqmAYkI0HCoCuaFGE8ud3J859jjMcUXTRFJyDsKKooa+FZCoEx2ToVMqnb4vjfr1gZifUrw4ZNd5cPoQKBgQC4v/fNTXuA21pb+l4fnqK0o3wFhiNJh920yIlF4Vd0Nsi2/TwqFK6cVhrUFAmKr88hTzY1vkOhd/HLlkWjNDR5OGx1K1BKUAZjWIfProv8lDSckADEI29lro9WzFGy0o4szlEJ2uuUfO/j9Qn2lmx5oFPsz0TI+HoSNFE0q/SlxQKBgQC1ToMLuh0OkucZm1SL6xcjudBX7U0ElZ/TIxRzfxQ/sN911/BRlxrSdCcDMXNuuFpV2ACjDNWWLJM1sRVsOWNA/oXzZf6VTvUDIAv8XrNUt/B87genBVuMTZ2RYmMWCrgW0PE1OrpKGuQCKVsn242B2Xpmee9OnHhBF2uTASDASQKBgBALvD38iMl8Q7DRYfNlF8SQnmjsaYwtXLgi4qlLFQlm6K/b9qnA+hlh8RqSUvHUqyy9cHvidoVDoaCJAKtYEWal2+WhSWvq32MpgUIsasQZKyid6TMf0MEIFDL5s+7QEsEZejhc5zESWNN3qNHd5rX5ktBygArkadXC7XqhpLHxAoGBAJ0dJEKNTZDLjKiMCoAVgT/cTcdkRFGst4tn4tkTTqDCzWJ5di++Geg173i86aMQ7ndlb2fcP1qb1hW5Fy9pq7Eu3zVFNZB9k6TZqIlSJ2VK4IPiYY9C/UpgGCNcdzEqqMxc1Cmkcrq1AtE8tVmc0Mutgnw7Pj2JKkx91yLU32TBAoGAKxssUdTLuf5Z5oFgzpoSES9qwc1h6jlMfsouDzHcZf0aYintD6Vby7SVul5540qYkDkNs0YZ3uZu74LHfoBaWJjYIIVAMSMX+3AtBpQUyYluex64V/g60t+0sFuDWqMvSPU7mZcv6+KIP6vW56GeYdhHf4JqttdIHm9SgkoJjjY="
|
||||
AlipayPublicKey: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2CqoCp95w/JV3RT/gzF4/8QmVT1HQNaeW7yUp+mA7x9AbjvlTW/+eRn6oGAL/XhZLjvHD0XjKLVKX0MJVS1aUQHEHEbOJN4Eu8II45OavD4iZISa7Kp9V6AM+i4qTyaeV2wNDnGxHQBaLVUGCfMR+56EK2YpORdE1H9uy72SSQseVb3bmpsV9EW/IJNmcVL/ut3uA1JWAoRmzlQ7ekxg7p8AYXzYPEHQr1tl7W+M4zv9wO9GKZCxIqMA8U3RP5npPfRaCfIRGzXzCqFEEUvWuidOB7frsvN4jiPD07qpL2Bi9LM1X/ee2kC/oM8Uhd7ERZhG8MbZfijZKxgrsDKBcwIDAQAB"
|
||||
IsProduction: false # 是否是生产环境,true为生产环境,false为沙箱环境
|
||||
TopUp:
|
||||
MaxTopUpAmount: 100000
|
||||
Domain:
|
||||
Front: "https://console.tianyuanapi.com"
|
||||
Backend: "https://console.tianyuanapi.com"
|
||||
NotifyURL: "https://6m4685017o.goho.co/api/console/"
|
||||
ReturnURL: "http://127.0.0.1:5173"
|
||||
@@ -8,4 +8,16 @@ DataSource: "tianyuanapi:g3h98u0291j@tcp(tyapi_mysql:3306)/tianyuanapi?charset=u
|
||||
CacheRedis:
|
||||
- Host: "tyapi_redis:6379"
|
||||
Pass: "" # Redis 密码,如果未设置则留空
|
||||
Type: "node" # 单节点模式
|
||||
Type: "node" # 单节点模式
|
||||
Alipay:
|
||||
AppID: "2021004181633376"
|
||||
PrivateKey: "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCC2GNEWrQUg6FVHBdlDcgL1SA1KmRI8IHgSJGvXEsgfo3g62aa5usFXHVz5bMzpIcDu0N+jGtZQIBuuq7TxGwhDvWBygEDXN17p00uwqik/3TsyFvJ4FfbkaS7pRIGfeO/cBTzjqznanPUdHJZ9L39QmTqTefIQQvGOCvgntKxPa/LdS24+ZLA2RNh3TsRzbSxOOJPmUrwvCX8U13F9jH250hvf+Tewz4hyG8CkiMM4d1UpGMndQNr8oTY0vwFbWAG0ZDGgkxjg0iRJ02fgxwShQS1TgY5NxPhpKBiN5C/WG15qCqEw0F3GlpfWZwzUhv1uMiy+xbZ2bGLo1YCtwUtAgMBAAECggEAQ8uk25T3u61cWYH9qTGT1nWug32ciqJ7WN+hBLCYiJSqJMEz380INzXp8Ywx5u83ubo8xYQyVwNxyG3YCge7UwGyOXaWQczLQbe06SaZRSzLw6gozxf7zdvP9B4akdyGtfl4EZ56fkmNDKbtXSjPjDrrmO+Wyg7R7/nI2lDQsF6dXTKD0YiHtTKz40amKgbIYX+qc3yVS0slkVjcfnRczr+PKM5RMsV3Jk2pr6IYeq3E24LnbuVtV76priTqJN3hVSy2Y6JqmAYkI0HCoCuaFGE8ud3J859jjMcUXTRFJyDsKKooa+FZCoEx2ToVMqnb4vjfr1gZifUrw4ZNd5cPoQKBgQC4v/fNTXuA21pb+l4fnqK0o3wFhiNJh920yIlF4Vd0Nsi2/TwqFK6cVhrUFAmKr88hTzY1vkOhd/HLlkWjNDR5OGx1K1BKUAZjWIfProv8lDSckADEI29lro9WzFGy0o4szlEJ2uuUfO/j9Qn2lmx5oFPsz0TI+HoSNFE0q/SlxQKBgQC1ToMLuh0OkucZm1SL6xcjudBX7U0ElZ/TIxRzfxQ/sN911/BRlxrSdCcDMXNuuFpV2ACjDNWWLJM1sRVsOWNA/oXzZf6VTvUDIAv8XrNUt/B87genBVuMTZ2RYmMWCrgW0PE1OrpKGuQCKVsn242B2Xpmee9OnHhBF2uTASDASQKBgBALvD38iMl8Q7DRYfNlF8SQnmjsaYwtXLgi4qlLFQlm6K/b9qnA+hlh8RqSUvHUqyy9cHvidoVDoaCJAKtYEWal2+WhSWvq32MpgUIsasQZKyid6TMf0MEIFDL5s+7QEsEZejhc5zESWNN3qNHd5rX5ktBygArkadXC7XqhpLHxAoGBAJ0dJEKNTZDLjKiMCoAVgT/cTcdkRFGst4tn4tkTTqDCzWJ5di++Geg173i86aMQ7ndlb2fcP1qb1hW5Fy9pq7Eu3zVFNZB9k6TZqIlSJ2VK4IPiYY9C/UpgGCNcdzEqqMxc1Cmkcrq1AtE8tVmc0Mutgnw7Pj2JKkx91yLU32TBAoGAKxssUdTLuf5Z5oFgzpoSES9qwc1h6jlMfsouDzHcZf0aYintD6Vby7SVul5540qYkDkNs0YZ3uZu74LHfoBaWJjYIIVAMSMX+3AtBpQUyYluex64V/g60t+0sFuDWqMvSPU7mZcv6+KIP6vW56GeYdhHf4JqttdIHm9SgkoJjjY="
|
||||
AlipayPublicKey: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2CqoCp95w/JV3RT/gzF4/8QmVT1HQNaeW7yUp+mA7x9AbjvlTW/+eRn6oGAL/XhZLjvHD0XjKLVKX0MJVS1aUQHEHEbOJN4Eu8II45OavD4iZISa7Kp9V6AM+i4qTyaeV2wNDnGxHQBaLVUGCfMR+56EK2YpORdE1H9uy72SSQseVb3bmpsV9EW/IJNmcVL/ut3uA1JWAoRmzlQ7ekxg7p8AYXzYPEHQr1tl7W+M4zv9wO9GKZCxIqMA8U3RP5npPfRaCfIRGzXzCqFEEUvWuidOB7frsvN4jiPD07qpL2Bi9LM1X/ee2kC/oM8Uhd7ERZhG8MbZfijZKxgrsDKBcwIDAQAB"
|
||||
IsProduction: true # 是否是生产环境,true为生产环境,false为沙箱环境
|
||||
TopUp:
|
||||
MaxTopUpAmount: 100000
|
||||
Domain:
|
||||
Front: "https://console.tianyuanapi.com"
|
||||
Backend: "https://console.tianyuanapi.com"
|
||||
NotifyURL: "http://console.tianyuanapi.com/api/console/"
|
||||
ReturnURL: "https://console.tianyuanapi.com/charge/recharge"
|
||||
@@ -9,4 +9,15 @@ type Config struct {
|
||||
zrpc.RpcServerConf
|
||||
DataSource string // 数据库连接的 DSN 字符串
|
||||
CacheRedis cache.CacheConf // 缓存配置,使用 go-zero 自带的缓存配置结构体
|
||||
Alipay AlipayConfig
|
||||
TopUp TopUpConfig
|
||||
}
|
||||
type AlipayConfig struct {
|
||||
AppID string
|
||||
PrivateKey string
|
||||
AlipayPublicKey string
|
||||
IsProduction bool
|
||||
}
|
||||
type TopUpConfig struct {
|
||||
MaxTopUpAmount int64
|
||||
}
|
||||
|
||||
@@ -24,7 +24,9 @@ func NewDeleteProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Del
|
||||
}
|
||||
|
||||
func (l *DeleteProductLogic) DeleteProduct(in *sentinel.DeleteProductRequest) (*sentinel.Product, error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
err := l.svcCtx.ProductsModel.Delete(l.ctx, in.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &sentinel.Product{}, nil
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@ package productlogic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"tianyuan-api/apps/sentinel/internal/model"
|
||||
"tianyuan-api/apps/sentinel/internal/svc"
|
||||
"tianyuan-api/apps/sentinel/sentinel"
|
||||
"tianyuan-api/pkg/sqlutil"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
@@ -24,7 +25,17 @@ func NewUpdateProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Upd
|
||||
}
|
||||
|
||||
func (l *UpdateProductLogic) UpdateProduct(in *sentinel.UpdateProductRequest) (*sentinel.Product, error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
err := l.svcCtx.ProductsModel.Update(l.ctx, &model.Products{
|
||||
Id: in.Id,
|
||||
ProductName: in.ProductName,
|
||||
ProductCode: in.ProductCode,
|
||||
ProductDescription: sqlutil.StringToNullString(in.ProductDescription),
|
||||
ProductContent: sqlutil.StringToNullString(in.ProductContent),
|
||||
ProductPrice: in.ProductPrice,
|
||||
ProductGroup: in.ProductGroup,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &sentinel.Product{}, nil
|
||||
}
|
||||
|
||||
65
apps/sentinel/internal/logic/topup/alitopuplogic.go
Normal file
65
apps/sentinel/internal/logic/topup/alitopuplogic.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package topuplogic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/smartwalle/alipay/v3"
|
||||
"tianyuan-api/apps/sentinel/internal/model"
|
||||
"tianyuan-api/apps/sentinel/internal/svc"
|
||||
"tianyuan-api/apps/sentinel/sentinel"
|
||||
"tianyuan-api/pkg/generate"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type AliTopUpLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewAliTopUpLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AliTopUpLogic {
|
||||
return &AliTopUpLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *AliTopUpLogic) AliTopUp(in *sentinel.AliTopUpRequest) (*sentinel.AliTopUpResponse, error) {
|
||||
if in.Amount > l.svcCtx.Config.TopUp.MaxTopUpAmount {
|
||||
return &sentinel.AliTopUpResponse{}, fmt.Errorf("充值金额最大不能超过%d元", l.svcCtx.Config.TopUp.MaxTopUpAmount)
|
||||
}
|
||||
// 使用从 svcCtx 中获取的支付宝客户端
|
||||
client := l.svcCtx.AlipayClient
|
||||
outTradeNo := generate.GenerateTransactionID()
|
||||
totalAmount := fmt.Sprintf("%.2f", float64(in.Amount))
|
||||
// 构造支付请求
|
||||
var p = alipay.TradePagePay{
|
||||
Trade: alipay.Trade{
|
||||
Subject: "天远数据API使用额度",
|
||||
OutTradeNo: outTradeNo,
|
||||
TotalAmount: totalAmount,
|
||||
ProductCode: "FAST_INSTANT_TRADE_PAY",
|
||||
NotifyURL: "https://console.tianyuanapi.com/api/console/", // 异步回调通知地址
|
||||
ReturnURL: "https://console.tianyuanapi.com/charge/recharge", // 支付成功后的跳转地址
|
||||
},
|
||||
}
|
||||
_, inserErr := l.svcCtx.PayOrderModel.Insert(l.ctx, &model.PayOrder{
|
||||
UserId: in.UserId,
|
||||
OutTradeNo: outTradeNo,
|
||||
Amount: float64(in.Amount),
|
||||
})
|
||||
if inserErr != nil {
|
||||
return nil, inserErr
|
||||
}
|
||||
// 生成支付链接
|
||||
url, err := client.TradePagePay(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &sentinel.AliTopUpResponse{
|
||||
PayUrl: url.String(),
|
||||
}, nil
|
||||
}
|
||||
77
apps/sentinel/internal/logic/topup/alitopupnotifylogic.go
Normal file
77
apps/sentinel/internal/logic/topup/alitopupnotifylogic.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package topuplogic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/smartwalle/alipay/v3"
|
||||
"math"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"tianyuan-api/apps/sentinel/internal/svc"
|
||||
"tianyuan-api/apps/sentinel/sentinel"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type AliTopUpNotifyLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewAliTopUpNotifyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AliTopUpNotifyLogic {
|
||||
return &AliTopUpNotifyLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *AliTopUpNotifyLogic) AliTopUpNotify(in *sentinel.AliTopUpNotifyRequest) (*sentinel.AliTopUpNotifyResponse, error) {
|
||||
globalErr := errors.New("error")
|
||||
// 初始化支付宝客户端
|
||||
client := l.svcCtx.AlipayClient
|
||||
|
||||
// 解析表单数据
|
||||
formData, err := url.ParseQuery(in.RawForm)
|
||||
if err != nil {
|
||||
l.Logger.Errorf("解析表单数据失败: %v", err)
|
||||
return nil, globalErr
|
||||
}
|
||||
|
||||
// 验证签名并解析通知
|
||||
notify, err := client.DecodeNotification(formData)
|
||||
if err != nil {
|
||||
l.Logger.Errorf("通知解析失败: %v", err)
|
||||
return nil, globalErr
|
||||
}
|
||||
|
||||
// 验证交易状态
|
||||
if notify.TradeStatus == alipay.TradeStatusSuccess {
|
||||
l.Logger.Infof("订单 %s 支付成功", notify.OutTradeNo)
|
||||
payOrder, findErr := l.svcCtx.PayOrderModel.FindOneByOutTradeNo(l.ctx, notify.OutTradeNo)
|
||||
if findErr != nil {
|
||||
return nil, globalErr
|
||||
}
|
||||
if payOrder.OutTradeNo == notify.OutTradeNo && payOrder.Status == 0 {
|
||||
notifyAmount, parseFloatErr := strconv.ParseFloat(notify.TotalAmount, 64)
|
||||
if parseFloatErr != nil {
|
||||
logx.Errorf("金额转换错误: %v", parseFloatErr)
|
||||
return nil, globalErr
|
||||
}
|
||||
logx.Infof("回调金额:%v,订单金额%v", notify.TotalAmount, payOrder.Amount)
|
||||
// 比较支付宝返回的金额与数据库存储的金额
|
||||
if math.Abs(notifyAmount-payOrder.Amount) < 1e-6 {
|
||||
// 金额匹配,继续处理
|
||||
} else {
|
||||
return nil, globalErr
|
||||
}
|
||||
}
|
||||
} else {
|
||||
l.Logger.Infof("订单 %s 支付状态: %s", notify.OutTradeNo, notify.TradeStatus)
|
||||
}
|
||||
|
||||
// 返回成功响应
|
||||
return &sentinel.AliTopUpNotifyResponse{Success: true}, nil
|
||||
}
|
||||
27
apps/sentinel/internal/model/payordermodel.go
Normal file
27
apps/sentinel/internal/model/payordermodel.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
var _ PayOrderModel = (*customPayOrderModel)(nil)
|
||||
|
||||
type (
|
||||
// PayOrderModel is an interface to be customized, add more methods here,
|
||||
// and implement the added methods in customPayOrderModel.
|
||||
PayOrderModel interface {
|
||||
payOrderModel
|
||||
}
|
||||
|
||||
customPayOrderModel struct {
|
||||
*defaultPayOrderModel
|
||||
}
|
||||
)
|
||||
|
||||
// NewPayOrderModel returns a model for the database table.
|
||||
func NewPayOrderModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) PayOrderModel {
|
||||
return &customPayOrderModel{
|
||||
defaultPayOrderModel: newPayOrderModel(conn, c, opts...),
|
||||
}
|
||||
}
|
||||
152
apps/sentinel/internal/model/payordermodel_gen.go
Normal file
152
apps/sentinel/internal/model/payordermodel_gen.go
Normal file
@@ -0,0 +1,152 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// versions:
|
||||
// goctl version: 1.7.2
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
)
|
||||
|
||||
var (
|
||||
payOrderFieldNames = builder.RawFieldNames(&PayOrder{})
|
||||
payOrderRows = strings.Join(payOrderFieldNames, ",")
|
||||
payOrderRowsExpectAutoSet = strings.Join(stringx.Remove(payOrderFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
|
||||
payOrderRowsWithPlaceHolder = strings.Join(stringx.Remove(payOrderFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
|
||||
|
||||
cachePayOrderIdPrefix = "cache:payOrder:id:"
|
||||
cachePayOrderOutTradeNoPrefix = "cache:payOrder:outTradeNo:"
|
||||
)
|
||||
|
||||
type (
|
||||
payOrderModel interface {
|
||||
Insert(ctx context.Context, data *PayOrder) (sql.Result, error)
|
||||
FindOne(ctx context.Context, id int64) (*PayOrder, error)
|
||||
FindOneByOutTradeNo(ctx context.Context, outTradeNo string) (*PayOrder, error)
|
||||
Update(ctx context.Context, data *PayOrder) error
|
||||
Delete(ctx context.Context, id int64) error
|
||||
}
|
||||
|
||||
defaultPayOrderModel struct {
|
||||
sqlc.CachedConn
|
||||
table string
|
||||
}
|
||||
|
||||
PayOrder struct {
|
||||
Id int64 `db:"id"` // 主键
|
||||
UserId int64 `db:"user_id"` // 用户ID
|
||||
OutTradeNo string `db:"out_trade_no"` // 商户订单号,唯一
|
||||
Amount float64 `db:"amount"` // 支付金额
|
||||
Status int64 `db:"status"` // 订单状态 0-待支付, 1-支付成功, 2-支付失败
|
||||
CreatedAt time.Time `db:"created_at"` // 创建时间
|
||||
UpdatedAt time.Time `db:"updated_at"` // 更新时间
|
||||
PaymentTime sql.NullTime `db:"payment_time"` // 支付完成时间
|
||||
}
|
||||
)
|
||||
|
||||
func newPayOrderModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) *defaultPayOrderModel {
|
||||
return &defaultPayOrderModel{
|
||||
CachedConn: sqlc.NewConn(conn, c, opts...),
|
||||
table: "`pay_order`",
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultPayOrderModel) Delete(ctx context.Context, id int64) error {
|
||||
data, err := m.FindOne(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
payOrderIdKey := fmt.Sprintf("%s%v", cachePayOrderIdPrefix, id)
|
||||
payOrderOutTradeNoKey := fmt.Sprintf("%s%v", cachePayOrderOutTradeNoPrefix, data.OutTradeNo)
|
||||
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
|
||||
return conn.ExecCtx(ctx, query, id)
|
||||
}, payOrderIdKey, payOrderOutTradeNoKey)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultPayOrderModel) FindOne(ctx context.Context, id int64) (*PayOrder, error) {
|
||||
payOrderIdKey := fmt.Sprintf("%s%v", cachePayOrderIdPrefix, id)
|
||||
var resp PayOrder
|
||||
err := m.QueryRowCtx(ctx, &resp, payOrderIdKey, func(ctx context.Context, conn sqlx.SqlConn, v any) error {
|
||||
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", payOrderRows, m.table)
|
||||
return conn.QueryRowCtx(ctx, v, query, id)
|
||||
})
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case sqlc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultPayOrderModel) FindOneByOutTradeNo(ctx context.Context, outTradeNo string) (*PayOrder, error) {
|
||||
payOrderOutTradeNoKey := fmt.Sprintf("%s%v", cachePayOrderOutTradeNoPrefix, outTradeNo)
|
||||
var resp PayOrder
|
||||
err := m.QueryRowIndexCtx(ctx, &resp, payOrderOutTradeNoKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v any) (i any, e error) {
|
||||
query := fmt.Sprintf("select %s from %s where `out_trade_no` = ? limit 1", payOrderRows, m.table)
|
||||
if err := conn.QueryRowCtx(ctx, &resp, query, outTradeNo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Id, nil
|
||||
}, m.queryPrimary)
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case sqlc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultPayOrderModel) Insert(ctx context.Context, data *PayOrder) (sql.Result, error) {
|
||||
payOrderIdKey := fmt.Sprintf("%s%v", cachePayOrderIdPrefix, data.Id)
|
||||
payOrderOutTradeNoKey := fmt.Sprintf("%s%v", cachePayOrderOutTradeNoPrefix, data.OutTradeNo)
|
||||
ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?)", m.table, payOrderRowsExpectAutoSet)
|
||||
return conn.ExecCtx(ctx, query, data.UserId, data.OutTradeNo, data.Amount, data.Status, data.PaymentTime)
|
||||
}, payOrderIdKey, payOrderOutTradeNoKey)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (m *defaultPayOrderModel) Update(ctx context.Context, newData *PayOrder) error {
|
||||
data, err := m.FindOne(ctx, newData.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
payOrderIdKey := fmt.Sprintf("%s%v", cachePayOrderIdPrefix, data.Id)
|
||||
payOrderOutTradeNoKey := fmt.Sprintf("%s%v", cachePayOrderOutTradeNoPrefix, data.OutTradeNo)
|
||||
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, payOrderRowsWithPlaceHolder)
|
||||
return conn.ExecCtx(ctx, query, newData.UserId, newData.OutTradeNo, newData.Amount, newData.Status, newData.PaymentTime, newData.Id)
|
||||
}, payOrderIdKey, payOrderOutTradeNoKey)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultPayOrderModel) formatPrimary(primary any) string {
|
||||
return fmt.Sprintf("%s%v", cachePayOrderIdPrefix, primary)
|
||||
}
|
||||
|
||||
func (m *defaultPayOrderModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary any) error {
|
||||
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", payOrderRows, m.table)
|
||||
return conn.QueryRowCtx(ctx, v, query, primary)
|
||||
}
|
||||
|
||||
func (m *defaultPayOrderModel) tableName() string {
|
||||
return m.table
|
||||
}
|
||||
34
apps/sentinel/internal/server/topup/topupserver.go
Normal file
34
apps/sentinel/internal/server/topup/topupserver.go
Normal file
@@ -0,0 +1,34 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.7.2
|
||||
// Source: sentinel.proto
|
||||
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"tianyuan-api/apps/sentinel/internal/logic/topup"
|
||||
"tianyuan-api/apps/sentinel/internal/svc"
|
||||
"tianyuan-api/apps/sentinel/sentinel"
|
||||
)
|
||||
|
||||
type TopUpServer struct {
|
||||
svcCtx *svc.ServiceContext
|
||||
sentinel.UnimplementedTopUpServer
|
||||
}
|
||||
|
||||
func NewTopUpServer(svcCtx *svc.ServiceContext) *TopUpServer {
|
||||
return &TopUpServer{
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *TopUpServer) AliTopUp(ctx context.Context, in *sentinel.AliTopUpRequest) (*sentinel.AliTopUpResponse, error) {
|
||||
l := topuplogic.NewAliTopUpLogic(ctx, s.svcCtx)
|
||||
return l.AliTopUp(in)
|
||||
}
|
||||
|
||||
func (s *TopUpServer) AliTopUpNotify(ctx context.Context, in *sentinel.AliTopUpNotifyRequest) (*sentinel.AliTopUpNotifyResponse, error) {
|
||||
l := topuplogic.NewAliTopUpNotifyLogic(ctx, s.svcCtx)
|
||||
return l.AliTopUpNotify(in)
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/smartwalle/alipay/v3"
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"tianyuan-api/apps/sentinel/internal/config"
|
||||
@@ -10,10 +12,12 @@ import (
|
||||
type ServiceContext struct {
|
||||
Config config.Config
|
||||
Redis *redis.Redis
|
||||
AlipayClient *alipay.Client
|
||||
WhitelistModel model.WhitelistModel
|
||||
SecretsModel model.SecretsModel
|
||||
ProductsModel model.ProductsModel
|
||||
UserProductsModel model.UserProductsModel
|
||||
PayOrderModel model.PayOrderModel
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
@@ -25,12 +29,26 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
}
|
||||
// 使用 MustNewRedis 来初始化 Redis 客户端
|
||||
rds := redis.MustNewRedis(redisConf)
|
||||
|
||||
// 创建支付宝客户端
|
||||
client, err := alipay.New(c.Alipay.AppID, c.Alipay.PrivateKey, c.Alipay.IsProduction)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("创建支付宝客户端失败: %v", err))
|
||||
}
|
||||
|
||||
// 加载支付宝公钥
|
||||
err = client.LoadAliPayPublicKey(c.Alipay.AlipayPublicKey)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("加载支付宝公钥失败: %v", err))
|
||||
}
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
Redis: rds,
|
||||
AlipayClient: client,
|
||||
WhitelistModel: model.NewWhitelistModel(rds, db, c.CacheRedis),
|
||||
SecretsModel: model.NewSecretsModel(db, c.CacheRedis),
|
||||
ProductsModel: model.NewProductsModel(db, c.CacheRedis),
|
||||
UserProductsModel: model.NewUserProductsModel(rds, db, c.CacheRedis),
|
||||
PayOrderModel: model.NewPayOrderModel(db, c.CacheRedis),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,6 +166,22 @@ message matchResponse {
|
||||
message MatchWhitelistByIpRequest{
|
||||
string ip = 1;
|
||||
}
|
||||
|
||||
message AliTopUpRequest {
|
||||
int64 user_id = 1;
|
||||
int64 amount = 2;
|
||||
}
|
||||
|
||||
message AliTopUpResponse {
|
||||
string pay_url = 1;
|
||||
}
|
||||
message AliTopUpNotifyRequest {
|
||||
string raw_form = 1; // 来自支付宝的原始表单数据
|
||||
}
|
||||
|
||||
message AliTopUpNotifyResponse {
|
||||
bool success = 1;
|
||||
}
|
||||
// Service definitions for Whitelist, Secrets, Products, and UserProducts
|
||||
service whitelist {
|
||||
// Whitelist methods
|
||||
@@ -190,9 +206,14 @@ service product {
|
||||
rpc GetProductById(GetRecordByIdRequest) returns (Product);
|
||||
rpc GetProductByCode(GetRecordByCodeRequest) returns (Product);
|
||||
}
|
||||
service userProduct {
|
||||
// UserProduct methods
|
||||
rpc CreateUserProduct(CreateUserProductRequest) returns (UserProductEmptyResponse);
|
||||
rpc GetUserProductPageList(UserProuctPageListRequest) returns (UserProductResponse);
|
||||
rpc MatchingUserIdProductCode(matchingUserIdProductCodeRequest) returns (matchResponse);
|
||||
}
|
||||
service userProduct {
|
||||
// UserProduct methods
|
||||
rpc CreateUserProduct(CreateUserProductRequest) returns (UserProductEmptyResponse);
|
||||
rpc GetUserProductPageList(UserProuctPageListRequest) returns (UserProductResponse);
|
||||
rpc MatchingUserIdProductCode(matchingUserIdProductCodeRequest) returns (matchResponse);
|
||||
}
|
||||
|
||||
service topUp {
|
||||
rpc AliTopUp (AliTopUpRequest) returns (AliTopUpResponse);
|
||||
rpc AliTopUpNotify (AliTopUpNotifyRequest) returns (AliTopUpNotifyResponse);
|
||||
}
|
||||
@@ -31,10 +31,22 @@ CREATE TABLE `products` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='产品表,存储产品的详细信息';
|
||||
|
||||
CREATE TABLE `user_products` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '用户产品ID',
|
||||
`user_id` INT(11) NOT NULL COMMENT '用户ID',
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '用户产品ID',
|
||||
`user_id` INT(11) NOT NULL COMMENT '用户ID',
|
||||
`product_id` INT(11) NOT NULL COMMENT '产品ID',
|
||||
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户产品表,存储用户开通的产品记录';
|
||||
|
||||
CREATE TABLE `pay_order` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`user_id` INT(11) NOT NULL COMMENT '用户ID',
|
||||
`out_trade_no` VARCHAR(64) NOT NULL UNIQUE COMMENT '商户订单号,唯一',
|
||||
`amount` DECIMAL(10, 2) NOT NULL COMMENT '支付金额',
|
||||
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '订单状态 0-待支付, 1-支付成功, 2-支付失败',
|
||||
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`payment_time` TIMESTAMP NULL COMMENT '支付完成时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付订单表';
|
||||
@@ -1832,6 +1832,202 @@ func (x *MatchWhitelistByIpRequest) GetIp() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type AliTopUpRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
Amount int64 `protobuf:"varint,2,opt,name=amount,proto3" json:"amount,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AliTopUpRequest) Reset() {
|
||||
*x = AliTopUpRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_sentinel_proto_msgTypes[30]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AliTopUpRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AliTopUpRequest) ProtoMessage() {}
|
||||
|
||||
func (x *AliTopUpRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_sentinel_proto_msgTypes[30]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AliTopUpRequest.ProtoReflect.Descriptor instead.
|
||||
func (*AliTopUpRequest) Descriptor() ([]byte, []int) {
|
||||
return file_sentinel_proto_rawDescGZIP(), []int{30}
|
||||
}
|
||||
|
||||
func (x *AliTopUpRequest) GetUserId() int64 {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *AliTopUpRequest) GetAmount() int64 {
|
||||
if x != nil {
|
||||
return x.Amount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type AliTopUpResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
PayUrl string `protobuf:"bytes,1,opt,name=pay_url,json=payUrl,proto3" json:"pay_url,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AliTopUpResponse) Reset() {
|
||||
*x = AliTopUpResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_sentinel_proto_msgTypes[31]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AliTopUpResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AliTopUpResponse) ProtoMessage() {}
|
||||
|
||||
func (x *AliTopUpResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_sentinel_proto_msgTypes[31]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AliTopUpResponse.ProtoReflect.Descriptor instead.
|
||||
func (*AliTopUpResponse) Descriptor() ([]byte, []int) {
|
||||
return file_sentinel_proto_rawDescGZIP(), []int{31}
|
||||
}
|
||||
|
||||
func (x *AliTopUpResponse) GetPayUrl() string {
|
||||
if x != nil {
|
||||
return x.PayUrl
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AliTopUpNotifyRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
RawForm string `protobuf:"bytes,1,opt,name=raw_form,json=rawForm,proto3" json:"raw_form,omitempty"` // 来自支付宝的原始表单数据
|
||||
}
|
||||
|
||||
func (x *AliTopUpNotifyRequest) Reset() {
|
||||
*x = AliTopUpNotifyRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_sentinel_proto_msgTypes[32]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AliTopUpNotifyRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AliTopUpNotifyRequest) ProtoMessage() {}
|
||||
|
||||
func (x *AliTopUpNotifyRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_sentinel_proto_msgTypes[32]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AliTopUpNotifyRequest.ProtoReflect.Descriptor instead.
|
||||
func (*AliTopUpNotifyRequest) Descriptor() ([]byte, []int) {
|
||||
return file_sentinel_proto_rawDescGZIP(), []int{32}
|
||||
}
|
||||
|
||||
func (x *AliTopUpNotifyRequest) GetRawForm() string {
|
||||
if x != nil {
|
||||
return x.RawForm
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AliTopUpNotifyResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AliTopUpNotifyResponse) Reset() {
|
||||
*x = AliTopUpNotifyResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_sentinel_proto_msgTypes[33]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AliTopUpNotifyResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AliTopUpNotifyResponse) ProtoMessage() {}
|
||||
|
||||
func (x *AliTopUpNotifyResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_sentinel_proto_msgTypes[33]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AliTopUpNotifyResponse.ProtoReflect.Descriptor instead.
|
||||
func (*AliTopUpNotifyResponse) Descriptor() ([]byte, []int) {
|
||||
return file_sentinel_proto_rawDescGZIP(), []int{33}
|
||||
}
|
||||
|
||||
func (x *AliTopUpNotifyResponse) GetSuccess() bool {
|
||||
if x != nil {
|
||||
return x.Success
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var File_sentinel_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_sentinel_proto_rawDesc = []byte{
|
||||
@@ -2026,74 +2222,95 @@ var file_sentinel_proto_rawDesc = []byte{
|
||||
0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x22, 0x2b, 0x0a, 0x19, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x57,
|
||||
0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x42, 0x79, 0x49, 0x70, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x02, 0x69, 0x70, 0x32, 0xb4, 0x02, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73,
|
||||
0x74, 0x12, 0x36, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x68, 0x69, 0x74, 0x65,
|
||||
0x6c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x68, 0x69,
|
||||
0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e,
|
||||
0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x0f, 0x55, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x55,
|
||||
0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73,
|
||||
0x74, 0x12, 0x36, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x68, 0x69, 0x74, 0x65,
|
||||
0x6c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x68, 0x69,
|
||||
0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e,
|
||||
0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x10, 0x47, 0x65, 0x74,
|
||||
0x57, 0x68, 0x69, 0x74, 0x65, 0x50, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x15, 0x2e,
|
||||
0x57, 0x68, 0x69, 0x74, 0x65, 0x50, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x12, 0x4d, 0x61, 0x74, 0x63,
|
||||
0x68, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x42, 0x79, 0x49, 0x70, 0x12, 0x1a,
|
||||
0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x42,
|
||||
0x79, 0x49, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x6d, 0x61, 0x74,
|
||||
0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xa9, 0x01, 0x0a, 0x06, 0x73,
|
||||
0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x2d, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53,
|
||||
0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x14, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65,
|
||||
0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x07, 0x2e, 0x53, 0x65,
|
||||
0x63, 0x72, 0x65, 0x74, 0x12, 0x33, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65,
|
||||
0x74, 0x42, 0x79, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x15, 0x2e, 0x47, 0x65, 0x74, 0x52,
|
||||
0x65, 0x63, 0x6f, 0x72, 0x64, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x07, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x3b, 0x0a, 0x13, 0x47, 0x65, 0x74,
|
||||
0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x42, 0x79, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x49, 0x64,
|
||||
0x12, 0x1b, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x42, 0x79, 0x53, 0x65,
|
||||
0x63, 0x72, 0x65, 0x74, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x07, 0x2e,
|
||||
0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x32, 0xc3, 0x02, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75,
|
||||
0x63, 0x74, 0x12, 0x30, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64,
|
||||
0x75, 0x63, 0x74, 0x12, 0x15, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64,
|
||||
0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x08, 0x2e, 0x50, 0x72, 0x6f,
|
||||
0x64, 0x75, 0x63, 0x74, 0x12, 0x30, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72,
|
||||
0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x15, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72,
|
||||
0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x08, 0x2e, 0x50,
|
||||
0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x30, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
|
||||
0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x15, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
|
||||
0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x08,
|
||||
0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x38, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x50,
|
||||
0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x50, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x10,
|
||||
0x2e, 0x50, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x10, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x31, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74,
|
||||
0x42, 0x79, 0x49, 0x64, 0x12, 0x15, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64,
|
||||
0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x08, 0x2e, 0x50, 0x72,
|
||||
0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x35, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64,
|
||||
0x75, 0x63, 0x74, 0x42, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x17, 0x2e, 0x47, 0x65, 0x74, 0x52,
|
||||
0x65, 0x63, 0x6f, 0x72, 0x64, 0x42, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x08, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x32, 0xf4, 0x01, 0x0a,
|
||||
0x0b, 0x75, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x49, 0x0a, 0x11,
|
||||
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63,
|
||||
0x74, 0x12, 0x19, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72,
|
||||
0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x55,
|
||||
0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x55, 0x73,
|
||||
0x65, 0x72, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x50, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x12, 0x1a, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x75, 0x63, 0x74, 0x50, 0x61,
|
||||
0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e,
|
||||
0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x19, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x55,
|
||||
0x73, 0x65, 0x72, 0x49, 0x64, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x43, 0x6f, 0x64, 0x65,
|
||||
0x12, 0x21, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x55, 0x73, 0x65, 0x72, 0x49,
|
||||
0x64, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75,
|
||||
0x02, 0x69, 0x70, 0x22, 0x42, 0x0a, 0x0f, 0x41, 0x6c, 0x69, 0x54, 0x6f, 0x70, 0x55, 0x70, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x2b, 0x0a, 0x10, 0x41, 0x6c, 0x69, 0x54, 0x6f,
|
||||
0x70, 0x55, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x70,
|
||||
0x61, 0x79, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x61,
|
||||
0x79, 0x55, 0x72, 0x6c, 0x22, 0x32, 0x0a, 0x15, 0x41, 0x6c, 0x69, 0x54, 0x6f, 0x70, 0x55, 0x70,
|
||||
0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a,
|
||||
0x08, 0x72, 0x61, 0x77, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x07, 0x72, 0x61, 0x77, 0x46, 0x6f, 0x72, 0x6d, 0x22, 0x32, 0x0a, 0x16, 0x41, 0x6c, 0x69, 0x54,
|
||||
0x6f, 0x70, 0x55, 0x70, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x32, 0xb4, 0x02, 0x0a,
|
||||
0x09, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x0f, 0x43, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e,
|
||||
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69,
|
||||
0x73, 0x74, 0x12, 0x36, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x68, 0x69, 0x74,
|
||||
0x65, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x68,
|
||||
0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a,
|
||||
0x2e, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x0f, 0x44, 0x65,
|
||||
0x6c, 0x65, 0x74, 0x65, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e,
|
||||
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69,
|
||||
0x73, 0x74, 0x12, 0x3d, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x57, 0x68, 0x69, 0x74, 0x65, 0x50, 0x61,
|
||||
0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x15, 0x2e, 0x57, 0x68, 0x69, 0x74, 0x65, 0x50, 0x61,
|
||||
0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e,
|
||||
0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x40, 0x0a, 0x12, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c,
|
||||
0x69, 0x73, 0x74, 0x42, 0x79, 0x49, 0x70, 0x12, 0x1a, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x57,
|
||||
0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x42, 0x79, 0x49, 0x70, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x65,
|
||||
0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x6e, 0x73, 0x65, 0x32, 0xa9, 0x01, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x2d,
|
||||
0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x14,
|
||||
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x07, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x33, 0x0a,
|
||||
0x11, 0x47, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x42, 0x79, 0x55, 0x73, 0x65, 0x72,
|
||||
0x49, 0x64, 0x12, 0x15, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x42, 0x79,
|
||||
0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x07, 0x2e, 0x53, 0x65, 0x63, 0x72,
|
||||
0x65, 0x74, 0x12, 0x3b, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x42,
|
||||
0x79, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x2e, 0x47, 0x65, 0x74, 0x53,
|
||||
0x65, 0x63, 0x72, 0x65, 0x74, 0x42, 0x79, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x49, 0x64, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x07, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x32,
|
||||
0xc3, 0x02, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x30, 0x0a, 0x0d, 0x43,
|
||||
0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x15, 0x2e, 0x43,
|
||||
0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x08, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x30, 0x0a,
|
||||
0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x15,
|
||||
0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x08, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12,
|
||||
0x30, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74,
|
||||
0x12, 0x15, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x08, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63,
|
||||
0x74, 0x12, 0x38, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x50,
|
||||
0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x10, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x50, 0x72, 0x6f, 0x64,
|
||||
0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x0e, 0x47,
|
||||
0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x42, 0x79, 0x49, 0x64, 0x12, 0x15, 0x2e,
|
||||
0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x08, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x35,
|
||||
0x0a, 0x10, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x42, 0x79, 0x43, 0x6f,
|
||||
0x64, 0x65, 0x12, 0x17, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x42, 0x79,
|
||||
0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x08, 0x2e, 0x50, 0x72,
|
||||
0x6f, 0x64, 0x75, 0x63, 0x74, 0x32, 0xf4, 0x01, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x50, 0x72,
|
||||
0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x49, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55,
|
||||
0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x19, 0x2e, 0x43, 0x72, 0x65,
|
||||
0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x64,
|
||||
0x75, 0x63, 0x74, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x4a, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x64, 0x75,
|
||||
0x63, 0x74, 0x50, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1a, 0x2e, 0x55, 0x73, 0x65,
|
||||
0x72, 0x50, 0x72, 0x6f, 0x75, 0x63, 0x74, 0x50, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f,
|
||||
0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x19,
|
||||
0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x50, 0x72,
|
||||
0x6f, 0x64, 0x75, 0x63, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x21, 0x2e, 0x6d, 0x61, 0x74, 0x63,
|
||||
0x68, 0x69, 0x6e, 0x67, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63,
|
||||
0x74, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x6d,
|
||||
0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x7b, 0x0a, 0x05,
|
||||
0x74, 0x6f, 0x70, 0x55, 0x70, 0x12, 0x2f, 0x0a, 0x08, 0x41, 0x6c, 0x69, 0x54, 0x6f, 0x70, 0x55,
|
||||
0x70, 0x12, 0x10, 0x2e, 0x41, 0x6c, 0x69, 0x54, 0x6f, 0x70, 0x55, 0x70, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x41, 0x6c, 0x69, 0x54, 0x6f, 0x70, 0x55, 0x70, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x41, 0x6c, 0x69, 0x54, 0x6f, 0x70,
|
||||
0x55, 0x70, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x16, 0x2e, 0x41, 0x6c, 0x69, 0x54, 0x6f,
|
||||
0x70, 0x55, 0x70, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x17, 0x2e, 0x41, 0x6c, 0x69, 0x54, 0x6f, 0x70, 0x55, 0x70, 0x4e, 0x6f, 0x74, 0x69, 0x66,
|
||||
0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x73,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -2108,7 +2325,7 @@ func file_sentinel_proto_rawDescGZIP() []byte {
|
||||
return file_sentinel_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_sentinel_proto_msgTypes = make([]protoimpl.MessageInfo, 30)
|
||||
var file_sentinel_proto_msgTypes = make([]protoimpl.MessageInfo, 34)
|
||||
var file_sentinel_proto_goTypes = []any{
|
||||
(*PageListRequest)(nil), // 0: PageListRequest
|
||||
(*UserProuctPageListRequest)(nil), // 1: UserProuctPageListRequest
|
||||
@@ -2140,6 +2357,10 @@ var file_sentinel_proto_goTypes = []any{
|
||||
(*MatchingUserIdProductCodeRequest)(nil), // 27: matchingUserIdProductCodeRequest
|
||||
(*MatchResponse)(nil), // 28: matchResponse
|
||||
(*MatchWhitelistByIpRequest)(nil), // 29: MatchWhitelistByIpRequest
|
||||
(*AliTopUpRequest)(nil), // 30: AliTopUpRequest
|
||||
(*AliTopUpResponse)(nil), // 31: AliTopUpResponse
|
||||
(*AliTopUpNotifyRequest)(nil), // 32: AliTopUpNotifyRequest
|
||||
(*AliTopUpNotifyResponse)(nil), // 33: AliTopUpNotifyResponse
|
||||
}
|
||||
var file_sentinel_proto_depIdxs = []int32{
|
||||
5, // 0: WhitelistResponse.whitelists:type_name -> Whitelist
|
||||
@@ -2163,25 +2384,29 @@ var file_sentinel_proto_depIdxs = []int32{
|
||||
23, // 18: userProduct.CreateUserProduct:input_type -> CreateUserProductRequest
|
||||
1, // 19: userProduct.GetUserProductPageList:input_type -> UserProuctPageListRequest
|
||||
27, // 20: userProduct.MatchingUserIdProductCode:input_type -> matchingUserIdProductCodeRequest
|
||||
5, // 21: whitelist.CreateWhitelist:output_type -> Whitelist
|
||||
5, // 22: whitelist.UpdateWhitelist:output_type -> Whitelist
|
||||
5, // 23: whitelist.DeleteWhitelist:output_type -> Whitelist
|
||||
9, // 24: whitelist.GetWhitePageList:output_type -> WhitelistResponse
|
||||
28, // 25: whitelist.MatchWhitelistByIp:output_type -> matchResponse
|
||||
10, // 26: secret.CreateSecret:output_type -> Secret
|
||||
10, // 27: secret.GetSecretByUserId:output_type -> Secret
|
||||
10, // 28: secret.GetSecretBySecretId:output_type -> Secret
|
||||
16, // 29: product.CreateProduct:output_type -> Product
|
||||
16, // 30: product.UpdateProduct:output_type -> Product
|
||||
16, // 31: product.DeleteProduct:output_type -> Product
|
||||
20, // 32: product.GetProductPageList:output_type -> ProductResponse
|
||||
16, // 33: product.GetProductById:output_type -> Product
|
||||
16, // 34: product.GetProductByCode:output_type -> Product
|
||||
21, // 35: userProduct.CreateUserProduct:output_type -> UserProductEmptyResponse
|
||||
26, // 36: userProduct.GetUserProductPageList:output_type -> UserProductResponse
|
||||
28, // 37: userProduct.MatchingUserIdProductCode:output_type -> matchResponse
|
||||
21, // [21:38] is the sub-list for method output_type
|
||||
4, // [4:21] is the sub-list for method input_type
|
||||
30, // 21: topUp.AliTopUp:input_type -> AliTopUpRequest
|
||||
32, // 22: topUp.AliTopUpNotify:input_type -> AliTopUpNotifyRequest
|
||||
5, // 23: whitelist.CreateWhitelist:output_type -> Whitelist
|
||||
5, // 24: whitelist.UpdateWhitelist:output_type -> Whitelist
|
||||
5, // 25: whitelist.DeleteWhitelist:output_type -> Whitelist
|
||||
9, // 26: whitelist.GetWhitePageList:output_type -> WhitelistResponse
|
||||
28, // 27: whitelist.MatchWhitelistByIp:output_type -> matchResponse
|
||||
10, // 28: secret.CreateSecret:output_type -> Secret
|
||||
10, // 29: secret.GetSecretByUserId:output_type -> Secret
|
||||
10, // 30: secret.GetSecretBySecretId:output_type -> Secret
|
||||
16, // 31: product.CreateProduct:output_type -> Product
|
||||
16, // 32: product.UpdateProduct:output_type -> Product
|
||||
16, // 33: product.DeleteProduct:output_type -> Product
|
||||
20, // 34: product.GetProductPageList:output_type -> ProductResponse
|
||||
16, // 35: product.GetProductById:output_type -> Product
|
||||
16, // 36: product.GetProductByCode:output_type -> Product
|
||||
21, // 37: userProduct.CreateUserProduct:output_type -> UserProductEmptyResponse
|
||||
26, // 38: userProduct.GetUserProductPageList:output_type -> UserProductResponse
|
||||
28, // 39: userProduct.MatchingUserIdProductCode:output_type -> matchResponse
|
||||
31, // 40: topUp.AliTopUp:output_type -> AliTopUpResponse
|
||||
33, // 41: topUp.AliTopUpNotify:output_type -> AliTopUpNotifyResponse
|
||||
23, // [23:42] is the sub-list for method output_type
|
||||
4, // [4:23] is the sub-list for method input_type
|
||||
4, // [4:4] is the sub-list for extension type_name
|
||||
4, // [4:4] is the sub-list for extension extendee
|
||||
0, // [0:4] is the sub-list for field type_name
|
||||
@@ -2553,6 +2778,54 @@ func file_sentinel_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_sentinel_proto_msgTypes[30].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*AliTopUpRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_sentinel_proto_msgTypes[31].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*AliTopUpResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_sentinel_proto_msgTypes[32].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*AliTopUpNotifyRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_sentinel_proto_msgTypes[33].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*AliTopUpNotifyResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
@@ -2560,9 +2833,9 @@ func file_sentinel_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_sentinel_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 30,
|
||||
NumMessages: 34,
|
||||
NumExtensions: 0,
|
||||
NumServices: 4,
|
||||
NumServices: 5,
|
||||
},
|
||||
GoTypes: file_sentinel_proto_goTypes,
|
||||
DependencyIndexes: file_sentinel_proto_depIdxs,
|
||||
|
||||
@@ -887,3 +887,132 @@ var UserProduct_ServiceDesc = grpc.ServiceDesc{
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "sentinel.proto",
|
||||
}
|
||||
|
||||
const (
|
||||
TopUp_AliTopUp_FullMethodName = "/topUp/AliTopUp"
|
||||
TopUp_AliTopUpNotify_FullMethodName = "/topUp/AliTopUpNotify"
|
||||
)
|
||||
|
||||
// TopUpClient is the client API for TopUp service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type TopUpClient interface {
|
||||
AliTopUp(ctx context.Context, in *AliTopUpRequest, opts ...grpc.CallOption) (*AliTopUpResponse, error)
|
||||
AliTopUpNotify(ctx context.Context, in *AliTopUpNotifyRequest, opts ...grpc.CallOption) (*AliTopUpNotifyResponse, error)
|
||||
}
|
||||
|
||||
type topUpClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewTopUpClient(cc grpc.ClientConnInterface) TopUpClient {
|
||||
return &topUpClient{cc}
|
||||
}
|
||||
|
||||
func (c *topUpClient) AliTopUp(ctx context.Context, in *AliTopUpRequest, opts ...grpc.CallOption) (*AliTopUpResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(AliTopUpResponse)
|
||||
err := c.cc.Invoke(ctx, TopUp_AliTopUp_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *topUpClient) AliTopUpNotify(ctx context.Context, in *AliTopUpNotifyRequest, opts ...grpc.CallOption) (*AliTopUpNotifyResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(AliTopUpNotifyResponse)
|
||||
err := c.cc.Invoke(ctx, TopUp_AliTopUpNotify_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// TopUpServer is the server API for TopUp service.
|
||||
// All implementations must embed UnimplementedTopUpServer
|
||||
// for forward compatibility
|
||||
type TopUpServer interface {
|
||||
AliTopUp(context.Context, *AliTopUpRequest) (*AliTopUpResponse, error)
|
||||
AliTopUpNotify(context.Context, *AliTopUpNotifyRequest) (*AliTopUpNotifyResponse, error)
|
||||
mustEmbedUnimplementedTopUpServer()
|
||||
}
|
||||
|
||||
// UnimplementedTopUpServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedTopUpServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedTopUpServer) AliTopUp(context.Context, *AliTopUpRequest) (*AliTopUpResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AliTopUp not implemented")
|
||||
}
|
||||
func (UnimplementedTopUpServer) AliTopUpNotify(context.Context, *AliTopUpNotifyRequest) (*AliTopUpNotifyResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AliTopUpNotify not implemented")
|
||||
}
|
||||
func (UnimplementedTopUpServer) mustEmbedUnimplementedTopUpServer() {}
|
||||
|
||||
// UnsafeTopUpServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to TopUpServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeTopUpServer interface {
|
||||
mustEmbedUnimplementedTopUpServer()
|
||||
}
|
||||
|
||||
func RegisterTopUpServer(s grpc.ServiceRegistrar, srv TopUpServer) {
|
||||
s.RegisterService(&TopUp_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _TopUp_AliTopUp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AliTopUpRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TopUpServer).AliTopUp(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: TopUp_AliTopUp_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TopUpServer).AliTopUp(ctx, req.(*AliTopUpRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _TopUp_AliTopUpNotify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AliTopUpNotifyRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TopUpServer).AliTopUpNotify(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: TopUp_AliTopUpNotify_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TopUpServer).AliTopUpNotify(ctx, req.(*AliTopUpNotifyRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// TopUp_ServiceDesc is the grpc.ServiceDesc for TopUp service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var TopUp_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "topUp",
|
||||
HandlerType: (*TopUpServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "AliTopUp",
|
||||
Handler: _TopUp_AliTopUp_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AliTopUpNotify",
|
||||
Handler: _TopUp_AliTopUpNotify_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "sentinel.proto",
|
||||
}
|
||||
|
||||
4
go.mod
4
go.mod
@@ -77,6 +77,10 @@ require (
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/redis/go-redis/v9 v9.6.1 // indirect
|
||||
github.com/segmentio/kafka-go v0.4.47 // indirect
|
||||
github.com/smartwalle/alipay/v3 v3.2.23 // indirect
|
||||
github.com/smartwalle/ncrypto v1.0.4 // indirect
|
||||
github.com/smartwalle/ngx v1.0.9 // indirect
|
||||
github.com/smartwalle/nsign v1.0.9 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/tjfoc/gmsm v1.3.2 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
|
||||
|
||||
8
go.sum
8
go.sum
@@ -234,6 +234,14 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/segmentio/kafka-go v0.4.47 h1:IqziR4pA3vrZq7YdRxaT3w1/5fvIH5qpCwstUanQQB0=
|
||||
github.com/segmentio/kafka-go v0.4.47/go.mod h1:HjF6XbOKh0Pjlkr5GVZxt6CsjjwnmhVOfURM5KMd8qg=
|
||||
github.com/smartwalle/alipay/v3 v3.2.23 h1:i1VwJeu70EmwpsXXz6GZZnMAtRx5MTfn2dPoql/L3zE=
|
||||
github.com/smartwalle/alipay/v3 v3.2.23/go.mod h1:lVqFiupPf8YsAXaq5JXcwqnOUC2MCF+2/5vub+RlagE=
|
||||
github.com/smartwalle/ncrypto v1.0.4 h1:P2rqQxDepJwgeO5ShoC+wGcK2wNJDmcdBOWAksuIgx8=
|
||||
github.com/smartwalle/ncrypto v1.0.4/go.mod h1:Dwlp6sfeNaPMnOxMNayMTacvC5JGEVln3CVdiVDgbBk=
|
||||
github.com/smartwalle/ngx v1.0.9 h1:pUXDvWRZJIHVrCKA1uZ15YwNti+5P4GuJGbpJ4WvpMw=
|
||||
github.com/smartwalle/ngx v1.0.9/go.mod h1:mx/nz2Pk5j+RBs7t6u6k22MPiBG/8CtOMpCnALIG8Y0=
|
||||
github.com/smartwalle/nsign v1.0.9 h1:8poAgG7zBd8HkZy9RQDwasC6XZvJpDGQWSjzL2FZL6E=
|
||||
github.com/smartwalle/nsign v1.0.9/go.mod h1:eY6I4CJlyNdVMP+t6z1H6Jpd4m5/V+8xi44ufSTxXgc=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.1.0 h1:MkTeG1DMwsrdH7QtLXy5W+fUxWq+vmb6cLmyJ7aRtF0=
|
||||
github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
|
||||
|
||||
36
pkg/generate/pay.go
Normal file
36
pkg/generate/pay.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
mathrand "math/rand"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GenerateTransactionID 生成唯一订单号的函数
|
||||
func GenerateTransactionID() string {
|
||||
length := 16
|
||||
// 获取当前时间戳
|
||||
timestamp := time.Now().UnixNano()
|
||||
|
||||
// 转换为字符串
|
||||
timeStr := strconv.FormatInt(timestamp, 10)
|
||||
|
||||
// 生成随机数
|
||||
mathrand.Seed(time.Now().UnixNano())
|
||||
randomPart := strconv.Itoa(mathrand.Intn(1000000))
|
||||
|
||||
// 组合时间戳和随机数
|
||||
combined := timeStr + randomPart
|
||||
|
||||
// 如果长度超出指定值,则截断;如果不够,则填充随机字符
|
||||
if len(combined) >= length {
|
||||
return combined[:length]
|
||||
}
|
||||
|
||||
// 如果长度不够,填充0
|
||||
for len(combined) < length {
|
||||
combined += strconv.Itoa(mathrand.Intn(10)) // 填充随机数
|
||||
}
|
||||
|
||||
return combined
|
||||
}
|
||||
Reference in New Issue
Block a user