diff --git a/internal/infrastructure/external/nuoer/nuoer_service.go b/internal/infrastructure/external/nuoer/nuoer_service.go index 348e8ea..ffcd1d6 100644 --- a/internal/infrastructure/external/nuoer/nuoer_service.go +++ b/internal/infrastructure/external/nuoer/nuoer_service.go @@ -3,7 +3,6 @@ package nuoer import ( "bytes" "context" - "crypto/md5" "encoding/json" "errors" "fmt" @@ -19,17 +18,19 @@ const defaultRequestTimeout = 4 * time.Second // queryBillingAPIKeys 查询计费接口:数据未查得(busiCode=1000)仍按成功计费,返回空数据 var queryBillingAPIKeys = map[string]struct{}{ - "idRiskTagV106": {}, // 身份风险V106 - "personalLawsuit_cv2": {}, // 企业诉讼定制版 - "personalLawsuit_cv1": {}, // 个人诉讼定制版 - "loanRiskTagV11": {}, // 借贷意向查询 - "loanRiskTagV5": {}, // 风险变量V5 - "loanRiskTagV12": {}, // 特殊名单 - "blackListV121_3_1": {}, // 债务逾期黑名单V3_1 - "blackListV110": {}, // 特殊名单V110 - "zhiTongModelG": {}, // 智瞳-通用版 - "zhitong_ultra_v4_score": {}, // 智瞳分尊享版 - "zhixiangScore": {}, // 智享分 + "idRiskTagV106": {}, // 身份风险V106 idRiskTagV106 + "personalLawsuit_cv2": {}, // 企业诉讼定制版 personallawsuit cv2 + "personalLawsuit_cv1": {}, // 个人诉讼定制版personalLawsuit_cv1 + "loanRiskTagV11": {}, // 借贷意向查询loanRiskTagV11 + "loanRiskTagV5": {}, // 风险变量V5loanRiskTagV5 + "loanRiskTagV12": {}, // 特殊名单 loanRiskTagV12 + "blackListV121_3_1": {}, // 债务逾期黑名单V3_1 blackListV121 3 1 + "blackListV110": {}, // 特殊名单V110 blackListV110 + "zhitong_ultra_v4_score": {}, // 智瞳分尊享版 zhitong ultra v4 score + "zhixiangScore": {}, // 智享分 zhixiangScore + "loanRiskTagV8": {}, // 风险变量V8 loanRiskTagV8 + "loanRiskTagV9": {}, // 风险变量V9 loanRiskTagV9 + "loanRiskTagV10": {}, // 风险变量V10 loanRiskTagV10 } func isQueryBillingAPIKey(apiKey string) bool { @@ -75,10 +76,18 @@ func NewNuoerService(url, appID, appSecret string, timeout time.Duration, logger } } -func (s *NuoerService) generateRequestID() string { - timestamp := time.Now().UnixNano() - hash := md5.Sum([]byte(fmt.Sprintf("%d_%s", timestamp, s.config.AppID))) - return fmt.Sprintf("nuoer_%x", hash[:8]) +func (s *NuoerService) logResponse(transactionID, apiKey string, statusCode int, duration time.Duration, seqNo string) { + if s.logger == nil { + return + } + s.logger.LogResponse(seqNo, transactionID, apiKey, statusCode, duration) +} + +func (s *NuoerService) logError(transactionID, apiKey, seqNo string, err error, payload interface{}) { + if s.logger == nil { + return + } + s.logger.LogError(seqNo, transactionID, apiKey, err, payload) } func (s *NuoerService) CallAPI(ctx context.Context, apiKey, apiPath string, body map[string]string) (*nuoerResponse, error) { @@ -90,7 +99,6 @@ func (s *NuoerService) CallAPI(ctx context.Context, apiKey, apiPath string, body requestURL += apiPath } - requestID := s.generateRequestID() startTime := time.Now() var transactionID string @@ -109,24 +117,20 @@ func (s *NuoerService) CallAPI(ctx context.Context, apiKey, apiPath string, body } if s.logger != nil { - s.logger.LogRequest(requestID, transactionID, apiKey, requestURL) + s.logger.LogRequest("", transactionID, apiKey, requestURL) } bodyBytes, err := json.Marshal(requestPayload) if err != nil { err = errors.Join(ErrSystem, err) - if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiKey, err, requestPayload) - } + s.logError(transactionID, apiKey, "", err, requestPayload) return nil, err } req, err := http.NewRequestWithContext(ctx, http.MethodPost, requestURL, bytes.NewBuffer(bodyBytes)) if err != nil { err = errors.Join(ErrSystem, err) - if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiKey, err, requestPayload) - } + s.logError(transactionID, apiKey, "", err, requestPayload) return nil, err } req.Header.Set("Content-Type", "application/json") @@ -135,9 +139,7 @@ func (s *NuoerService) CallAPI(ctx context.Context, apiKey, apiPath string, body resp, err := client.Do(req) if err != nil { err = wrapHTTPError(err) - if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiKey, err, requestPayload) - } + s.logError(transactionID, apiKey, "", err, requestPayload) return nil, err } defer resp.Body.Close() @@ -145,86 +147,72 @@ func (s *NuoerService) CallAPI(ctx context.Context, apiKey, apiPath string, body respBody, err := io.ReadAll(resp.Body) if err != nil { err = errors.Join(ErrSystem, err) - if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiKey, err, requestPayload) - } + s.logError(transactionID, apiKey, "", err, requestPayload) return nil, err } - if s.logger != nil { - s.logger.LogResponse(requestID, transactionID, apiKey, resp.StatusCode, time.Since(startTime)) - } + duration := time.Since(startTime) if resp.StatusCode != http.StatusOK { err = errors.Join(ErrDatasource, fmt.Errorf("HTTP状态码 %d", resp.StatusCode)) - if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiKey, err, requestPayload) - } + s.logError(transactionID, apiKey, "", err, requestPayload) return nil, err } var nuoerResp nuoerResponse if err := json.Unmarshal(respBody, &nuoerResp); err != nil { err = errors.Join(ErrSystem, fmt.Errorf("响应解析失败: %w", err)) - if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiKey, err, requestPayload) - } + s.logError(transactionID, apiKey, "", err, requestPayload) return nil, err } if nuoerResp.Code != CodeSuccess { if nuoerResp.Code == BusiCodeNotFound && isQueryBillingAPIKey(apiKey) { nuoerResp.Data = map[string]interface{}{} + s.logResponse(transactionID, apiKey, resp.StatusCode, duration, nuoerResp.SeqNo) return &nuoerResp, nil } nuoerErr := NewNuoerError(nuoerResp.Code, nuoerResp.Msg) err = errors.Join(GetErrByPlatformCode(nuoerResp.Code), nuoerErr) - if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiKey, nuoerErr, requestPayload) - } + s.logError(transactionID, apiKey, nuoerResp.SeqNo, nuoerErr, requestPayload) return nil, err } if nuoerResp.Data == nil { err = errors.Join(ErrSystem, errors.New("响应 data 为空")) - if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiKey, err, requestPayload) - } + s.logError(transactionID, apiKey, nuoerResp.SeqNo, err, requestPayload) return nil, err } busiCode, busiMsg, ok := parseDataBusiInfo(nuoerResp.Data) if !ok { err = errors.Join(ErrSystem, errors.New("响应 data 无法解析 busiCode")) - if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiKey, err, requestPayload) - } + s.logError(transactionID, apiKey, nuoerResp.SeqNo, err, requestPayload) return nil, err } if busiCode != BusiCodeSuccess { if busiCode == BusiCodeNotFound && isQueryBillingAPIKey(apiKey) { nuoerResp.Data = map[string]interface{}{} + s.logResponse(transactionID, apiKey, resp.StatusCode, duration, nuoerResp.SeqNo) return &nuoerResp, nil } busiErr := NewNuoerBusiError(busiCode, busiMsg) err = errors.Join(GetErrByBusiCode(busiCode), busiErr) - if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiKey, busiErr, requestPayload) - } + s.logError(transactionID, apiKey, nuoerResp.SeqNo, busiErr, requestPayload) return nil, err } cleanedData, err := stripBusiMetaFromData(nuoerResp.Data) if err != nil { err = errors.Join(ErrSystem, fmt.Errorf("响应 data 清理失败: %w", err)) - if s.logger != nil { - s.logger.LogError(requestID, transactionID, apiKey, err, requestPayload) - } + s.logError(transactionID, apiKey, nuoerResp.SeqNo, err, requestPayload) return nil, err } nuoerResp.Data = cleanedData + s.logResponse(transactionID, apiKey, resp.StatusCode, duration, nuoerResp.SeqNo) + return &nuoerResp, nil }