diff --git a/app/main/api/internal/service/apirequestService.go b/app/main/api/internal/service/apirequestService.go index 5834ea9..ee6e7f5 100644 --- a/app/main/api/internal/service/apirequestService.go +++ b/app/main/api/internal/service/apirequestService.go @@ -24,6 +24,33 @@ func convertTianyuanResponse(resp *tianyuanapi.Response) ([]byte, error) { return json.Marshal(resp.Data) } +// convertTianyuanBundleResponse 检测并转换组合包响应 +// 如果响应是组合包格式(包含 "responses" 字段),则转换为统一格式 +// 否则直接返回原始响应数据 +func convertTianyuanBundleResponse(resp *tianyuanapi.Response) ([]byte, error) { + // 先将响应数据转换为 JSON 字节 + respData, err := json.Marshal(resp.Data) + if err != nil { + return nil, fmt.Errorf("序列化响应数据失败: %v", err) + } + + // 检测是否是组合包响应格式(包含 "responses" 字段) + if gjson.GetBytes(respData, "responses").Exists() { + // 这是组合包响应,转换为统一格式 + bundleResults, convertErr := convertBundleResponseToStandard(respData) + if convertErr != nil { + // 转换失败,返回原始数据并记录错误 + logx.Errorf("转换组合包响应失败: %v", convertErr) + return respData, nil + } + // 转换成功,返回转换后的 JSON + return json.Marshal(bundleResults) + } + + // 不是组合包响应,直接返回原始数据 + return respData, nil +} + // 生成认证时间范围:当前时间前后两天的YYYYMMDD-YYMMDD格式 func generateAuthDateRange() string { now := time.Now() @@ -121,6 +148,59 @@ type APIResponseData struct { Error string `json:"error,omitempty"` } +// BundleResponseItem 组合包响应中的单个项 +type BundleResponseItem struct { + ApiCode string `json:"api_code"` + Success bool `json:"success"` + Data json.RawMessage `json:"data"` + Error string `json:"error,omitempty"` +} + +// BundleResponse 组合包响应结构 +type BundleResponse struct { + Responses []BundleResponseItem `json:"responses"` +} + +// convertBundleResponseToStandard 将组合包响应格式转换为统一格式 +func convertBundleResponseToStandard(bundleResp []byte) ([]APIResponseData, error) { + var bundle BundleResponse + if err := json.Unmarshal(bundleResp, &bundle); err != nil { + return nil, fmt.Errorf("解析组合包响应失败: %v", err) + } + + timestamp := time.Now().Format("2006-01-02 15:04:05") + var result []APIResponseData + + for _, item := range bundle.Responses { + apiResp := APIResponseData{ + ApiID: item.ApiCode, + Success: item.Success, + Timestamp: timestamp, + } + + // 处理 data 字段 + if len(item.Data) > 0 { + // 如果 data 是 null 的 JSON 字符串,转换为 null + if string(item.Data) == "null" { + apiResp.Data = []byte("null") + } else { + apiResp.Data = item.Data + } + } else { + apiResp.Data = []byte("null") + } + + // 处理 error 字段 + if !item.Success && item.Error != "" { + apiResp.Error = item.Error + } + + result = append(result, apiResp) + } + + return result, nil +} + // ProcessRequests 处理请求 func (a *ApiRequestService) ProcessRequests(ctx context.Context, params []byte, productID string) ([]byte, error) { var cancel context.CancelFunc @@ -249,10 +329,49 @@ func (a *ApiRequestService) ProcessRequests(ctx context.Context, params []byte, close(resultsCh) close(errorsCh) }() - // 收集所有结果并合并z + // 收集所有结果并合并 var responseData []APIResponseData for result := range resultsCh { - responseData = append(responseData, result) + if result.Success && len(result.Data) > 0 { + // 先检查是否是已拆开的组合包(统一格式数组) + // 特征:是数组格式,且第一个元素包含 "apiID"、"success"、"timestamp" 字段 + firstItem := gjson.GetBytes(result.Data, "0") + if firstItem.Exists() { + firstApiID := firstItem.Get("apiID") + firstSuccess := firstItem.Get("success") + firstTimestamp := firstItem.Get("timestamp") + // 如果第一个元素有 apiID、success、timestamp 字段,说明是已拆开的组合包 + if firstApiID.Exists() && firstSuccess.Exists() && firstTimestamp.Exists() { + // 这是已拆开的组合包(统一格式数组),直接展开添加到结果中 + var bundleResults []APIResponseData + if err := json.Unmarshal(result.Data, &bundleResults); err == nil { + responseData = append(responseData, bundleResults...) + continue + } + // 解析失败,作为普通响应处理 + } + } + + // 检查是否包含 "responses" 字段(未拆开的组合包) + if gjson.GetBytes(result.Data, "responses").Exists() { + // 这是未拆开的组合包响应,需要转换 + bundleResults, convertErr := convertBundleResponseToStandard(result.Data) + if convertErr != nil { + // 转换失败,记录错误但保留原始结果 + logx.Errorf("转换组合包响应失败: %v", convertErr) + responseData = append(responseData, result) + } else { + // 转换成功,用转换后的结果替换原始结果 + responseData = append(responseData, bundleResults...) + } + } else { + // 普通响应,直接添加 + responseData = append(responseData, result) + } + } else { + // 失败或空响应,直接添加 + responseData = append(responseData, result) + } } if atomic.LoadInt32(&errorCount) >= int32(errorLimit) { var allErrors []error @@ -304,6 +423,7 @@ var requestProcessors = map[string]func(*ApiRequestService, context.Context, []b "JRZQ7F1A": (*ApiRequestService).ProcessJRZQ7F1ARequest, "IVYZ3P9M": (*ApiRequestService).ProcessIVYZ3P9MRequest, "JRZQ6F2A": (*ApiRequestService).ProcessJRZQ6F2ARequest, + "COMBQN12": (*ApiRequestService).ProcessCOMBQN12Request, } // PreprocessRequestApi 调用指定的请求处理函数 @@ -1696,3 +1816,27 @@ func (a *ApiRequestService) ProcessJRZQ6F2ARequest(ctx context.Context, params [ return convertTianyuanResponse(resp) } + +// ProcessCOMBQN12Request 全能入职背调报告(标准版) - 组合包 +func (a *ApiRequestService) ProcessCOMBQN12Request(ctx context.Context, params []byte) ([]byte, error) { + name := gjson.GetBytes(params, "name") + idCard := gjson.GetBytes(params, "id_card") + mobile := gjson.GetBytes(params, "mobile") + if !name.Exists() || !idCard.Exists() || !mobile.Exists() { + return nil, errors.New("api请求, COMBQN12, 获取相关参数失败") + } + + resp, err := a.callTianyuanApiWithLog(ctx, "", "COMBQN12", map[string]interface{}{ + "name": name.String(), + "id_card": idCard.String(), + "mobile_no": mobile.String(), + "authorized": "1", + }) + + if err != nil { + return nil, err + } + + // 使用组合包响应转换函数,自动检测并转换 + return convertTianyuanBundleResponse(resp) +}