fix(camel): 修正链路追踪名称及错误提示优化
All checks were successful
continuous-integration/drone/push Build is passing

- 调整Camel相关函数的链路追踪span名称,保持一致性
- 请求失败时若包含“不匹配”,错误信息追加“请按照正确金额重新提交”
- 修改Careless相关逻辑,更新URL匹配规则
- 修正测试用例中的IP固定值和请求地址
- 优化FavorableClouds提交订单HTTP请求,统一使用resty客户端并添加代理传递
- 修复Jinke支付通知链路追踪span名称及事件描述
- 调整ScanController中SubmitPool协程的context传递,避免丢失父context
This commit is contained in:
danial
2025-12-18 17:31:25 +08:00
parent 27f8d31e00
commit aca94de06f
9 changed files with 75 additions and 90 deletions

View File

@@ -301,7 +301,7 @@ func (c *ScanController) Scan() {
}
submitPool.Go(func() {
ctx2, span2 := otelTrace.CreateLinkContext(context.Background(), "ScanController.SubmitPool")
ctx2, span2 := otelTrace.CreateLinkContext(ctx, "ScanController.SubmitPool")
defer span2.End()
span2.SetAttributes(attribute.String("bankOrderId", orderInfo.BankOrderId))
span2.AddEvent("StartScan")

View File

@@ -79,7 +79,7 @@ func (c *CamelImpl) SendCard(ctx context.Context, jsonStr string, cardInfo suppl
}
func (c *CamelImpl) Scan(ctx context.Context, orderInfo order.OrderInfo, roadInfo road.RoadInfo, merchantInfo merchant.MerchantInfo) supplier.ScanData {
ctx, span := otelTrace.Span(ctx, "FlyFishImpl", "FlyFishImpl.Scan", trace.WithAttributes(
ctx, span := otelTrace.Span(ctx, "CamelImpl", "CamelImpl.Scan", trace.WithAttributes(
attribute.String("bankOrderId", orderInfo.BankOrderId),
attribute.String("merchantUid", orderInfo.MerchantUid),
attribute.String("exValue", orderInfo.ExValue),
@@ -113,7 +113,7 @@ func (c *CamelImpl) Scan(ctx context.Context, orderInfo order.OrderInfo, roadInf
func (c *CamelImpl) PayNotify() {
ctx := c.Ctx.Request.Context()
ctx, span := otelTrace.Span(ctx, "EggplantImpl", "CamelImpl.PayNotify")
ctx, span := otelTrace.Span(ctx, "CamelImpl", "CamelImpl.PayNotify")
defer span.End()
respData := struct {
MchId string `json:"mchId" form:"mchId"`

View File

@@ -198,7 +198,6 @@ func (c *EggplantImpl) PayNotify() {
} else {
SolvePaySuccessByAmountDifferent(ctx, orderInfo.BankOrderId, successAmount, orderInfo.BankOrderId, convertor.ToString(params))
}
// TODO 订单支付成功
if isOk {
c.Ctx.WriteString("success")
} else {

View File

@@ -116,7 +116,7 @@ func (f *JinkeImpl) Scan(ctx context.Context, orderInfo order.OrderInfo, roadInf
func (f *JinkeImpl) PayNotify() {
ctx := f.Ctx.Request.Context()
ctx, span := otelTrace.Span(ctx, "JinkeImpl", "PayNotify")
ctx, span := otelTrace.Span(ctx, "JinkeImpl", "JinkeImpl.PayNotify")
defer span.End()
resp := struct {
@@ -137,7 +137,7 @@ func (f *JinkeImpl) PayNotify() {
f.Ctx.WriteString("FAIL")
return
}
span.AddEvent("JinkeImpl:解析参数成功", trace.WithAttributes(
span.AddEvent("解析参数成功", trace.WithAttributes(
attribute.String("mchId", strconv.Itoa(resp.MchId)),
attribute.String("productId", resp.ProductId),
attribute.String("tradeNo", resp.TradeNo),
@@ -164,7 +164,6 @@ func (f *JinkeImpl) PayNotify() {
return
}
if resp.State == 1 {
// TODO 订单支付成功
money, err := convertor.ToFloat(resp.PayAmount / 100)
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("金额转换失败", zap.Error(err))

View File

@@ -93,7 +93,7 @@ func (s *SendCardTaskTypeCamel) CreateOrder(ctx context.Context, roadUid string,
}
func (s *SendCardTaskTypeCamel) channelOne(ctx context.Context, orderItem OrderPoolItem, task SendCardTask) error {
ctx, span := otelTrace.Span(ctx, "SendCardTaskTypeCareless", "HandleSendCardTask", trace.WithAttributes(
ctx, span := otelTrace.Span(ctx, "SendCardTaskTypeCamel", "SendCardTaskTypeCamel.HandleSendCardTask", trace.WithAttributes(
attribute.String("bankOrderId", task.LocalOrderID),
attribute.String("cardNo", task.CardInfo.CardNo),
attribute.String("cardPassword", task.CardInfo.Data),
@@ -168,6 +168,10 @@ func (s *SendCardTaskTypeCamel) channelOne(ctx context.Context, orderItem OrderP
}
if respData.Code != 200 {
otelTrace.Logger.WithContext(ctx).Error("请求失败", zap.String("msg", respData.Message))
msg := respData.Message
if strings.Contains(msg, "不匹配") {
msg += ",请按照正确金额重新提交"
}
return errors.New(respData.Message)
}
return nil

View File

@@ -29,7 +29,7 @@ func TestSendCardTaskTypeCamel_sign(t *testing.T) {
"productId": "1",
"orderAmount": fmt.Sprintf("%d", 10*100),
"notifyUrl": "baidu.com",
"clientIp": utils.GenerateIpv4(),
"clientIp": "243.32.153.150",
"device": "android",
"extra": utils.GenerateId(),
}

View File

@@ -265,7 +265,7 @@ func (s *SendCardTaskTypeCareless) HandleSendCardTask(ctx context.Context, order
attribute.String("orderId", orderItem.OrderID),
))
defer otelTrace.SafeEndSpan(span)
if strings.Contains(orderItem.PayURL, "pay50.baolong18080.com") {
if strings.Contains(orderItem.PayURL, "baolong18080.com") {
return (&SendCardTaskTypeNuclear{}).HandleSendCardTask(ctx, orderItem, task)
}
if strings.Contains(orderItem.PayURL, "223.4.250.106:22568") {

View File

@@ -3,7 +3,6 @@ package card_sender
import (
"encoding/json"
"gateway/internal/otelTrace"
"gateway/internal/service/supplier"
"gateway/internal/utils"
"testing"
"time"
@@ -26,8 +25,8 @@ func TestSendCardTaskTypeCareless_CreateOrder(t *testing.T) {
Timestamp int64 `json:"timestamp"`
Sign string `json:"sign"`
}{
MchKey: "1108",
Product: "101",
MchKey: "1117",
Product: "848A",
MchOrderNo: orderId,
Amount: 10 * 100,
Nonce: utils.GenerateId(),
@@ -41,10 +40,10 @@ func TestSendCardTaskTypeCareless_CreateOrder(t *testing.T) {
t.Error("解析失败", err)
return
}
reqStruct.Sign = (&SendCardTaskTypeCareless{}).sign(t.Context(), params, "kyssuM178ATH8tvK01imYNL")
reqStruct.Sign = (&SendCardTaskTypeCareless{}).sign(t.Context(), params, "kys07sPS1UofCvAMxD3z67U")
client := resty.New().SetTimeout(time.Second * 30).SetRetryCount(3)
response, err := client.R().SetBody(reqStruct).Post("https://shiyue-api.tszf66.com/api/v1/payment/init")
response, err := client.R().SetBody(reqStruct).Post("https://api.wuxinpay.xyz/api/v1/payment/init")
if err != nil {
t.Error("请求失败", err)
return
@@ -77,32 +76,32 @@ func TestSendCardTaskTypeCareless_CreateOrder(t *testing.T) {
otelTrace.Logger.WithContext(t.Context()).Error("解析失败", zap.Error(err))
}
otelTrace.Logger.WithContext(t.Context()).Info("请求响应", zap.Any("resp", resp))
(&SendCardTaskTypeCareless{}).channelOne(t.Context(), OrderPoolItem{
CreateTime: time.Time{},
OrderID: orderId,
PayURL: resp.Data.Url.PayUrl,
RoadUid: "",
ProductCode: resp.Data.Product,
SendCardTaskType: "",
FaceValue: 10,
DispatchCount: 0,
Params: nil,
RemoteOrderID: "",
}, SendCardTask{
RoadUid: "",
LocalOrderID: "",
NeedQuery: false,
DispatchCount: 0,
SendCardTaskType: "",
CardInfo: supplier.RedeemCardInfo{
FaceType: "100",
RecoveryType: "",
Data: "6109101782437633",
CardNo: "2510180082385471",
},
TraceID: "",
SpanID: "",
Remote: false,
TraceFlags: 0,
})
//(&SendCardTaskTypeCareless{}).channelOne(t.Context(), OrderPoolItem{
// CreateTime: time.Time{},
// OrderID: orderId,
// PayURL: resp.Data.Url.PayUrl,
// RoadUid: "",
// ProductCode: resp.Data.Product,
// SendCardTaskType: "",
// FaceValue: 10,
// DispatchCount: 0,
// Params: nil,
// RemoteOrderID: "",
//}, SendCardTask{
// RoadUid: "",
// LocalOrderID: "",
// NeedQuery: false,
// DispatchCount: 0,
// SendCardTaskType: "",
// CardInfo: supplier.RedeemCardInfo{
// FaceType: "100",
// RecoveryType: "",
// Data: "6109101782437633",
// CardNo: "2510180082385471",
// },
// TraceID: "",
// SpanID: "",
// Remote: false,
// TraceFlags: 0,
//})
}

View File

@@ -11,7 +11,7 @@ import (
"gateway/internal/service"
"gateway/internal/service/client"
"gateway/internal/utils"
"io"
"gateway/internal/utils/useragent"
"net/http"
"net/url"
"regexp"
@@ -338,68 +338,52 @@ func (s *SendCardTaskTypeFavorableClouds) fcProcessStrategy2(ctx context.Context
reqId = arr[len(arr)-1]
}
}
req := httplib.NewBeegoRequestWithCtx(ctx, fmt.Sprintf("%s/order/setUserPayInfo", reqUrl), "POST").
SetTimeout(time.Second*5, time.Second*5).
Retries(1).SetProxy(func(req *http.Request) (*url.URL, error) {
client := resty.New().SetHeaders(map[string]string{
"user-agent": useragent.GetRandomDevice(useragent.PlatformPhone),
}).OnBeforeRequest(func(client *resty.Client, request *resty.Request) error {
proxy, err2 := utils.GetProxy(ctx, bankOrderId, SendCardTaskTypeEnumFavorableClouds.String()+"channel_4")
if err2 != nil || proxy == "" {
otelTrace.Logger.WithContext(ctx).Error("获取代理失败", zap.Error(err))
return nil, nil
return nil
}
return url.Parse(proxy)
client.SetProxy(proxy)
return nil
})
otelresty.TraceClient(client)
type PayUrlData struct {
payUrlData := struct {
Id string `json:"id"`
Ip string `json:"ip"`
UserPayInfo string `json:"userPayInfo"`
Device string `json:"device"`
}
otelTrace.Logger.WithContext(ctx).Info("请求参数", zap.Any("reqId", PayUrlData{
}{
Id: reqId,
Ip: utils.GenerateIpv4(),
UserPayInfo: fmt.Sprintf("%s,%s", cardNo, cardPwd),
Device: "null,",
}), zap.Any("payUrl", payUrl))
req, err = req.JSONBody(PayUrlData{
Id: reqId,
Ip: utils.GenerateIpv4(),
UserPayInfo: fmt.Sprintf("%s,%s", cardNo, cardPwd),
Device: "null,",
})
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("提交订单失败", zap.Error(err))
return false, ""
}
respCode, err := req.Response()
if err != nil || respCode.StatusCode != http.StatusOK {
otelTrace.Logger.WithContext(ctx).Error("提交订单失败", zap.Error(err), zap.Any("respCode", respCode.StatusCode))
return false, ""
}
defer func(Body io.ReadCloser) {
err2 := Body.Close()
if err2 != nil {
otelTrace.Logger.WithContext(ctx).Error("关闭response body失败", zap.Error(err2))
}
}(respCode.Body)
responseBytes, err := io.ReadAll(respCode.Body)
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("提交订单失败", zap.Error(err))
return false, ""
}
// 解析unicode编码
responseBytes, err = utils.UnescapeUnicode(responseBytes)
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("提交订单失败", zap.Error(err))
return false, ""
}
response := string(responseBytes)
otelTrace.Logger.WithContext(ctx).Info("请求参数", zap.Any("reqId", payUrlData), zap.Any("payUrl", payUrl))
response, err := client.R().SetContext(ctx).SetBody(payUrlData).Post(fmt.Sprintf("%s/order/setUserPayInfo", reqUrl))
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("请求结果失败", zap.Error(err))
return false, "请求结果失败"
}
if !response.IsSuccess() {
otelTrace.Logger.WithContext(ctx).Error("请求结果失败", zap.Error(err))
return false, "请求结果失败"
}
otelTrace.Logger.WithContext(ctx).Info("返回结果", zap.Any("response", response))
// 解析unicode编码
responseBytes, err := utils.UnescapeUnicode(response.Body())
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("提交订单失败", zap.Error(err))
return false, "请求结果失败"
}
var resData2 struct {
Code int `json:"code"`
Msg string `json:"msg"`
@@ -408,10 +392,10 @@ func (s *SendCardTaskTypeFavorableClouds) fcProcessStrategy2(ctx context.Context
} `json:"data"`
}
err = json.Unmarshal([]byte(response), &resData2)
err = json.Unmarshal(responseBytes, &resData2)
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("提交订单失败", zap.Error(err))
return false, "订单返回数据错误"
return false, "请求结果失败"
}
if resData2.Code != 0 {