feat(supplier): 添加瓦文卡券查询功能
- 新增 waveCard 方法,实现瓦文卡券余额查询 - 通过验证码图像识别实现自动验证码处理 - 完善查询失败及错误日志记录 - 添加对应单元测试覆盖 waveCard 功能 - 更新第三方依赖版本,提升性能与安全 - 升级 go-redis、zap 和其他 go.mod 依赖版本 - 重构鲁班卡密发送相关代码,使用 resty 替代 httplib - 优化鲁班回调请求及返回值处理逻辑 - 调整 OCRClient 单例初始化方式,保证线程安全 - 修正 Base64Decode 函数注释规范为驼峰形式
This commit is contained in:
@@ -1 +1 @@
|
||||
golang 1.25.2
|
||||
golang 1.25.3
|
||||
|
||||
14
go.mod
14
go.mod
@@ -14,11 +14,11 @@ require (
|
||||
github.com/forgoer/openssl v1.8.0
|
||||
github.com/go-resty/resty/v2 v2.16.5
|
||||
github.com/go-sql-driver/mysql v1.9.3
|
||||
github.com/go-stomp/stomp/v3 v3.1.3
|
||||
github.com/go-stomp/stomp/v3 v3.1.5
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
|
||||
github.com/prometheus/client_golang v1.23.2
|
||||
github.com/redis/go-redis/v9 v9.14.0
|
||||
github.com/redis/go-redis/v9 v9.17.2
|
||||
github.com/shopspring/decimal v1.4.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/widuu/gojson v0.0.0-20170212122013-7da9d2cd949b
|
||||
@@ -34,7 +34,7 @@ require (
|
||||
go.opentelemetry.io/otel/sdk/log v0.14.0
|
||||
go.opentelemetry.io/otel/sdk/metric v1.38.0
|
||||
go.opentelemetry.io/otel/trace v1.38.0
|
||||
go.uber.org/zap v1.27.0
|
||||
go.uber.org/zap v1.27.1
|
||||
golang.org/x/exp v0.0.0-20250911091902-df9299821621
|
||||
)
|
||||
|
||||
@@ -69,10 +69,10 @@ require (
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||
golang.org/x/arch v0.21.0 // indirect
|
||||
golang.org/x/crypto v0.42.0 // indirect
|
||||
golang.org/x/net v0.44.0 // indirect
|
||||
golang.org/x/sys v0.36.0 // indirect
|
||||
golang.org/x/text v0.29.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/text v0.31.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250922171735-9219d122eba9 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9 // indirect
|
||||
google.golang.org/grpc v1.75.1 // indirect
|
||||
|
||||
28
go.sum
28
go.sum
@@ -48,8 +48,8 @@ github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptd
|
||||
github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA=
|
||||
github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
|
||||
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||
github.com/go-stomp/stomp/v3 v3.1.3 h1:5/wi+bI38O1Qkf2cc7Gjlw7N5beHMWB/BxpX+4p/MGI=
|
||||
github.com/go-stomp/stomp/v3 v3.1.3/go.mod h1:ztzZej6T2W4Y6FlD+Tb5n7HQP3/O5UNQiuC169pIp10=
|
||||
github.com/go-stomp/stomp/v3 v3.1.5 h1:Pikz1OSusmSKUm5mRKYfXQZaDatfZ+EnBBA1JJ2xENQ=
|
||||
github.com/go-stomp/stomp/v3 v3.1.5/go.mod h1:ztzZej6T2W4Y6FlD+Tb5n7HQP3/O5UNQiuC169pIp10=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
@@ -96,8 +96,8 @@ github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9Z
|
||||
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
|
||||
github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
|
||||
github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
|
||||
github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01jfAE=
|
||||
github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
|
||||
github.com/redis/go-redis/v9 v9.17.2 h1:P2EGsA4qVIM3Pp+aPocCJ7DguDHhqrXNhVcEp4ViluI=
|
||||
github.com/redis/go-redis/v9 v9.17.2/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/shiena/ansicolor v0.0.0-20230509054315-a9deabde6e02 h1:v9ezJDHA1XGxViAUSIoO/Id7Fl63u6d0YmsAm+/p2hs=
|
||||
@@ -162,8 +162,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
|
||||
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
|
||||
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
|
||||
golang.org/x/arch v0.21.0 h1:iTC9o7+wP6cPWpDWkivCvQFGAHDQ59SrSxsLPcnkArw=
|
||||
@@ -175,8 +175,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
|
||||
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU=
|
||||
golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
@@ -196,8 +196,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
|
||||
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -220,8 +220,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
||||
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -240,8 +240,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"gateway/internal/otelTrace"
|
||||
"sync"
|
||||
|
||||
"github.com/dubonzi/otelresty"
|
||||
"github.com/go-resty/resty/v2"
|
||||
@@ -17,8 +18,13 @@ import (
|
||||
type OCRClient struct {
|
||||
}
|
||||
|
||||
var ocrClient *OCRClient
|
||||
|
||||
func NewOCRClient() *OCRClient {
|
||||
return &OCRClient{}
|
||||
sync.OnceFunc(func() {
|
||||
ocrClient = &OCRClient{}
|
||||
})()
|
||||
return ocrClient
|
||||
}
|
||||
|
||||
type CalcInput struct {
|
||||
|
||||
@@ -613,3 +613,90 @@ func (c *cardTypeQuery) jisuCard(ctx context.Context) (balance float64, err erro
|
||||
}
|
||||
return respData2.Data.Amount, nil
|
||||
}
|
||||
|
||||
func (c *cardTypeQuery) waveCard(ctx context.Context) (balance float64, err error) {
|
||||
webClient := resty.New().SetTimeout(time.Second * 5).SetRetryCount(3).SetHeaders(map[string]string{
|
||||
"user-agent": useragent.GetUserAgentByPlatform(useragent.PlatformPhone),
|
||||
}).OnBeforeRequest(func(c *resty.Client, request *resty.Request) error {
|
||||
//proxy, _ := utils.GetProxy(ctx, utils.GenerateId(), "waveCard")
|
||||
//if proxy != "" {
|
||||
// c.SetProxy(proxy)
|
||||
//}
|
||||
return nil
|
||||
})
|
||||
otelresty.TraceClient(webClient)
|
||||
|
||||
for range 10 {
|
||||
captchaResp, err2 := webClient.R().SetContext(ctx).Get("https://www.wavencard.com/ergouzi/auth/card_captcha.jpg")
|
||||
if err2 != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("【瓦文】获取验证码失败", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
captchaRespData := struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data struct {
|
||||
Img string `json:"img"`
|
||||
Key string `json:"key"`
|
||||
} `json:"data,omitempty"`
|
||||
}{}
|
||||
err = json.Unmarshal(captchaResp.Body(), &captchaRespData)
|
||||
if err != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("【瓦文】获取验证码失败", zap.Error(err2))
|
||||
continue
|
||||
}
|
||||
img, err2 := utils.Base64Decode(strings.ReplaceAll(captchaRespData.Data.Img, "data:image/png;base64,", ""))
|
||||
if err2 != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("【瓦文】获取验证码失败", zap.Error(err2))
|
||||
continue
|
||||
}
|
||||
captchaRes, err2 := client.NewOCRClient().Calc(ctx, &client.CalcInput{
|
||||
File: img,
|
||||
FileName: "card_captcha.png",
|
||||
Category: "calc",
|
||||
Length: 4,
|
||||
})
|
||||
if err2 != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("【瓦文】获取验证码失败", zap.Error(err2))
|
||||
continue
|
||||
}
|
||||
response, err2 := webClient.R().SetContext(ctx).SetQueryParams(map[string]string{
|
||||
"cardAccount": c.CardNo,
|
||||
"cardPwd": c.CardPwd,
|
||||
"verificationCode": captchaRes,
|
||||
"captchaKey": captchaRespData.Data.Key,
|
||||
"currentLang": "zh",
|
||||
}).Get("https://www.wavencard.com/ergouzi/v_card/find_public_card_account")
|
||||
if err2 != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("【瓦文】查询订单失败", zap.Error(err2))
|
||||
continue
|
||||
}
|
||||
|
||||
otelTrace.Logger.WithContext(ctx).Info("【瓦文】查询订单返回", zap.Any("resp", response.String()))
|
||||
respData := struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data struct {
|
||||
Amount string `json:"amount"`
|
||||
Status string `json:"status"`
|
||||
} `json:"data,omitempty"`
|
||||
}{}
|
||||
if err2 = json.Unmarshal(response.Body(), &respData); err2 != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("查卡错误", zap.Error(err2))
|
||||
continue
|
||||
}
|
||||
if respData.Code != 200 {
|
||||
return c.Balance, errors.New(respData.Msg)
|
||||
}
|
||||
amount, err2 := convertor.ToFloat(strings.TrimSpace(strings.ReplaceAll(respData.Data.Amount, "CNY", "")))
|
||||
if err2 != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("【瓦文】查询订单失败", zap.Error(err2))
|
||||
return c.Balance, errors.New("查卡失败")
|
||||
}
|
||||
if respData.Data.Status != "未使用" {
|
||||
return c.Balance, errors.New("该卡已被其他用户绑定!")
|
||||
}
|
||||
return amount, nil
|
||||
}
|
||||
return c.Balance, errors.New("查卡失败")
|
||||
}
|
||||
|
||||
@@ -128,3 +128,16 @@ func Test_cardTypeQuery_jvnkaQuery(t *testing.T) {
|
||||
otelTrace.Logger.WithContext(t.Context()).Info("查询结果", zap.Float64("balance", balance), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
func Test_cardTypeQuery_waveCard(t *testing.T) {
|
||||
cardQuery := cardTypeQuery{
|
||||
Balance: 20,
|
||||
CardNo: "w66444748872831218",
|
||||
CardPwd: "57217792940",
|
||||
QueryType: "outletcard",
|
||||
}
|
||||
for range 3 {
|
||||
balance, err := cardQuery.waveCard(t.Context())
|
||||
otelTrace.Logger.WithContext(t.Context()).Info("查询结果", zap.Float64("balance", balance), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/beego/beego/v2/client/httplib"
|
||||
"github.com/dubonzi/otelresty"
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
"github.com/duke-git/lancet/v2/maputil"
|
||||
@@ -108,26 +107,18 @@ func (s *SendCardTaskTypeLuban) channelOne(ctx context.Context, orderItem OrderP
|
||||
"card_no": task.CardInfo.CardNo,
|
||||
"card_pwd": task.CardInfo.Data,
|
||||
}
|
||||
|
||||
var response string
|
||||
for range 3 {
|
||||
request := httplib.NewBeegoRequestWithCtx(ctx, orderUrl, "GET").
|
||||
SetTimeout(time.Second*5, time.Second*5).Retries(3).RetryDelay(3 * time.Second)
|
||||
|
||||
jsonBody, _ := json.Marshal(params)
|
||||
request.Param("json", string(jsonBody))
|
||||
request, _ = request.JSONBody(params)
|
||||
response, err = request.String()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !strings.Contains(response, "PROXY") && !strings.Contains(response, "RET") {
|
||||
break
|
||||
}
|
||||
otelTrace.Logger.WithContext(ctx).Info("鲁班发送通知失败", zap.String("response", response), zap.Any("params", params), zap.String("orderUrl", orderUrl))
|
||||
jsonBody, _ := json.Marshal(params)
|
||||
client := resty.New().SetTimeout(time.Second * 5).SetTimeout(time.Second * 5)
|
||||
otelresty.TraceClient(client)
|
||||
response, err := client.R().SetContext(ctx).SetQueryParams(map[string]string{
|
||||
"json": string(jsonBody),
|
||||
}).Get("orderUrl")
|
||||
if err != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("请求失败", zap.Error(err))
|
||||
return errors.New("请求失败")
|
||||
}
|
||||
|
||||
otelTrace.Logger.WithContext(ctx).Info("鲁班回调通知", zap.String("response", response), zap.Any("params", params), zap.String("orderUrl", orderUrl))
|
||||
otelTrace.Logger.WithContext(ctx).Info("回调", zap.String("response", response.String()), zap.Any("params", params), zap.String("orderUrl", orderUrl))
|
||||
|
||||
submitData := struct {
|
||||
Code int64 `json:"code"`
|
||||
@@ -135,8 +126,53 @@ func (s *SendCardTaskTypeLuban) channelOne(ctx context.Context, orderItem OrderP
|
||||
Data string `json:"data"`
|
||||
}{}
|
||||
|
||||
if err := json.Unmarshal([]byte(response), &submitData); err != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("转换返回值失败", zap.Error(err), zap.String("response", response))
|
||||
if err = json.Unmarshal([]byte(response.String()), &submitData); err != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("转换返回值失败", zap.Error(err), zap.String("response", response.String()))
|
||||
return errors.New("转换返回值失败")
|
||||
}
|
||||
|
||||
if submitData.Code != 200 {
|
||||
return errors.New(submitData.Msg)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SendCardTaskTypeLuban) channelTwo(ctx context.Context, orderItem OrderPoolItem, task SendCardTask) error {
|
||||
otelTrace.Logger.WithContext(ctx).Info("处理任务", zap.Any("orderItem", orderItem), zap.Any("task", task))
|
||||
query, err := url.Parse(orderItem.PayURL)
|
||||
if err != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("解析URL失败", zap.Error(err))
|
||||
return errors.New("解析URL失败")
|
||||
}
|
||||
orderUrl := fmt.Sprintf("https://abc.pvcrr.com/baolingqiu/tdeal_order/postCardAndSecret")
|
||||
params := map[string]any{
|
||||
"tradeNo": query.Query().Get("tradeNo"),
|
||||
"sign": query.Query().Get("sign"),
|
||||
"card_no": task.CardInfo.CardNo,
|
||||
"card_pwd": task.CardInfo.Data,
|
||||
}
|
||||
jsonBody, _ := json.Marshal(params)
|
||||
client := resty.New().SetTimeout(time.Second * 5).SetTimeout(time.Second * 5)
|
||||
otelresty.TraceClient(client)
|
||||
response, err := client.R().SetContext(ctx).SetQueryParams(map[string]string{
|
||||
"json": string(jsonBody),
|
||||
}).Get("orderUrl")
|
||||
if err != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("请求失败", zap.Error(err))
|
||||
return errors.New("请求失败")
|
||||
}
|
||||
|
||||
otelTrace.Logger.WithContext(ctx).Info("回调", zap.String("response", response.String()), zap.Any("params", params), zap.String("orderUrl", orderUrl))
|
||||
|
||||
submitData := struct {
|
||||
Code int64 `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data string `json:"data"`
|
||||
}{}
|
||||
|
||||
if err = json.Unmarshal([]byte(response.String()), &submitData); err != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("转换返回值失败", zap.Error(err), zap.String("response", response.String()))
|
||||
return errors.New("转换返回值失败")
|
||||
}
|
||||
|
||||
@@ -159,6 +195,10 @@ func (s *SendCardTaskTypeLuban) HandleSendCardTask(ctx context.Context, orderIte
|
||||
err2 := (&SendCardTaskTypeFatSix{}).HandleSendCardTask(ctx, orderItem, task)
|
||||
return err2
|
||||
}
|
||||
|
||||
if strings.Contains(orderItem.PayURL, "abc.pvcrr.com") {
|
||||
return s.channelTwo(ctx, orderItem, task)
|
||||
}
|
||||
return s.channelOne(ctx, orderItem, task)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ func TestSendCardTaskTypeLuban_CreateOrder(t *testing.T) {
|
||||
|
||||
orderId := utils.GenerateId()
|
||||
params := map[string]any{
|
||||
"mchId": "20000046",
|
||||
"productId": "8011",
|
||||
"mchId": "158",
|
||||
"productId": "8010",
|
||||
"currency": "cny",
|
||||
"amount": 10 * 100,
|
||||
"mchOrderNo": orderId,
|
||||
@@ -30,11 +30,11 @@ func TestSendCardTaskTypeLuban_CreateOrder(t *testing.T) {
|
||||
"version": "1.0",
|
||||
}
|
||||
|
||||
params["sign"] = (&SendCardTaskTypeLuban{}).sign(t.Context(), params, "ROFMXGAPRQ7Y90AZXJL1DWR08S07SE3J5YXATKD9T8MVMBO0VICPYCFRNGWIVW8VFXZ9KYVISPIIWZAOEWDYCZEQ7CXFLMN82SHBQHTQZDBDPHL5OVJ5F4A4O7OUKC2R")
|
||||
params["sign"] = (&SendCardTaskTypeLuban{}).sign(t.Context(), params, "POWTDMQWZOFYMFBADVCHPJNNQQQIUQSBQUZFZ37KF9NVPJBGN93PCMOESBWQPCSPABJXD5UIJZVYSJJ7UYW9WODJM4IURRSHPFLZBTNYIUGQEAPHFFINWZUU9RXI9WEK")
|
||||
paramsStr := map[string]string{}
|
||||
for k, v := range params {
|
||||
paramsStr[k] = convertor.ToString(v)
|
||||
}
|
||||
response, _ := webClient.R().SetFormData(paramsStr).Post("http://gdxzf.info:56700/api/pay/create_order")
|
||||
response, _ := webClient.R().SetFormData(paramsStr).Post("http://jiuzpay.xyz:56700/api/pay/create_order")
|
||||
otelTrace.Logger.WithContext(t.Context()).Info("请求结果", zap.String("response", response.String()), zap.Any("params", params))
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ func Base64Encode(raw []byte) string {
|
||||
return t
|
||||
}
|
||||
|
||||
// base64解码
|
||||
// Base64Decode base64解码
|
||||
func Base64Decode(raw string) ([]byte, error) {
|
||||
return base64.StdEncoding.DecodeString(raw)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user