package COMB import ( "context" "encoding/hex" "encoding/json" "sync" "tianyuan-api/apps/api/internal/common" "tianyuan-api/apps/api/internal/svc" "tianyuan-api/apps/api/internal/types" "tianyuan-api/apps/api/internal/validator" "tianyuan-api/apps/api/internal/westmodel" "tianyuan-api/pkg/crypto" "tianyuan-api/pkg/errs" "github.com/zeromicro/go-zero/core/logx" ) type COMB298YLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } // WestAPIRequest 定义西部API请求结构 type APIRequest struct { SourceId string ServiceId string Request map[string]interface{} Mapping map[string]string Wrap string Service string } // WestAPIResponse 定义西部API响应结构 type APIResponse struct { ServiceId string Resp json.RawMessage Success bool } // 将所有响应组装成JSON type ResponseData struct { Responses []struct { ServiceId string `json:"api_code"` Data json.RawMessage `json:"data"` Success bool `json:"success"` } `json:"responses"` } func NewCOMB298YLogic(ctx context.Context, svcCtx *svc.ServiceContext) *COMB298YLogic { return &COMB298YLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *COMB298YLogic) COMB298Y(req *types.Request) (resp string, err *errs.AppError) { var status string var charges bool var remark = "" secretKey, ok := l.ctx.Value("secretKey").(string) if !ok { return "", errs.ErrSystem } transactionID, ok := l.ctx.Value("transactionID").(string) if !ok { return "", errs.ErrSystem } userId, userIdOk := l.ctx.Value("userId").(int64) if !userIdOk { return "", errs.ErrSystem } productCode, productCodeOk := l.ctx.Value("productCode").(string) if !productCodeOk || productCode == "" { return "", errs.ErrSystem } defer func() { if err != nil { status = "failed" charges = false } else { status = "success" charges = true } sendApiRequestMessageErr := l.svcCtx.ApiRequestMqsService.SendApiRequestMessage(l.ctx, transactionID, userId, productCode, status, charges, remark) if sendApiRequestMessageErr != nil { logx.Errorf("发送 API 请求消息失败: %v", err) } }() // 1、解密 key, decodeErr := hex.DecodeString(secretKey) if decodeErr != nil { return "", errs.ErrSystem } decryptData, aesDecryptErr := crypto.AesDecrypt(req.Data, key) if aesDecryptErr != nil || len(decryptData) == 0 { return "", errs.ErrParamDecryption } // 2、校验 var data validator.COMB298YRequest if validatorErr := validator.ValidateAndParse(decryptData, &data); validatorErr != nil { return "", errs.ErrParamValidation } // 准备并发请求 apiRequests := []APIRequest{ // {SourceId: "G16BJ02", ServiceId: "YYSY09CD", Mapping: westmodel.YYSY09CDFieldMapping, Wrap: "data", Service: "west"}, // {SourceId: "G27BJ05", ServiceId: "JRZQ0A03", Mapping: westmodel.JRZQ0A03FieldMapping, Wrap: "data", Service: "west"}, // {SourceId: "G28BJ05", ServiceId: "JRZQ8203", Mapping: westmodel.JRZQ8203FieldMapping, Wrap: "data", Service: "west"}, // {SourceId: "G26BJ05", ServiceId: "FLXG3D56", Mapping: westmodel.FLXG3D56FieldMapping, Wrap: "data", Service: "west"}, // {SourceId: "G22SC01", ServiceId: "FLXGCA3D", Mapping: westmodel.FLXGCA3DFieldMapping, Wrap: "data", Service: "west"}, // {SourceId: "G29BJ05", ServiceId: "JRZQ4AA8", Mapping: westmodel.JRZQ4AA8FieldMapping, Wrap: "data", Service: "west"}, // {SourceId: "G30BJ05", ServiceId: "FLXGC9D1", Mapping: westmodel.FLXGC9D1FieldMapping, Wrap: "data", Service: "west"}, // {SourceId: "G32BJ05", ServiceId: "FLXG162A", Mapping: westmodel.FLXG162AFieldMapping, Wrap: "data", Service: "west"}, // {SourceId: "G03HZ01", ServiceId: "FLXG54F5", Mapping: westmodel.FLXG54F5FieldMapping, Wrap: "data", Service: "west"}, // {SourceId: "G09XM02", ServiceId: "IVYZ5733", Mapping: westmodel.IVYZ5733FieldMapping, Wrap: "data", Service: "west"}, // {SourceId: "G11BJ06", ServiceId: "IVYZ9A2B", Mapping: westmodel.IVYZ9A2BFieldMapping, Wrap: "data", Service: "west"}, {SourceId: "G05HZ01", ServiceId: "QYGLB4C0", Mapping: westmodel.QYGLB4C0FieldMapping, Wrap: "", Service: "west"}, // {SourceId: "RIS031", ServiceId: "FLXG8UI0", Mapping: westmodel.FLXG8UI0FieldMapping, Wrap: "", Service: "yushan"}, } // 为每个请求构建对应的请求参数 for i := range apiRequests { if apiRequests[i].Service == "west" { // 西部服务:先加密后mapping westConfig := l.svcCtx.Config.WestConfig if apiRequests[i].SourceId == "G05HZ01" { // G05HZ01 不需要加密,直接使用原始数据 dataMap, err := common.StructToMap(data) if err != nil { logx.Errorf("结构体转map失败:%v", err) return "", errs.ErrSystem } logx.Infof("G05HZ01 原始数据: %+v", data) logx.Infof("G05HZ01 转换后数据: %+v", dataMap) apiRequests[i].Request = common.MapStructToAPIRequest(dataMap, apiRequests[i].Mapping, apiRequests[i].Wrap) logx.Infof("G05HZ01 最终请求数据: %+v", apiRequests[i].Request) } else { // 其他西部服务需要加密 encryptedRequest, encryptErr := common.EncryptStructFields(data, westConfig.Key) if encryptErr != nil { logx.Errorf("西部加密错误:%v", encryptErr) return "", errs.ErrSystem } apiRequests[i].Request = common.MapStructToAPIRequest(encryptedRequest, apiRequests[i].Mapping, apiRequests[i].Wrap) } } else { // 如果是 RIS031,添加 type: 3 if apiRequests[i].SourceId == "RIS031" { apiRequests[i].Request = map[string]interface{}{ "keyWord": data.IDCard, "type": 3, } } } logx.Infof("sourceId:%s,请求参数:%v", apiRequests[i].SourceId, apiRequests[i].Request) } // 创建响应通道 responseChan := make(chan APIResponse, len(apiRequests)) var wg sync.WaitGroup // 并发处理请求 for _, apiReq := range apiRequests { wg.Add(1) go func(req APIRequest) { defer wg.Done() success := true var westResp string var callAPIErr *errs.AppError // 根据服务类型选择不同的调用方式 switch req.Service { case "west": // 4、发送请求到西部 logx.Infof("交易号:%s", transactionID) var respData []byte var err error if req.SourceId == "G05HZ01" { respData, err = l.svcCtx.WestDexService.CallAPISecond(req.SourceId, req.Request, l.svcCtx.Config.WestConfig.SecretId) } else { respData, err = l.svcCtx.WestDexService.CallAPI(req.SourceId, req.Request, l.svcCtx.Config.WestConfig.SecretId) } if err != nil { logx.Errorf("西部请求失败:sourceId:%s,err:%v, resp:%s", req.SourceId, err, string(respData)) if appErr, ok := err.(*errs.AppError); ok { callAPIErr = appErr } else { callAPIErr = errs.ErrSystem } westResp = "{}" // 发生错误时返回空对象 } else { // 确保返回的是有效的 JSON if len(respData) == 0 { westResp = "{}" } else { // 验证 JSON 是否有效 var jsonCheck interface{} if json.Unmarshal(respData, &jsonCheck) != nil { westResp = "{}" } else { westResp = string(respData) } } } case "yushan": respData, err := l.svcCtx.YushanService.Request(req.SourceId, req.Request) if err != nil { logx.Errorf("羽山请求失败:sourceId:%s,err:%v", req.SourceId, err) if appErr, ok := err.(*errs.AppError); ok { callAPIErr = appErr } else { callAPIErr = errs.ErrSystem } westResp = "{}" // 发生错误时返回空对象 } else { // 确保返回的是有效的 JSON if len(respData) == 0 { westResp = "{}" } else { // 验证 JSON 是否有效 var jsonCheck interface{} if json.Unmarshal(respData, &jsonCheck) != nil { westResp = "{}" } else { westResp = string(respData) } } } default: success = false westResp = "{}" logx.Errorf("未知的服务类型:%s", req.Service) } if callAPIErr != nil { success = false } // 确保响应是有效的 JSON var jsonResp json.RawMessage if err := json.Unmarshal([]byte(westResp), &jsonResp); err != nil { jsonResp = json.RawMessage("{}") } responseChan <- APIResponse{ ServiceId: req.ServiceId, Resp: jsonResp, Success: success, } }(apiReq) } // 等待所有请求完成 go func() { wg.Wait() close(responseChan) }() // 处理响应 var responses []APIResponse for resp := range responseChan { responses = append(responses, resp) } responseData := ResponseData{ Responses: make([]struct { ServiceId string `json:"api_code"` Data json.RawMessage `json:"data"` Success bool `json:"success"` }, len(responses)), } for i, resp := range responses { responseData.Responses[i] = struct { ServiceId string `json:"api_code"` Data json.RawMessage `json:"data"` Success bool `json:"success"` }{ ServiceId: resp.ServiceId, Data: resp.Resp, Success: resp.Success, } } // 将响应数据转换为JSON jsonData, marshalErr := json.Marshal(responseData) if marshalErr != nil { logx.Errorf("JSON编码错误:%v", marshalErr) return "", errs.ErrSystem } // 加密JSON数据 encryptData, aesEncrypt := crypto.AesEncrypt(jsonData, key) if aesEncrypt != nil { return "", errs.ErrSystem } return string(encryptData), nil }