From bf0678f5870b6b7a92ab0d96e73e7c76c0daa773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=AD=90=E9=93=AD?= Date: Wed, 6 Nov 2024 10:13:29 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9B=B4=E8=BF=9E=E5=A4=A9=E4=B8=8B=EF=BC=8Cv2?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 6 + plugins/zltx_v2/go.mod | 44 +++++ plugins/zltx_v2/go.sum | 78 +++++++++ plugins/zltx_v2/internal/transform.go | 194 +++++++++++++++++++++++ plugins/zltx_v2/internal/util.go | 43 +++++ plugins/zltx_v2/internal/vo/status.go | 51 ++++++ plugins/zltx_v2/internal/zltx_v2.go | 111 +++++++++++++ plugins/zltx_v2/internal/zltx_v2_test.go | 109 +++++++++++++ plugins/zltx_v2/main.go | 15 ++ 9 files changed, 651 insertions(+) create mode 100644 plugins/zltx_v2/go.mod create mode 100644 plugins/zltx_v2/go.sum create mode 100644 plugins/zltx_v2/internal/transform.go create mode 100644 plugins/zltx_v2/internal/util.go create mode 100644 plugins/zltx_v2/internal/vo/status.go create mode 100644 plugins/zltx_v2/internal/zltx_v2.go create mode 100644 plugins/zltx_v2/internal/zltx_v2_test.go create mode 100644 plugins/zltx_v2/main.go diff --git a/Makefile b/Makefile index 64eac0a..f913055 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,12 @@ zltx_card: make build-linux name=zltx_card && \ make build-win name=zltx_card +.PHONY: zltx_v2 +zltx_v2: + make build-mac name=zltx_v2 && \ + make build-linux name=zltx_v2 && \ + make build-win name=zltx_v2 + .PHONY: union_pay_cpn union_pay_cpn: make build-mac name=union_pay_cpn && \ diff --git a/plugins/zltx_v2/go.mod b/plugins/zltx_v2/go.mod new file mode 100644 index 0000000..0a81379 --- /dev/null +++ b/plugins/zltx_v2/go.mod @@ -0,0 +1,44 @@ +module plugins/zltxv2 + +go 1.22.2 + +replace plugins/utils => ../../utils + +require ( + gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca + gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2 v0.0.0-20240919023950-493c464e0ed7 + github.com/carlmjohnson/requests v0.24.2 + github.com/go-playground/validator/v10 v10.22.0 + github.com/hashicorp/go-plugin v1.6.1 + github.com/stretchr/testify v1.9.0 + plugins/utils v0.0.0-00010101000000-000000000000 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fatih/color v1.7.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/hashicorp/go-hclog v0.14.1 // indirect + github.com/hashicorp/yamux v0.1.1 // indirect + github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect + github.com/json-iterator/go v1.1.5 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-colorable v0.1.4 // indirect + github.com/mattn/go-isatty v0.0.10 // indirect + github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect + github.com/oklog/run v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/grpc v1.64.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/plugins/zltx_v2/go.sum b/plugins/zltx_v2/go.sum new file mode 100644 index 0000000..2e30056 --- /dev/null +++ b/plugins/zltx_v2/go.sum @@ -0,0 +1,78 @@ +gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca h1:snL161P7OynMA8hRVMLDjwnzZA2Q4mePg/iT/dyIfzA= +gitea.cdlsxd.cn/sdk/plugin v0.0.0-20240911021858-7f3ba37bbbca/go.mod h1:cd+ZFTmd/ZxrrVc1OZCkrh2wAMPDaAa8ce13FAAkBg0= +gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2 v0.0.0-20240919023950-493c464e0ed7 h1:2wOzkUfS17P6U/i6CWFjLyXrdLMnW3osk897ZfOUCxY= +gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2 v0.0.0-20240919023950-493c464e0ed7/go.mod h1:aS6ecVHvGLGzYYFIhxBrRWmq69ifo6pt1G92QblSdQQ= +github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= +github.com/carlmjohnson/requests v0.24.2 h1:JDakhAmTIKL/qL/1P7Kkc2INGBJIkIFP6xUeUmPzLso= +github.com/carlmjohnson/requests v0.24.2/go.mod h1:duYA/jDnyZ6f3xbcF5PpZ9N8clgopubP2nK5i6MVMhU= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= +github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU= +github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-plugin v1.6.1 h1:P7MR2UP6gNKGPp+y7EZw2kOiq4IR9WiqLvp0XOsVdwI= +github.com/hashicorp/go-plugin v1.6.1/go.mod h1:XPHFku2tFo3o3QKFgSYo+cghcUhw1NA1hZyMK0PWAw0= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= +github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE= +github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= +google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/plugins/zltx_v2/internal/transform.go b/plugins/zltx_v2/internal/transform.go new file mode 100644 index 0000000..89eec35 --- /dev/null +++ b/plugins/zltx_v2/internal/transform.go @@ -0,0 +1,194 @@ +package internal + +import ( + "encoding/json" + "gitea.cdlsxd.cn/sdk/plugin/proto" + "gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2/api" + "gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2/notify" + "gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2/sdk" + "plugins/utils/helper" + "plugins/zltxv2/internal/vo" +) + +type Config struct { + AppId string `json:"app_id"` + AppKey string `json:"app_key"` + BaseUri string `json:"base_uri"` + NotifyUrl string `json:"notify_url"` +} + +type Card struct { + Number string `json:"number"` + Password string `json:"password"` +} + +func (c *Card) ToJson() []byte { + bytes, _ := json.Marshal(c) + return bytes +} + +func transConfig(config []byte) (*Config, error) { + var c Config + err := json.Unmarshal(config, &c) + if err != nil { + return nil, err + } + return &c, nil +} + +func (c *Config) client() (*sdk.Client, error) { + scheme := getScheme(c.BaseUri) + domain, err := getDomain(c.BaseUri, scheme) + if err != nil { + return nil, err + } + return sdk.NewClientWithAccessKey(c.AppKey, scheme, domain) +} + +func (c *Config) orderReq(in *proto.OrderRequest) *api.OrderCreateReq { + accountType := int64(0) + if in.Order.Account == "" { + accountType = 0 + } else if helper.IsPhoneNumber(in.Order.Account) { + accountType = 1 + } else if helper.IsEmail(in.Order.Account) { + accountType = 2 + } + return &api.OrderCreateReq{ + OutTradeNo: in.Order.OrderNo, // 商户侧订单号长度只能是1-64位 + ProductId: in.Product.ProductNo, // 产品编码不能为空 + Number: int(in.Order.Quantity), // 部分商品存在限购数量,具体可联系商务 + NotifyUrl: c.NotifyUrl, // 订单回调通知地址长度不能为空,且长度不能超过255 + Extends: string(in.Order.Extra), // 部分特殊商品需要,具体可联系商务 + RechargeAccount: in.Order.Account, // 账号类型:直充类型商品必传,商品为卡密类型时,则表示接收卡密的手机号 + AccountType: accountType, // 直充类型商品必传 - 1:手机号 - 2: QQ 号 + Attach: "", // 透传参数,当传了此参数时,查询和回调接口中将原样携带此参数 + UnitPrice: 0, // 交易商品单价,单位:元(最多保留4位小数) - 0或不传表示不限制 - 当此价格小于采购价时,下单失败 + } +} + +func orderResp(request *proto.OrderRequest, resp *api.OrderCreateResp) *proto.OrderResponse { + data, _ := json.Marshal(resp) + return &proto.OrderResponse{ + Result: &proto.Result{ + Status: proto.Status_ING, + OrderNo: request.Order.OrderNo, + TradeNo: resp.OrderNo, // 平台订单号 + Message: "成功", + Data: data, + }, + } +} + +func (c *Config) queryReq(in *proto.QueryRequest) *api.OrderQueryReq { + return &api.OrderQueryReq{ + OutTradeNo: in.Order.OrderNo, + } +} + +func queryResp(appKey string, request *proto.QueryRequest, resp *api.OrderQueryResp) (*proto.QueryResponse, error) { + data, err := json.Marshal(resp) + if err != nil { + return nil, err + } + status := vo.OrderStatus(resp.TradeStatus) + pb := &proto.QueryResponse{ + Result: &proto.Result{ + Status: status.GetOrderStatus(), + OrderNo: request.Order.OrderNo, + TradeNo: resp.OrderNo, + Message: resp.TradeStateDesc, + Data: data, + Extra: nil, + }, + } + if len(resp.Cards) > 0 { + c, err := getQueryCard(appKey, &resp.Cards[0]) + if err != nil { + return nil, err + } + pb.Result.Extra = c.ToJson() + } + return pb, nil +} + +func getQueryCard(appKey string, card *api.Cards) (*Card, error) { + // - 1:卡密+卡密:no和pwd都不为空 + // - 2:卡密,pwd不为空 + // - 3:链接,url不为空 + car := &Card{} + if card.CardType == 1 { + pwd, err := decryptAES(card.Pwd, appKey) + if err != nil { + return nil, err + } + no, err := decryptAES(card.No, appKey) + if err != nil { + return nil, err + } + car.Password = pwd + car.Number = no + } else if card.CardType == 2 { + pwd, err := decryptAES(card.Pwd, appKey) + if err != nil { + return nil, err + } + car.Password = pwd + } else if card.CardType == 3 { + // 无 + } + return car, nil +} + +func notifyResp(appKey string, resp *notify.OrderReq) (*proto.NotifyResponse, error) { + data, err := json.Marshal(resp) + if err != nil { + return nil, err + } + status := vo.OrderStatus(resp.TradeStatus) + pb := &proto.NotifyResponse{ + Result: &proto.Result{ + Status: status.GetOrderStatus(), + OrderNo: resp.OutTradeNo, + TradeNo: resp.OrderNo, + Message: resp.TradeStateDesc, + Data: data, + Extra: nil, + }, + } + b, err := getNotifyCard(appKey, resp.Cards) + if err != nil { + return nil, err + } + pb.Result.Extra = b + return pb, nil +} + +func getNotifyCard(appKey string, cards []notify.Cards) ([]byte, error) { + if len(cards) == 0 { + return nil, nil + } + card := cards[0] + car := &Card{} + if card.CardType == 1 { + pwd, err := decryptAES(card.Pwd, appKey) + if err != nil { + return nil, err + } + no, err := decryptAES(card.No, appKey) + if err != nil { + return nil, err + } + car.Password = pwd + car.Number = no + } else if card.CardType == 2 { + pwd, err := decryptAES(card.Pwd, appKey) + if err != nil { + return nil, err + } + car.Password = pwd + } else if card.CardType == 3 { + // 无 + } + return car.ToJson(), nil +} diff --git a/plugins/zltx_v2/internal/util.go b/plugins/zltx_v2/internal/util.go new file mode 100644 index 0000000..fbaf233 --- /dev/null +++ b/plugins/zltx_v2/internal/util.go @@ -0,0 +1,43 @@ +package internal + +import ( + "crypto/aes" + "encoding/base64" + "fmt" + "gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2/sdk/requests" + "strings" +) + +func getScheme(url string) string { + if strings.HasPrefix(url, "https://") { + return requests.HTTPS + } + return requests.HTTP +} + +func getDomain(url, scheme string) (string, error) { + if strings.HasPrefix(url, fmt.Sprintf("%s://", strings.ToLower(scheme))) { + parts := strings.Split(url, "//") + if len(parts) >= 2 { + return parts[1], nil + } + } + return "", fmt.Errorf("invalid url") +} + +func decryptAES(encryptedData string, secretKey string) (string, error) { + // 第一步:对加密的卡密做base64 decode + encryptedBytes, err := base64.StdEncoding.DecodeString(encryptedData) + if err != nil { + return "", err + } + // 第二步:使用aes-256-ecb解密 + cipher, _ := aes.NewCipher([]byte(secretKey)) + decrypted := make([]byte, len(encryptedBytes)) + size := 16 + for bs, be := 0, size; bs < len(encryptedBytes); bs, be = bs+size, be+size { + cipher.Decrypt(decrypted[bs:be], encryptedBytes[bs:be]) + } + paddingSize := int(decrypted[len(decrypted)-1]) + return string(decrypted[0 : len(decrypted)-paddingSize]), nil +} diff --git a/plugins/zltx_v2/internal/vo/status.go b/plugins/zltx_v2/internal/vo/status.go new file mode 100644 index 0000000..8914087 --- /dev/null +++ b/plugins/zltx_v2/internal/vo/status.go @@ -0,0 +1,51 @@ +package vo + +import ( + "gitea.cdlsxd.cn/sdk/plugin/proto" +) + +type OrderStatus string + +const ( + OrderSuccess OrderStatus = "SUCCESS" // 充值成功 + OrderIng OrderStatus = "RECHARGING" // 充值处理中 + OrderFail OrderStatus = "FAIL" // 充值失败 +) + +var orderStatusMap = map[OrderStatus]proto.Status{ + OrderSuccess: proto.Status_SUCCESS, + OrderIng: proto.Status_ING, + OrderFail: proto.Status_FAIL, +} + +var orderStatusTextMap = map[OrderStatus]string{ + OrderSuccess: "充值成功", + OrderIng: "充值处理中", + OrderFail: "充值失败", +} + +func (o OrderStatus) IsSuccess() bool { + return o == OrderSuccess +} + +func (o OrderStatus) IsIng() bool { + return o == OrderIng +} + +func (o OrderStatus) IsFail() bool { + return o == OrderFail +} + +func (o OrderStatus) GetOrderStatus() proto.Status { + if resultStatus, ok := orderStatusMap[o]; ok { + return resultStatus + } + return proto.Status_ING +} + +func (o OrderStatus) GetOrderStatusText() string { + if text, ok := orderStatusTextMap[o]; ok { + return text + } + return "" +} diff --git a/plugins/zltx_v2/internal/zltx_v2.go b/plugins/zltx_v2/internal/zltx_v2.go new file mode 100644 index 0000000..765b8f8 --- /dev/null +++ b/plugins/zltx_v2/internal/zltx_v2.go @@ -0,0 +1,111 @@ +package internal + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "gitea.cdlsxd.cn/sdk/plugin/proto" + "gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2/api" + "gitee.com/chengdu_blue_brothers/openapi-go-sdk-v2/notify" + "io/ioutil" + "net/http" +) + +// 插件通信信息,若不对应则会报错panic +const ( + Tag = "zltx_v2" + Version = 1 + CookieKey = "zltx_v2" + CookieValue = "zltx_v2" +) + +type ZLTXV2Service struct{} + +func (p *ZLTXV2Service) Order(ctx context.Context, request *proto.OrderRequest) (*proto.OrderResponse, error) { + c, err := transConfig(request.Config) + if err != nil { + return nil, err + } + client, err := c.client() + if err != nil { + return nil, err + } + response, errResp, err := api.OrderCreate(ctx, client, c.AppId, c.orderReq(request)) + if err != nil { + return nil, fmt.Errorf("请求异常[%v]", err) + } + if errResp != nil { + return nil, fmt.Errorf("请求错误[code:%d]-[reason:%s]-[msg:%s]", errResp.Code, errResp.Reason, errResp.Message) + } + + return orderResp(request, response), nil +} + +func (p *ZLTXV2Service) Query(ctx context.Context, request *proto.QueryRequest) (*proto.QueryResponse, error) { + c, err := transConfig(request.Config) + if err != nil { + return nil, err + } + client, err := c.client() + if err != nil { + return nil, err + } + + response, errResp, err := api.OrderQuery(ctx, client, c.AppId, c.queryReq(request)) + if err != nil { + return nil, fmt.Errorf("请求异常[%v]", err) + } + if errResp != nil { + return nil, fmt.Errorf("请求错误[code:%d]-[reason:%s]-[msg:%s]", errResp.Code, errResp.Reason, errResp.Message) + } + + return queryResp(c.AppKey, request, response) +} + +func (p *ZLTXV2Service) Notify(_ context.Context, request *proto.NotifyRequest) (*proto.NotifyResponse, error) { + req := &http.Request{ + Method: "", + URL: nil, + Proto: "", + ProtoMajor: 0, + ProtoMinor: 0, + Header: nil, + Body: nil, + GetBody: nil, + ContentLength: 0, + TransferEncoding: nil, + Close: false, + Host: "", + Form: nil, + PostForm: nil, + MultipartForm: nil, + Trailer: nil, + RemoteAddr: "", + RequestURI: "", + TLS: nil, + Cancel: nil, + Response: nil, + } + headers := make(map[string]string) + if err := json.Unmarshal(request.Headers, &headers); err != nil { + return nil, fmt.Errorf("headers Unmarshal err [%v]", err) + } + httpHeaders := make(http.Header, len(headers)) + for k, value := range headers { + httpHeaders.Add(k, value) + } + req.Header = httpHeaders + req.Body = ioutil.NopCloser(bytes.NewBuffer(request.Body)) + + c, err := transConfig(request.Config) + if err != nil { + return nil, err + } + n, err := notify.NewNotify(c.AppId, c.AppKey).ParseAndVerify(req) + if err != nil { + return nil, err + } + + return notifyResp(c.AppKey, n) +} diff --git a/plugins/zltx_v2/internal/zltx_v2_test.go b/plugins/zltx_v2/internal/zltx_v2_test.go new file mode 100644 index 0000000..b9b8f6e --- /dev/null +++ b/plugins/zltx_v2/internal/zltx_v2_test.go @@ -0,0 +1,109 @@ +package internal + +import ( + "context" + "encoding/json" + "fmt" + "gitea.cdlsxd.cn/sdk/plugin/proto" + "github.com/stretchr/testify/assert" + "testing" +) + +var zltx = &ZLTXV2Service{} + +func config() []byte { + c := &Config{ + AppId: "23329", + AppKey: "8db16e8cc8363ed4eb4c14f9520bcc32", + BaseUri: "http://211.137.105.198:17100", + NotifyUrl: "http://192.168.6.184:8090/ping", + } + marshal, _ := json.Marshal(c) + return marshal +} + +func TestConfig(t *testing.T) { + t.Run("TestConfig", func(t *testing.T) { + c := config() + fmt.Printf("%+s\n", string(c)) + assert.NotEmpty(t, c) + }) +} + +func TestOrder(t *testing.T) { + request := &proto.OrderRequest{ + Config: config(), + Order: &proto.OrderRequest_Order{ + OrderNo: "test_zltx_v2_3", + Account: "", + Quantity: 1, + Extra: nil, + }, + Product: &proto.OrderRequest_Product{ + ProductNo: "CEMLKRLK9640", + Extra: []byte(`{}`), + }, + } + + t.Run("TestOrder", func(t *testing.T) { + got, err := zltx.Order(context.Background(), request) + if err != nil { + t.Errorf("Order() error = %v", err) + return + } + fmt.Printf("%+v\n", got) + assert.Equal(t, int(proto.Status_ING), int(got.Result.Status)) + }) +} + +func TestQuery(t *testing.T) { + request := &proto.QueryRequest{ + Config: config(), + Order: &proto.QueryRequest_Order{ + OrderNo: "test_zltx_v2_3", + TradeNo: "", + Account: "", + Extra: nil, + }, + } + t.Run("TestQuery", func(t *testing.T) { + got, err := zltx.Query(context.Background(), request) + if err != nil { + t.Errorf("Query() error = %v", err) + return + } + fmt.Printf("%+v\n", got) + assert.Equal(t, int(proto.Status_SUCCESS), int(got.Result.Status)) + }) +} + +func TestNotify(t *testing.T) { + jsonData := `{ + "tradeStatus": "SUCCESS", + "orderNo": "C2081410801687044096", + "tradeStateDesc": "成功", + "cards": [ + {"no":"*","pwd":"*","deadline":"2024-07-03 23:59:59","cardType":1} + ], + "mchId": 23329, + "outTradeNo": "20240802212326527830", + "rechargeAccount": "17384082748", + "unitPrice":102.5 + }` + headers := `{"Authorization":"292e21f3683219369cf68dede0d45730","Content-Type":"application/json"}` + in := &proto.NotifyRequest{ + Config: config(), + Queries: nil, + Headers: []byte(headers), + Body: []byte(jsonData), + } + t.Run("TestNotify", func(t *testing.T) { + got, err := zltx.Notify(context.Background(), in) + if !assert.Nil(t, err) { + t.Errorf("Notify() error = %v", err) + return + } + fmt.Printf("%s \n", got.String()) + assert.Equal(t, int(proto.Status_SUCCESS), int(got.Result.Status)) + }) +} diff --git a/plugins/zltx_v2/main.go b/plugins/zltx_v2/main.go new file mode 100644 index 0000000..d71f976 --- /dev/null +++ b/plugins/zltx_v2/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "gitea.cdlsxd.cn/sdk/plugin/shared" + "github.com/hashicorp/go-plugin" + "plugins/zltxv2/internal" +) + +func main() { + plugin.Serve(&plugin.ServeConfig{ + HandshakeConfig: shared.HandshakeConfig(internal.Version, internal.CookieKey, internal.CookieValue), + Plugins: shared.PluginSet(shared.NewPlugin(&internal.ZLTXV2Service{}, internal.Tag)), + GRPCServer: plugin.DefaultGRPCServer, + }) +}