From 8af968dc22d7ea44c7c686a67219c809c546e2bb Mon Sep 17 00:00:00 2001 From: guzeng Date: Wed, 16 Jun 2021 10:23:29 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- pay/client.go | 141 ++++++++++++++++++++++++++++ pay/pay.pb.go | 198 +++++++++++++++++++++++++++++++++++++++ pay/pay.proto | 23 +++++ user/user.client_test.go | 13 ++- 5 files changed, 372 insertions(+), 5 deletions(-) create mode 100644 pay/client.go create mode 100644 pay/pay.pb.go create mode 100644 pay/pay.proto diff --git a/README.md b/README.md index e985a40..e197902 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# rpc +# 此目录将作废 rpc \ No newline at end of file diff --git a/pay/client.go b/pay/client.go new file mode 100644 index 0000000..ed0a898 --- /dev/null +++ b/pay/client.go @@ -0,0 +1,141 @@ +package pay + +import ( + "crypto/md5" + "encoding/hex" + "encoding/json" + "errors" + "strconv" + "strings" + "time" + + "git.tetele.net/tgo/crypter" + + "github.com/golang/protobuf/proto" +) + +type PayToBusinessReq struct { + SiteId string `json:"site_id"` + Dbname string `json:"dbname"` + UserId string `json:"user_id"` + BusinessId string `json:"business_id"` + BalanceTypeId string `json:"balance_type"` + Money float64 `json:"money"` + Payer string `json:"payer"` + Memo string `json:"memo"` + PayType string `json:"pay_type"` +} + +type PayToBusinessRes struct { + Id string + Sn string +} + +const DES_KEY string = "paypayda" + +/** + * 向商家支付 + * 请求及回均加密验签 + * 2021/02/18 + * GZ + */ +func Pay(req PayToBusinessReq, url ...string) (*PayToBusinessRes, error) { + + var pay_rpc_url string = "127.0.0.1:7967" + if len(url) > 0 && url[0] != "" { + pay_rpc_url = url[0] + } + conn, _, err := DialSiteService("tcp", pay_rpc_url) + if err != nil { + return nil, err + } + defer conn.Close() + + data_json, err := json.Marshal(req) + if err != nil { + return nil, err + } + now_int64 := time.Now().Unix() + + encryData := crypter.DesEn(string(data_json), DES_KEY) + + now := strconv.FormatInt(now_int64, 10) + + sign := Sign(encryData, now) + + req := &PayRequest{proto.String(encryData), proto.String(now), proto.String(sign), nil} + + res := &PayResponse{} + + err = conn.PayToBusiness(req, res) + + if err != nil { + return nil, err + } + + res_data := res.GetData() + + if res_data != "" { + + time_int64, err := strconv.ParseInt(res.GetTime(), 10, 64) + if err != nil { + return nil, err + } + + now_int64 = time.Now().Unix() + + if now_int64-time_int64 > 10 || time_int64-now_int64 > 10 { + //时间误差前后10秒,返回 + return nil, errors.New("返回时间错误") + } + + check_sign := CheckSign(res.GetSign(), res_data, res.GetTime()) + if !check_sign { + return nil, errors.New("返回数据签名错误") + } + + //解密 + res_data_de := crypter.DesDe(res_data, DES_KEY) + + var res_arr PayToBusinessRes + + err = json.Unmarshal([]byte(res_data_de), &res_arr) + + if err != nil { + return nil, err + } + return &res_arr, nil + } + + return nil, nil +} + +/** + * 签名 + */ +func Sign(data string, salt string) string { + + var build strings.Builder + + build.WriteString(data) + build.WriteString(salt) + build.WriteString("pay66sign33") + + data_str := build.String() + + h := md5.New() + h.Write([]byte(data_str)) // 需要加密的字符串 + return hex.EncodeToString(h.Sum(nil)) // 输出加密结果 + +} + +/** + * 验证签名 + */ +func CheckSign(sign_str, data, salt string) bool { + sign := Sign(data, salt) + if strings.Compare(sign_str, sign) > -1 { + return true + } + return false +} diff --git a/pay/pay.pb.go b/pay/pay.pb.go new file mode 100644 index 0000000..f3f0385 --- /dev/null +++ b/pay/pay.pb.go @@ -0,0 +1,198 @@ +// Code generated by protoc-gen-go. +// source: pay.proto +// DO NOT EDIT! + +/* +Package pay is a generated protocol buffer package. + +It is generated from these files: + pay.proto + +It has these top-level messages: + PayRequest + PayResponse +*/ +package pay + +import proto "github.com/chai2010/protorpc/proto" +import math "math" + +import "io" +import "log" +import "net" +import "net/rpc" +import "time" +import protorpc "github.com/chai2010/protorpc" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = math.Inf + +// 配置信息请求结构 +type PayRequest struct { + Data *string `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"` + Time *string `protobuf:"bytes,2,opt,name=time" json:"time,omitempty"` + Sign *string `protobuf:"bytes,3,opt,name=sign" json:"sign,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *PayRequest) Reset() { *m = PayRequest{} } +func (m *PayRequest) String() string { return proto.CompactTextString(m) } +func (*PayRequest) ProtoMessage() {} + +func (m *PayRequest) GetData() string { + if m != nil && m.Data != nil { + return *m.Data + } + return "" +} + +func (m *PayRequest) GetTime() string { + if m != nil && m.Time != nil { + return *m.Time + } + return "" +} + +func (m *PayRequest) GetSign() string { + if m != nil && m.Sign != nil { + return *m.Sign + } + return "" +} + +// 配置信息响应结构 +type PayResponse struct { + Data *string `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"` + Time *string `protobuf:"bytes,2,opt,name=time" json:"time,omitempty"` + Sign *string `protobuf:"bytes,3,opt,name=sign" json:"sign,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *PayResponse) Reset() { *m = PayResponse{} } +func (m *PayResponse) String() string { return proto.CompactTextString(m) } +func (*PayResponse) ProtoMessage() {} + +func (m *PayResponse) GetData() string { + if m != nil && m.Data != nil { + return *m.Data + } + return "" +} + +func (m *PayResponse) GetTime() string { + if m != nil && m.Time != nil { + return *m.Time + } + return "" +} + +func (m *PayResponse) GetSign() string { + if m != nil && m.Sign != nil { + return *m.Sign + } + return "" +} + +func init() { +} + +type PayService interface { + PayToBusiness(in *PayRequest, out *PayResponse) error + PayToUser(in *PayRequest, out *PayResponse) error +} + +// AcceptPayServiceClient accepts connections on the listener and serves requests +// for each incoming connection. Accept blocks; the caller typically +// invokes it in a go statement. +func AcceptPayServiceClient(lis net.Listener, x PayService) { + srv := rpc.NewServer() + if err := srv.RegisterName("PayService", x); err != nil { + log.Fatal(err) + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeCodec(protorpc.NewServerCodec(conn)) + } +} + +// RegisterPayService publish the given PayService implementation on the server. +func RegisterPayService(srv *rpc.Server, x PayService) error { + if err := srv.RegisterName("PayService", x); err != nil { + return err + } + return nil +} + +// NewPayServiceServer returns a new PayService Server. +func NewPayServiceServer(x PayService) *rpc.Server { + srv := rpc.NewServer() + if err := srv.RegisterName("PayService", x); err != nil { + log.Fatal(err) + } + return srv +} + +// ListenAndServePayService listen announces on the local network address laddr +// and serves the given PayService implementation. +func ListenAndServePayService(network, addr string, x PayService) error { + lis, err := net.Listen(network, addr) + if err != nil { + return err + } + defer lis.Close() + + srv := rpc.NewServer() + if err := srv.RegisterName("PayService", x); err != nil { + return err + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeCodec(protorpc.NewServerCodec(conn)) + } +} + +type PayServiceClient struct { + *rpc.Client +} + +// NewPayServiceClient returns a PayService rpc.Client and stub to handle +// requests to the set of PayService at the other end of the connection. +func NewPayServiceClient(conn io.ReadWriteCloser) (*PayServiceClient, *rpc.Client) { + c := rpc.NewClientWithCodec(protorpc.NewClientCodec(conn)) + return &PayServiceClient{c}, c +} + +func (c *PayServiceClient) PayToBusiness(in *PayRequest, out *PayResponse) error { + return c.Call("PayService.PayToBusiness", in, out) +} +func (c *PayServiceClient) PayToUser(in *PayRequest, out *PayResponse) error { + return c.Call("PayService.PayToUser", in, out) +} + +// DialPayService connects to an PayService at the specified network address. +func DialPayService(network, addr string) (*PayServiceClient, *rpc.Client, error) { + c, err := protorpc.Dial(network, addr) + if err != nil { + return nil, nil, err + } + return &PayServiceClient{c}, c, nil +} + +// DialPayServiceTimeout connects to an PayService at the specified network address. +func DialPayServiceTimeout(network, addr string, + timeout time.Duration) (*PayServiceClient, *rpc.Client, error) { + c, err := protorpc.DialTimeout(network, addr, timeout) + if err != nil { + return nil, nil, err + } + return &PayServiceClient{c}, c, nil +} diff --git a/pay/pay.proto b/pay/pay.proto new file mode 100644 index 0000000..2c2b0f8 --- /dev/null +++ b/pay/pay.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; +package pay; + +// 配置信息请求结构 +message PayRequest { + string data = 1; + string time = 2; + string sign = 3; +} + +// 配置信息响应结构 +message PayResponse { + string data = 1; + string time = 2; + string sign = 3; +} + + +// rpc方法 +service PayService { + rpc payToBusiness (PayRequest) returns (PayResponse); // 用户各商家支付 + rpc payToUser (PayRequest) returns (PayResponse); // 商家向用户支付(退款) +} \ No newline at end of file diff --git a/user/user.client_test.go b/user/user.client_test.go index f154741..7a78fa8 100644 --- a/user/user.client_test.go +++ b/user/user.client_test.go @@ -12,10 +12,15 @@ func Test_GetUserByToken(t *testing.T) { t.Log(res["UserId"]) t.Log(err) - // res, err = GetUserById(dbname, "114") - // t.Log(res) - // t.Log(res["UserId"]) - // t.Log(err) + res, err = GetUserByUsername(dbname, "tetele") + t.Log(res) + t.Log(res["UserId"]) + t.Log(err) + + res, err = GetUserByUsercode(dbname, "2233") + t.Log(res) + t.Log(res["UserId"]) + t.Log(err) } func Test_Login(t *testing.T) {