From 1d4411a94055b9de6c4b755f8dd2d235ffe8a08f Mon Sep 17 00:00:00 2001 From: liangzai <2440983361@qq.com> Date: Wed, 31 Dec 2025 17:46:03 +0800 Subject: [PATCH] add --- internal/domains/api/dto/api_request_dto.go | 7 ++- .../api/services/api_request_service.go | 1 + .../api/services/form_config_service.go | 1 + .../processors/ivyz/ivyz9h2m_processor.go | 8 ++-- .../processors/qcxg/qcxg5f3a_processor.go | 47 +++++++++++++++++++ .../infrastructure/external/jiguang/crypto.go | 3 +- .../external/jiguang/jiguang_service.go | 13 +++-- 7 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 internal/domains/api/services/processors/qcxg/qcxg5f3a_processor.go diff --git a/internal/domains/api/dto/api_request_dto.go b/internal/domains/api/dto/api_request_dto.go index 06f3634..9ce65a9 100644 --- a/internal/domains/api/dto/api_request_dto.go +++ b/internal/domains/api/dto/api_request_dto.go @@ -272,6 +272,9 @@ type QCXG4896Req struct { PlateNo string `json:"plate_no" validate:"required"` AuthDate string `json:"auth_date" validate:"required,validAuthDate" encrypt:"false"` } +type QCXG5F3AReq struct { + IDCard string `json:"id_card" validate:"required,validIDCard"` +} type COMENT01Req struct { EntName string `json:"ent_name" validate:"required,min=1,validEnterpriseName"` EntCode string `json:"ent_code" validate:"required,validUSCI"` @@ -724,8 +727,8 @@ type IVYZ6M8PReq struct { } type IVYZ9H2MReq struct { - IDNo string `json:"id_no" validate:"required,validIDCard"` - Name string `json:"name" validate:"required,min=1,validName"` + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` } type YYSY9E4AReq struct { diff --git a/internal/domains/api/services/api_request_service.go b/internal/domains/api/services/api_request_service.go index 9b6b44c..8587da5 100644 --- a/internal/domains/api/services/api_request_service.go +++ b/internal/domains/api/services/api_request_service.go @@ -224,6 +224,7 @@ func registerAllProcessors(combService *comb.CombService) { "QCXG8A3D": qcxg.ProcessQCXG8A3DRequest, "QCXG6B4E": qcxg.ProcessQCXG6B4ERequest, "QCXG4896": qcxg.ProcessQCXG4896Request, + "QCXG5F3A": qcxg.ProcessQCXG5F3ARequest, // 极光个人车辆查询 // DWBG系列处理器 - 多维报告 "DWBG6A2C": dwbg.ProcessDWBG6A2CRequest, diff --git a/internal/domains/api/services/form_config_service.go b/internal/domains/api/services/form_config_service.go index 2100677..d9c3546 100644 --- a/internal/domains/api/services/form_config_service.go +++ b/internal/domains/api/services/form_config_service.go @@ -204,6 +204,7 @@ func (s *FormConfigServiceImpl) getDTOStruct(ctx context.Context, apiCode string "IVYZZQT3": &dto.IVYZZQT3Req{}, //人脸比对V3 "IVYZBPQ2": &dto.IVYZBPQ2Req{}, //人脸比对V2 "IVYZSFEL": &dto.IVYZSFELReq{}, //全国自然人人像三要素核验_V1 + "QCXG5F3A": &dto.QCXG5F3AReq{}, //极光个人车辆查询 } // 优先返回已配置的DTO diff --git a/internal/domains/api/services/processors/ivyz/ivyz9h2m_processor.go b/internal/domains/api/services/processors/ivyz/ivyz9h2m_processor.go index dfc7638..c9e9286 100644 --- a/internal/domains/api/services/processors/ivyz/ivyz9h2m_processor.go +++ b/internal/domains/api/services/processors/ivyz/ivyz9h2m_processor.go @@ -23,12 +23,14 @@ func ProcessIVYZ9H2MRequest(ctx context.Context, params []byte, deps *processors // 构建请求参数 reqData := map[string]interface{}{ - "idNo": paramsDto.IDNo, + "idNo": paramsDto.IDCard, "name": paramsDto.Name, } - // 调用极光API,apiCode为 marriage-single-v2 - respBytes, err := deps.JiguangService.CallAPI(ctx, "marriage-single-v2", reqData) + // 调用极光API + // apiCode: marriage-single-v2 (用于请求头) + // apiPath: marriage/single-v2 (用于URL路径) + respBytes, err := deps.JiguangService.CallAPI(ctx, "marriage-single-v2", "marriage/single-v2", reqData) if err != nil { // 根据错误类型返回相应的错误 if errors.Is(err, jiguang.ErrNotFound) { diff --git a/internal/domains/api/services/processors/qcxg/qcxg5f3a_processor.go b/internal/domains/api/services/processors/qcxg/qcxg5f3a_processor.go new file mode 100644 index 0000000..a5ab3ba --- /dev/null +++ b/internal/domains/api/services/processors/qcxg/qcxg5f3a_processor.go @@ -0,0 +1,47 @@ +package qcxg + +import ( + "context" + "encoding/json" + "errors" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/jiguang" +) + +// ProcessQCXG5F3ARequest QCXG5F3A API处理方法 - 极光个人车辆查询 +func ProcessQCXG5F3ARequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.QCXG5F3AReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, errors.Join(processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, errors.Join(processors.ErrInvalidParam, err) + } + + // 构建请求参数 + reqData := map[string]interface{}{ + "id_card": paramsDto.IDCard, + } + + // 调用极光API + // apiCode: vehicle-person-vehicles (用于请求头) + // apiPath: vehicle/person-vehicles (用于URL路径) + respBytes, err := deps.JiguangService.CallAPI(ctx, "vehicle-person-vehicles", "vehicle/person-vehicles", reqData) + if err != nil { + // 根据错误类型返回相应的错误 + if errors.Is(err, jiguang.ErrNotFound) { + return nil, errors.Join(processors.ErrNotFound, err) + } else if errors.Is(err, jiguang.ErrDatasource) { + return nil, errors.Join(processors.ErrDatasource, err) + } else { + return nil, errors.Join(processors.ErrSystem, err) + } + } + + // 极光服务已经返回了 data 字段的 JSON,直接返回即可 + return respBytes, nil +} + diff --git a/internal/infrastructure/external/jiguang/crypto.go b/internal/infrastructure/external/jiguang/crypto.go index 3d897a7..fe82437 100644 --- a/internal/infrastructure/external/jiguang/crypto.go +++ b/internal/infrastructure/external/jiguang/crypto.go @@ -5,6 +5,7 @@ import ( "crypto/md5" "encoding/hex" "fmt" + "strings" ) // SignMethod 签名方法类型 @@ -38,7 +39,7 @@ func GenerateSign(timestamp string, appSecret string, signMethod SignMethod) (st } // 将二进制转化为大写的十六进制(正确签名应该为32大写字符串) - return hex.EncodeToString(hashBytes), nil + return strings.ToUpper(hex.EncodeToString(hashBytes)), nil } // GenerateSignWithDefault 使用默认的 HMAC-MD5 方法生成签名 diff --git a/internal/infrastructure/external/jiguang/jiguang_service.go b/internal/infrastructure/external/jiguang/jiguang_service.go index 1547ffe..7d3549f 100644 --- a/internal/infrastructure/external/jiguang/jiguang_service.go +++ b/internal/infrastructure/external/jiguang/jiguang_service.go @@ -10,6 +10,7 @@ import ( "io" "net/http" "strconv" + "strings" "time" "tyapi-server/internal/shared/external_logger" @@ -76,9 +77,10 @@ func (j *JiguangService) generateRequestID() string { } // CallAPI 调用极光API -// apiCode: API服务编码(如 marriage-single-v2) +// apiCode: API服务编码(如 marriage-single-v2),用于请求头 +// apiPath: API路径(如 marriage/single-v2),用于URL路径 // params: 请求参数(会作为JSON body发送) -func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, params map[string]interface{}) (resp []byte, err error) { +func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, apiPath string, params map[string]interface{}) (resp []byte, err error) { startTime := time.Now() requestID := j.generateRequestID() @@ -101,9 +103,12 @@ func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, params map return nil, err } + // 构建完整的请求URL,使用apiPath作为路径 + requestURL := strings.TrimSuffix(j.config.URL, "/") + "/" + strings.TrimPrefix(apiPath, "/") + // 记录请求日志 if j.logger != nil { - j.logger.LogRequest(requestID, transactionID, apiCode, j.config.URL, params) + j.logger.LogRequest(requestID, transactionID, apiCode, requestURL, params) } // 将请求参数转换为JSON @@ -117,7 +122,7 @@ func (j *JiguangService) CallAPI(ctx context.Context, apiCode string, params map } // 创建HTTP POST请求 - req, newRequestErr := http.NewRequestWithContext(ctx, "POST", j.config.URL, bytes.NewBuffer(jsonData)) + req, newRequestErr := http.NewRequestWithContext(ctx, "POST", requestURL, bytes.NewBuffer(jsonData)) if newRequestErr != nil { err = errors.Join(ErrSystem, newRequestErr) if j.logger != nil {