diff --git a/app/user/cmd/api/desc/query.api b/app/user/cmd/api/desc/query.api index 63b29e7..ec8d195 100644 --- a/app/user/cmd/api/desc/query.api +++ b/app/user/cmd/api/desc/query.api @@ -58,3 +58,12 @@ service main { @handler queryRetry post /query/retry/:id (QueryRetryReq) returns (QueryRetryResp) } +@server ( + prefix: api/v1 + group: query +) +service main { + @handler querySingleTest + post /query/single/test (QuerySingleTestReq) returns (QuerySingleTestResp) +} + diff --git a/app/user/cmd/api/desc/query/query.api b/app/user/cmd/api/desc/query/query.api index 5cd3205..f7edfd7 100644 --- a/app/user/cmd/api/desc/query/query.api +++ b/app/user/cmd/api/desc/query/query.api @@ -103,3 +103,13 @@ type ( QueryRetryResp {} ) +type QuerySingleTestReq { + params map[string]interface{} `json:"params"` + Api string `json:"api"` +} + +type QuerySingleTestResp { + Data interface{} `json:"data"` + Api string `json:"api"` +} + diff --git a/app/user/cmd/api/internal/handler/query/querysingletesthandler.go b/app/user/cmd/api/internal/handler/query/querysingletesthandler.go new file mode 100644 index 0000000..2e51879 --- /dev/null +++ b/app/user/cmd/api/internal/handler/query/querysingletesthandler.go @@ -0,0 +1,29 @@ +package query + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "qnc-server/app/user/cmd/api/internal/logic/query" + "qnc-server/app/user/cmd/api/internal/svc" + "qnc-server/app/user/cmd/api/internal/types" + "qnc-server/common/result" + "qnc-server/pkg/lzkit/validator" +) + +func QuerySingleTestHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.QuerySingleTestReq + if err := httpx.Parse(r, &req); err != nil { + result.ParamErrorResult(r, w, err) + return + } + if err := validator.Validate(req); err != nil { + result.ParamValidateErrorResult(r, w, err) + return + } + l := query.NewQuerySingleTestLogic(r.Context(), svcCtx) + resp, err := l.QuerySingleTest(&req) + result.HttpResult(r, w, resp, err) + } +} diff --git a/app/user/cmd/api/internal/handler/routes.go b/app/user/cmd/api/internal/handler/routes.go index cc7d6b8..80f4648 100644 --- a/app/user/cmd/api/internal/handler/routes.go +++ b/app/user/cmd/api/internal/handler/routes.go @@ -196,6 +196,17 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { rest.WithPrefix("/api/v1"), ) + server.AddRoutes( + []rest.Route{ + { + Method: http.MethodPost, + Path: "/query/single/test", + Handler: query.QuerySingleTestHandler(serverCtx), + }, + }, + rest.WithPrefix("/api/v1"), + ) + server.AddRoutes( []rest.Route{ { diff --git a/app/user/cmd/api/internal/logic/query/querysingletestlogic.go b/app/user/cmd/api/internal/logic/query/querysingletestlogic.go new file mode 100644 index 0000000..00d72b7 --- /dev/null +++ b/app/user/cmd/api/internal/logic/query/querysingletestlogic.go @@ -0,0 +1,51 @@ +package query + +import ( + "context" + "encoding/json" + "github.com/pkg/errors" + "qnc-server/common/xerr" + + "qnc-server/app/user/cmd/api/internal/svc" + "qnc-server/app/user/cmd/api/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type QuerySingleTestLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewQuerySingleTestLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QuerySingleTestLogic { + return &QuerySingleTestLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *QuerySingleTestLogic) QuerySingleTest(req *types.QuerySingleTestReq) (resp *types.QuerySingleTestResp, err error) { + //featrueModel, err := l.svcCtx.FeatureModel.FindOneByApiId(l.ctx, req.Api) + //if err != nil { + // return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "单查测试, 获取接口失败 : %d", err) + //} + marshalParams, err := json.Marshal(req.Params) + if err != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "单查测试, 序列化参数失败 : %d", err) + } + apiResp, err := l.svcCtx.ApiRequestService.PreprocessRequestApi(marshalParams, req.Api) + if err != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "单查测试, 获取接口失败 : %d", err) + } + var respData interface{} + err = json.Unmarshal(apiResp, &respData) + if err != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "单查测试, 反序列化接口失败 : %d", err) + } + return &types.QuerySingleTestResp{ + Data: respData, + Api: req.Api, + }, nil +} diff --git a/app/user/cmd/api/internal/service/apirequestService.go b/app/user/cmd/api/internal/service/apirequestService.go index 4bfb6e4..96b5ff4 100644 --- a/app/user/cmd/api/internal/service/apirequestService.go +++ b/app/user/cmd/api/internal/service/apirequestService.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "github.com/Masterminds/squirrel" + "github.com/bytedance/sonic" "github.com/tidwall/gjson" "github.com/zeromicro/go-zero/core/logx" "io" @@ -14,6 +15,7 @@ import ( "qnc-server/app/user/cmd/api/internal/config" "qnc-server/app/user/model" "qnc-server/pkg/lzkit/crypto" + "qnc-server/pkg/lzkit/lzUtils" "strings" "sync" "sync/atomic" @@ -195,6 +197,10 @@ var requestProcessors = map[string]func(*ApiRequestService, []byte) ([]byte, err "CAR079": (*ApiRequestService).ProcessCAR079Request, "CAR066": (*ApiRequestService).ProcessCAR066Request, "CAR100": (*ApiRequestService).ProcessCAR100Request, + "G37SC01": (*ApiRequestService).ProcessG37SC01Request, + "G36SC01": (*ApiRequestService).ProcessG36SC01Request, + "G22SC01": (*ApiRequestService).ProcessG22SC01Request, + "Q03SC01": (*ApiRequestService).ProcessQ03SC01Request, } // PreprocessRequestApi 调用指定的请求处理函数 @@ -1056,3 +1062,145 @@ func (a *ApiRequestService) ProcessG20GZ01Request(params []byte) ([]byte, error) return resultBytes, nil } + +// G37SC01 自然人失信信息 +func (a *ApiRequestService) ProcessG37SC01Request(params []byte) ([]byte, error) { + name := gjson.GetBytes(params, "name") + idCard := gjson.GetBytes(params, "id_card") + + if !name.Exists() || !idCard.Exists() { + return nil, errors.New("api请求, G37SC01, 获取相关参数失败") + } + + request := map[string]interface{}{ + "data": map[string]interface{}{ + "name": a.westDexService.Encrypt(name.String()), + "idcard": a.westDexService.Encrypt(idCard.String()), + }, + } + resp, callApiErr := a.westDexService.CallAPI("G37SC01", request) + if callApiErr != nil { + return nil, callApiErr + } + // 第一步:提取外层的 data 字段 + dataResult := gjson.GetBytes(resp, "data") + if !dataResult.Exists() { + return nil, fmt.Errorf("外层 data 字段不存在") + } + + // 解析 data 字符串为 JSON 对象 + parsedData := gjson.Parse(dataResult.String()) + sxbzxr := parsedData.Get("sxbzxr") + if !sxbzxr.Exists() { + return nil, fmt.Errorf("内层 sxbzxr 字段不存在") + } + return []byte(sxbzxr.Raw), nil +} + +// G36SC01 自然人限高信息 +func (a *ApiRequestService) ProcessG36SC01Request(params []byte) ([]byte, error) { + name := gjson.GetBytes(params, "name") + idCard := gjson.GetBytes(params, "id_card") + + if !name.Exists() || !idCard.Exists() { + return nil, errors.New("api请求, G36SC01, 获取相关参数失败") + } + + request := map[string]interface{}{ + "data": map[string]interface{}{ + "name": a.westDexService.Encrypt(name.String()), + "idcard": a.westDexService.Encrypt(idCard.String()), + }, + } + resp, callApiErr := a.westDexService.CallAPI("G36SC01", request) + if callApiErr != nil { + return nil, callApiErr + } + // 第一步:提取外层的 data 字段 + dataResult := gjson.GetBytes(resp, "data") + if !dataResult.Exists() { + return nil, fmt.Errorf("外层 data 字段不存在") + } + + // 解析 data 字符串为 JSON 对象 + parsedData := gjson.Parse(dataResult.String()) + xgbzxr := parsedData.Get("xgbzxr") + if !xgbzxr.Exists() { + return nil, fmt.Errorf("内层 xgbzxr 字段不存在") + } + return []byte(xgbzxr.Raw), nil +} + +// G22SC01 自然人司法模型 +func (a *ApiRequestService) ProcessG22SC01Request(params []byte) ([]byte, error) { + name := gjson.GetBytes(params, "name") + idCard := gjson.GetBytes(params, "id_card") + + if !name.Exists() || !idCard.Exists() { + return nil, errors.New("api请求, G22SC01, 获取相关参数失败") + } + + request := map[string]interface{}{ + "data": map[string]interface{}{ + "name": a.westDexService.Encrypt(name.String()), + "idcard": a.westDexService.Encrypt(idCard.String()), + "inquired_auth": a.westDexService.GetDateRange(), + }, + } + resp, callApiErr := a.westDexService.CallAPI("G22SC01", request) + if callApiErr != nil { + return nil, callApiErr + } + // 第一步:提取外层的 data 字段 + dataResult := gjson.GetBytes(resp, "data") + if !dataResult.Exists() { + return nil, fmt.Errorf("外层 data 字段不存在") + } + + parseResult, err := lzUtils.RecursiveParse(dataResult.Raw) + if err != nil { + return nil, fmt.Errorf("递归反序列化") + } + marshal, err := sonic.Marshal(parseResult) + if err != nil { + return nil, fmt.Errorf("序列化失败: %v", err) + } + return marshal, nil +} + +// Q03SC01 企业涉诉信息 +func (a *ApiRequestService) ProcessQ03SC01Request(params []byte) ([]byte, error) { + entName := gjson.GetBytes(params, "ent_name") + entCode := gjson.GetBytes(params, "ent_code") + + if !entName.Exists() || !entCode.Exists() { + return nil, errors.New("api请求, Q03SC01, 获取相关参数失败") + } + + request := map[string]interface{}{ + "data": map[string]interface{}{ + "uscc": a.westDexService.Encrypt(entCode.String()), + "org_name": a.westDexService.Encrypt(entName.String()), + "inquired_auth": a.westDexService.GetDateRange(), + }, + } + resp, callApiErr := a.westDexService.CallAPI("Q03SC01", request) + if callApiErr != nil { + return nil, callApiErr + } + // 第一步:提取外层的 data 字段 + dataResult := gjson.GetBytes(resp, "data") + if !dataResult.Exists() { + return nil, fmt.Errorf("外层 data 字段不存在") + } + + parseResult, err := lzUtils.RecursiveParse(dataResult.Raw) + if err != nil { + return nil, fmt.Errorf("递归反序列化") + } + marshal, err := sonic.Marshal(parseResult) + if err != nil { + return nil, fmt.Errorf("序列化失败: %v", err) + } + return marshal, nil +} diff --git a/app/user/cmd/api/internal/types/types.go b/app/user/cmd/api/internal/types/types.go index 53d1d32..afa2700 100644 --- a/app/user/cmd/api/internal/types/types.go +++ b/app/user/cmd/api/internal/types/types.go @@ -204,6 +204,16 @@ type QueryServiceResp struct { Id string `json:"id"` } +type QuerySingleTestReq struct { + Params map[string]interface{} `json:"params"` + Api string `json:"api"` +} + +type QuerySingleTestResp struct { + Data interface{} `json:"data"` + Api string `json:"api"` +} + type RegisterReq struct { Mobile string `json:"mobile" validate:"required,mobile"` Password string `json:"password" validate:"required,min=11,max=11,password"` diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 703b933..2bf12ac 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -63,6 +63,21 @@ services: depends_on: - redis + phpmyadmin: + image: phpmyadmin/phpmyadmin + container_name: qnc_phpmyadmin + restart: unless-stopped + environment: + PMA_HOST: qnc_mysql + PMA_PORT: 3306 + PMA_USER: qnc + PMA_PASSWORD: 5vg67b3UNHu8 + ports: + - "20004:80" + depends_on: + - mysql + networks: + - qnc_net networks: qnc_net: diff --git a/go.mod b/go.mod index 536573b..0ca625c 100644 --- a/go.mod +++ b/go.mod @@ -30,9 +30,12 @@ require ( github.com/alibabacloud-go/tea-xml v1.1.3 // indirect github.com/aliyun/credentials-go v1.3.10 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/bytedance/sonic v1.13.1 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/clbanning/mxj/v2 v2.5.5 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/fatih/color v1.17.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect @@ -46,6 +49,7 @@ require ( github.com/hibiken/asynq v0.25.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/leodido/go-urn v1.4.0 // indirect @@ -74,6 +78,7 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect @@ -86,6 +91,7 @@ require ( go.opentelemetry.io/otel/trace v1.24.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/automaxprocs v1.6.0 // indirect + golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect golang.org/x/crypto v0.28.0 // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/sync v0.10.0 // indirect diff --git a/go.sum b/go.sum index 75bd389..a2952c3 100644 --- a/go.sum +++ b/go.sum @@ -72,6 +72,11 @@ github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/bytedance/sonic v1.13.1 h1:Jyd5CIvdFnkOWuKXr+wm4Nyk2h0yAFsr8ucJgEasO3g= +github.com/bytedance/sonic v1.13.1/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -80,6 +85,9 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E= github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -146,6 +154,9 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -234,6 +245,7 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -252,6 +264,8 @@ github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhso github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/wechatpay-apiv3/wechatpay-go v0.2.20 h1:gS8oFn1bHGnyapR2Zb4aqTV6l4kJWgbtqjCq6k1L9DQ= github.com/wechatpay-apiv3/wechatpay-go v0.2.20/go.mod h1:A254AUBVB6R+EqQFo3yTgeh7HtyqRRtN2w9hQSOrd4Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -287,6 +301,8 @@ go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -437,3 +453,4 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/pkg/lzkit/lzUtils/json.go b/pkg/lzkit/lzUtils/json.go new file mode 100644 index 0000000..e44c371 --- /dev/null +++ b/pkg/lzkit/lzUtils/json.go @@ -0,0 +1,35 @@ +package lzUtils + +import "github.com/bytedance/sonic" + +func RecursiveParse(data interface{}) (interface{}, error) { + switch v := data.(type) { + case string: + // 尝试解析字符串是否为嵌套 JSON + var parsed interface{} + if err := sonic.Unmarshal([]byte(v), &parsed); err == nil { + return RecursiveParse(parsed) + } + return v, nil // 普通字符串直接返回 + case map[string]interface{}: + for key, val := range v { + parsed, err := RecursiveParse(val) + if err != nil { + return nil, err + } + v[key] = parsed + } + return v, nil + case []interface{}: + for i, item := range v { + parsed, err := RecursiveParse(item) + if err != nil { + return nil, err + } + v[i] = parsed + } + return v, nil + default: + return v, nil + } +} diff --git a/test/test.go b/test/test.go deleted file mode 100644 index 8aded0f..0000000 --- a/test/test.go +++ /dev/null @@ -1,148 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "github.com/tidwall/gjson" - "sync" - "time" -) - -func processG35SC01Response(resp []byte) ([]byte, error) { - // 第一步:提取外层的 data 字段 - dataResult := gjson.GetBytes(resp, "data") - if !dataResult.Exists() { - return nil, fmt.Errorf("外层 data 字段不存在") - } - - // 第二步:解析外层 data 的 JSON 字符串 - var outerDataMap map[string]interface{} - if err := json.Unmarshal([]byte(dataResult.String()), &outerDataMap); err != nil { - return nil, fmt.Errorf("解析外层 data 字段失败: %v", err) - } - - // 第三步:提取内层的 data 字段 - innerData, ok := outerDataMap["data"].(string) - if !ok { - return nil, fmt.Errorf("内层 data 字段不存在或类型错误") - } - - // 第四步:解析内层 data 的 JSON 字符串 - var finalDataMap map[string]interface{} - if err := json.Unmarshal([]byte(innerData), &finalDataMap); err != nil { - return nil, fmt.Errorf("解析内层 data 字段失败: %v", err) - } - - // 将最终的 JSON 对象编码为字节数组返回 - finalDataBytes, err := json.Marshal(finalDataMap) - if err != nil { - return nil, fmt.Errorf("编码最终的 JSON 对象失败: %v", err) - } - - return finalDataBytes, nil -} -func main() { - a := map[string]interface{}{ - "data": "{\"msg\":\"接口调用成功\",\"data\":\"{\\\"preservation\\\":{},\\\"crc\\\":41615638,\\\"cases_tree\\\":{},\\\"administrative\\\":{},\\\"civil\\\":{},\\\"count\\\":{\\\"money_jie_total\\\":0,\\\"count_total\\\":5,\\\"larq_stat\\\":\\\"2013(1),2016(4)\\\",\\\"area_stat\\\":\\\"广西壮族自治区(5)\\\",\\\"money_jie_beigao\\\":0,\\\"count_jie_total\\\":5,\\\"money_jie_other\\\":0,\\\"count_wei_total\\\":0,\\\"count_jie_beigao\\\":4,\\\"money_yuangao\\\":0,\\\"money_beigao\\\":0,\\\"ay_stat\\\":\\\"未知(5)\\\",\\\"count_wei_other\\\":0,\\\"count_wei_beigao\\\":0,\\\"count_wei_yuangao\\\":0,\\\"money_other\\\":0,\\\"count_yuangao\\\":1,\\\"money_wei_yuangao\\\":0,\\\"money_jie_yuangao\\\":0,\\\"money_wei_beigao\\\":0,\\\"count_jie_yuangao\\\":1,\\\"count_other\\\":0,\\\"count_jie_other\\\":0,\\\"count_beigao\\\":4,\\\"money_wei_total\\\":0,\\\"money_wei_other\\\":0,\\\"money_total\\\":0,\\\"jafs_stat\\\":\\\"执行完毕(5)\\\"},\\\"implement\\\":{\\\"cases\\\":[{\\\"d_jarq\\\":\\\"2013-04-18\\\",\\\"n_jaay\\\":\\\"未知\\\",\\\"n_ssdw\\\":\\\"申请执行人\\\",\\\"c_ah\\\":\\\"(2013)城中执字第66号\\\",\\\"c_ssdy\\\":\\\"广西壮族自治区\\\",\\\"n_jafs\\\":\\\"执行完毕\\\",\\\"n_ajbs\\\":\\\"a77a247bf43b60846393460d5d0c5a16\\\",\\\"n_jbfy_cj\\\":\\\"基层法院\\\",\\\"c_id\\\":\\\"686a6371ca4af42d2a3a8207e7bb57be\\\",\\\"n_crc\\\":514109936,\\\"n_ajlx\\\":\\\"首次执行\\\",\\\"n_ajjzjd\\\":\\\"已结案\\\",\\\"c_dsrxx\\\":[{\\\"n_ssdw\\\":\\\"申请执行人\\\",\\\"c_mc\\\":\\\"伍艳红\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"申请执行人\\\",\\\"c_mc\\\":\\\"庞汉章\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"申请执行人\\\",\\\"c_mc\\\":\\\"曹智\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"申请执行人\\\",\\\"c_mc\\\":\\\"李健\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"申请执行人\\\",\\\"c_mc\\\":\\\"李强\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"申请执行人\\\",\\\"c_mc\\\":\\\"梁辉\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"申请执行人\\\",\\\"c_mc\\\":\\\"中国农业银行股份有限公司柳州城中支行\\\",\\\"n_dsrlx\\\":\\\"企业组织\\\"}],\\\"n_laay\\\":\\\"未知\\\",\\\"n_jbfy\\\":\\\"柳州市城中区人民法院\\\",\\\"d_larq\\\":\\\"2013-02-27\\\"},{\\\"d_jarq\\\":\\\"2016-12-20\\\",\\\"n_jaay\\\":\\\"民事\\\",\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_gkws_glah\\\":\\\"(2016)桂0107民初1800号\\\",\\\"c_ah\\\":\\\"(2016)桂0107执1708号\\\",\\\"c_gkws_pjjg\\\":\\\"查封被执行人广西鼎铭房地产开发有限公司名下所有的位于南宁市西乡塘区秀灵路7号鼎盛国际B座单元1028号商铺,期限为三年。\\\",\\\"c_ssdy\\\":\\\"广西壮族自治区\\\",\\\"c_gkws_dsr\\\":\\\"申请执行人张海婷,女,1977年6月7日出生,汉族,住所地位于江苏省泰兴市。被执行人广西鼎铭房地产开发有限公司,住所地位于南宁市西乡塘区科园大道31号高新苑29栋06号。法定代表人李强,董事长。\\\",\\\"n_jafs\\\":\\\"执行完毕\\\",\\\"n_ajbs\\\":\\\"5ac3742e7b01d827596138397a183bc8\\\",\\\"n_jbfy_cj\\\":\\\"基层法院\\\",\\\"c_id\\\":\\\"565dc891866688bf1cad480d1abf4c00\\\",\\\"n_sqzxbdje\\\":1947919,\\\"n_crc\\\":606433511,\\\"n_ajlx\\\":\\\"首次执行\\\",\\\"n_ajjzjd\\\":\\\"已结案\\\",\\\"c_dsrxx\\\":[{\\\"n_ssdw\\\":\\\"其他\\\",\\\"c_mc\\\":\\\"张海婷\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"申请执行人\\\",\\\"c_mc\\\":\\\"张海婷\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_mc\\\":\\\"李强\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_mc\\\":\\\"广西鼎铭房地产开发有限公司\\\",\\\"n_dsrlx\\\":\\\"企业组织\\\"},{\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_mc\\\":\\\"广西鼎铭房地产开发有限公司\\\",\\\"n_dsrlx\\\":\\\"企业组织\\\"}],\\\"n_laay\\\":\\\"民事\\\",\\\"n_jbfy\\\":\\\"南宁市西乡塘区人民法院\\\",\\\"d_larq\\\":\\\"2016-10-25\\\",\\\"c_gkws_id\\\":\\\"e1c1ca9a-e48a-4fb2-ba51-228965d31e39\\\"},{\\\"d_jarq\\\":\\\"2016-12-20\\\",\\\"n_jaay\\\":\\\"民事\\\",\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_ah\\\":\\\"(2016)桂0107执1710号\\\",\\\"c_gkws_pjjg\\\":\\\"终结本次执行程序。终结本次执行程序后,如申请执行人发现被执行人有财产可供执行或原不具备执行条件的财产现已具备执行条件的,可就尚未实现的债权向本院申请恢复执行。申请执行人提出恢复执行申请不受申请执行期间的限制。对尚在查封、冻结期间的被执行人财产,查封、冻结期间届满后,申请执行人需要续行查封、冻结的,应当在查封、冻结期间届满前十五日内,向本院提出续行查封、冻结的书面申请,逾期不提出申请的,由申请执行人承担相应财产损失的风险或申请法律责任。本裁定送达后即发生法律效力。\\\",\\\"c_ssdy\\\":\\\"广西壮族自治区\\\",\\\"c_gkws_dsr\\\":\\\"申请执行人张海婷,女,1977年6月7日出生,住所地江苏省泰兴市。被执行人广西鼎铭房地产开发有限公司,住所地南宁市西乡塘区科园大道31号高新苑29栋06号。法定代表人李强。\\\",\\\"n_jafs\\\":\\\"执行完毕\\\",\\\"n_ajbs\\\":\\\"021d2380c9950416f7bd983f05219cc6\\\",\\\"n_jbfy_cj\\\":\\\"基层法院\\\",\\\"c_id\\\":\\\"eaccfca0a102cb365322b76ea6303e03\\\",\\\"n_sqzxbdje\\\":1130985.9,\\\"n_crc\\\":2061482197,\\\"n_ajlx\\\":\\\"首次执行\\\",\\\"n_ajjzjd\\\":\\\"已结案\\\",\\\"c_dsrxx\\\":[{\\\"n_ssdw\\\":\\\"其他\\\",\\\"c_mc\\\":\\\"张海婷\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"申请执行人\\\",\\\"c_mc\\\":\\\"张海婷\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_mc\\\":\\\"李强\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_mc\\\":\\\"广西鼎铭房地产开发有限公司\\\",\\\"n_dsrlx\\\":\\\"企业组织\\\"},{\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_mc\\\":\\\"广西鼎铭房地产开发有限公司\\\",\\\"n_dsrlx\\\":\\\"企业组织\\\"}],\\\"n_laay\\\":\\\"民事\\\",\\\"n_jbfy\\\":\\\"南宁市西乡塘区人民法院\\\",\\\"d_larq\\\":\\\"2016-10-25\\\",\\\"c_gkws_id\\\":\\\"86cb5b7f-6b46-4bce-9ee1-a93a0039aa4f\\\"},{\\\"d_jarq\\\":\\\"2016-12-21\\\",\\\"n_jaay\\\":\\\"民事\\\",\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_ah\\\":\\\"(2016)桂0107执1869号\\\",\\\"c_gkws_pjjg\\\":\\\"终结本次执行程序。终结本次执行程序后,如申请执行人发现被执行人有财产可供执行或原不具备执行条件的财产现已具备执行条件的,可就尚未实现的债权向本院申请恢复执行。申请执行人提出恢复执行申请不受申请执行期间的限制。对尚在查封、冻结期间的被执行人财产,查封、冻结期间届满后,申请执行人需要续行查封、冻结的,应当在查封、冻结期间届满前十五日内,向本院提出续行查封、冻结的书面申请,逾期不提出申请的,由申请执行人承担相应财产损失的风险或申请法律责任。本裁定送达后即发生法律效力。\\\",\\\"c_ssdy\\\":\\\"广西壮族自治区\\\",\\\"c_gkws_dsr\\\":\\\"申请执行人中国农业银行股份有限公司南宁友爱支行,地址南宁市友爱南路41号商住楼一层。法定代表人刘杰。被执行人梁玉芬,女,1973年02月10日出生,地址南宁市。被执行人吴华,男,1971年04月02日出生,地址南宁市。被执行人广西鼎铭房地产开发有限公司,地址南宁市西乡塘区科园大道31号高新苑29栋06号。法定代表人李强。\\\",\\\"n_jafs\\\":\\\"执行完毕\\\",\\\"n_ajbs\\\":\\\"6634a3e3f074e5456947271023459150\\\",\\\"n_jbfy_cj\\\":\\\"基层法院\\\",\\\"c_id\\\":\\\"e691fe40a1ac30b8484bd4fa19c0af85\\\",\\\"n_sqzxbdje\\\":175923.69,\\\"n_crc\\\":2194376894,\\\"n_ajlx\\\":\\\"首次执行\\\",\\\"n_ajjzjd\\\":\\\"已结案\\\",\\\"c_dsrxx\\\":[{\\\"n_ssdw\\\":\\\"其他\\\",\\\"c_mc\\\":\\\"中国农业银行股份有限公司南宁友爱支行\\\",\\\"n_dsrlx\\\":\\\"企业组织\\\"},{\\\"n_ssdw\\\":\\\"申请执行人\\\",\\\"c_mc\\\":\\\"中国农业银行股份有限公司南宁友爱支行\\\",\\\"n_dsrlx\\\":\\\"企业组织\\\"},{\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_mc\\\":\\\"吴华\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_mc\\\":\\\"李强\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_mc\\\":\\\"梁玉芬\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_mc\\\":\\\"广西鼎铭房地产开发有限公司\\\",\\\"n_dsrlx\\\":\\\"企业组织\\\"},{\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_mc\\\":\\\"广西鼎铭房地产开发有限公司\\\",\\\"n_dsrlx\\\":\\\"企业组织\\\"}],\\\"n_laay\\\":\\\"民事\\\",\\\"n_jbfy\\\":\\\"南宁市西乡塘区人民法院\\\",\\\"d_larq\\\":\\\"2016-11-14\\\",\\\"c_gkws_id\\\":\\\"2fe3d400-471b-456b-a8a5-a939003ff785\\\"},{\\\"d_jarq\\\":\\\"2016-12-21\\\",\\\"n_jaay\\\":\\\"民事\\\",\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_ah\\\":\\\"(2016)桂0107执1871号\\\",\\\"c_gkws_pjjg\\\":\\\"终结本次执行程序。终结本次执行程序后,如申请执行人发现被执行人有财产可供执行或原不具备执行条件的财产现已具备执行条件的,可就尚未实现的债权向本院申请恢复执行。申请执行人提出恢复执行申请不受申请执行期间的限制。对尚在查封、冻结期间的被执行人财产,查封、冻结期间届满后,申请执行人需要续行查封、冻结的,应当在查封、冻结期间届满前十五日内,向本院提出续行查封、冻结的书面申请,逾期不提出申请的,由申请执行人承担相应财产损失的风险或申请法律责任。本裁定送达后即发生法律效力。\\\",\\\"c_ssdy\\\":\\\"广西壮族自治区\\\",\\\"c_gkws_dsr\\\":\\\"申请执行人中国农业银行股份有限公司南宁友爱支行,地址南宁市友爱南路41号商住楼一层。法定代表人刘杰。被执行人唐觉荣,男,1982年11月21日出生,地址南宁市。被执行人广西鼎铭房地产开发有限公司,地址南宁市西乡塘区科园大道31号高新苑29栋06号。法定代表人李强。\\\",\\\"n_jafs\\\":\\\"执行完毕\\\",\\\"n_ajbs\\\":\\\"07c9ef9256bb9cb96031d83ce207122c\\\",\\\"n_jbfy_cj\\\":\\\"基层法院\\\",\\\"c_id\\\":\\\"3061de19534438ebecf50ed03e6b536f\\\",\\\"n_sqzxbdje\\\":138564.6,\\\"n_crc\\\":594016140,\\\"n_ajlx\\\":\\\"首次执行\\\",\\\"n_ajjzjd\\\":\\\"已结案\\\",\\\"c_dsrxx\\\":[{\\\"n_ssdw\\\":\\\"其他\\\",\\\"c_mc\\\":\\\"中国农业银行股份有限公司南宁友爱支行\\\",\\\"n_dsrlx\\\":\\\"企业组织\\\"},{\\\"n_ssdw\\\":\\\"申请执行人\\\",\\\"c_mc\\\":\\\"中国农业银行股份有限公司南宁友爱支行\\\",\\\"n_dsrlx\\\":\\\"企业组织\\\"},{\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_mc\\\":\\\"唐觉荣\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_mc\\\":\\\"李强\\\",\\\"n_dsrlx\\\":\\\"自然人\\\"},{\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_mc\\\":\\\"广西鼎铭房地产开发有限公司\\\",\\\"n_dsrlx\\\":\\\"企业组织\\\"},{\\\"n_ssdw\\\":\\\"被执行人\\\",\\\"c_mc\\\":\\\"广西鼎铭房地产开发有限公司\\\",\\\"n_dsrlx\\\":\\\"企业组织\\\"}],\\\"n_laay\\\":\\\"民事\\\",\\\"n_jbfy\\\":\\\"南宁市西乡塘区人民法院\\\",\\\"d_larq\\\":\\\"2016-11-14\\\",\\\"c_gkws_id\\\":\\\"3e497ad6-41e7-4a3d-9745-a93900418792\\\"}],\\\"count\\\":{\\\"money_jie_total\\\":0,\\\"count_total\\\":5,\\\"larq_stat\\\":\\\"2013(1),2016(4)\\\",\\\"area_stat\\\":\\\"广西壮族自治区(5)\\\",\\\"money_jie_beigao\\\":0,\\\"count_jie_total\\\":5,\\\"money_jie_other\\\":0,\\\"count_wei_total\\\":0,\\\"count_jie_beigao\\\":4,\\\"money_yuangao\\\":0,\\\"money_beigao\\\":0,\\\"ay_stat\\\":\\\"未知(5)\\\",\\\"count_wei_other\\\":0,\\\"count_wei_beigao\\\":0,\\\"count_wei_yuangao\\\":0,\\\"money_other\\\":0,\\\"count_yuangao\\\":1,\\\"money_wei_yuangao\\\":0,\\\"money_jie_yuangao\\\":0,\\\"money_wei_beigao\\\":0,\\\"count_jie_yuangao\\\":1,\\\"count_other\\\":0,\\\"count_jie_other\\\":0,\\\"count_beigao\\\":4,\\\"money_wei_total\\\":0,\\\"money_wei_other\\\":0,\\\"money_total\\\":0,\\\"jafs_stat\\\":\\\"执行完毕(5)\\\"}},\\\"criminal\\\":{},\\\"bankrupt\\\":{}}\"}", - "message": "调用成功", - "resultCode": "200", - "success": true, - } - marshal, err := json.Marshal(a) - if err != nil { - fmt.Println(err) - return - } - resp, err := processG35SC01Response(marshal) - if err != nil { - fmt.Println(err) - return - } - fmt.Println(string(resp)) - -} -func (w *WestDexService) ProcessRequests(data interface{}, requests []types.WestDexServiceRequestParams) ([]byte, error) { - var wg sync.WaitGroup - responseData := make([]APIResponseData, len(requests)) // 使用 APIResponseData 结构存储响应数据 - var errorsCh []error - mutex := sync.Mutex{} - encryptedFields, err := w.EncryptStructFields(data) - if err != nil { - return nil, fmt.Errorf("西部请求, 生成请求数据失败: %+v", err) - } - - ctx, cancel := context.WithCancel(context.Background()) // 创建 context - defer cancel() // 确保函数结束时取消 context - - errorLimit := 3 - errorCount := 0 // 记录错误次数 - - // 并发处理每个请求 - for i, req := range requests { - wg.Add(1) - go func(i int, req types.WestDexServiceRequestParams) { - defer wg.Done() - - select { - case <-ctx.Done(): // 检查 context 是否已取消 - return - default: - } - - // 将加密后的数据映射成 API 请求格式 - apiRequest := w.MapStructToAPIRequest(encryptedFields, req.FieldMapping, "data") - resp, callApiErr := w.CallAPI(req.ApiID, apiRequest) - timestamp := time.Now().Format(time.RFC3339) - var processedResp []byte - if resp != nil { - processedResp = processResponse(resp, req.ApiID) - } - if callApiErr != nil { - mutex.Lock() - defer mutex.Unlock() - - errorsCh = append(errorsCh, fmt.Errorf("西部请求, 请求失败: %+v", callApiErr)) - errorCount++ - - // 如果错误次数超过限制,取消 context - if errorCount >= errorLimit { - cancel() - } - - // 存储失败的响应 - responseData[i] = APIResponseData{ - ApiID: req.ApiID, - Error: callApiErr.Error(), - Data: processedResp, - Success: false, - Timestamp: timestamp, - } - return - } - - // 存储成功的响应数据,使用 RawMessage 来存储原始数据 - mutex.Lock() - responseData[i] = APIResponseData{ - ApiID: req.ApiID, - Data: processedResp, // 保持原始数据 - Success: true, - Timestamp: timestamp, - } - mutex.Unlock() - }(i, req) - } - - wg.Wait() // 等待所有 goroutine 完成 - - if errorCount >= errorLimit { - return nil, fmt.Errorf("请求失败次数超过 %d 次: %+v", errorLimit, errorsCh) - } - - // 将 responseData 转换为 JSON - combinedResponse, err := json.Marshal(responseData) - if err != nil { - return nil, fmt.Errorf("响应数据转 JSON 失败: %+v", err) - } - - return combinedResponse, nil -}