This commit is contained in:
2026-04-21 22:36:48 +08:00
commit 488c695fdf
748 changed files with 266838 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"strings"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
)
// ProcessCOMENT01Request COMENT01 API处理方法 - 企业风险报告
func ProcessCOMENT01Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.COMENT01Req
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 构建请求体
requestBody := map[string]string{
"company_name": paramsDto.EntName,
"credit_code": paramsDto.EntCode,
}
requestBodyBytes, err := json.Marshal(requestBody)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
// 创建HTTP请求
url := "https://api.v1.tybigdata.com/api/v1/enterprise/risk-report"
req, err := http.NewRequestWithContext(ctx, "POST", url, strings.NewReader(string(requestBodyBytes)))
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
// 设置请求头
req.Header.Set("Content-Type", "application/json")
req.Header.Set("apikey", "1000000$BUsWYV5DQ3CSvPWYYegkr3$TZmMl7WZ29Zj5gcRmgieoqVs1oBjOt3BPWGq7iTSF5o")
// 发送请求
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, errors.Join(processors.ErrDatasource, err)
}
defer resp.Body.Close()
// 检查HTTP状态码
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%s: HTTP状态码异常: %d", processors.ErrDatasource, resp.StatusCode)
}
// 读取响应
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBody, nil
}

View File

@@ -0,0 +1,24 @@
package qygl
import (
"errors"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/tianyancha"
)
// convertTianYanChaError 将天眼查服务的错误转换为处理器层的标准错误
func convertTianYanChaError(err error) error {
if err == nil {
return nil
}
if errors.Is(err, tianyancha.ErrDatasource) {
return errors.Join(processors.ErrDatasource, err)
}
if errors.Is(err, tianyancha.ErrInvalidParam) {
return errors.Join(processors.ErrInvalidParam, err)
}
// 默认作为系统错误处理
return errors.Join(processors.ErrSystem, err)
}

View File

@@ -0,0 +1,121 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"fmt"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"github.com/tidwall/gjson"
)
// ProcessQYGL23T7Request QYGL23T7 API处理方法 - 企业四要素验证
func ProcessQYGL23T7Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL23T7Req
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 构建API调用参数
apiParams := map[string]string{
"code": paramsDto.EntCode,
"name": paramsDto.EntName,
"legalPersonName": paramsDto.LegalPerson,
}
// 调用天眼查API - 使用通用的CallAPI方法
response, err := deps.TianYanChaService.CallAPI(ctx, "VerifyThreeElements", apiParams)
if err != nil {
return nil, convertTianYanChaError(err)
}
// 检查天眼查API调用是否成功
if !response.Success {
// 天眼查API调用失败返回企业信息校验不通过
return createStatusResponse(1), nil
}
// 解析天眼查响应数据
if response.Data == nil {
// 天眼查响应数据为空,返回企业信息校验不通过
return createStatusResponse(1), nil
}
// 将response.Data转换为JSON字符串然后使用gjson解析
dataBytes, err := json.Marshal(response.Data)
if err != nil {
// 数据序列化失败,返回企业信息校验不通过
return createStatusResponse(1), nil
}
// 使用gjson解析嵌套的data.result.data字段
result := gjson.GetBytes(dataBytes, "result")
if !result.Exists() {
// 字段不存在,返回企业信息校验不通过
return createStatusResponse(1), nil
}
// 检查data.result.data是否等于1
if result.Int() != 1 {
// 不等于1返回企业信息校验不通过
return createStatusResponse(1), nil
}
// 天眼查三要素验证通过,继续调用阿里云身份证二要素验证
// 构建阿里云二要素验证请求参数
reqData := map[string]interface{}{
"name": paramsDto.LegalPerson,
"idcard": paramsDto.IDCard,
}
// 调用阿里云二要素验证API
respBytes, err := deps.AlicloudService.CallAPI("api-mall/api/id_card/check", reqData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
// 解析阿里云响应
var alicloudResponse struct {
Msg string `json:"msg"`
Success bool `json:"success"`
Code int `json:"code"`
Data struct {
Birthday string `json:"birthday"`
Result int `json:"result"`
Address string `json:"address"`
OrderNo string `json:"orderNo"`
Sex string `json:"sex"`
Desc string `json:"desc"`
} `json:"data"`
}
if err := json.Unmarshal(respBytes, &alicloudResponse); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
// 检查响应状态
if alicloudResponse.Code != 200 && alicloudResponse.Code != 400 {
return nil, fmt.Errorf("%s: %s", processors.ErrDatasource, alicloudResponse.Msg)
}
// 根据阿里云响应结果返回状态
if alicloudResponse.Code == 400 {
// 身份证号格式错误返回状态2
return createStatusResponse(2), nil
} else {
if alicloudResponse.Data.Result == 0 {
// 验证通过返回状态0
return createStatusResponse(0), nil
} else {
// 验证失败返回状态2
return createStatusResponse(2), nil
}
}
}

View File

@@ -0,0 +1,57 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
)
// ProcessQYGL2ACDRequest QYGL2ACD API处理方法
func ProcessQYGL2ACDRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL2ACDReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
encryptedEntName, err := deps.WestDexService.Encrypt(paramsDto.EntName)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedLegalPerson, err := deps.WestDexService.Encrypt(paramsDto.LegalPerson)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedEntCode, err := deps.WestDexService.Encrypt(paramsDto.EntCode)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"data": map[string]interface{}{
"name": encryptedEntName,
"oper_name": encryptedLegalPerson,
"keyword": encryptedEntCode,
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "WEST00022", reqData)
if err != nil {
if errors.Is(err, westdex.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,59 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"fmt"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/zhicha"
)
// ProcessQYGL2B5CRequest QYGL2B5C API处理方法 - 企业联系人实际经营地址
func ProcessQYGL2B5CRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL2B5CReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 两选一校验EntName 和 EntCode 至少传一个
var keyword string
if paramsDto.EntName == "" && paramsDto.EntCode == "" {
return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, errors.New("必须提供企业名称或企业统一信用代码中的其中一个"))
}
// 确定使用哪个值作为 keyword
if paramsDto.EntName != "" {
keyword = paramsDto.EntName
} else {
keyword = paramsDto.EntCode
}
reqData := map[string]interface{}{
"keyword": keyword,
"authorized": paramsDto.Authorized,
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI050", reqData)
if err != nil {
if errors.Is(err, zhicha.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
// 将响应数据转换为 JSON 字节
respBytes, err := json.Marshal(respData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,58 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"strconv"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
)
// ProcessQYGL2naoRequest QYGL2NAO API处理方法 - 股权变更
func ProcessQYGL2naoRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL2naoReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 设置默认值
pageSize := paramsDto.PageSize
if pageSize == 0 {
pageSize = int64(20)
}
pageNum := paramsDto.PageNum
if pageNum == 0 {
pageNum = int64(1)
}
// 构建API调用参数
apiParams := map[string]string{
"keyword": paramsDto.EntCode,
"pageSize": strconv.FormatInt(pageSize, 10),
"pageNum": strconv.FormatInt(pageNum, 10),
}
// 调用天眼查API - 企业基本信息
response, err := deps.TianYanChaService.CallAPI(ctx, "holderChange", apiParams)
if err != nil {
return nil, convertTianYanChaError(err)
}
// 检查天眼查API调用是否成功
if !response.Success {
return nil, errors.Join(processors.ErrDatasource, errors.New(response.Message))
}
// 返回天眼查响应数据
respBytes, err := json.Marshal(response.Data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,79 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"fmt"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/xingwei"
)
// Processqygl2s0wRequest QYGL2S0W API处理方法 - 失信被执行企业个人查询
func ProcessQYGL2S0WRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL2S0WReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 验证逻辑
var nameValue string
if paramsDto.Type == "per" {
// 个人查询idCardNum 必填
nameValue = paramsDto.Name
if paramsDto.IDCard == "" {
fmt.Print("个人身份证件号不能为空")
return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, errors.New("当失信被执行人类型为个人时,身份证件号不能为空"))
}
if paramsDto.IDCard == "410482198504029333" {
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
}
} else if paramsDto.Type == "ent" {
// 企业查询name 和 entMark 两者必填其一
nameValue = paramsDto.EntName
if paramsDto.EntName == "" && paramsDto.EntCode == "" {
return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, errors.New("当查询为企业时,企业名称和企业标识统一代码注册号两者必填其一"))
} // 确定使用哪个值作为 name
if paramsDto.EntName != "" {
nameValue = paramsDto.EntName
} else {
nameValue = paramsDto.EntCode
}
}
fmt.Println("dto2s0w", paramsDto)
// 构建请求数据(不传的参数也需要添加,值为空字符串)
reqData := map[string]interface{}{
"idCardNum": paramsDto.IDCard,
"name": nameValue,
"entMark": paramsDto.EntCode,
"type": paramsDto.Type,
}
// 调用行为数据API使用指定的project_id
projectID := "CDJ-1079244717102657536"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
// 查空情况,返回特定的查空错误
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
// 数据源错误
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
// 系统错误
return nil, errors.Join(processors.ErrSystem, err)
} else {
// 其他未知错误
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,66 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
)
// ProcessQYGL45BDRequest QYGL45BD API处理方法
func ProcessQYGL45BDRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL45BDReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
encryptedEntName, err := deps.WestDexService.Encrypt(paramsDto.EntName)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedLegalPerson, err := deps.WestDexService.Encrypt(paramsDto.LegalPerson)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedEntCode, err := deps.WestDexService.Encrypt(paramsDto.EntCode)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedIDCard, err := deps.WestDexService.Encrypt(paramsDto.IDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"data": map[string]interface{}{
"entname": encryptedEntName,
"realname": encryptedLegalPerson,
"entmark": encryptedEntCode,
"idcard": encryptedIDCard,
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "WEST00021", reqData)
if err != nil {
if errors.Is(err, westdex.ErrDatasource) {
if respBytes != nil {
return respBytes,nil
}
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,59 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"strconv"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
)
// ProcessQYGL4B2ERequest QYGL4B2E API处理方法 - 税收违法
func ProcessQYGL4B2ERequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL5A3CReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 设置默认值
pageSize := paramsDto.PageSize
if pageSize == 0 {
pageSize = int64(20)
}
pageNum := paramsDto.PageNum
if pageNum == 0 {
pageNum = int64(1)
}
// 构建API调用参数
apiParams := map[string]string{
"keyword": paramsDto.EntCode,
"pageSize": strconv.FormatInt(pageSize, 10),
"pageNum": strconv.FormatInt(pageNum, 10),
}
// 调用天眼查API - 税收违法
response, err := deps.TianYanChaService.CallAPI(ctx, "TaxContravention", apiParams)
if err != nil {
return nil, convertTianYanChaError(err)
}
// 检查天眼查API调用是否成功
if !response.Success {
return nil, errors.Join(processors.ErrDatasource, errors.New(response.Message))
}
// 返回天眼查响应数据
respBytes, err := json.Marshal(response.Data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,59 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"strconv"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
)
// ProcessQYGL5A3CRequest QYGL5A3C API处理方法 - 对外投资历史
func ProcessQYGL5A3CRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL5A3CReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 设置默认值
pageSize := paramsDto.PageSize
if pageSize == 0 {
pageSize = int64(20)
}
pageNum := paramsDto.PageNum
if pageNum == 0 {
pageNum = int64(1)
}
// 构建API调用参数
apiParams := map[string]string{
"keyword": paramsDto.EntCode,
"pageSize": strconv.FormatInt(pageSize, 10),
"pageNum": strconv.FormatInt(pageNum, 10),
}
// 调用天眼查API - 对外投资历史
response, err := deps.TianYanChaService.CallAPI(ctx, "InvestHistory", apiParams)
if err != nil {
return nil, convertTianYanChaError(err)
}
// 检查天眼查API调用是否成功
if !response.Success {
return nil, errors.Join(processors.ErrDatasource, errors.New(response.Message))
}
// 返回天眼查响应数据
respBytes, err := json.Marshal(response.Data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,64 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"fmt"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/xingwei"
)
// Processqygl5a9tRequest QYGL5A9T API处理方法 - 全国企业各类工商风险统计数量查询
func ProcessQYGL5A9TRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL5A9TReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 两选一校验EntName 和 EntCode 至少传一个
var keyword string
if paramsDto.EntName == "" && paramsDto.EntCode == "" {
return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, errors.New("必须提供企业名称或企业统一信用代码中的其中一个"))
}
// 确定使用哪个值作为 keyword
if paramsDto.EntName != "" {
keyword = paramsDto.EntName
} else {
keyword = paramsDto.EntCode
}
// 构建请求数据,
reqData := map[string]interface{}{
"nameCode": keyword,
}
// 调用行为数据API使用指定的project_id
projectID := "CDJ-1054665422426533888"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
// 查空情况,返回特定的查空错误
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
// 数据源错误
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
// 系统错误
return nil, errors.Join(processors.ErrSystem, err)
} else {
// 其他未知错误
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,128 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"fmt"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/xingwei"
"github.com/tidwall/gjson"
)
// ProcessQYGL5CMPRequest QYGL5CMP API处理方法 - 企业五要素验证
func ProcessQYGL5CMPRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL5CMPReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 第一步:企业信息验证 - 调用天眼查API
_, err := verifyEnterpriseInfo(ctx, paramsDto, deps)
if err != nil {
// 企业信息验证失败,只返回简单的状态码
return createStatusResponse(1), nil
}
// 企业信息验证通过,继续个人信息验证
_, err = verifyPersonalInfo(ctx, paramsDto, deps)
if err != nil {
// 个人信息验证失败,只返回简单的状态码
return createStatusResponse(1), nil
}
// 两个验证都通过,只返回成功状态码
return createStatusResponse(0), nil
}
// verifyEnterpriseInfo 验证企业信息
func verifyEnterpriseInfo(ctx context.Context, paramsDto dto.QYGL5CMPReq, deps *processors.ProcessorDependencies) (map[string]interface{}, error) {
// 构建API调用参数
apiParams := map[string]string{
"code": paramsDto.EntCode,
"name": paramsDto.EntName,
"legalPersonName": paramsDto.LegalPerson,
}
// 调用天眼查API - 使用通用的CallAPI方法
response, err := deps.TianYanChaService.CallAPI(ctx, "VerifyThreeElements", apiParams)
if err != nil {
return nil, convertTianYanChaError(err)
}
// 检查天眼查API调用是否成功
if !response.Success {
return nil, fmt.Errorf("天眼查API调用失败")
}
// 解析天眼查响应数据
if response.Data == nil {
return nil, fmt.Errorf("天眼查响应数据为空")
}
// 将response.Data转换为JSON字符串然后使用gjson解析
dataBytes, err := json.Marshal(response.Data)
if err != nil {
return nil, fmt.Errorf("数据序列化失败")
}
// 使用gjson解析嵌套的data.result.data字段
result := gjson.GetBytes(dataBytes, "result")
if !result.Exists() {
return nil, fmt.Errorf("result字段不存在")
}
// 检查data.result.data是否等于1
if result.Int() != 1 {
return nil, fmt.Errorf("企业信息验证不通过")
}
// 构建天眼查API返回的数据结构
return map[string]interface{}{
"success": response.Success,
"message": response.Message,
"data": response.Data,
}, nil
}
// verifyPersonalInfo 验证个人信息并返回API数据
func verifyPersonalInfo(ctx context.Context, paramsDto dto.QYGL5CMPReq, deps *processors.ProcessorDependencies) (map[string]interface{}, error) {
// 构建请求数据,将项目规范的字段名转换为 XingweiService 需要的字段名
reqData := map[string]interface{}{
"name": paramsDto.LegalPerson,
"idCardNum": paramsDto.IDCard,
"phoneNumber": paramsDto.MobileNo,
}
// 调用行为数据API使用指定的project_id
projectID := "CDJ-1100244702166183936"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil {
// 个人信息验证失败,返回错误状态
if errors.Is(err, xingwei.ErrNotFound) {
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
return nil, errors.Join(processors.ErrSystem, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
// 解析星维API返回的数据
var xingweiData map[string]interface{}
if err := json.Unmarshal(respBytes, &xingweiData); err != nil {
return nil, errors.Join(processors.ErrSystem, fmt.Errorf("解析星维API响应失败: %w", err))
}
// 返回星维API的全部数据
return xingweiData, nil
}

View File

@@ -0,0 +1,48 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"fmt"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/xingwei"
)
// ProcessQYGL5F6ARequest QYGL5F6A API处理方法 - 企业相关查询
func ProcessQYGL5F6ARequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL5F6AReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
fmt.Println("paramsDto", paramsDto)
// 构建请求数据,将项目规范的字段名转换为 XingweiService 需要的字段名
reqData := map[string]interface{}{
"idCardNum": paramsDto.IDCard,
}
// 调用行为数据API使用指定的project_id
projectID := "CDJ-1101695397213958144"
fmt.Println("reqData", reqData)
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
return nil, errors.Join(processors.ErrSystem, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,59 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/zhicha"
)
// ProcessQYGL5S1IReq QYGL5S1I API处理方法 - 企业司法涉诉V2
func ProcessQYGL5S1IRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL5S1IReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
encryptedEntName, err := deps.ZhichaService.Encrypt(paramsDto.EntName)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedEntCode, err := deps.ZhichaService.Encrypt(paramsDto.EntCode)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
// 按企业名称时传 enterpriseNo加密名按统一信用代码时传 enterpriseName加密代码
reqData := map[string]interface{}{}
if paramsDto.EntName != "" {
reqData["enterpriseName"] = encryptedEntName
}
if paramsDto.EntCode != "" {
reqData["enterpriseNo"] = encryptedEntCode
}
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI088", reqData)
if err != nil {
if errors.Is(err, zhicha.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
// 将响应数据转换为JSON字节
respBytes, err := json.Marshal(respData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,53 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/xingwei"
)
// Processqygl66slRequest QYGL66SL API处理方法 - 全国企业司法模型服务查询_V1
func ProcessQYGL66SLRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL66SLReq
if err := json.Unmarshal(params, &paramsDto); 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{}{
"orgName": paramsDto.EntName,
"inquiredAuth": "authed:" + paramsDto.AuthDate,
"uscc": paramsDto.EntCode,
"authAuthorizeFileCode": paramsDto.AuthAuthorizeFileCode,
}
// 调用行为数据API使用指定的project_id
projectID := "CDJ-1068350101956521984"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
// 查空情况,返回特定的查空错误
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
// 数据源错误
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
// 系统错误
return nil, errors.Join(processors.ErrSystem, err)
} else {
// 其他未知错误
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,45 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
)
// ProcessQYGL6F2DRequest QYGL6F2D API处理方法
func ProcessQYGL6F2DRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL6F2DReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
encryptedIDCard, err := deps.WestDexService.Encrypt(paramsDto.IDCard)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"data": map[string]interface{}{
"idno": encryptedIDCard,
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "G05XM02", reqData)
if err != nil {
if errors.Is(err, westdex.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,128 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"strconv"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shujubao"
)
// ProcessQYGL6S1BRequest QYGL6S1B API处理方法 - 董监高司法综合信息核验(使用数据宝服务)
func ProcessQYGL6S1BRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL6S1BReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 构建数据宝入参
reqParams := map[string]interface{}{
"key": "1cce582f0a6f3ca40de80f1bea9b9698",
"idcard": paramsDto.IDCard,
}
// 调用数据宝API
apiPath := "/communication/personal/10166"
data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams)
if err != nil {
if errors.Is(err, shujubao.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
}
if errors.Is(err, shujubao.ErrQueryEmpty) {
return nil, errors.Join(processors.ErrNotFound, err)
}
return nil, errors.Join(processors.ErrSystem, err)
}
// 解析响应中的 JSON 字符串(使用 RecursiveParse
parsedResp, err := RecursiveParse(data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
// 提取 resultData 字段
resultData, ok := parsedResp.(map[string]interface{})
if !ok {
return nil, errors.Join(processors.ErrSystem, errors.New("invalid response format"))
}
resultDataValue, exists := resultData["resultData"]
if !exists {
// 如果 resultData 不存在,说明查询为空,返回空的业务数据结构
emptyResult := map[string]interface{}{
"caseInfoList": []interface{}{},
"legRepInfoList": []interface{}{},
"lossPromiseList": []interface{}{},
"performerList": []interface{}{},
"ryPosPerList": []interface{}{},
"shareholderList": []interface{}{},
}
return json.Marshal(emptyResult)
}
// 转换数据类型:将数字字段转换为字符串
convertedData, err := convertDataTypes(resultDataValue)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
respBytes, err := json.Marshal(convertedData)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}
// convertDataTypes 递归转换数据类型,将数字字段转换为字符串以保持与原有格式一致
func convertDataTypes(data interface{}) (interface{}, error) {
switch v := data.(type) {
case map[string]interface{}:
for key, val := range v {
converted, err := convertDataTypes(val)
if err != nil {
return nil, err
}
v[key] = converted
}
return v, nil
case []interface{}:
for i, item := range v {
converted, err := convertDataTypes(item)
if err != nil {
return nil, err
}
v[i] = converted
}
return v, nil
case float64:
// 将 float64 类型转换为字符串JSON 解析后数字默认为 float64
if v == float64(int64(v)) {
return strconv.FormatInt(int64(v), 10), nil
}
return strconv.FormatFloat(v, 'f', -1, 64), nil
case int:
return strconv.Itoa(v), nil
case int32:
return strconv.FormatInt(int64(v), 10), nil
case int64:
return strconv.FormatInt(v, 10), nil
case string:
// 尝试解析字符串中的 JSON
var parsed interface{}
if err := json.Unmarshal([]byte(v), &parsed); err == nil {
return convertDataTypes(parsed)
}
return v, nil
default:
return v, nil
}
}

View File

@@ -0,0 +1,61 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"fmt"
"strconv"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
)
// ProcessQYGL7C1ARequest QYGL7C1A API处理方法 - 经营异常
func ProcessQYGL7C1ARequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL7C1AReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
fmt.Println("paramsDto", paramsDto)
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 设置默认值
pageSize := paramsDto.PageSize
if pageSize == 0 {
pageSize = int64(20)
}
pageNum := paramsDto.PageNum
if pageNum == 0 {
pageNum = int64(1)
}
// 构建API调用参数
apiParams := map[string]string{
"keyword": paramsDto.EntCode,
"pageSize": strconv.FormatInt(pageSize, 10),
"pageNum": strconv.FormatInt(pageNum, 10),
}
// 调用天眼查API - 经营异常
response, err := deps.TianYanChaService.CallAPI(ctx, "AbnormalInfo", apiParams)
if err != nil {
return nil, convertTianYanChaError(err)
}
// 检查天眼查API调用是否成功
if !response.Success {
return nil, errors.Join(processors.ErrDatasource, errors.New(response.Message))
}
// 返回天眼查响应数据
respBytes, err := json.Marshal(response.Data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,59 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"strconv"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
)
// ProcessQYGL7D9ARequest QYGL7D9A API处理方法 - 欠税公告
func ProcessQYGL7D9ARequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL5A3CReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 设置默认值
pageSize := paramsDto.PageSize
if pageSize == 0 {
pageSize = int64(20)
}
pageNum := paramsDto.PageNum
if pageNum == 0 {
pageNum = int64(1)
}
// 构建API调用参数
apiParams := map[string]string{
"keyword": paramsDto.EntCode,
"pageSize": strconv.FormatInt(pageSize, 10),
"pageNum": strconv.FormatInt(pageNum, 10),
}
// 调用天眼查API - 欠税公告
response, err := deps.TianYanChaService.CallAPI(ctx, "OwnTax", apiParams)
if err != nil {
return nil, convertTianYanChaError(err)
}
// 检查天眼查API调用是否成功
if !response.Success {
return nil, errors.Join(processors.ErrDatasource, errors.New(response.Message))
}
// 返回天眼查响应数据
respBytes, err := json.Marshal(response.Data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,45 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
)
// ProcessQYGL8261Request QYGL8261 API处理方法
func ProcessQYGL8261Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL8261Req
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
encryptedEntName, err := deps.WestDexService.Encrypt(paramsDto.EntName)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"data": map[string]interface{}{
"ent_name": encryptedEntName,
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "Q03BJ03", reqData)
if err != nil {
if errors.Is(err, westdex.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else {
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,90 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"fmt"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
"github.com/tidwall/gjson"
)
// ProcessQYGL8271Request QYGL8271 API处理方法
func ProcessQYGL8271Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL8271Req
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
encryptedEntName, err := deps.WestDexService.Encrypt(paramsDto.EntName)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
encryptedEntCode, err := deps.WestDexService.Encrypt(paramsDto.EntCode)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if deps.CallContext.ContractCode == "" {
return nil, fmt.Errorf("%s: %w", processors.ErrSystem, errors.New("合同编号不能为空"))
}
encryptedAuthAuthorizeFileCode, err := deps.WestDexService.Encrypt(deps.CallContext.ContractCode)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
reqData := map[string]interface{}{
"data": map[string]interface{}{
"org_name": encryptedEntName,
"uscc": encryptedEntCode,
"auth_authorizeFileCode": encryptedAuthAuthorizeFileCode,
"inquired_auth": fmt.Sprintf("authed:%s", paramsDto.AuthDate),
},
}
respBytes, err := deps.WestDexService.CallAPI(ctx, "Q03SC01", reqData)
if err != nil {
// 数据源错误
if errors.Is(err, westdex.ErrDatasource) {
// 如果有返回内容,优先解析返回内容
if respBytes != nil {
parsed, parseErr := ParseJsonResponse(respBytes)
if parseErr == nil {
// 通过gjson获取指定路径的数据
contentResult := gjson.GetBytes(parsed, "Q03SC0101.Q03SC0102.content")
if contentResult.Exists() {
return []byte(contentResult.Raw), errors.Join(processors.ErrDatasource, err)
}
return parsed, errors.Join(processors.ErrDatasource, err)
}
// 解析失败,返回原始内容和系统错误
return respBytes, fmt.Errorf("%s: %w", processors.ErrSystem, parseErr)
}
// 没有返回内容,直接返回数据源错误
return nil, errors.Join(processors.ErrDatasource, err)
}
// 其他系统错误
return nil, errors.Join(processors.ErrSystem, err)
}
// 正常返回 - 不管有没有deps.Options.Json都进行ParseJsonResponse
parsed, parseErr := ParseJsonResponse(respBytes)
if parseErr != nil {
return nil, fmt.Errorf("%s: %w", processors.ErrSystem, parseErr)
}
// 通过gjson获取指定路径的数据
contentResult := gjson.GetBytes(parsed, "Q03SC0101.Q03SC0102.content")
if contentResult.Exists() {
return []byte(contentResult.Raw), nil
} else {
return nil, errors.Join(processors.ErrDatasource, err)
}
}

View File

@@ -0,0 +1,68 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shujubao"
)
// ProcessQYGL8848Request QYGL8848 企业税收违法核查 API 处理方法(使用数据宝服务示例)
func ProcessQYGL8848Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGLDJ12Req
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 企业名称(entName)、统一社会信用代码(creditCode)、企业注册号(entRegNo) 至少传其一;多填时优先用 creditCode 传参
hasEntName := paramsDto.EntName != ""
hasEntCode := paramsDto.EntCode != ""
hasEntRegNo := paramsDto.EntRegNo != ""
if !hasEntName && !hasEntCode && !hasEntRegNo { // 三个都未填才报错
return nil, errors.Join(processors.ErrInvalidParam, errors.New("ent_name、ent_code、ent_reg_no 至少需要传其中一个"))
}
// 构建数据宝入参(多填时优先取 creditCode
reqParams := map[string]interface{}{
"key": "c67673dd2e92deb2d2ec91b87bb0a81c",
}
if hasEntCode {
reqParams["creditCode"] = paramsDto.EntCode
} else if hasEntName {
reqParams["entName"] = paramsDto.EntName
} else if hasEntRegNo {
reqParams["regCode"] = paramsDto.EntRegNo
}
// 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197
apiPath := "/communication/personal/10233"
data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams)
if err != nil {
if errors.Is(err, shujubao.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
}
if errors.Is(err, shujubao.ErrQueryEmpty) {
return nil, errors.Join(processors.ErrNotFound, err)
}
return nil, errors.Join(processors.ErrSystem, err)
}
// 解析响应中的 JSON 字符串(使用 qyglb4c0 中的 RecursiveParse
parsedResp, err := RecursiveParse(data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
respBytes, err := json.Marshal(parsedResp)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,59 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"strconv"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
)
// ProcessQYGL8B4DRequest QYGL8B4D API处理方法 - 融资历史
func ProcessQYGL8B4DRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL8B4DReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 设置默认值
pageSize := paramsDto.PageSize
if pageSize == 0 {
pageSize = int64(20)
}
pageNum := paramsDto.PageNum
if pageNum == 0 {
pageNum = int64(1)
}
// 构建API调用参数
apiParams := map[string]string{
"keyword": paramsDto.EntCode,
"pageSize": strconv.FormatInt(pageSize, 10),
"pageNum": strconv.FormatInt(pageNum, 10),
}
// 调用天眼查API - 融资历史
response, err := deps.TianYanChaService.CallAPI(ctx, "FinancingHistory", apiParams)
if err != nil {
return nil, convertTianYanChaError(err)
}
// 检查天眼查API调用是否成功
if !response.Success {
return nil, errors.Join(processors.ErrDatasource, errors.New(response.Message))
}
// 返回天眼查响应数据
respBytes, err := json.Marshal(response.Data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,59 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"strconv"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
)
// ProcessQYGL9E2FRequest QYGL9E2F API处理方法 - 行政处罚
func ProcessQYGL9E2FRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL9E2FReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 设置默认值
pageSize := paramsDto.PageSize
if pageSize == 0 {
pageSize = int64(20)
}
pageNum := paramsDto.PageNum
if pageNum == 0 {
pageNum = int64(1)
}
// 构建API调用参数
apiParams := map[string]string{
"keyword": paramsDto.EntCode,
"pageSize": strconv.FormatInt(pageSize, 10),
"pageNum": strconv.FormatInt(pageNum, 10),
}
// 调用天眼查API - 行政处罚
response, err := deps.TianYanChaService.CallAPI(ctx, "PunishmentInfo", apiParams)
if err != nil {
return nil, convertTianYanChaError(err)
}
// 检查天眼查API调用是否成功
if !response.Success {
return nil, errors.Join(processors.ErrDatasource, errors.New(response.Message))
}
// 返回天眼查响应数据
respBytes, err := json.Marshal(response.Data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,55 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/xingwei"
)
// Processqygl9t1qRequest QYGL9T1Q API处理方法 - 全国企业借贷意向验证查询_V1
func ProcessQYGL9T1QRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGL9T1QReq
if err := json.Unmarshal(params, &paramsDto); 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{}{
"ownerType": paramsDto.OwnerType,
"phoneNumber": paramsDto.MobileNo,
"idCardNum": paramsDto.IDCard,
"name": paramsDto.Name,
"searchKey": paramsDto.EntCode, // 企业统一信用代码和注册号两者必填其一
"authAuthorizeFileCode": paramsDto.Authorized,
}
// 调用行为数据API使用指定的project_id
projectID := "CDJ-1078965351139438592"
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
if err != nil {
if errors.Is(err, xingwei.ErrNotFound) {
// 查空情况,返回特定的查空错误
return nil, errors.Join(processors.ErrNotFound, err)
} else if errors.Is(err, xingwei.ErrDatasource) {
// 数据源错误
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, xingwei.ErrSystem) {
// 系统错误
return nil, errors.Join(processors.ErrSystem, err)
} else {
// 其他未知错误
return nil, errors.Join(processors.ErrSystem, err)
}
}
return respBytes, nil
}

View File

@@ -0,0 +1,105 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/westdex"
"github.com/tidwall/gjson"
)
// ProcessQYGLB4C0Request QYGLB4C0 API处理方法
func ProcessQYGLB4C0Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGLB4C0Req
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
encryptedIDCard := deps.WestDexService.Md5Encrypt(paramsDto.IDCard)
reqData := map[string]interface{}{
"pid": encryptedIDCard,
}
respBytes, err := deps.WestDexService.G05HZ01CallAPI(ctx, "G05HZ01", reqData)
if err != nil {
// 数据源错误
if errors.Is(err, westdex.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
} else if errors.Is(err, westdex.ErrNotFound) {
return nil, errors.Join(processors.ErrNotFound, err)
}
// 其他系统错误
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}
// ParseWestResponse 解析西部返回的响应数据获取data字段后解析
// westResp: 西部返回的原始响应
// Returns: 解析后的数据字节数组
func ParseWestResponse(westResp []byte) ([]byte, error) {
dataResult := gjson.GetBytes(westResp, "data")
if !dataResult.Exists() {
return nil, errors.New("data not found")
}
return ParseJsonResponse([]byte(dataResult.Raw))
}
// ParseJsonResponse 直接解析JSON响应数据
// jsonResp: JSON响应数据
// Returns: 解析后的数据字节数组
func ParseJsonResponse(jsonResp []byte) ([]byte, error) {
parseResult, err := RecursiveParse(string(jsonResp))
if err != nil {
return nil, err
}
resultResp, marshalErr := json.Marshal(parseResult)
if marshalErr != nil {
return nil, err
}
return resultResp, nil
}
// RecursiveParse 递归解析JSON数据
func RecursiveParse(data interface{}) (interface{}, error) {
switch v := data.(type) {
case string:
var parsed interface{}
if err := json.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
}
}

View File

@@ -0,0 +1,67 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shujubao"
)
// ProcessQYGLDJ12Request QYGLDJ12 企业年报信息核验 API 处理方法(使用数据宝服务示例)
func ProcessQYGLDJ12Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGLDJ12Req
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 企业名称(entName)、统一社会信用代码(creditCode)、企业注册号(entRegNo) 至少传其一;多填时优先用 creditCode 传参
hasEntName := paramsDto.EntName != ""
hasEntCode := paramsDto.EntCode != ""
hasEntRegNo := paramsDto.EntRegNo != ""
if !hasEntName && !hasEntCode && !hasEntRegNo { // 三个都未填才报错
return nil, errors.Join(processors.ErrInvalidParam, errors.New("ent_name、ent_code、ent_reg_no 至少需要传其中一个"))
}
// 构建数据宝入参sign 外的业务参数可按需 AES 加密后作为 bodyData
reqParams := map[string]interface{}{
"key": "112813815e2cc281ad8f552deb7a3c7f",
}
if hasEntCode {
reqParams["creditCode"] = paramsDto.EntCode
} else if hasEntName {
reqParams["entName"] = paramsDto.EntName
} else if hasEntRegNo {
reqParams["regCode"] = paramsDto.EntRegNo
}
// 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197
apiPath := "/communication/personal/10192"
data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams)
if err != nil {
if errors.Is(err, shujubao.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
}
if errors.Is(err, shujubao.ErrQueryEmpty) {
return nil, errors.Join(processors.ErrNotFound, err)
}
return nil, errors.Join(processors.ErrSystem, err)
}
// 解析响应中的 JSON 字符串(使用 qyglb4c0 中的 RecursiveParse
parsedResp, err := RecursiveParse(data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
respBytes, err := json.Marshal(parsedResp)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,65 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shujubao"
)
// ProcessQYGLJ0Q1Request QYGLJ0Q1 企业股权结构全景查询 API 处理方法(使用数据宝服务示例)
func ProcessQYGLJ0Q1Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGLJ0Q1Req
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 二选一:企业名称(entName) 与 统一社会信用代码(creditCode) 必须且仅能传其一
hasEntName := paramsDto.EntName != ""
hasEntCode := paramsDto.EntCode != ""
if hasEntName == hasEntCode { // 两个都填或两个都未填
return nil, errors.Join(processors.ErrInvalidParam, errors.New("ent_name 与 ent_code 二选一,必须且仅能传其中一个"))
}
// 构建数据宝入参sign 外的业务参数可按需 AES 加密后作为 bodyData
reqParams := map[string]interface{}{
"key": "adac456f7b4ced764b606c8b07fed4d3",
}
if hasEntName {
reqParams["entName"] = paramsDto.EntName
} else {
reqParams["creditCode"] = paramsDto.EntCode
}
// 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197
apiPath := "/communication/personal/10216"
data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams)
if err != nil {
if errors.Is(err, shujubao.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
}
if errors.Is(err, shujubao.ErrQueryEmpty) {
return nil, errors.Join(processors.ErrNotFound, err)
}
return nil, errors.Join(processors.ErrSystem, err)
}
// 解析响应中的 JSON 字符串(使用 qyglb4c0 中的 RecursiveParse
parsedResp, err := RecursiveParse(data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
respBytes, err := json.Marshal(parsedResp)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,231 @@
package qygl
import (
"context"
"crypto/rand"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"net/url"
"strings"
"sync"
"time"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/entities"
"hyapi-server/internal/domains/api/services/processors"
)
// ProcessQYGLJ1U9Request 企业全景报告处理器:并发调用企业全量(QYGLUY3S)、股权全景(QYGLJ0Q1)、司法涉诉(QYGL5S1I)、
// 企业年报(QYGLDJ12)、税收违法(QYGL8848)、欠税公告(QYGL7D9A)。
// 单路失败、查无、解析失败时该路按空数据处理并继续合并;仅当合并后的报告仍无任何可展示的企业要素时返回查询为空。
func ProcessQYGLJ1U9Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
// 复用 QYGLUY3S 的入参结构:企业名称/注册号/统一社会信用代码
var p dto.QYGLJ1U9Req
if err := json.Unmarshal(params, &p); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(p); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 并发调用六个子处理器;单路失败或无数据时降级为空结果,仅当合并后仍无任何企业要素时返回查询为空
type apiResult struct {
key string
data map[string]interface{}
err error
}
resultsCh := make(chan apiResult, 6)
var wg sync.WaitGroup
call := func(key string, req interface{}, fn func(context.Context, []byte, *processors.ProcessorDependencies) ([]byte, error)) {
wg.Add(1)
go func() {
defer wg.Done()
b, err := json.Marshal(req)
if err != nil {
resultsCh <- apiResult{key: key, err: err}
return
}
resp, err := fn(ctx, b, deps)
if err != nil {
resultsCh <- apiResult{key: key, err: err}
return
}
var m map[string]interface{}
var uerr error
// 根节点可能是数组或非对象,与欠税接口一致用宽松解析
if key == "taxArrears" || key == "annualReport" || key == "taxViolation" {
m, uerr = unmarshalToReportMap(resp)
} else {
uerr = json.Unmarshal(resp, &m)
}
if uerr != nil {
resultsCh <- apiResult{key: key, err: uerr}
return
}
resultsCh <- apiResult{key: key, data: m}
}()
}
// 企业全量信息核验V2QYGLUY3S
call("jiguangFull", map[string]interface{}{
"ent_name": p.EntName,
"ent_code": p.EntCode,
}, ProcessQYGLUY3SRequest)
// 企业股权结构全景QYGLJ0Q1
call("equityPanorama", map[string]interface{}{
"ent_name": p.EntName,
}, ProcessQYGLJ0Q1Request)
// 企业司法涉诉V2QYGL5S1I
call("judicialCertFull", map[string]interface{}{
"ent_name": p.EntName,
"ent_code": p.EntCode,
}, ProcessQYGL5S1IRequest)
// 企业年报信息核验QYGLDJ12
call("annualReport", map[string]interface{}{
"ent_name": p.EntName,
"ent_code": p.EntCode,
}, ProcessQYGLDJ12Request)
// 企业税收违法核查QYGL8848
call("taxViolation", map[string]interface{}{
"ent_name": p.EntName,
"ent_code": p.EntCode,
}, ProcessQYGL8848Request)
// 欠税公告QYGL7D9A天眼查 OwnTaxkeyword 为统一社会信用代码)
call("taxArrears", map[string]interface{}{
"ent_code": p.EntCode,
"page_size": 20,
"page_num": 1,
}, ProcessQYGL7D9ARequest)
wg.Wait()
close(resultsCh)
jiguang := map[string]interface{}{}
judicial := map[string]interface{}{}
equity := map[string]interface{}{}
annualReport := map[string]interface{}{}
taxViolation := map[string]interface{}{}
taxArrears := map[string]interface{}{}
for r := range resultsCh {
if r.err != nil || r.data == nil {
continue
}
switch r.key {
case "jiguangFull":
jiguang = r.data
case "judicialCertFull":
judicial = r.data
case "equityPanorama":
equity = r.data
case "annualReport":
annualReport = r.data
case "taxViolation":
taxViolation = r.data
case "taxArrears":
taxArrears = r.data
}
}
// 复用构建逻辑生成企业报告结构(含年报 / 税收违法 / 欠税公告的转化结果)
report := buildReport(jiguang, judicial, equity, annualReport, taxViolation, taxArrears)
if !qyglJ1U9ReportHasSubstantiveData(report) {
return nil, errors.Join(processors.ErrNotFound, errors.New("未查询到可用于生成报告的企业数据"))
}
// 为报告生成唯一编号并缓存,供后续通过编号查看
reportID := saveQYGLReport(report)
report["reportId"] = reportID
// 异步预生成 PDF写入磁盘缓存用户点击「保存为 PDF」时可直读缓存
if deps.ReportPDFScheduler != nil {
deps.ReportPDFScheduler.ScheduleQYGLReportPDF(context.Background(), reportID)
}
// 持久化企业报告记录到数据库(忽略持久化失败,不影响接口主流程)
if deps.ReportRepo != nil {
reqJSON, _ := json.Marshal(p)
reportJSON, _ := json.Marshal(report)
_ = deps.ReportRepo.Create(ctx, &entities.Report{
ReportID: reportID,
Type: "enterprise",
ApiCode: "QYGLJ1U9",
EntName: p.EntName,
EntCode: p.EntCode,
RequestParams: string(reqJSON),
ReportData: string(reportJSON),
})
}
// 为报告补充前端查看链接,供调用方直接跳转到企业报告页面(通过编号访问)
report["reportUrl"] = buildQYGLReportURLByID(deps.APIPublicBaseURL, reportID)
out, err := json.Marshal(report)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return out, nil
}
// unmarshalToReportMap 将 JSON 解析为报告用 map根节点非对象时包在 data 下(兼容欠税等接口根为数组的情况)。
func unmarshalToReportMap(b []byte) (map[string]interface{}, error) {
var raw interface{}
if err := json.Unmarshal(b, &raw); err != nil {
return nil, err
}
if m, ok := raw.(map[string]interface{}); ok {
return m, nil
}
return map[string]interface{}{"data": raw}, nil
}
// 内存中的企业报告缓存(简单实现,进程重启后清空)
var qyglReportStore = struct {
sync.RWMutex
data map[string]map[string]interface{}
}{
data: make(map[string]map[string]interface{}),
}
// saveQYGLReport 保存报告并返回生成的编号
func saveQYGLReport(report map[string]interface{}) string {
id := generateQYGLReportID()
qyglReportStore.Lock()
qyglReportStore.data[id] = report
qyglReportStore.Unlock()
return id
}
// GetQYGLReport 根据编号获取报告(供页面渲染使用)
func GetQYGLReport(id string) (map[string]interface{}, bool) {
qyglReportStore.RLock()
defer qyglReportStore.RUnlock()
r, ok := qyglReportStore.data[id]
return r, ok
}
// generateQYGLReportID 生成短编号
func generateQYGLReportID() string {
b := make([]byte, 8)
if _, err := rand.Read(b); err == nil {
return hex.EncodeToString(b)
}
// 随机数失败时退化为时间戳
return fmt.Sprintf("%d", time.Now().UnixNano())
}
// buildQYGLReportURLByID 构造企业报告前端查看链接(通过编号查看)。
// publicBase 为对外 API 基址(如 https://api.example.com空则返回站内相对路径。
func buildQYGLReportURLByID(publicBase, id string) string {
path := "/reports/qygl/" + url.PathEscape(id)
if publicBase == "" {
return path
}
return strings.TrimRight(publicBase, "/") + path
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
package qygl
import (
"testing"
"hyapi-server/internal/domains/api/dto"
sharedvalidator "hyapi-server/internal/shared/validator"
)
// TestQYGLJ1U9Req_ValidateParams 仅验证 QYGLJ1U9 入参的校验规则(特别是 validUSCI
func TestQYGLJ1U9Req_ValidateParams(t *testing.T) {
// 使用全局业务校验器
bv := sharedvalidator.NewBusinessValidator()
t.Run("invalid_usci_should_fail", func(t *testing.T) {
req := dto.QYGLJ1U9Req{
EntName: "测试企业有限公司",
EntCode: "123", // 明显不符合 validUSCI
}
if err := bv.ValidateStruct(req); err == nil {
t.Fatalf("expected validation error for invalid ent_code, got nil")
}
})
t.Run("valid_usci_should_pass", func(t *testing.T) {
req := dto.QYGLJ1U9Req{
EntName: "杭州娃哈哈集团有限公司",
EntCode: "91330000142916567N", // 符合 validUSCI 正则的示例
}
if err := bv.ValidateStruct(req); err != nil {
t.Fatalf("expected no validation error for valid ent_code, got: %v", err)
}
})
}

View File

@@ -0,0 +1,46 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
)
// ProcessQYGLNIO8Request QYGLNIO8 API处理方法 - 企业基本信息
func ProcessQYGLNIO8Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGLNIO8Req
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 构建API调用参数
apiParams := map[string]string{
"keyword": paramsDto.EntCode,
}
// 调用天眼查API - 企业基本信息
response, err := deps.TianYanChaService.CallAPI(ctx, "baseinfo", apiParams)
if err != nil {
return nil, convertTianYanChaError(err)
}
// 检查天眼查API调用是否成功
if !response.Success {
return nil, errors.Join(processors.ErrDatasource, errors.New(response.Message))
}
// 返回天眼查响应数据
respBytes, err := json.Marshal(response.Data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,68 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
)
// ProcessQYGLP0HTRequest QYGLP0HT API处理方法 - 股权穿透
func ProcessQYGLP0HTRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGLP0HTReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 设置默认值
flag := paramsDto.Flag
if flag == "" {
flag = "4"
}
dir := paramsDto.Dir
if dir == "" {
dir = "down"
}
minPercent := paramsDto.MinPercent
if minPercent == "" {
minPercent = "0"
}
maxPercent := paramsDto.MaxPercent
if maxPercent == "" {
maxPercent = "1"
}
// 构建API调用参数
apiParams := map[string]string{
"keyword": paramsDto.EntCode,
"flag": flag,
"dir": dir,
"minPercent": minPercent,
"maxPercent": maxPercent,
}
// 调用天眼查API - 企股权穿透
response, err := deps.TianYanChaService.CallAPI(ctx, "investtree", apiParams)
if err != nil {
return nil, convertTianYanChaError(err)
}
// 检查天眼查API调用是否成功
if !response.Success {
return nil, errors.Join(processors.ErrDatasource, errors.New(response.Message))
}
// 返回天眼查响应数据
respBytes, err := json.Marshal(response.Data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,56 @@
package qygl
import (
"context"
"encoding/json"
"errors"
"hyapi-server/internal/domains/api/dto"
"hyapi-server/internal/domains/api/services/processors"
"hyapi-server/internal/infrastructure/external/shujubao"
)
// ProcessQYGLUY3SRequest QYGLUY3S 企业全量信息核验V2 可用 API 处理方法(使用数据宝服务示例)
func ProcessQYGLUY3SRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
var paramsDto dto.QYGLUY3SReq
if err := json.Unmarshal(params, &paramsDto); err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err)
}
// 构建数据宝入参姓名、身份证、手机号、银行卡号sign 外的业务参数可按需 AES 加密后作为 bodyData
reqParams := map[string]interface{}{
"key": "5131227a847c06c111f624a22ebacc06",
"entName": paramsDto.EntName,
"regno": paramsDto.EntRegno,
"creditcode": paramsDto.EntCode,
}
// 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197
apiPath := "/communication/personal/10195"
data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams)
if err != nil {
if errors.Is(err, shujubao.ErrDatasource) {
return nil, errors.Join(processors.ErrDatasource, err)
}
if errors.Is(err, shujubao.ErrQueryEmpty) {
return nil, errors.Join(processors.ErrNotFound, err)
}
return nil, errors.Join(processors.ErrSystem, err)
}
// 解析响应中的 JSON 字符串(使用 qyglb4c0 中的 RecursiveParse
parsedResp, err := RecursiveParse(data)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
respBytes, err := json.Marshal(parsedResp)
if err != nil {
return nil, errors.Join(processors.ErrSystem, err)
}
return respBytes, nil
}

View File

@@ -0,0 +1,12 @@
package qygl
import "encoding/json"
// createStatusResponse 创建状态响应
func createStatusResponse(status int) []byte {
response := map[string]interface{}{
"status": status,
}
respBytes, _ := json.Marshal(response)
return respBytes
}