邮乐服务

This commit is contained in:
Rzy 2024-07-16 16:51:39 +08:00
commit 6f255b66d2
48 changed files with 8167 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/.idea
/cmd/api/etc
/genModel.sh

32
Dockerfile Normal file
View File

@ -0,0 +1,32 @@
FROM registry.cn-chengdu.aliyuncs.com/go_ls/go-zero:v1 AS builder
LABEL stage=gobuilder
ENV CGO_ENABLED 0
ENV GOPROXY https://goproxy.cn,direct
WORKDIR /src
COPY ../.. .
RUN go mod tidy
RUN go build -ldflags="-s -w" -o /src/cmd/api/yl cmd/api/yl.go
FROM registry.cn-chengdu.aliyuncs.com/go_ls/alpha:v1 AS runtime
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
ENV TZ Asia/Shanghai
COPY --from=builder /src /src
RUN mkdir "/var/log/supervisor"
ADD ./sh/startup.sh /opt/startup.sh
RUN sed -i 's/\r//g' /opt/startup.sh
ADD ./sh/supervisord.conf /etc/supervisord.conf
WORKDIR /src
EXPOSE 10102
#CMD ["sh","/opt/startup.sh"]

73
Makefile Normal file
View File

@ -0,0 +1,73 @@
GOHOSTOS:=$(shell go env GOHOSTOS)
GOPATH:=$(shell go env GOPATH)
VERSION=$(shell git describe --tags --always)
ifeq ($(GOHOSTOS), windows)
#the `find.exe` is different from `find` in bash/shell.
#to see https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/find.
#changed to use git-bash.exe to run find cli or other cli friendly, caused of every developer has a Git.
#Git_Bash= $(subst cmd\,bin\bash.exe,$(dir $(shell where git)))
Git_Bash=$(subst \,/,$(subst cmd\,bin\bash.exe,$(dir $(shell where git))))
INTERNAL_PROTO_FILES=$(shell $(Git_Bash) -c "find internal -name *.proto")
API_PROTO_FILES=$(shell $(Git_Bash) -c "find api -name *.proto")
else
INTERNAL_PROTO_FILES=$(shell find internal -name *.proto)
API_PROTO_FILES=$(shell find api -name *.proto)
endif
.PHONY: apigen
# 根据api创建http文件
apigen:
cd cmd/api/doc && goctl api go -api *.api -dir ../ --style=goZero
.PHONY: rpcgen
# 根据protoc创建rpc文件
rpcgen:
cd cmd/rpc/pb && goctl rpc protoc *.proto --go_out=../pb --go-grpc_out=../pb --zrpc_out=../ --client=false --style=goZero
.PHONY: apiinitrpc
# api端生成rpc
apiinitrpc:
cd rpc && goctl rpc protoc *.proto --go_out=./ --go-grpc_out=./ --zrpc_out=./ --client=true --style=goZero && rm -r etc && rm -r internal && rm *.go
.PHONY: rpcrun
# 运行rpc
rpcrun:
cd cmd/rpc && go run yl.go
.PHONY: apirun
# 运行rpc
apirun:
cd cmd/api && go run yl.go
.PHONY: apivalidate
# 运行rpc
apivalidate:
cd cmd/api/doc && goctl api validate --api *.api
.PHONY: apiformat
# 运行rpc
apiformat:
cd cmd/api/doc && goctl api format --dir ./
.PHONY: apitodoc
# 运行rpc
apitodoc:
cd cmd/api/doc && goctl api doc --dir ./
.PHONY: templateUpdate
# rpcdocker
templateUpdate:
cd template && goctl template update --home ./
.PHONY: rpcdocker
# rpcdocker
rpcdocker:
goctl docker -go ./cmd/rpc/transfer.go

25
cmd/api/doc/api.api Normal file
View File

@ -0,0 +1,25 @@
syntax = "v1"
info (
title: "邮乐"
desc: "邮乐"
author: "RZY"
email: "465386466@qq.com"
version: "v1"
)
import (
"vo/base.api"
)
@server (
prefix: /market
group: yl
middleware: SignMiddleware
)
service yl {
@doc "卡密同步发放接口"
@handler yl
post /key/send (Req) returns (Resp)
}

31
cmd/api/doc/vo/base.api Normal file
View File

@ -0,0 +1,31 @@
syntax = "v1"
type Empty {}
type Req{
DeliverOrderNo string `json:"deliverOrderNo"`
RequestTime int64 `json:"requestTime"`
CreateTime int64 `json:"createTime"`
SupplierSkuId int64 `json:"supplierSkuId"`
ThirdSkuId string `json:"thirdSkuId"`
SupplierId int64 `json:"supplierId"`
ExtendParams string `json:"extendParams"`
Sign string `json:"sign"`
}
type Resp{
CdKey string `json:"cdKey"`
CdNum string `json:"cdNum"`
ExchangeUrl string `json:"exchangeUrl"`
SupplierOrderNo string `json:"supplierOrderNo"`
startTime string `json:"startTime"`
endTime string `json:"endTime"`
}

View File

@ -0,0 +1,25 @@
package config
import (
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/rest"
)
type Config struct {
rest.RestConf
Rpc
Cache cache.CacheConf
Sys struct {
PrimaryKey string
Url string
Key string
}
}
type Rpc struct {
Nacos Nacos
}
type Nacos struct {
Target string
}

View File

@ -0,0 +1,28 @@
// Code generated by goctl. DO NOT EDIT.
package handler
import (
"net/http"
yl "rs/cmd/api/internal/handler/yl"
"rs/cmd/api/internal/svc"
"github.com/zeromicro/go-zero/rest"
)
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes(
rest.WithMiddlewares(
[]rest.Middleware{serverCtx.SignMiddleware},
[]rest.Route{
{
// 卡密同步发放接口
Method: http.MethodPost,
Path: "/key/send",
Handler: yl.YlHandler(serverCtx),
},
}...,
),
rest.WithPrefix("/market"),
)
}

View File

@ -0,0 +1,31 @@
package yl
import (
"net/http"
"rs/untils/response"
"github.com/zeromicro/go-zero/rest/httpx"
"rs/cmd/api/internal/logic/yl"
"rs/cmd/api/internal/svc"
"rs/cmd/api/internal/types"
)
// 卡密同步发放接口
func YlHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.Req
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := yl.NewYlLogic(r.Context(), svcCtx)
resp, err := l.Yl(&req)
if err != nil {
response.Err(w, response.HTTP_REUEST_FAIL, err.Error())
} else {
response.Suc(w, response.HTTP_SUCCESS, resp)
}
}
}

View File

@ -0,0 +1,27 @@
package do
import (
"context"
"encoding/json"
"rs/cmd/api/internal/svc"
"rs/cmd/api/internal/types"
)
func NotifyInfo(req any, SipOrderNo string, svcCtx *svc.ServiceContext, ctx context.Context) (notify types.NotifyTypes, requestBody map[string]string, err error) {
requestBody = make(map[string]string, 3)
reqJson, _ := json.Marshal(req)
_ = json.Unmarshal(reqJson, &requestBody)
orderInfo, err := svcCtx.TransferOrder.FindByOutBizNo(ctx, SipOrderNo)
if err != nil {
return notify, requestBody, err
}
merchantInfo, err := svcCtx.MerchantWechat.FindOneByMerchantId(ctx, orderInfo.VoucherNum)
if err != nil {
return notify, requestBody, err
}
err = json.Unmarshal([]byte(merchantInfo.NotifyUrl.String), &notify)
if err != nil {
return notify, requestBody, err
}
return notify, requestBody, err
}

View File

@ -0,0 +1,5 @@
package vo
const (
RES_SUCCESS = "00"
)

View File

@ -0,0 +1,81 @@
package yl
import (
"context"
"fmt"
"github.com/bytedance/sonic"
"rs/cmd/api/internal/logic/vo"
"rs/rpc/transfer"
"time"
"rs/cmd/api/internal/svc"
"rs/cmd/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type YlLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// 卡密同步发放接口
func NewYlLogic(ctx context.Context, svcCtx *svc.ServiceContext) *YlLogic {
return &YlLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *YlLogic) Yl(req *types.Req) (resp *types.Resp, err error) {
var (
reqData transfer.MarketKeySendReq
extendParam types.KeySendExtendParam
)
err = sonic.Unmarshal([]byte(req.ExtendParams), &extendParam)
if err != nil {
return nil, fmt.Errorf("extendParam 格式错误")
}
reqData = transfer.MarketKeySendReq{
AppId: extendParam.AppId,
ReqCode: "voucher.create",
MemId: fmt.Sprintf("%d", req.SupplierId),
ReqSerialNo: req.DeliverOrderNo,
Timestamp: time.Unix(req.CreateTime, 0).Format("20060102150405"),
PosId: extendParam.PosId,
VoucherId: req.ThirdSkuId,
VoucherNum: extendParam.Num,
MobileNo: extendParam.MobileNo,
SendMsg: extendParam.SendMsg,
}
if reqData.SendMsg == "" {
reqData.SendMsg = "2"
}
reqData.Sign = l.svcCtx.Config.Sys.PrimaryKey
result, err := l.svcCtx.TransferRpc.MarketKeySend(l.ctx, &reqData)
if err != nil {
return nil, fmt.Errorf("请求失败:%v", err)
}
if result.ErrCode != vo.RES_SUCCESS {
return nil, fmt.Errorf("请求失败:%v", result.Msg)
}
startTime, err := time.Parse("20060102", result.Data.VoucherSdate)
if err != nil {
startTime = time.Now()
}
endTime, err := time.Parse("20060102", result.Data.VoucherEdate)
if err != nil {
endTime = startTime.AddDate(0, 0, 30).Add(23*time.Hour + 59*time.Minute + 59*time.Second)
}
return &types.Resp{
CdKey: result.Data.VoucherCode,
CdNum: "",
ExchangeUrl: fmt.Sprintf("%s%s", l.svcCtx.Config.Sys.Url, result.Data.VoucherCode),
SupplierOrderNo: req.DeliverOrderNo,
StartTime: startTime.Format(time.DateTime),
EndTime: endTime.Add(23*time.Hour + 59*time.Minute + 59*time.Second).Format(time.DateTime),
}, nil
}

View File

@ -0,0 +1,54 @@
package middleware
import (
"bytes"
"encoding/json"
"io"
"net/http"
"rs/cmd/api/internal/config"
"rs/untils/response"
"rs/untils/sign"
)
type SignMiddleware struct {
c *config.Config
}
func NewSignMiddleware(c *config.Config) *SignMiddleware {
return &SignMiddleware{
c: c,
}
}
func (m *SignMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var (
reqDataMap map[string]interface{}
)
originalBody, err := io.ReadAll(r.Body)
reqData := make([]byte, len(originalBody))
copy(reqData, originalBody)
r.Body = io.NopCloser(bytes.NewReader(originalBody))
if err != nil {
response.Err(w, response.HTTP_AUTH_FAIL, "获取请求参数失败")
}
err = json.Unmarshal(reqData, &reqDataMap)
if err != nil {
response.Err(w, response.HTTP_AUTH_FAIL, "获取请求参数失败")
}
if _, ok := reqDataMap["sign"]; !ok {
response.Err(w, response.HTTP_AUTH_FAIL, "未找到签名字段")
}
if _, ok := reqDataMap["sign"]; !ok {
response.Err(w, response.HTTP_AUTH_FAIL, err.Error())
}
signString := reqDataMap["sign"].(string)
sysSign, err := sign.GetSign(reqDataMap, m.c.Sys.Key)
if sysSign != signString {
response.Err(w, response.HTTP_AUTH_FAIL, "签名不正确")
return
}
next(w, r)
}
}

View File

@ -0,0 +1,34 @@
package svc
import (
"github.com/zeromicro/go-zero/rest"
"github.com/zeromicro/go-zero/zrpc"
_ "github.com/zeromicro/zero-contrib/zrpc/registry/nacos"
"rs/cmd/api/internal/config"
"rs/cmd/api/internal/middleware"
"rs/cmd/api/internal/types"
"rs/rpc/transferClient"
)
type ServiceContext struct {
*types.BaseServiceContext
SignMiddleware rest.Middleware
}
func NewServiceContext(c config.Config) *ServiceContext {
conn := zrpc.MustNewClient(zrpc.RpcClientConf{
Target: c.Nacos.Target,
//Endpoints: []string{"127.0.0.1:10001"},
})
client := transferClient.NewTransfer(conn)
base := types.BaseServiceContext{
Config: c,
TransferRpc: client,
}
return &ServiceContext{
BaseServiceContext: &base,
SignMiddleware: middleware.NewSignMiddleware(&c).Handle,
}
}

View File

@ -0,0 +1,24 @@
package test
import (
"encoding/json"
"fmt"
"rs/untils/sign"
"testing"
)
const PrimaryKey = "da4953198bce4bc8eca9ff7101ae7eb8"
func TestSign(t *testing.T) {
var (
reqDataMap map[string]interface{}
)
j := "{\"createTime\":1721111144,\"deliverOrderNo\":\"DELIVER_1721111144961285\",\"extendParams\":\"{\\\"appId\\\":2783278,\\\"num\\\":1,\\\"posId\\\":2783278}\",\"requestTime\":1721111144,\"sign\":\"NDEyNWNhODMwY2FjYjJmNTgwYWY5Njk1ODJjMTI1YmEyYzNlN2M0MTlmNDliZjg5MDc0NTQ3MDVkYjI1MDAyOA==\",\"supplierId\":51,\"supplierSkuId\":808,\"thirdSkuId\":\"yl20240712\"}"
err := json.Unmarshal([]byte(j), &reqDataMap)
if err != nil {
panic("j")
}
sysSign, err := sign.GetSign(reqDataMap, PrimaryKey)
fmt.Println(sysSign)
}

View File

@ -0,0 +1,38 @@
package types
import (
"rs/cmd/api/internal/config"
"rs/genModel"
"rs/rpc/transferClient"
)
type BaseServiceContext struct {
Config config.Config
TransferRpc transferClient.Transfer // 调用transfer服务
ProductRedirectConf genModel.ProductRedirectConfModel
Merchant genModel.MerchantModel
TransferOrder genModel.ServerOrderModel
MerchantWechat genModel.MerchantWechatModel
}
type DecryptReqData struct {
SipOrderNo string `json:"sipOrderNo"`
VoucherTag string `json:"voucherTag"`
AccountType int32 `json:"accountType"`
AccountNo string `json:"accountNo"`
AccountInfo string `json:"accountInfo,optional"`
Num int32 `json:"num"`
}
type NotifyTypes struct {
Coupon string `json:"coupon_grant_order"`
Grant string `json:"wechat_coupon_status"`
}
type KeySendExtendParam struct {
AppId string `json:"appId"`
PosId string `json:"posId"`
Num int64 `json:"num"`
MobileNo string `json:"mobileNo"`
SendMsg string `json:"sendMsg"`
}

View File

@ -0,0 +1,25 @@
// Code generated by goctl. DO NOT EDIT.
package types
type Empty struct {
}
type Req struct {
DeliverOrderNo string `json:"deliverOrderNo"`
RequestTime int64 `json:"requestTime"`
CreateTime int64 `json:"createTime"`
SupplierSkuId int64 `json:"supplierSkuId"`
ThirdSkuId string `json:"thirdSkuId"`
SupplierId int64 `json:"supplierId"`
ExtendParams string `json:"extendParams"`
Sign string `json:"sign"`
}
type Resp struct {
CdKey string `json:"cdKey"`
CdNum string `json:"cdNum"`
ExchangeUrl string `json:"exchangeUrl"`
SupplierOrderNo string `json:"supplierOrderNo"`
StartTime string `json:"startTime"`
EndTime string `json:"endTime"`
}

31
cmd/api/yl.go Normal file
View File

@ -0,0 +1,31 @@
package main
import (
"flag"
"fmt"
"rs/cmd/api/internal/config"
"rs/cmd/api/internal/handler"
"rs/cmd/api/internal/svc"
"github.com/zeromicro/go-zero/core/conf"
"github.com/zeromicro/go-zero/rest"
)
var configFile = flag.String("f", "etc/yl-test.yaml", "the config file")
func main() {
flag.Parse()
var c config.Config
conf.MustLoad(*configFile, &c)
server := rest.MustNewServer(c.RestConf)
defer server.Stop()
ctx := svc.NewServiceContext(c)
handler.RegisterHandlers(server, ctx)
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
server.Start()
}

27
genModel/merchantModel.go Normal file
View File

@ -0,0 +1,27 @@
package genModel
import (
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
var _ MerchantModel = (*customMerchantModel)(nil)
type (
// MerchantModel is an interface to be customized, add more methods here,
// and implement the added methods in customMerchantModel.
MerchantModel interface {
merchantModel
}
customMerchantModel struct {
*defaultMerchantModel
}
)
// NewMerchantModel returns a model for the database table.
func NewMerchantModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) MerchantModel {
return &customMerchantModel{
defaultMerchantModel: newMerchantModel(conn, c, opts...),
}
}

View File

@ -0,0 +1,160 @@
// Code generated by goctl. DO NOT EDIT.
package genModel
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 (
merchantFieldNames = builder.RawFieldNames(&Merchant{})
merchantRows = strings.Join(merchantFieldNames, ",")
merchantRowsExpectAutoSet = strings.Join(stringx.Remove(merchantFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
merchantRowsWithPlaceHolder = strings.Join(stringx.Remove(merchantFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
cacheCouponOpenMerchantIdPrefix = "cache:couponOpen:merchant:id:"
cacheCouponOpenMerchantMerchantIdPrefix = "cache:couponOpen:merchant:merchantId:"
)
type (
merchantModel interface {
Insert(ctx context.Context, data *Merchant) (sql.Result, error)
FindOne(ctx context.Context, id uint64) (*Merchant, error)
FindOneByMerchantId(ctx context.Context, merchantId string) (*Merchant, error)
Update(ctx context.Context, data *Merchant) error
Delete(ctx context.Context, id uint64) error
}
defaultMerchantModel struct {
sqlc.CachedConn
table string
}
Merchant struct {
Id uint64 `db:"id"`
MerchantId string `db:"merchant_id"` // 商户号
FullName string `db:"full_name"` // 商户全称
Status int64 `db:"status"` // 状态 1可用 2禁用
SignatureMethod uint64 `db:"signature_method"` // 签名方式1 Rsa2 2 Sm
RsaPublicKey sql.NullString `db:"rsa_public_key"` // rsa公钥
RsaPrivateKey sql.NullString `db:"rsa_private_key"` // rsa私钥
MchRsaPublicKey sql.NullString `db:"mch_rsa_public_key"`
Sm2PublicKey sql.NullString `db:"sm2_public_key"` // 国密sm2公钥
Sm2PrivateKey sql.NullString `db:"sm2_private_key"` // 国密sm2私钥
MchSm2PublicKey sql.NullString `db:"mch_sm2_public_key"` // 商户侧国密sm2公钥
Sm4SecretKey sql.NullString `db:"sm4_secret_key"` // 国密sm4报文加密密钥
IpAccess sql.NullString `db:"ip_access"` // ip白名单["192.168.6.18"]
RequestRate sql.NullString `db:"request_rate"` // 请求频率限制{ "default": "500", "wechat_coupon_send" : "500"}
UpdateTime sql.NullTime `db:"update_time"` // 更新时间
CreateTime time.Time `db:"create_time"` // 创建时间
Password string `db:"password"` // 登陆密码
Phone sql.NullString `db:"phone"` // 手机号
}
)
func newMerchantModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) *defaultMerchantModel {
return &defaultMerchantModel{
CachedConn: sqlc.NewConn(conn, c, opts...),
table: "`merchant`",
}
}
func (m *defaultMerchantModel) Delete(ctx context.Context, id uint64) error {
data, err := m.FindOne(ctx, id)
if err != nil {
return err
}
couponOpenMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantIdPrefix, id)
couponOpenMerchantMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantMerchantIdPrefix, data.MerchantId)
_, 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)
}, couponOpenMerchantIdKey, couponOpenMerchantMerchantIdKey)
return err
}
func (m *defaultMerchantModel) FindOne(ctx context.Context, id uint64) (*Merchant, error) {
couponOpenMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantIdPrefix, id)
var resp Merchant
err := m.QueryRowCtx(ctx, &resp, couponOpenMerchantIdKey, func(ctx context.Context, conn sqlx.SqlConn, v any) error {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", merchantRows, 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 *defaultMerchantModel) FindOneByMerchantId(ctx context.Context, merchantId string) (*Merchant, error) {
couponOpenMerchantMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantMerchantIdPrefix, merchantId)
var resp Merchant
err := m.QueryRowIndexCtx(ctx, &resp, couponOpenMerchantMerchantIdKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v any) (i any, e error) {
query := fmt.Sprintf("select %s from %s where `merchant_id` = ? limit 1", merchantRows, m.table)
if err := conn.QueryRowCtx(ctx, &resp, query, merchantId); 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 *defaultMerchantModel) Insert(ctx context.Context, data *Merchant) (sql.Result, error) {
couponOpenMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantIdPrefix, data.Id)
couponOpenMerchantMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantMerchantIdPrefix, data.MerchantId)
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, merchantRowsExpectAutoSet)
return conn.ExecCtx(ctx, query, data.MerchantId, data.FullName, data.Status, data.SignatureMethod, data.RsaPublicKey, data.RsaPrivateKey, data.MchRsaPublicKey, data.Sm2PublicKey, data.Sm2PrivateKey, data.MchSm2PublicKey, data.Sm4SecretKey, data.IpAccess, data.RequestRate, data.Password, data.Phone)
}, couponOpenMerchantIdKey, couponOpenMerchantMerchantIdKey)
return ret, err
}
func (m *defaultMerchantModel) Update(ctx context.Context, newData *Merchant) error {
data, err := m.FindOne(ctx, newData.Id)
if err != nil {
return err
}
couponOpenMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantIdPrefix, data.Id)
couponOpenMerchantMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantMerchantIdPrefix, data.MerchantId)
_, 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, merchantRowsWithPlaceHolder)
return conn.ExecCtx(ctx, query, newData.MerchantId, newData.FullName, newData.Status, newData.SignatureMethod, newData.RsaPublicKey, newData.RsaPrivateKey, newData.MchRsaPublicKey, newData.Sm2PublicKey, newData.Sm2PrivateKey, newData.MchSm2PublicKey, newData.Sm4SecretKey, newData.IpAccess, newData.RequestRate, newData.Password, newData.Phone, newData.Id)
}, couponOpenMerchantIdKey, couponOpenMerchantMerchantIdKey)
return err
}
func (m *defaultMerchantModel) formatPrimary(primary any) string {
return fmt.Sprintf("%s%v", cacheCouponOpenMerchantIdPrefix, primary)
}
func (m *defaultMerchantModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary any) error {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", merchantRows, m.table)
return conn.QueryRowCtx(ctx, v, query, primary)
}
func (m *defaultMerchantModel) tableName() string {
return m.table
}

View File

@ -0,0 +1,29 @@
package genModel
import "github.com/zeromicro/go-zero/core/stores/sqlx"
var _ MerchantWechatModel = (*customMerchantWechatModel)(nil)
type (
// MerchantWechatModel is an interface to be customized, add more methods here,
// and implement the added methods in customMerchantWechatModel.
MerchantWechatModel interface {
merchantWechatModel
withSession(session sqlx.Session) MerchantWechatModel
}
customMerchantWechatModel struct {
*defaultMerchantWechatModel
}
)
// NewMerchantWechatModel returns a model for the database table.
func NewMerchantWechatModel(conn sqlx.SqlConn) MerchantWechatModel {
return &customMerchantWechatModel{
defaultMerchantWechatModel: newMerchantWechatModel(conn),
}
}
func (m *customMerchantWechatModel) withSession(session sqlx.Session) MerchantWechatModel {
return NewMerchantWechatModel(sqlx.NewSqlConnFromSession(session))
}

View File

@ -0,0 +1,102 @@
// Code generated by goctl. DO NOT EDIT.
package genModel
import (
"context"
"database/sql"
"fmt"
"strings"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
merchantWechatFieldNames = builder.RawFieldNames(&MerchantWechat{})
merchantWechatRows = strings.Join(merchantWechatFieldNames, ",")
merchantWechatRowsExpectAutoSet = strings.Join(stringx.Remove(merchantWechatFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
merchantWechatRowsWithPlaceHolder = strings.Join(stringx.Remove(merchantWechatFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
)
type (
merchantWechatModel interface {
Insert(ctx context.Context, data *MerchantWechat) (sql.Result, error)
FindOne(ctx context.Context, id uint64) (*MerchantWechat, error)
Update(ctx context.Context, data *MerchantWechat) error
Delete(ctx context.Context, id uint64) error
FindOneByMerchantId(ctx context.Context, merchant_id string) (*MerchantWechat, error)
}
defaultMerchantWechatModel struct {
conn sqlx.SqlConn
table string
}
MerchantWechat struct {
Id uint64 `db:"id"`
MerchantId sql.NullString `db:"merchant_id"` // 商户号
WechatMerchantId sql.NullString `db:"wechat_merchant_id"` // sip的微信商户号
WechatAppId sql.NullString `db:"wechat_app_id"` // sip的微信app_id [{"appid" :"xxxxx", "default": "1"}]支持设置多个appid 但是只能设置一个default = 1 代码当前商户正在用的appid。 如果需要使用其他appid发券 那么需要商户侧通过接口传入appid
NotifyUrl sql.NullString `db:"notify_url"` // 回调通知地址[{"coupon_grant_order":"xxxx"},{"wechat_coupon_status":"xxxxx"}]
CreateTime sql.NullTime `db:"create_time"`
}
)
func newMerchantWechatModel(conn sqlx.SqlConn) *defaultMerchantWechatModel {
return &defaultMerchantWechatModel{
conn: conn,
table: "`merchant_wechat`",
}
}
func (m *defaultMerchantWechatModel) Delete(ctx context.Context, id uint64) error {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, id)
return err
}
func (m *defaultMerchantWechatModel) FindOne(ctx context.Context, id uint64) (*MerchantWechat, error) {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", merchantWechatRows, m.table)
var resp MerchantWechat
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultMerchantWechatModel) FindOneByMerchantId(ctx context.Context, merchant_id string) (*MerchantWechat, error) {
query := fmt.Sprintf("select %s from %s where `merchant_id` = ? limit 1", merchantWechatRows, m.table)
var resp MerchantWechat
err := m.conn.QueryRowCtx(ctx, &resp, query, merchant_id)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultMerchantWechatModel) Insert(ctx context.Context, data *MerchantWechat) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?)", m.table, merchantWechatRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.MerchantId, data.WechatMerchantId, data.WechatAppId, data.NotifyUrl)
return ret, err
}
func (m *defaultMerchantWechatModel) Update(ctx context.Context, data *MerchantWechat) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, merchantWechatRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, data.MerchantId, data.WechatMerchantId, data.WechatAppId, data.NotifyUrl, data.Id)
return err
}
func (m *defaultMerchantWechatModel) tableName() string {
return m.table
}

View File

@ -0,0 +1,27 @@
package genModel
import (
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
var _ ProductRedirectConfModel = (*customProductRedirectConfModel)(nil)
type (
// ProductRedirectConfModel is an interface to be customized, add more methods here,
// and implement the added methods in customProductRedirectConfModel.
ProductRedirectConfModel interface {
productRedirectConfModel
}
customProductRedirectConfModel struct {
*defaultProductRedirectConfModel
}
)
// NewProductRedirectConfModel returns a model for the database table.
func NewProductRedirectConfModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) ProductRedirectConfModel {
return &customProductRedirectConfModel{
defaultProductRedirectConfModel: newProductRedirectConfModel(conn, c, opts...),
}
}

View File

@ -0,0 +1,132 @@
// Code generated by goctl. DO NOT EDIT.
package genModel
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 (
productRedirectConfFieldNames = builder.RawFieldNames(&ProductRedirectConf{})
productRedirectConfRows = strings.Join(productRedirectConfFieldNames, ",")
productRedirectConfRowsExpectAutoSet = strings.Join(stringx.Remove(productRedirectConfFieldNames, "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
productRedirectConfRowsWithPlaceHolder = strings.Join(stringx.Remove(productRedirectConfFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
cacheCouponOpenProductRedirectConfIdPrefix = "cache:couponOpen:productRedirectConf:id:"
cacheCouponOpenProductRedirectConfProductNoPrefixPrefix = "cache:couponOpen:productRedirectConf:product_no_prefix:"
)
type (
productRedirectConfModel interface {
Insert(ctx context.Context, data *ProductRedirectConf) (sql.Result, error)
FindOne(ctx context.Context, id int64) (*ProductRedirectConf, error)
Update(ctx context.Context, data *ProductRedirectConf) error
Delete(ctx context.Context, id int64) error
FindOneByProductNoPrefix(ctx context.Context, productNoPrefix string) (*ProductRedirectConf, error)
}
defaultProductRedirectConfModel struct {
sqlc.CachedConn
table string
}
ProductRedirectConf struct {
Id int64 `db:"id"`
ProductNoPrefix string `db:"product_no_prefix"` // 商品编号前缀
RequestUrl string `db:"request_url"` // 分发地址
Method string `db:"method"` // 请求方式
Encrypt uint64 `db:"encrypt"` // 是否需要加密、加签
CreateTime time.Time `db:"create_time"`
}
)
func newProductRedirectConfModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) *defaultProductRedirectConfModel {
return &defaultProductRedirectConfModel{
CachedConn: sqlc.NewConn(conn, c, opts...),
table: "`product_redirect_conf`",
}
}
func (m *defaultProductRedirectConfModel) Delete(ctx context.Context, id int64) error {
couponOpenProductRedirectConfIdKey := fmt.Sprintf("%s%v", cacheCouponOpenProductRedirectConfIdPrefix, id)
_, 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)
}, couponOpenProductRedirectConfIdKey)
return err
}
func (m *defaultProductRedirectConfModel) FindOne(ctx context.Context, id int64) (*ProductRedirectConf, error) {
couponOpenProductRedirectConfIdKey := fmt.Sprintf("%s%v", cacheCouponOpenProductRedirectConfIdPrefix, id)
var resp ProductRedirectConf
err := m.QueryRowCtx(ctx, &resp, couponOpenProductRedirectConfIdKey, func(ctx context.Context, conn sqlx.SqlConn, v any) error {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", productRedirectConfRows, 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 *defaultProductRedirectConfModel) Insert(ctx context.Context, data *ProductRedirectConf) (sql.Result, error) {
couponOpenProductRedirectConfIdKey := fmt.Sprintf("%s%v", cacheCouponOpenProductRedirectConfIdPrefix, data.Id)
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, productRedirectConfRowsExpectAutoSet)
return conn.ExecCtx(ctx, query, data.Id, data.ProductNoPrefix, data.RequestUrl, data.Method, data.Encrypt)
}, couponOpenProductRedirectConfIdKey)
return ret, err
}
func (m *defaultProductRedirectConfModel) Update(ctx context.Context, data *ProductRedirectConf) error {
couponOpenProductRedirectConfIdKey := fmt.Sprintf("%s%v", cacheCouponOpenProductRedirectConfIdPrefix, data.Id)
_, 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, productRedirectConfRowsWithPlaceHolder)
return conn.ExecCtx(ctx, query, data.ProductNoPrefix, data.RequestUrl, data.Method, data.Encrypt, data.Id)
}, couponOpenProductRedirectConfIdKey)
return err
}
func (m *defaultProductRedirectConfModel) formatPrimary(primary any) string {
return fmt.Sprintf("%s%v", cacheCouponOpenProductRedirectConfIdPrefix, primary)
}
func (m *defaultProductRedirectConfModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary any) error {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", productRedirectConfRows, m.table)
return conn.QueryRowCtx(ctx, v, query, primary)
}
func (m *defaultProductRedirectConfModel) FindOneByProductNoPrefix(ctx context.Context, productNoPrefix string) (*ProductRedirectConf, error) {
cacheCouponOpenProductRedirectConfProductNoPrefixPrefix := fmt.Sprintf("%s%v", cacheCouponOpenProductRedirectConfProductNoPrefixPrefix, productNoPrefix)
var resp ProductRedirectConf
err := m.QueryRowCtx(ctx, &resp, cacheCouponOpenProductRedirectConfProductNoPrefixPrefix, func(ctx context.Context, conn sqlx.SqlConn, v any) error {
query := fmt.Sprintf("select %s from %s where `product_no_prefix` = ? limit 1", productRedirectConfRows, m.table)
return conn.QueryRowCtx(ctx, v, query, productNoPrefix)
})
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, nil
default:
return nil, err
}
}
func (m *defaultProductRedirectConfModel) tableName() string {
return m.table
}

View File

@ -0,0 +1,29 @@
package genModel
import "github.com/zeromicro/go-zero/core/stores/sqlx"
var _ ServerOrderModel = (*customServerOrderModel)(nil)
type (
// ServerOrderModel is an interface to be customized, add more methods here,
// and implement the added methods in customServerOrderModel.
ServerOrderModel interface {
serverOrderModel
withSession(session sqlx.Session) ServerOrderModel
}
customServerOrderModel struct {
*defaultServerOrderModel
}
)
// NewServerOrderModel returns a model for the database table.
func NewServerOrderModel(conn sqlx.SqlConn) ServerOrderModel {
return &customServerOrderModel{
defaultServerOrderModel: newServerOrderModel(conn),
}
}
func (m *customServerOrderModel) withSession(session sqlx.Session) ServerOrderModel {
return NewServerOrderModel(sqlx.NewSqlConnFromSession(session))
}

View File

@ -0,0 +1,110 @@
// Code generated by goctl. DO NOT EDIT.
package genModel
import (
"context"
"database/sql"
"fmt"
"strings"
"time"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
serverOrderFieldNames = builder.RawFieldNames(&ServerOrder{})
serverOrderRows = strings.Join(serverOrderFieldNames, ",")
serverOrderRowsExpectAutoSet = strings.Join(stringx.Remove(serverOrderFieldNames, "`order_id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
serverOrderRowsWithPlaceHolder = strings.Join(stringx.Remove(serverOrderFieldNames, "`order_id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
)
type (
serverOrderModel interface {
Insert(ctx context.Context, data *ServerOrder) (sql.Result, error)
FindOne(ctx context.Context, orderId uint64) (*ServerOrder, error)
Update(ctx context.Context, data *ServerOrder) error
Delete(ctx context.Context, orderId uint64) error
FindByOutBizNo(ctx context.Context, out_biz_no string) (*ServerOrder, error)
}
defaultServerOrderModel struct {
conn sqlx.SqlConn
table string
}
ServerOrder struct {
OrderId uint64 `db:"order_id"`
PlatformId int64 `db:"platform_id"` // 下游平台id
OutBizNo string `db:"out_biz_no"` // 用户侧流水号
VoucherNum string `db:"voucher_num"` // 商户号
OrderNum string `db:"order_num"` // 系统侧订单号
ProductId int64 `db:"product_id"` // 平台提供商品id
Num int64 `db:"num"` // 购买数量
LogId sql.NullInt64 `db:"log_id"` // 对应的日志id
ReqTime time.Time `db:"req_time"` // 请求时间
CreateTime time.Time `db:"create_time"`
UpdateTime time.Time `db:"update_time"`
Status int64 `db:"status"` // 状态
}
)
func newServerOrderModel(conn sqlx.SqlConn) *defaultServerOrderModel {
return &defaultServerOrderModel{
conn: conn,
table: "`server_order`",
}
}
func (m *defaultServerOrderModel) Delete(ctx context.Context, orderId uint64) error {
query := fmt.Sprintf("delete from %s where `order_id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, orderId)
return err
}
func (m *defaultServerOrderModel) FindOne(ctx context.Context, orderId uint64) (*ServerOrder, error) {
query := fmt.Sprintf("select %s from %s where `order_id` = ? limit 1", serverOrderRows, m.table)
var resp ServerOrder
err := m.conn.QueryRowCtx(ctx, &resp, query, orderId)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultServerOrderModel) FindByOutBizNo(ctx context.Context, out_biz_no string) (*ServerOrder, error) {
query := fmt.Sprintf("select %s from %s where `out_biz_no` = ? limit 1", serverOrderRows, m.table)
var resp ServerOrder
err := m.conn.QueryRowCtx(ctx, &resp, query, out_biz_no)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultServerOrderModel) Insert(ctx context.Context, data *ServerOrder) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, serverOrderRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.PlatformId, data.OutBizNo, data.VoucherNum, data.OrderNum, data.ProductId, data.Num, data.LogId, data.ReqTime, data.Status)
return ret, err
}
func (m *defaultServerOrderModel) Update(ctx context.Context, data *ServerOrder) error {
query := fmt.Sprintf("update %s set %s where `order_id` = ?", m.table, serverOrderRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, data.PlatformId, data.OutBizNo, data.VoucherNum, data.OrderNum, data.ProductId, data.Num, data.LogId, data.ReqTime, data.Status, data.OrderId)
return err
}
func (m *defaultServerOrderModel) tableName() string {
return m.table
}

5
genModel/vars.go Normal file
View File

@ -0,0 +1,5 @@
package genModel
import "github.com/zeromicro/go-zero/core/stores/sqlx"
var ErrNotFound = sqlx.ErrNotFound

112
go.mod Normal file
View File

@ -0,0 +1,112 @@
module rs
go 1.21
require (
github.com/jinzhu/copier v0.4.0
github.com/zeromicro/go-zero v1.6.4
github.com/zeromicro/zero-contrib/zrpc/registry/nacos v0.0.0-20231030135404-af9ae855016f
google.golang.org/grpc v1.63.2
google.golang.org/protobuf v1.33.0
)
require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/bytedance/sonic v1.11.9 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/go-sql-driver/mysql v1.8.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nacos-group/nacos-sdk-go/v2 v2.2.3 // indirect
github.com/openzipkin/zipkin-go v0.4.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.18.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/redis/go-redis/v9 v9.4.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
go.etcd.io/etcd/api/v3 v3.5.13 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.13 // indirect
go.etcd.io/etcd/client/v3 v3.5.13 // indirect
go.opentelemetry.io/otel v1.19.0 // indirect
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0 // indirect
go.opentelemetry.io/otel/exporters/zipkin v1.19.0 // indirect
go.opentelemetry.io/otel/metric v1.19.0 // indirect
go.opentelemetry.io/otel/sdk v1.19.0 // indirect
go.opentelemetry.io/otel/trace v1.19.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/automaxprocs v1.5.3 // indirect
go.uber.org/multierr v1.9.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/oauth2 v0.17.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/term v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.66.2 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.29.3 // indirect
k8s.io/apimachinery v0.29.3 // indirect
k8s.io/client-go v0.29.3 // indirect
k8s.io/klog/v2 v2.110.1 // indirect
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)

2320
go.sum Normal file

File diff suppressed because it is too large Load Diff

232
rpc/transfer.proto Normal file
View File

@ -0,0 +1,232 @@
syntax = "proto3";
package transfer;
option go_package="./transfer";
message DefaultRes {
string code=1;
string message=2;
}
message DefaultReq {
string merchantId = 1;
uint64 timeStamp = 2;
string sign = 3;
}
service Transfer {
rpc zltxOrderRecharge(ZltxOrderRechargeReq) returns(DefaultRes);
rpc zltxOrderRechargeQuery(ZltxOrderRechargeQueryReq) returns(ZltxOrderRechargeQueryRes);
rpc zltxOrderCard(ZltxOrderCardReq) returns(DefaultRes);
rpc zltxOrderCardQuery(ZltxOrderCardQueryReq) returns(ZltxOrderCardQueryRes);
rpc zltxOrderSms(ZltxOrderSmsReq) returns(ZltxOrderSmsRes);
rpc zltxRechargeInfo(DefaultReq) returns(ZltxRechargeInfoRes);
rpc zltxRechargeProduct(DefaultReq) returns(ZltxRechargeProductRes);
rpc zltxRsMiXue(RsCouponGrantReq) returns(RsCouponGrantRes);
rpc marketKeySend(MarketKeySendReq) returns(MarketKeySendRes);
rpc marketKeyDiscard(MarketKeyDiscardReq) returns(MarketKeyDiscardRes);
rpc marketQuery(MarketQueryReq) returns(MarketQueryRes);
rpc rsCouponGrant(RsCouponGrantReq) returns(RsCouponGrantRes);
}
message RsCouponGrantReq {
string vendorNo = 1;
string data = 2;
string out_biz_no = 3;
int32 num=4;
string sign = 5;
}
message RsCouponGrantRes {
string code = 1;
string message = 2;
string status = 3;
Data data = 4;
message Data {
string sipOrderNo = 1;
string vendorOrderNo = 2;
repeated VoucherInfo voucherInfo = 3;
message VoucherInfo {
string voucherCode = 1;
string voucherPassword = 2;
string voucherDesc = 3;
string qrCodeUrl = 4;
string startTime = 5;
string endTime = 6;
}
}
}
message MarketQueryRes {
string errCode=1;
string msg=2;
Data data=3;
message Data{
string voucher_id = 1;
string voucher_code = 2;
string voucher_status = 5;
}
}
message MarketQueryReq {
string app_id = 1;
uint64 sign = 2;
string req_code = 3;
string mem_id = 4;
string req_serial_no = 5;
string timestamp = 6;
string voucher_id = 8;
string voucher_code = 9;
}
message MarketKeyDiscardRes {
string errCode=1;
string msg=2;
Data data=3;
message Data{
string voucher_id = 1;
string voucher_code = 2;
string voucher_date = 4;
string status = 5;
}
}
message MarketKeyDiscardReq {
string app_id = 1;
uint64 sign = 2;
string req_code = 3;
string mem_id = 4;
string req_serial_no = 5;
string timestamp = 6;
string voucher_id = 8;
string voucher_code = 9;
}
message MarketKeySendRes {
string errCode=1;
string msg=2;
Data data=3;
message Data{
string voucher_id = 1;
string voucher_code = 2;
string short_url = 3;
string voucher_sdate = 4;
string voucher_edate = 5;
string code_type = 6;
}
}
message MarketKeySendReq {
string app_id = 1;
string sign = 2;
string req_code = 3;
string mem_id = 4;
string req_serial_no = 5;
string timestamp = 6;
string pos_id = 7;
string voucher_id = 8;
int64 voucher_num = 9;
string mobile_no = 10;
string send_msg = 11;
string store_id = 12;
}
message ZltxRechargeProductRes {
string code=1;
string message=2;
repeated Product products=3;
message Product{
int64 productId=1;
string channelPrice=2;
string itemName=3;
string originalPrice=4;
}
}
message ZltxRechargeInfoRes {
string code=1;
string balance=2;
}
message ZltxOrderSmsRes {
string code=1;
string message=2;
string status = 3;
string outTradeNo=4;
}
message ZltxOrderSmsReq {
int64 merchantId = 1;
uint64 timeStamp = 2;
string sign = 3;
string outTradeNo = 4;
}
message ZltxOrderCardQueryRes {
string code=1;
string message=2;
string status = 3;
string outTradeNo=4;
}
message ZltxOrderCardQueryReq {
int64 merchantId = 1;
uint64 timeStamp = 2;
string sign = 3;
string outTradeNo = 4;
}
message ZltxOrderCardReq {
int64 merchantId = 1;
string sign = 2;
uint64 timeStamp = 3;
string outTradeNo = 4;
int64 productId=5;
string mobile=6;
uint32 accountType=7;
int32 number=8;
string notifyUrl=9;
string extendParameter=10;
}
message ZltxOrderRechargeQueryRes {
string code=1;
string message=2;
string status = 3;
string outTradeNo=4;
}
message ZltxOrderRechargeQueryReq {
uint64 merchantId = 1;
uint64 timeStamp = 2;
string sign = 3;
string outTradeNo = 4;
}
message ZltxOrderRechargeReq {
uint64 merchantId = 1;
string sign = 2;
uint64 timeStamp = 3;
string outTradeNo = 4;
int64 productId=5;
string rechargeAccount=6;
uint32 accountType=7;
int32 number=8;
string notifyUrl=9;
string extendParameter=10;
}

2795
rpc/transfer/transfer.pb.go Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,516 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc v3.6.1
// source: transfer.proto
package transfer
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const (
Transfer_ZltxOrderRecharge_FullMethodName = "/transfer.Transfer/zltxOrderRecharge"
Transfer_ZltxOrderRechargeQuery_FullMethodName = "/transfer.Transfer/zltxOrderRechargeQuery"
Transfer_ZltxOrderCard_FullMethodName = "/transfer.Transfer/zltxOrderCard"
Transfer_ZltxOrderCardQuery_FullMethodName = "/transfer.Transfer/zltxOrderCardQuery"
Transfer_ZltxOrderSms_FullMethodName = "/transfer.Transfer/zltxOrderSms"
Transfer_ZltxRechargeInfo_FullMethodName = "/transfer.Transfer/zltxRechargeInfo"
Transfer_ZltxRechargeProduct_FullMethodName = "/transfer.Transfer/zltxRechargeProduct"
Transfer_ZltxRsMiXue_FullMethodName = "/transfer.Transfer/zltxRsMiXue"
Transfer_MarketKeySend_FullMethodName = "/transfer.Transfer/marketKeySend"
Transfer_MarketKeyDiscard_FullMethodName = "/transfer.Transfer/marketKeyDiscard"
Transfer_MarketQuery_FullMethodName = "/transfer.Transfer/marketQuery"
Transfer_RsCouponGrant_FullMethodName = "/transfer.Transfer/rsCouponGrant"
)
// TransferClient is the client API for Transfer 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 TransferClient interface {
ZltxOrderRecharge(ctx context.Context, in *ZltxOrderRechargeReq, opts ...grpc.CallOption) (*DefaultRes, error)
ZltxOrderRechargeQuery(ctx context.Context, in *ZltxOrderRechargeQueryReq, opts ...grpc.CallOption) (*ZltxOrderRechargeQueryRes, error)
ZltxOrderCard(ctx context.Context, in *ZltxOrderCardReq, opts ...grpc.CallOption) (*DefaultRes, error)
ZltxOrderCardQuery(ctx context.Context, in *ZltxOrderCardQueryReq, opts ...grpc.CallOption) (*ZltxOrderCardQueryRes, error)
ZltxOrderSms(ctx context.Context, in *ZltxOrderSmsReq, opts ...grpc.CallOption) (*ZltxOrderSmsRes, error)
ZltxRechargeInfo(ctx context.Context, in *DefaultReq, opts ...grpc.CallOption) (*ZltxRechargeInfoRes, error)
ZltxRechargeProduct(ctx context.Context, in *DefaultReq, opts ...grpc.CallOption) (*ZltxRechargeProductRes, error)
ZltxRsMiXue(ctx context.Context, in *RsCouponGrantReq, opts ...grpc.CallOption) (*RsCouponGrantRes, error)
MarketKeySend(ctx context.Context, in *MarketKeySendReq, opts ...grpc.CallOption) (*MarketKeySendRes, error)
MarketKeyDiscard(ctx context.Context, in *MarketKeyDiscardReq, opts ...grpc.CallOption) (*MarketKeyDiscardRes, error)
MarketQuery(ctx context.Context, in *MarketQueryReq, opts ...grpc.CallOption) (*MarketQueryRes, error)
RsCouponGrant(ctx context.Context, in *RsCouponGrantReq, opts ...grpc.CallOption) (*RsCouponGrantRes, error)
}
type transferClient struct {
cc grpc.ClientConnInterface
}
func NewTransferClient(cc grpc.ClientConnInterface) TransferClient {
return &transferClient{cc}
}
func (c *transferClient) ZltxOrderRecharge(ctx context.Context, in *ZltxOrderRechargeReq, opts ...grpc.CallOption) (*DefaultRes, error) {
out := new(DefaultRes)
err := c.cc.Invoke(ctx, Transfer_ZltxOrderRecharge_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *transferClient) ZltxOrderRechargeQuery(ctx context.Context, in *ZltxOrderRechargeQueryReq, opts ...grpc.CallOption) (*ZltxOrderRechargeQueryRes, error) {
out := new(ZltxOrderRechargeQueryRes)
err := c.cc.Invoke(ctx, Transfer_ZltxOrderRechargeQuery_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *transferClient) ZltxOrderCard(ctx context.Context, in *ZltxOrderCardReq, opts ...grpc.CallOption) (*DefaultRes, error) {
out := new(DefaultRes)
err := c.cc.Invoke(ctx, Transfer_ZltxOrderCard_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *transferClient) ZltxOrderCardQuery(ctx context.Context, in *ZltxOrderCardQueryReq, opts ...grpc.CallOption) (*ZltxOrderCardQueryRes, error) {
out := new(ZltxOrderCardQueryRes)
err := c.cc.Invoke(ctx, Transfer_ZltxOrderCardQuery_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *transferClient) ZltxOrderSms(ctx context.Context, in *ZltxOrderSmsReq, opts ...grpc.CallOption) (*ZltxOrderSmsRes, error) {
out := new(ZltxOrderSmsRes)
err := c.cc.Invoke(ctx, Transfer_ZltxOrderSms_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *transferClient) ZltxRechargeInfo(ctx context.Context, in *DefaultReq, opts ...grpc.CallOption) (*ZltxRechargeInfoRes, error) {
out := new(ZltxRechargeInfoRes)
err := c.cc.Invoke(ctx, Transfer_ZltxRechargeInfo_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *transferClient) ZltxRechargeProduct(ctx context.Context, in *DefaultReq, opts ...grpc.CallOption) (*ZltxRechargeProductRes, error) {
out := new(ZltxRechargeProductRes)
err := c.cc.Invoke(ctx, Transfer_ZltxRechargeProduct_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *transferClient) ZltxRsMiXue(ctx context.Context, in *RsCouponGrantReq, opts ...grpc.CallOption) (*RsCouponGrantRes, error) {
out := new(RsCouponGrantRes)
err := c.cc.Invoke(ctx, Transfer_ZltxRsMiXue_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *transferClient) MarketKeySend(ctx context.Context, in *MarketKeySendReq, opts ...grpc.CallOption) (*MarketKeySendRes, error) {
out := new(MarketKeySendRes)
err := c.cc.Invoke(ctx, Transfer_MarketKeySend_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *transferClient) MarketKeyDiscard(ctx context.Context, in *MarketKeyDiscardReq, opts ...grpc.CallOption) (*MarketKeyDiscardRes, error) {
out := new(MarketKeyDiscardRes)
err := c.cc.Invoke(ctx, Transfer_MarketKeyDiscard_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *transferClient) MarketQuery(ctx context.Context, in *MarketQueryReq, opts ...grpc.CallOption) (*MarketQueryRes, error) {
out := new(MarketQueryRes)
err := c.cc.Invoke(ctx, Transfer_MarketQuery_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *transferClient) RsCouponGrant(ctx context.Context, in *RsCouponGrantReq, opts ...grpc.CallOption) (*RsCouponGrantRes, error) {
out := new(RsCouponGrantRes)
err := c.cc.Invoke(ctx, Transfer_RsCouponGrant_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// TransferServer is the server API for Transfer service.
// All implementations must embed UnimplementedTransferServer
// for forward compatibility
type TransferServer interface {
ZltxOrderRecharge(context.Context, *ZltxOrderRechargeReq) (*DefaultRes, error)
ZltxOrderRechargeQuery(context.Context, *ZltxOrderRechargeQueryReq) (*ZltxOrderRechargeQueryRes, error)
ZltxOrderCard(context.Context, *ZltxOrderCardReq) (*DefaultRes, error)
ZltxOrderCardQuery(context.Context, *ZltxOrderCardQueryReq) (*ZltxOrderCardQueryRes, error)
ZltxOrderSms(context.Context, *ZltxOrderSmsReq) (*ZltxOrderSmsRes, error)
ZltxRechargeInfo(context.Context, *DefaultReq) (*ZltxRechargeInfoRes, error)
ZltxRechargeProduct(context.Context, *DefaultReq) (*ZltxRechargeProductRes, error)
ZltxRsMiXue(context.Context, *RsCouponGrantReq) (*RsCouponGrantRes, error)
MarketKeySend(context.Context, *MarketKeySendReq) (*MarketKeySendRes, error)
MarketKeyDiscard(context.Context, *MarketKeyDiscardReq) (*MarketKeyDiscardRes, error)
MarketQuery(context.Context, *MarketQueryReq) (*MarketQueryRes, error)
RsCouponGrant(context.Context, *RsCouponGrantReq) (*RsCouponGrantRes, error)
mustEmbedUnimplementedTransferServer()
}
// UnimplementedTransferServer must be embedded to have forward compatible implementations.
type UnimplementedTransferServer struct {
}
func (UnimplementedTransferServer) ZltxOrderRecharge(context.Context, *ZltxOrderRechargeReq) (*DefaultRes, error) {
return nil, status.Errorf(codes.Unimplemented, "method ZltxOrderRecharge not implemented")
}
func (UnimplementedTransferServer) ZltxOrderRechargeQuery(context.Context, *ZltxOrderRechargeQueryReq) (*ZltxOrderRechargeQueryRes, error) {
return nil, status.Errorf(codes.Unimplemented, "method ZltxOrderRechargeQuery not implemented")
}
func (UnimplementedTransferServer) ZltxOrderCard(context.Context, *ZltxOrderCardReq) (*DefaultRes, error) {
return nil, status.Errorf(codes.Unimplemented, "method ZltxOrderCard not implemented")
}
func (UnimplementedTransferServer) ZltxOrderCardQuery(context.Context, *ZltxOrderCardQueryReq) (*ZltxOrderCardQueryRes, error) {
return nil, status.Errorf(codes.Unimplemented, "method ZltxOrderCardQuery not implemented")
}
func (UnimplementedTransferServer) ZltxOrderSms(context.Context, *ZltxOrderSmsReq) (*ZltxOrderSmsRes, error) {
return nil, status.Errorf(codes.Unimplemented, "method ZltxOrderSms not implemented")
}
func (UnimplementedTransferServer) ZltxRechargeInfo(context.Context, *DefaultReq) (*ZltxRechargeInfoRes, error) {
return nil, status.Errorf(codes.Unimplemented, "method ZltxRechargeInfo not implemented")
}
func (UnimplementedTransferServer) ZltxRechargeProduct(context.Context, *DefaultReq) (*ZltxRechargeProductRes, error) {
return nil, status.Errorf(codes.Unimplemented, "method ZltxRechargeProduct not implemented")
}
func (UnimplementedTransferServer) ZltxRsMiXue(context.Context, *RsCouponGrantReq) (*RsCouponGrantRes, error) {
return nil, status.Errorf(codes.Unimplemented, "method ZltxRsMiXue not implemented")
}
func (UnimplementedTransferServer) MarketKeySend(context.Context, *MarketKeySendReq) (*MarketKeySendRes, error) {
return nil, status.Errorf(codes.Unimplemented, "method MarketKeySend not implemented")
}
func (UnimplementedTransferServer) MarketKeyDiscard(context.Context, *MarketKeyDiscardReq) (*MarketKeyDiscardRes, error) {
return nil, status.Errorf(codes.Unimplemented, "method MarketKeyDiscard not implemented")
}
func (UnimplementedTransferServer) MarketQuery(context.Context, *MarketQueryReq) (*MarketQueryRes, error) {
return nil, status.Errorf(codes.Unimplemented, "method MarketQuery not implemented")
}
func (UnimplementedTransferServer) RsCouponGrant(context.Context, *RsCouponGrantReq) (*RsCouponGrantRes, error) {
return nil, status.Errorf(codes.Unimplemented, "method RsCouponGrant not implemented")
}
func (UnimplementedTransferServer) mustEmbedUnimplementedTransferServer() {}
// UnsafeTransferServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to TransferServer will
// result in compilation errors.
type UnsafeTransferServer interface {
mustEmbedUnimplementedTransferServer()
}
func RegisterTransferServer(s grpc.ServiceRegistrar, srv TransferServer) {
s.RegisterService(&Transfer_ServiceDesc, srv)
}
func _Transfer_ZltxOrderRecharge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ZltxOrderRechargeReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TransferServer).ZltxOrderRecharge(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Transfer_ZltxOrderRecharge_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TransferServer).ZltxOrderRecharge(ctx, req.(*ZltxOrderRechargeReq))
}
return interceptor(ctx, in, info, handler)
}
func _Transfer_ZltxOrderRechargeQuery_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ZltxOrderRechargeQueryReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TransferServer).ZltxOrderRechargeQuery(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Transfer_ZltxOrderRechargeQuery_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TransferServer).ZltxOrderRechargeQuery(ctx, req.(*ZltxOrderRechargeQueryReq))
}
return interceptor(ctx, in, info, handler)
}
func _Transfer_ZltxOrderCard_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ZltxOrderCardReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TransferServer).ZltxOrderCard(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Transfer_ZltxOrderCard_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TransferServer).ZltxOrderCard(ctx, req.(*ZltxOrderCardReq))
}
return interceptor(ctx, in, info, handler)
}
func _Transfer_ZltxOrderCardQuery_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ZltxOrderCardQueryReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TransferServer).ZltxOrderCardQuery(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Transfer_ZltxOrderCardQuery_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TransferServer).ZltxOrderCardQuery(ctx, req.(*ZltxOrderCardQueryReq))
}
return interceptor(ctx, in, info, handler)
}
func _Transfer_ZltxOrderSms_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ZltxOrderSmsReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TransferServer).ZltxOrderSms(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Transfer_ZltxOrderSms_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TransferServer).ZltxOrderSms(ctx, req.(*ZltxOrderSmsReq))
}
return interceptor(ctx, in, info, handler)
}
func _Transfer_ZltxRechargeInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DefaultReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TransferServer).ZltxRechargeInfo(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Transfer_ZltxRechargeInfo_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TransferServer).ZltxRechargeInfo(ctx, req.(*DefaultReq))
}
return interceptor(ctx, in, info, handler)
}
func _Transfer_ZltxRechargeProduct_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DefaultReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TransferServer).ZltxRechargeProduct(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Transfer_ZltxRechargeProduct_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TransferServer).ZltxRechargeProduct(ctx, req.(*DefaultReq))
}
return interceptor(ctx, in, info, handler)
}
func _Transfer_ZltxRsMiXue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(RsCouponGrantReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TransferServer).ZltxRsMiXue(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Transfer_ZltxRsMiXue_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TransferServer).ZltxRsMiXue(ctx, req.(*RsCouponGrantReq))
}
return interceptor(ctx, in, info, handler)
}
func _Transfer_MarketKeySend_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MarketKeySendReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TransferServer).MarketKeySend(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Transfer_MarketKeySend_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TransferServer).MarketKeySend(ctx, req.(*MarketKeySendReq))
}
return interceptor(ctx, in, info, handler)
}
func _Transfer_MarketKeyDiscard_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MarketKeyDiscardReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TransferServer).MarketKeyDiscard(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Transfer_MarketKeyDiscard_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TransferServer).MarketKeyDiscard(ctx, req.(*MarketKeyDiscardReq))
}
return interceptor(ctx, in, info, handler)
}
func _Transfer_MarketQuery_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MarketQueryReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TransferServer).MarketQuery(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Transfer_MarketQuery_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TransferServer).MarketQuery(ctx, req.(*MarketQueryReq))
}
return interceptor(ctx, in, info, handler)
}
func _Transfer_RsCouponGrant_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(RsCouponGrantReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TransferServer).RsCouponGrant(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Transfer_RsCouponGrant_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TransferServer).RsCouponGrant(ctx, req.(*RsCouponGrantReq))
}
return interceptor(ctx, in, info, handler)
}
// Transfer_ServiceDesc is the grpc.ServiceDesc for Transfer service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Transfer_ServiceDesc = grpc.ServiceDesc{
ServiceName: "transfer.Transfer",
HandlerType: (*TransferServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "zltxOrderRecharge",
Handler: _Transfer_ZltxOrderRecharge_Handler,
},
{
MethodName: "zltxOrderRechargeQuery",
Handler: _Transfer_ZltxOrderRechargeQuery_Handler,
},
{
MethodName: "zltxOrderCard",
Handler: _Transfer_ZltxOrderCard_Handler,
},
{
MethodName: "zltxOrderCardQuery",
Handler: _Transfer_ZltxOrderCardQuery_Handler,
},
{
MethodName: "zltxOrderSms",
Handler: _Transfer_ZltxOrderSms_Handler,
},
{
MethodName: "zltxRechargeInfo",
Handler: _Transfer_ZltxRechargeInfo_Handler,
},
{
MethodName: "zltxRechargeProduct",
Handler: _Transfer_ZltxRechargeProduct_Handler,
},
{
MethodName: "zltxRsMiXue",
Handler: _Transfer_ZltxRsMiXue_Handler,
},
{
MethodName: "marketKeySend",
Handler: _Transfer_MarketKeySend_Handler,
},
{
MethodName: "marketKeyDiscard",
Handler: _Transfer_MarketKeyDiscard_Handler,
},
{
MethodName: "marketQuery",
Handler: _Transfer_MarketQuery_Handler,
},
{
MethodName: "rsCouponGrant",
Handler: _Transfer_RsCouponGrant_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "transfer.proto",
}

View File

@ -0,0 +1,127 @@
// Code generated by goctl. DO NOT EDIT.
// Source: transfer.proto
package transferClient
import (
"context"
"rs/rpc/transfer"
"github.com/zeromicro/go-zero/zrpc"
"google.golang.org/grpc"
)
type (
DefaultReq = transfer.DefaultReq
DefaultRes = transfer.DefaultRes
MarketKeyDiscardReq = transfer.MarketKeyDiscardReq
MarketKeyDiscardRes = transfer.MarketKeyDiscardRes
MarketKeyDiscardRes_Data = transfer.MarketKeyDiscardRes_Data
MarketKeySendReq = transfer.MarketKeySendReq
MarketKeySendRes = transfer.MarketKeySendRes
MarketKeySendRes_Data = transfer.MarketKeySendRes_Data
MarketQueryReq = transfer.MarketQueryReq
MarketQueryRes = transfer.MarketQueryRes
MarketQueryRes_Data = transfer.MarketQueryRes_Data
RsCouponGrantReq = transfer.RsCouponGrantReq
RsCouponGrantRes = transfer.RsCouponGrantRes
RsCouponGrantRes_Data = transfer.RsCouponGrantRes_Data
RsCouponGrantRes_Data_VoucherInfo = transfer.RsCouponGrantRes_Data_VoucherInfo
ZltxOrderCardQueryReq = transfer.ZltxOrderCardQueryReq
ZltxOrderCardQueryRes = transfer.ZltxOrderCardQueryRes
ZltxOrderCardReq = transfer.ZltxOrderCardReq
ZltxOrderRechargeQueryReq = transfer.ZltxOrderRechargeQueryReq
ZltxOrderRechargeQueryRes = transfer.ZltxOrderRechargeQueryRes
ZltxOrderRechargeReq = transfer.ZltxOrderRechargeReq
ZltxOrderSmsReq = transfer.ZltxOrderSmsReq
ZltxOrderSmsRes = transfer.ZltxOrderSmsRes
ZltxRechargeInfoRes = transfer.ZltxRechargeInfoRes
ZltxRechargeProductRes = transfer.ZltxRechargeProductRes
ZltxRechargeProductRes_Product = transfer.ZltxRechargeProductRes_Product
Transfer interface {
ZltxOrderRecharge(ctx context.Context, in *ZltxOrderRechargeReq, opts ...grpc.CallOption) (*DefaultRes, error)
ZltxOrderRechargeQuery(ctx context.Context, in *ZltxOrderRechargeQueryReq, opts ...grpc.CallOption) (*ZltxOrderRechargeQueryRes, error)
ZltxOrderCard(ctx context.Context, in *ZltxOrderCardReq, opts ...grpc.CallOption) (*DefaultRes, error)
ZltxOrderCardQuery(ctx context.Context, in *ZltxOrderCardQueryReq, opts ...grpc.CallOption) (*ZltxOrderCardQueryRes, error)
ZltxOrderSms(ctx context.Context, in *ZltxOrderSmsReq, opts ...grpc.CallOption) (*ZltxOrderSmsRes, error)
ZltxRechargeInfo(ctx context.Context, in *DefaultReq, opts ...grpc.CallOption) (*ZltxRechargeInfoRes, error)
ZltxRechargeProduct(ctx context.Context, in *DefaultReq, opts ...grpc.CallOption) (*ZltxRechargeProductRes, error)
ZltxRsMiXue(ctx context.Context, in *RsCouponGrantReq, opts ...grpc.CallOption) (*RsCouponGrantRes, error)
MarketKeySend(ctx context.Context, in *MarketKeySendReq, opts ...grpc.CallOption) (*MarketKeySendRes, error)
MarketKeyDiscard(ctx context.Context, in *MarketKeyDiscardReq, opts ...grpc.CallOption) (*MarketKeyDiscardRes, error)
MarketQuery(ctx context.Context, in *MarketQueryReq, opts ...grpc.CallOption) (*MarketQueryRes, error)
RsCouponGrant(ctx context.Context, in *RsCouponGrantReq, opts ...grpc.CallOption) (*RsCouponGrantRes, error)
}
defaultTransfer struct {
cli zrpc.Client
}
)
func NewTransfer(cli zrpc.Client) Transfer {
return &defaultTransfer{
cli: cli,
}
}
func (m *defaultTransfer) ZltxOrderRecharge(ctx context.Context, in *ZltxOrderRechargeReq, opts ...grpc.CallOption) (*DefaultRes, error) {
client := transfer.NewTransferClient(m.cli.Conn())
return client.ZltxOrderRecharge(ctx, in, opts...)
}
func (m *defaultTransfer) ZltxOrderRechargeQuery(ctx context.Context, in *ZltxOrderRechargeQueryReq, opts ...grpc.CallOption) (*ZltxOrderRechargeQueryRes, error) {
client := transfer.NewTransferClient(m.cli.Conn())
return client.ZltxOrderRechargeQuery(ctx, in, opts...)
}
func (m *defaultTransfer) ZltxOrderCard(ctx context.Context, in *ZltxOrderCardReq, opts ...grpc.CallOption) (*DefaultRes, error) {
client := transfer.NewTransferClient(m.cli.Conn())
return client.ZltxOrderCard(ctx, in, opts...)
}
func (m *defaultTransfer) ZltxOrderCardQuery(ctx context.Context, in *ZltxOrderCardQueryReq, opts ...grpc.CallOption) (*ZltxOrderCardQueryRes, error) {
client := transfer.NewTransferClient(m.cli.Conn())
return client.ZltxOrderCardQuery(ctx, in, opts...)
}
func (m *defaultTransfer) ZltxOrderSms(ctx context.Context, in *ZltxOrderSmsReq, opts ...grpc.CallOption) (*ZltxOrderSmsRes, error) {
client := transfer.NewTransferClient(m.cli.Conn())
return client.ZltxOrderSms(ctx, in, opts...)
}
func (m *defaultTransfer) ZltxRechargeInfo(ctx context.Context, in *DefaultReq, opts ...grpc.CallOption) (*ZltxRechargeInfoRes, error) {
client := transfer.NewTransferClient(m.cli.Conn())
return client.ZltxRechargeInfo(ctx, in, opts...)
}
func (m *defaultTransfer) ZltxRechargeProduct(ctx context.Context, in *DefaultReq, opts ...grpc.CallOption) (*ZltxRechargeProductRes, error) {
client := transfer.NewTransferClient(m.cli.Conn())
return client.ZltxRechargeProduct(ctx, in, opts...)
}
func (m *defaultTransfer) ZltxRsMiXue(ctx context.Context, in *RsCouponGrantReq, opts ...grpc.CallOption) (*RsCouponGrantRes, error) {
client := transfer.NewTransferClient(m.cli.Conn())
return client.ZltxRsMiXue(ctx, in, opts...)
}
func (m *defaultTransfer) MarketKeySend(ctx context.Context, in *MarketKeySendReq, opts ...grpc.CallOption) (*MarketKeySendRes, error) {
client := transfer.NewTransferClient(m.cli.Conn())
return client.MarketKeySend(ctx, in, opts...)
}
func (m *defaultTransfer) MarketKeyDiscard(ctx context.Context, in *MarketKeyDiscardReq, opts ...grpc.CallOption) (*MarketKeyDiscardRes, error) {
client := transfer.NewTransferClient(m.cli.Conn())
return client.MarketKeyDiscard(ctx, in, opts...)
}
func (m *defaultTransfer) MarketQuery(ctx context.Context, in *MarketQueryReq, opts ...grpc.CallOption) (*MarketQueryRes, error) {
client := transfer.NewTransferClient(m.cli.Conn())
return client.MarketQuery(ctx, in, opts...)
}
func (m *defaultTransfer) RsCouponGrant(ctx context.Context, in *RsCouponGrantReq, opts ...grpc.CallOption) (*RsCouponGrantRes, error) {
client := transfer.NewTransferClient(m.cli.Conn())
return client.RsCouponGrant(ctx, in, opts...)
}

14
sh/create.sh Normal file
View File

@ -0,0 +1,14 @@
#!/bin/bash
IMAGE="transfer_rs:v1"
CONTAINER="transfer_rs"
API_PORT="10102"
V_REFLECT=""
docker build -t "${IMAGE}" . --no-cache
docker stop "${CONTAINER}"
docker rm "${CONTAINER}"
#docker run -it -p "${API_PORT}:${API_PORT}" --name "$CONTAINER" "${IMAGE}"

14
sh/create_produce.sh Normal file
View File

@ -0,0 +1,14 @@
#!/bin/bash
IMAGE="transfer_yl"
RPC_CONTAINER="transfer_yl"
RPC_PORT="10102"
V_REFLECT=""
TAGS_NAME="v1.3"
ADDRESS="registry.cn-chengdu.aliyuncs.com/go_ls/transfer_yl_produce"
docker build -t "${IMAGE}:${TAGS_NAME}" . --no-cache
docker tag "${IMAGE}:${TAGS_NAME}" ${ADDRESS}:${TAGS_NAME}
docker push ${ADDRESS}:${TAGS_NAME}

14
sh/create_test.sh Normal file
View File

@ -0,0 +1,14 @@
#!/bin/bash
IMAGE="transfer_yl"
RPC_CONTAINER="transfer_yl"
RPC_PORT="10102"
V_REFLECT=""
TAGS_NAME="v1.4"
ADDRESS="registry.cn-chengdu.aliyuncs.com/go_ls/transfer_yl"
docker build -t "${IMAGE}:${TAGS_NAME}" . --no-cache
docker tag "${IMAGE}:${TAGS_NAME}" ${ADDRESS}:${TAGS_NAME}
docker push ${ADDRESS}:${TAGS_NAME}

9
sh/startup.sh Normal file
View File

@ -0,0 +1,9 @@
#!/bin/bash
# supervisord
supervisord -c /etc/supervisord.conf

29
sh/supervisord.conf Normal file
View File

@ -0,0 +1,29 @@
; supervisor config file
[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
chmod=0700 ; sockef file mode (default 0700)
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = /src/sh/supervisord_include/*.conf

View File

@ -0,0 +1,21 @@
[program:api]
directory=/src/cmd/api
# 执行的命令
command=/src/cmd/api/yl
#在 supervisord 启动的时候也自动启动
autorstart=false
#程序异常退出后自动重启
autorestart=true
#启动 5 秒后没有异常退出,就当作已经正常启动了
startsecs=5
#启动失败自动重试次数,默认是 3
startretries=3
#把 stderr 重定向到 stdout默认 false
redirect_stderr=false
#stdout 日志文件大小,默认 50MB
stdout_logfile_maxbytes = 20MB
#stdout 日志文件备份数
stdout_logfile_backups = 20
stdout_logfile=/var/log/out.log
stderr_logfile=/var/log/err.log

63
untils/common/func.go Normal file
View File

@ -0,0 +1,63 @@
package common
import (
"crypto/md5"
"encoding/hex"
"reflect"
"strings"
)
func GetMD5Hash(input string) string {
hash := md5.Sum([]byte(input))
return hex.EncodeToString(hash[:])
}
// toMap 将结构体转换为map[string]interface{}
// StructToMap 将一个struct转换为map[string]interface{}
func StructToMap(obj interface{}) map[string]interface{} {
// 获取obj的类型
val := reflect.ValueOf(obj)
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
// 确保obj是一个struct
if val.Kind() != reflect.Struct {
return nil
}
// 创建一个map来保存结果
data := make(map[string]interface{})
// 遍历struct的字段
for i := 0; i < val.NumField(); i++ {
// 获取字段的类型和值
valueField := val.Field(i)
typeField := val.Type().Field(i)
jsonTag := typeField.Tag.Get("json")
if idx := strings.Index(jsonTag, ","); idx != -1 {
// 如果有逗号,则取逗号之前的部分
jsonTag = jsonTag[:idx]
}
// 忽略未导出的字段(字段名首字母小写)
if !typeField.IsExported() {
continue
}
// 将字段名和值添加到map中
data[jsonTag] = valueField.Interface()
}
return data
}
// mergeMaps 合并任意数量的map
func MergeMaps(maps ...map[string]interface{}) map[string]interface{} {
merged := make(map[string]interface{})
for _, m := range maps {
for k, v := range m {
merged[k] = v
}
}
return merged
}

137
untils/market/market.go Normal file
View File

@ -0,0 +1,137 @@
package market
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"errors"
"fmt"
"sort"
)
// getSignString 使用 xx=aa&yy=bb 的字符串拼接
func getSignString(data map[string]interface{}) string {
keys := make([]string, 0, len(data))
for key := range data {
keys = append(keys, key)
}
sort.Strings(keys)
signString := ""
separator := ""
for _, key := range keys {
value := data[key]
if key == "sign" || value == nil {
continue
}
signString += fmt.Sprintf("%s%s=%v", separator, key, value)
separator = "&"
}
return signString
}
// VerifyRsaSign 签名验证
func VerifyRsaSign(publicKey string, data map[string]interface{}) (map[string]interface{}, error) {
// 对 sign nonce timestamp appId 升序排序
// 使用 xx=aa&yy=bb 的字符串拼接
// 商户的公钥验签 RSA2验签
signString := getSignString(data)
rsaPubKey, err := parseRSAPublicKeyFromPEM([]byte(publicKey))
if err != nil {
return nil, err
}
signature, err := base64.StdEncoding.DecodeString(data["sign"].(string))
if err != nil {
return nil, err
}
hashed := sha256.Sum256([]byte(signString))
err = rsa.VerifyPKCS1v15(rsaPubKey, crypto.SHA256, hashed[:], signature)
if err != nil {
return nil, errors.New("签名验证失败")
}
return data, nil
}
// MakeRsaSign 生成签名
func MarketMakeRsaSign(privateKey string, data map[string]interface{}) (string, error) {
// 对 sign nonce timestamp appId 升序排序
// 使用 xx=aa&yy=bb 的字符串拼接
// 营销系统生成的私钥生成签名 RSA2加签
signString := getSignString(data)
privKey, err := parseRSAPrivateKeyFromPEM([]byte(privateKey))
if err != nil {
return "", errors.New(fmt.Sprintf("私钥解析失败:%s", err.Error()))
}
hashed := sha256.Sum256([]byte(signString))
signature, err := rsa.SignPKCS1v15(rand.Reader, privKey, crypto.SHA256, hashed[:])
if err != nil {
return "", errors.New("签名失败")
}
return base64.StdEncoding.EncodeToString(signature), nil
}
// ParseRSAPrivateKeyFromPEM 解析私钥
func parseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {
var err error
// Parse PEM block
var block *pem.Block
if block, _ = pem.Decode(key); block == nil {
return nil, errors.New("私钥解析失败: 无效的PEM格式")
}
var parsedKey interface{}
if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
return nil, err
}
}
var pkey *rsa.PrivateKey
var ok bool
if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok {
return nil, errors.New("密钥不是有效的RSA私钥")
}
return pkey, nil
}
// parseRSAPublicKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 public key
func parseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) {
var err error
// Parse PEM block
var block *pem.Block
if block, _ = pem.Decode(key); block == nil {
return nil, errors.New("公钥解析失败: 无效的PEM格式")
}
// Parse the key
var parsedKey interface{}
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
parsedKey = cert.PublicKey
} else {
return nil, err
}
}
var pkey *rsa.PublicKey
var ok bool
if pkey, ok = parsedKey.(*rsa.PublicKey); !ok {
return nil, errors.New("密钥不是有效的RSA公钥")
}
return pkey, nil
}

130
untils/request/request.go Normal file
View File

@ -0,0 +1,130 @@
package request
import (
"encoding/json"
"io"
"net/http"
"net/url"
"strings"
"time"
)
// 请求结构体
type Request struct {
Method string `json:"method"` // 请求方法
Url string `json:"url"` // 请求url
Params map[string]string `json:"params"` // Query参数
Headers map[string]string `json:"headers"` // 请求头
Cookies map[string]string `json:"cookies"` // todo 处理 Cookies
Data map[string]string `json:"data"` // 表单格式请求数据
Json map[string]string `json:"json"` // JSON格式请求数据 todo 多层 嵌套
Files map[string]string `json:"files"` // todo 处理 Files
Raw string `json:"raw"` // 原始请求数据
JsonByte []byte `json:"json_raw"` // JSON格式请求数据 todo 多层 嵌套
}
// 响应结构体
type Response struct {
StatusCode int `json:"status_code"` // 状态码
Reason string `json:"reason"` // 状态码说明
Elapsed float64 `json:"elapsed"` // 请求耗时(秒)
Content []byte `json:"content"` // 响应二进制内容
Text string `json:"text"` // 响应文本
Headers map[string]string `json:"headers"` // 响应头
Cookies map[string]string `json:"cookies"` // todo 添加响应Cookies
Request *Request `json:"request"` // 原始请求
}
// 处理请求方法
func (r *Request) getMethod() string {
return strings.ToUpper(r.Method) // 必须转为全部大写
}
// 组装URL
func (r *Request) getUrl() string {
if r.Params != nil {
urlValues := url.Values{}
Url, _ := url.Parse(r.Url) // todo 处理err
for key, value := range r.Params {
urlValues.Set(key, value)
}
Url.RawQuery = urlValues.Encode()
return Url.String()
}
return r.Url
}
// 组装请求数据
func (r *Request) getData() io.Reader {
var reqBody string
if r.Headers == nil {
r.Headers = make(map[string]string, 1)
}
if r.Raw != "" {
reqBody = r.Raw
} else if r.Data != nil {
urlValues := url.Values{}
for key, value := range r.Data {
urlValues.Add(key, value)
}
reqBody = urlValues.Encode()
r.Headers["Content-Type"] = "application/x-www-form-urlencoded"
} else if r.Json != nil {
bytesData, _ := json.Marshal(r.Json)
reqBody = string(bytesData)
r.Headers["Content-Type"] = "application/json"
} else if r.JsonByte != nil {
reqBody = string(r.JsonByte)
r.Headers["Content-Type"] = "application/json"
}
return strings.NewReader(reqBody)
}
// 添加请求头-需要在getData后使用
func (r *Request) addHeaders(req *http.Request) {
if r.Headers != nil {
for key, value := range r.Headers {
req.Header.Add(key, value)
}
}
}
// 准备请求
func (r *Request) prepare() *http.Request {
Method := r.getMethod()
Url := r.getUrl()
Data := r.getData()
req, _ := http.NewRequest(Method, Url, Data)
r.addHeaders(req)
return req
}
// 组装响应对象
func (r *Request) packResponse(res *http.Response, elapsed float64) Response {
var resp Response
resBody, _ := io.ReadAll(res.Body)
resp.Content = resBody
resp.Text = string(resBody)
resp.StatusCode = res.StatusCode
resp.Reason = strings.Split(res.Status, " ")[1]
resp.Elapsed = elapsed
resp.Headers = map[string]string{}
for key, value := range res.Header {
resp.Headers[key] = strings.Join(value, ";")
}
return resp
}
// 发送请求
func (r *Request) Send() (Response, error) {
req := r.prepare()
client := &http.Client{}
start := time.Now()
res, err := client.Do(req)
if err != nil {
return Response{}, err
}
defer res.Body.Close()
elapsed := time.Since(start).Seconds()
return r.packResponse(res, elapsed), nil
}

View File

@ -0,0 +1,83 @@
package test
import (
"fmt"
"testing"
"trasfer_middleware/until/request"
)
// 发送GET 请求
func TestGet(t *testing.T) {
r := request.Request{
Method: "GET",
Url: "https://httpbin.org/get?name=张三&age=12",
Headers: map[string]string{"Cookie": "abc", "Token": "123"}}
resp, _ := r.Send()
fmt.Printf("状态码: %d\n", resp.StatusCode)
fmt.Printf("原因: %s\n", resp.Reason)
fmt.Printf("响应时间: %f秒\n", resp.Elapsed)
fmt.Printf("响应文本: %s\n", resp.Text)
}
// 发送GET 带单独Query参数请求
func TestWAccessToken(t *testing.T) {
appid := "wx381e6a04ab7f69b6"
secret := "16f6152c216c07fdff4c0ecaf1a173ed"
r := request.Request{
Method: "GET",
Url: "https://api.weixin.qq.com/cgi-bin/token",
Params: map[string]string{"grant_type": "client_credential", "appid": appid, "secret": secret},
}
resp, err := r.Send()
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("状态码: %d\n", resp.StatusCode)
fmt.Printf("原因: %s\n", resp.Reason)
fmt.Printf("响应时间: %f秒\n", resp.Elapsed)
fmt.Printf("响应文本: %s\n", resp.Text)
}
func TestDtalkBlackBard(t *testing.T) {
r := request.Request{
Method: "POST",
Url: "https://httpbin.org/post",
Data: map[string]string{"name": "张三", "age": "12"},
Headers: map[string]string{"Cookie": "abc", "Token": "123"}}
resp, _ := r.Send()
fmt.Printf("状态码: %d\n", resp.StatusCode)
fmt.Printf("原因: %s\n", resp.Reason)
fmt.Printf("响应时间: %f秒\n", resp.Elapsed)
fmt.Printf("响应文本: %s\n", resp.Text)
}
// 发送POST 表单请求
func TestPostForm(t *testing.T) {
r := request.Request{
Method: "POST",
Url: "https://httpbin.org/post",
Data: map[string]string{"name": "张三", "age": "12"},
Headers: map[string]string{"Cookie": "abc", "Token": "123"}}
resp, _ := r.Send()
fmt.Printf("状态码: %d\n", resp.StatusCode)
fmt.Printf("原因: %s\n", resp.Reason)
fmt.Printf("响应时间: %f秒\n", resp.Elapsed)
fmt.Printf("响应文本: %s\n", resp.Text)
}
// 发送POST JSON请求
func TestPostJson(t *testing.T) {
r := request.Request{
Method: "POST",
Url: "https://httpbin.org/post",
Json: map[string]string{"name": "张三", "age": "12"},
Headers: map[string]string{"Cookie": "abc", "Token": "123"}}
resp, _ := r.Send()
fmt.Printf("状态码: %d\n", resp.StatusCode)
fmt.Printf("原因: %s\n", resp.Reason)
fmt.Printf("响应时间: %f秒\n", resp.Elapsed)
fmt.Printf("响应文本: %s\n", resp.Text)
}

12
untils/response/code.go Normal file
View File

@ -0,0 +1,12 @@
package response
const (
HTTP_SUCCESS = "000000"
HTTP_AUTH_FAIL = "000101"
HTTP_REUEST_FAIL = "000102"
)
var CodeMsg = map[string]string{
HTTP_SUCCESS: "操作成功",
HTTP_AUTH_FAIL: "验签失败",
}

View File

@ -0,0 +1,29 @@
package response
import (
"fmt"
"github.com/zeromicro/go-zero/rest/httpx"
"net/http"
)
type Body struct {
Code string `json:"retCode"`
Data interface{} `json:"apiResult"`
Msg string `json:"retMsg"`
}
func Err(w http.ResponseWriter, code string, msg string) {
httpx.OkJson(w, Body{
Code: code,
Data: nil,
Msg: fmt.Sprintf("%s:%s", CodeMsg[code], msg),
})
}
func Suc(w http.ResponseWriter, code string, data interface{}) {
httpx.OkJson(w, Body{
Code: code,
Data: data,
Msg: "发送成功",
})
}

110
untils/rsa/rsa.go Normal file
View File

@ -0,0 +1,110 @@
package rsa
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
)
// parseRSAPublicKeyFromPEM 解析PEM编码的RSA公钥
func parseRSAPublicKeyFromPEM(pemData []byte) (*rsa.PublicKey, error) {
block, _ := pem.Decode(pemData)
if block == nil || block.Type != "PUBLIC KEY" {
return nil, fmt.Errorf("failed to parse PEM block containing the RSA public key")
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
switch pub := pub.(type) {
case *rsa.PublicKey:
return pub, nil
default:
return nil, fmt.Errorf("unknown public key type in PKIX wrapping")
}
}
// encrypt 使用RSA公钥加密数据
func Encrypt(publicKeyPEM string, plaintext []byte) ([]byte, error) {
// 将PEM编码的公钥转换为[]byte
pemData := []byte(publicKeyPEM)
// 解析PEM数据以获取公钥
pubKey, err := parseRSAPublicKeyFromPEM(pemData)
if err != nil {
return nil, err
}
// 创建用于加密的随机填充
label := []byte("") // OAEP标签对于某些情况可能是非空的
ciphertext, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, pubKey, plaintext, label)
if err != nil {
return nil, err
}
return ciphertext, nil
}
// parseRSAPrivateKeyFromPEM 解析PEM编码的RSA私钥
func parseRSAPrivateKeyFromPEM(pemData []byte) (*rsa.PrivateKey, error) {
block, _ := pem.Decode(pemData)
if block == nil || block.Type != "RSA PRIVATE KEY" {
return nil, fmt.Errorf("failed to parse PEM block containing the RSA private key")
}
// 尝试使用PKCS#1 v1.5
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
// 如果失败尝试使用PKCS#8
privInterface, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
switch k := privInterface.(type) {
case *rsa.PrivateKey:
priv = k
default:
return nil, fmt.Errorf("unknown private key type in PKCS#8 wrapping")
}
}
return priv, nil
}
// decrypt 使用RSA私钥解密数据
func Decrypt(privateKeyPEM string, encryptedDataBase64 string) ([]byte, error) {
// 将PEM编码的私钥转换为[]byte
pemData := []byte(privateKeyPEM)
// 解析PEM数据以获取私钥
privKey, err := parseRSAPrivateKeyFromPEM(pemData)
if err != nil {
return nil, err
}
// 将Base64编码的加密数据解码为字节切片
encryptedData, err := base64.StdEncoding.DecodeString(encryptedDataBase64)
if err != nil {
return nil, err
}
// 根据你的加密方式选择合适的解密函数
// 这里假设使用的是OAEP填充和SHA-256哈希函数
label := []byte("") // OAEP标签对于某些情况可能是非空的
decrypted, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, privKey, encryptedData, label)
if err != nil {
// 如果失败可以尝试使用PKCS#1 v1.5填充
decrypted, err = rsa.DecryptPKCS1v15(rand.Reader, privKey, encryptedData)
if err != nil {
return nil, err
}
}
return decrypted, nil
}

41
untils/rsa/rsa_test.go Normal file
View File

@ -0,0 +1,41 @@
package rsa
import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/bytedance/sonic"
"testing"
)
const prik = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCmjK6SPkrP03ssex5Dxn4KZeVm9rQoJMslru13GNgoGKJAq13xwUGl6lpGlhzM9IMzg0ldOO2a0SQPPjc0fLrDjIgHPfIT6H1hDGkZdPaF4D0OfiHGzlLwXq7FyyyGc2JXILsniMBXcCxNFhbW0jAaJyYrBJb3q84a5y5AtK3IC+eDV6Bj2J4HlQVGKgW9u2ic6Jxl23sacXY6iifi+KEuoXNCJrmYlgRWTaQovLmTCLkErkzxzG9DFRDWGoz25LthDPqcCSUmWEbJ+obwIGB4r2WCbFXvaeVBQORlyVRyNUvYMItjHBQIKinDWZ6y8KzA0YKOoxEfr0KfE8Uk4PQBAgMBAAECggEABTAX0PzelN4uyvTT0sMi/R0YRKPgepP40vtBsNvF10E7Lp4ClAupHpYFSrJq178xu1/2dVBXEGM9hw8GUQd7RCjuD3cFwcp/EKU+Zy6uQ38iZRTskEDa3bC+q3EXzuFXDxqOfIhai262UTlkATw0sjUwJRdkbMxoeWHkSNuH7UBVddxFL8Bq1DKaPzRCqQ8zlkMZHy8Xbf2b8rFoi1oPBoPjHyxCo33zcnSg5xntIoA5pkD6x4z5cAnU55aBoYUiRv7jmG+MVp1jpDvAmJLfUayVZNakgX1r74bMPsl9kpA7dVdgOlWrIkbJE1plVXXswBb8QKN0/Yx2vv/YASSi0QKBgQDaO9BkRjvht/lrsQEur1wXf5ITnsVWsqlUhYQKGHihzOj7e0rGO9QICM4eQZH9ssHfxEXhmEoFdkaqo3Fo47NI+yinpWm+KruwrRFkCGejlKZ4bhn9zWPb8L1qJbN4UD1c5jUNk1B0EEdnLRFg0/O7xm602bGilvY5x2nf0v95+QKBgQDDXyiiGNV7GO4h8OQYJwq0IqenPyIanRgYI3rw//tg147mhWcxT6ms6dMUh9nEXEFali2J1En+aVvx1Xn47CuGrRmZOLaGkw9ESFA/4ngYdea+xgttbKMXm0QwIwvATq2jxxrYEKmnr/+EUUWzIWioM1zQffAhVlkLFVnImquMSQKBgDe7qNfC/A4ELwWqubOTg0BZCxRJqvoePJJiWrs9Tql7rFB1Rz5jDx5SKVmew0r4OP0Nog8gFl9YumlfvlncNPBBfDt8SgoP3ckcGeHjJ5ymHPGKpMaliogj7ivKnw/t5g3wmMHzyksp0SJvZw3Ec22UGrfDFNOCHDXbUJWhzC75AoGBALbM6rAAnH65LNcFFeajYRh69HNAVyCfrFOpnvawDPzntAVs/MjeyNvJTH8BPXjE+UFREvrLbxBkdGsqWx3VnEQ+4pzCu8XfA4HYR33+4G/CoUwO8dJIu7DyzjJcGDqvYzjCqxNPQ+5qdqHPiW+56rq2lDlgHLaUnGwKZh+U2L5BAoGAeogtSQbnZaLQofSGcUOol2fyG24NU1JK3My+N1ypkSpD+y1KiFQeM5kg7UcJB6LBKZ/lRCKcjEMaxMyj57ETMkbRVKBLvsIL5QYolJLIHYqBul0AeFJ4K51SKK2Xk5rFvyuJKkJBux26WodtCXTnEzP1KRZGlSxJeN/V1yXjSEU="
const pubk = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApoyukj5Kz9N7LHseQ8Z+CmXlZva0KCTLJa7tdxjYKBiiQKtd8cFBpepaRpYczPSDM4NJXTjtmtEkDz43NHy6w4yIBz3yE+h9YQxpGXT2heA9Dn4hxs5S8F6uxcsshnNiVyC7J4jAV3AsTRYW1tIwGicmKwSW96vOGucuQLStyAvng1egY9ieB5UFRioFvbtonOicZdt7GnF2Ooon4vihLqFzQia5mJYEVk2kKLy5kwi5BK5M8cxvQxUQ1hqM9uS7YQz6nAklJlhGyfqG8CBgeK9lgmxV72nlQUDkZclUcjVL2DCLYxwUCCopw1mesvCswNGCjqMRH69CnxPFJOD0AQIDAQAB"
func Test_en(t *testing.T) {
data := make(map[string]interface{}, 2)
data["a"] = 1
data["b"] = "sdadas"
dataJson, _ := json.Marshal(data)
pub := `-----BEGIN PUBLIC KEY-----
` + pubk + `
-----END PUBLIC KEY-----`
res, err := Encrypt(pub, dataJson)
fmt.Println(base64.StdEncoding.EncodeToString(res), err)
}
func Test_de(t *testing.T) {
data := "oSpZJFBORDtJDpKjk5q4C1ex7CbgDW+YjMS7gCQHIsn1dgrSXEvjgeuA2jhc29CstkIDjwQ/qhInXVl/M9hphB9oujfegD+FPRspRhDrBY1csuPLDiKZh82LQfPMMXCQcZk73F+OfHl9cX/QLi/2uRUw3UsEO8Hv6o9VM1mSkg+uWAqqFKZKvVXJBTNHRzlQ56LTMZG8kwGGQisoCvi+f+6B/3Kd9co+csMAEeE+gK/Ix+c8jLs5lL8QKZW9vALa8zgTPG3oicxIYHqNoPqc8Z/R+C69k30QRsbWhyixPpSGxGkV9Pvy8czj/t+uoDiZ7hOQugR9ss7DIwZHuyDcHA=="
privateKeyPEM := `-----BEGIN RSA PRIVATE KEY-----
` + prik + `
-----END RSA PRIVATE KEY-----`
res, err := Decrypt(privateKeyPEM, data)
fmt.Println(string(res), err)
}
func Test_sonic(t *testing.T) {
var a map[string]interface{}
b := "{\"severType\":\"sms\",\"msgType\":\"sms\",\"base\":{\"serverIndex\":\"sms\",\"tempIndex\":\"sms\"},\"config\":\"{\\\"param\\\":\\\"{\\\\\\\"plan_id\\\\\\\":\\\\\\\"1234\\\\\\\",\\\\\\\"key_batch_id\\\\\\\":\\\\\\\"1234\\\\\\\",\\\\\\\"stock\\\\\\\":\\\\\\\"1234\\\\\\\",\\\\\\\"warning_num\\\\\\\":\\\\\\\"1234\\\\\\\",\\\\\\\"per\\\\\\\":\\\\\\\"1234\\\\\\\"}\\\",\\\"tels\\\":\\\"15082245107\\\"}\"}"
sonic.Unmarshal([]byte(b), &a)
fmt.Println(a)
}

105
untils/rsa/sonic_test.go Normal file
View File

@ -0,0 +1,105 @@
package rsa
import (
"encoding/json"
"fmt"
"github.com/bytedance/sonic"
"testing"
"time"
)
type Book struct {
Name string `json:"title"`
Price float64
Tags []string
Press string
Author People
Social
}
type People struct {
Name string
Age int
School string
Company string
Title string
}
type Social struct {
A [][]string
B [][][]string
C [][][][]string
D string
E string
}
var (
people = People{
Name: "张三",
Age: 18,
School: "社会大学",
Company: "大乔乔教育",
Title: "开发工程师",
}
book = Book{
Name: "高性能golang",
Price: 58.0,
Tags: []string{"golang", "编程", "计算机"},
Press: "机械工业出版社",
Author: people,
Social: social,
}
social = Social{
A: [][]string{{"golang", "编程", "计算机"}, {"golang", "编程", "计算机"}, {"golang", "编程", "计算机"}},
B: [][][]string{{{"golang", "编程", "计算机"}, {"golang", "编程", "计算机"}}, {{"golang", "编程", "计算机"}, {"golang", "编程", "计算机"}, {"golang", "编程", "计算机"}}},
C: [][][][]string{{{{"golang", "编程", "计算机"}, {"golang", "编程", "计算机"}}, {{"golang", "编程", "计算机"}, {"golang", "编程", "计算机"}}}, {{{"golang", "编程", "计算机"}, {"golang", "编程", "计算机"}}}},
D: "大乔乔教育",
E: "开发工程师",
}
)
func TestStdJson(t *testing.T) {
start := time.Now()
bs, _ := sonic.Marshal(book)
var book2 Book
if err := sonic.Unmarshal(bs, &book2); err != nil {
fmt.Println(err)
t.Fail()
} else {
fmt.Printf("%+v\n", book2)
}
elapsed := time.Since(start)
fmt.Printf("TestSomething took %v\n", elapsed)
}
func TestSonic(t *testing.T) {
start := time.Now()
bs, _ := sonic.Marshal(book)
var book2 Book
if err := sonic.Unmarshal(bs, &book2); err != nil {
fmt.Println(err)
t.Fail()
} else {
fmt.Printf("%+v\n", book2)
}
elapsed := time.Since(start)
fmt.Printf("TestSomething took %v\n", elapsed)
}
func BenchmarkStdJson(b *testing.B) {
for i := 0; i < b.N; i++ {
bs, _ := json.Marshal(book)
var book2 Book
json.Unmarshal(bs, &book2)
}
}
func BenchmarkSonic(b *testing.B) {
for i := 0; i < b.N; i++ {
bs, _ := sonic.Marshal(book)
var book2 Book
sonic.Unmarshal(bs, &book2)
}
}

66
untils/sign/sign.go Normal file
View File

@ -0,0 +1,66 @@
package sign
import (
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"fmt"
"github.com/spf13/cast"
"sort"
)
var filterKeys = []string{"sign", "extendParams", "msg"}
func GetSign(data map[string]interface{}, primary string) (string, error) {
filterData(&data)
sysSign, err := hash256AndBase64(sortValue(data, primary))
if err != nil {
return "", fmt.Errorf("参数加密失败")
}
return sysSign, nil
}
func filterData(data *map[string]interface{}) {
for _, key := range filterKeys {
delete(*data, key)
}
}
func sortValue(data map[string]interface{}, primary string) string {
var sortValueString string
data["key"] = primary
keys := make([]string, 0, len(data))
for k := range data {
keys = append(keys, k)
}
// 对键进行排序
sort.Strings(keys)
// 按照排序后的键的顺序输出map的值
for _, v := range keys {
sortValueString += cast.ToString(data[v])
}
return sortValueString
}
func hash256AndBase64(valueString string) (string, error) {
// 创建一个新的hash.Hash计算器并指定算法为sha256
hasher := sha256.New()
// 写入数据到hash计算器
hasher.Write([]byte(valueString))
// Sum方法返回计算出的哈希值的字节切片
hashBytes := hasher.Sum(nil)
//将字符串编码为16进制格式,返回字符串
hashCode := hex.EncodeToString(hashBytes)
// 将哈希值的字节切片编码为Base64字符串
hashBase64 := base64.StdEncoding.EncodeToString([]byte(hashCode))
return hashBase64, nil
}