f
This commit is contained in:
@@ -682,6 +682,8 @@ type HuiboConfig struct {
|
||||
AESKey string `mapstructure:"aes_key"`
|
||||
WorkOrderCode string `mapstructure:"work_order_code"`
|
||||
ProductCode string `mapstructure:"product_code"`
|
||||
BaseURL2 string `mapstructure:"baseUrl2"`
|
||||
AppCode2 string `mapstructure:"app_code2"`
|
||||
|
||||
Logging HuiboLoggingConfig `mapstructure:"logging"`
|
||||
}
|
||||
|
||||
@@ -534,6 +534,12 @@ type IVYZ4Y27Req struct {
|
||||
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||
AuthAuthorizeFileBase64 string `json:"auth_authorize_file_base64" validate:"required,validBase64PDF"`
|
||||
}
|
||||
|
||||
type FLXGHB4FReq struct {
|
||||
Name string `json:"name" validate:"required,min=1,validName"`
|
||||
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||
}
|
||||
|
||||
type IVYZP2Q6Req struct {
|
||||
Name string `json:"name" validate:"required,min=1,validName"`
|
||||
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||
@@ -572,6 +578,10 @@ type QYGL5A3CReq struct {
|
||||
PageNum int64 `json:"page_num" validate:"omitempty,min=1"`
|
||||
}
|
||||
|
||||
type QYGLBH7YReq struct {
|
||||
EntName string `json:"ent_name" validate:"omitempty,min=1,validEnterpriseName"`
|
||||
}
|
||||
|
||||
type QYGL2naoReq struct {
|
||||
EntCode string `json:"ent_code" validate:"required,validUSCI"`
|
||||
PageSize int64 `json:"page_size" validate:"omitempty,min=1,max=100"`
|
||||
|
||||
@@ -186,6 +186,7 @@ func registerAllProcessors(combService *comb.CombService) {
|
||||
"FLXG3A9B": flxg.ProcessFLXG3A9BRequest,
|
||||
"FLXGK5D2": flxg.ProcessFLXGK5D2Request,
|
||||
"FLXGDJG3": flxg.ProcessFLXGDJG3Request, //董监高司法综合信息核验
|
||||
"FLXGHB4F": flxg.ProcessFLXGHB4FRequest, //个人涉诉案件查询汇博
|
||||
// JRZQ系列处理器
|
||||
"JRZQ8203": jrzq.ProcessJRZQ8203Request,
|
||||
"JRZQ0A03": jrzq.ProcessJRZQ0A03Request,
|
||||
@@ -254,6 +255,7 @@ func registerAllProcessors(combService *comb.CombService) {
|
||||
"QYGLDJ12": qygl.ProcessQYGLDJ12Request, //企业年报信息核验
|
||||
"QYGL8848": qygl.ProcessQYGL8848Request, //企业税收违法核查
|
||||
"QYGLDJ33": qygl.ProcessQYGLDJ33Request, //企业年报信息核验
|
||||
"QYGLBH7Y": qygl.ProcessQYGLBH7YRequest, //企业涉诉案件查询汇博
|
||||
|
||||
// YYSY系列处理器
|
||||
"YYSY35TA": yysy.ProcessYYSY35TARequest, //运营商归属地数卖
|
||||
|
||||
@@ -281,6 +281,8 @@ func (s *FormConfigServiceImpl) getDTOStruct(ctx context.Context, apiCode string
|
||||
"IVYZRAX1": &dto.IVYZRAX1Req{}, //融安信用分
|
||||
"IVYZRAX2": &dto.IVYZRAX1Req{}, //融御反欺诈
|
||||
"IVYZ2MN7": &dto.IVYZ2MN6Req{}, //学历Bzhicha
|
||||
"FLXGHB4F": &dto.FLXGHB4FReq{}, //个人涉诉案件查询汇博
|
||||
"QYGLBH7Y": &dto.QYGLBH7YReq{}, //企业涉诉案件查询汇博
|
||||
}
|
||||
|
||||
// 优先返回已配置的DTO
|
||||
|
||||
@@ -25,7 +25,7 @@ func ProcessFLXG0V4BRequest(ctx context.Context, params []byte, deps *processors
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
// 去掉司法案件案件去掉身份证号码
|
||||
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" {
|
||||
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" || paramsDto.IDCard == "420116198907031413" {
|
||||
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
|
||||
}
|
||||
encryptedName, err := deps.WestDexService.Encrypt(paramsDto.Name)
|
||||
|
||||
@@ -20,7 +20,7 @@ func ProcessFLXG5A3BRequest(ctx context.Context, params []byte, deps *processors
|
||||
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" {
|
||||
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" || paramsDto.IDCard == "420116198907031413" {
|
||||
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ func ProcessFLXG7E8FRequest(ctx context.Context, params []byte, deps *processors
|
||||
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" {
|
||||
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" || paramsDto.IDCard == "420116198907031413" {
|
||||
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ func ProcessFLXGCA3DRequest(ctx context.Context, params []byte, deps *processors
|
||||
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" {
|
||||
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" || paramsDto.IDCard == "420116198907031413" {
|
||||
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
|
||||
}
|
||||
encryptedName, err := deps.WestDexService.Encrypt(paramsDto.Name)
|
||||
|
||||
@@ -21,7 +21,7 @@ func ProcessFLXGDEA8Request(ctx context.Context, params []byte, deps *processors
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
// 去掉司法案件案件去掉身份证号码
|
||||
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" {
|
||||
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" || paramsDto.IDCard == "420116198907031413" {
|
||||
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ func ProcessFLXGDEA9Request(ctx context.Context, params []byte, deps *processors
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" {
|
||||
if paramsDto.IDCard == "350681198611130611" || paramsDto.IDCard == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" || paramsDto.IDCard == "431027198810290730" || paramsDto.IDCard == "362502199510298017" || paramsDto.IDCard == "340826199008250378" || paramsDto.IDCard == "321027198304072129" || paramsDto.IDCard == "420116198907031413" {
|
||||
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
|
||||
}
|
||||
encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard)
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package flxg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"tyapi-server/internal/domains/api/dto"
|
||||
"tyapi-server/internal/domains/api/services/processors"
|
||||
"tyapi-server/internal/infrastructure/external/huibo"
|
||||
)
|
||||
|
||||
// ProcessFLXGHB4FRequest FLXGHB4F API处理方法 - 个人涉诉案件查询汇博
|
||||
func ProcessFLXGHB4FRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.FLXGHB4FReq
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
if deps.HuiboService == nil {
|
||||
return nil, errors.Join(processors.ErrSystem, errors.New("汇博服务未初始化"))
|
||||
}
|
||||
|
||||
// 使用 MD5 加密 name 和 idCard
|
||||
encryptedName := "MD5:" + huibo.MD5Encrypt(paramsDto.Name, deps.HuiboService.GetConfig().AppKey)
|
||||
encryptedIDCard := "MD5:" + huibo.MD5Encrypt(paramsDto.IDCard, deps.HuiboService.GetConfig().AppKey)
|
||||
|
||||
reqdata := map[string]interface{}{
|
||||
"name": encryptedName,
|
||||
"idCard": encryptedIDCard,
|
||||
}
|
||||
|
||||
respBytes, err := deps.HuiboService.CallAPI2(ctx, "P_004_0271", reqdata)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
}
|
||||
|
||||
// 解析响应
|
||||
var response huibo.CallAPI2Response
|
||||
if err := json.Unmarshal(respBytes, &response); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
// 处理状态码
|
||||
switch response.Code {
|
||||
case huibo.CallAPI2StatusSuccess:
|
||||
// 查询成功
|
||||
if response.Data == nil {
|
||||
return []byte("{}"), nil
|
||||
}
|
||||
return respBytes, nil
|
||||
case huibo.CallAPI2StatusNoData:
|
||||
// 查询成功,无数据 - 按产品约定按调用成功计费
|
||||
return []byte("{}"), nil
|
||||
default:
|
||||
// 其他错误状态码
|
||||
message := huibo.GetCallAPI2StatusMessage(response.Code)
|
||||
return nil, errors.Join(processors.ErrDatasource, errors.New(message))
|
||||
}
|
||||
}
|
||||
@@ -37,9 +37,9 @@ func ProcessJRZQ2F8ARequest(ctx context.Context, params []byte, deps *processors
|
||||
}
|
||||
|
||||
reqData := map[string]interface{}{
|
||||
"name": encryptedName,
|
||||
"idCard": encryptedIDCard,
|
||||
"phone": encryptedMobileNo,
|
||||
"name": encryptedName,
|
||||
"idCard": encryptedIDCard,
|
||||
"phone": encryptedMobileNo,
|
||||
"authorized": paramsDto.Authorized,
|
||||
}
|
||||
|
||||
@@ -60,4 +60,3 @@ func ProcessJRZQ2F8ARequest(ctx context.Context, params []byte, deps *processors
|
||||
|
||||
return respBytes, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package qygl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"tyapi-server/internal/domains/api/dto"
|
||||
"tyapi-server/internal/domains/api/services/processors"
|
||||
"tyapi-server/internal/infrastructure/external/huibo"
|
||||
)
|
||||
|
||||
// ProcessQYGLBH7YRequest QYGLBH7Y API处理方法 - 个人涉诉案件查询汇博
|
||||
func ProcessQYGLBH7YRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.QYGLBH7YReq
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
if deps.HuiboService == nil {
|
||||
return nil, errors.Join(processors.ErrSystem, errors.New("汇博服务未初始化"))
|
||||
}
|
||||
|
||||
reqdata := map[string]interface{}{
|
||||
"name": paramsDto.EntName,
|
||||
}
|
||||
|
||||
respBytes, err := deps.HuiboService.CallAPI2(ctx, "E_004_0261", reqdata)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
}
|
||||
|
||||
// 解析响应
|
||||
var response huibo.CallAPI2Response
|
||||
if err := json.Unmarshal(respBytes, &response); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
// 处理状态码
|
||||
switch response.Code {
|
||||
case huibo.CallAPI2StatusSuccess:
|
||||
// 查询成功
|
||||
if response.Data == nil {
|
||||
return []byte("{}"), nil
|
||||
}
|
||||
return respBytes, nil
|
||||
case huibo.CallAPI2StatusNoData:
|
||||
// 查询成功,无数据 - 按产品约定按调用成功计费
|
||||
return []byte("{}"), nil
|
||||
default:
|
||||
// 其他错误状态码
|
||||
message := huibo.GetCallAPI2StatusMessage(response.Code)
|
||||
return nil, errors.Join(processors.ErrDatasource, errors.New(message))
|
||||
}
|
||||
}
|
||||
90
internal/infrastructure/external/huibo/2.md
vendored
Normal file
90
internal/infrastructure/external/huibo/2.md
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
自然人公开涉诉信息查询接口文档
|
||||
接口编码:BHSC-P_004_0271
|
||||
版本:V1.0
|
||||
实施日期:2026-04-13
|
||||
适用场景:合作厂家接入中胜信用平台,用于个人涉诉案件查询(含失信、限高)
|
||||
1. 通信说明
|
||||
请求方式:HTTP POST
|
||||
数据格式:JSON
|
||||
编码格式:UTF-8
|
||||
安全要求:请求 IP 需提前绑定
|
||||
2. 请求信息
|
||||
请求地址
|
||||
http://host:port/api/data
|
||||
请求头(Header)
|
||||
表格
|
||||
参数名 含义 必填 类型 备注
|
||||
AppCode 接口授权码 Y String 接口服务商提供
|
||||
pcode 产品编码 Y String 固定值:P_004_0271
|
||||
请求体(Body)
|
||||
表格
|
||||
参数名 含义 必填 类型 说明
|
||||
name 姓名 Y String 支持明文 / MD5 加密
|
||||
idCard 身份证号 Y String 支持明文 / MD5 加密
|
||||
请求示例(明文)
|
||||
json
|
||||
{
|
||||
"idCard": "2103111*****0",
|
||||
"name": "*****"
|
||||
}
|
||||
请求示例(加密)
|
||||
json
|
||||
{
|
||||
"name": "MD5:3e29aae20b7b92775*****",
|
||||
"idCard": "MD5:a0c28f3a5a*****14"
|
||||
}
|
||||
3. 响应信息
|
||||
表格
|
||||
字段名 含义 类型 备注
|
||||
code 状态码 String 参考状态码说明
|
||||
message 描述信息 String -
|
||||
orderNo 订单号 String -
|
||||
pcode 产品编码 String 与请求一致
|
||||
param 请求参数 Object 原样返回
|
||||
charge 是否收费 Boolean true = 收费;false = 不收费
|
||||
time 响应时间戳 String 13 位毫秒
|
||||
data 业务数据 Object 涉诉 / 失信 / 限高数据
|
||||
响应示例
|
||||
json
|
||||
{
|
||||
"code": "100",
|
||||
"orderNo": "1361269246899077120",
|
||||
"charge": true,
|
||||
"data": {
|
||||
"ss": {
|
||||
"preservation": { "count": {} },
|
||||
"crc": 35****4186,
|
||||
"cases_tree": {},
|
||||
"administrative": {},
|
||||
"civil": {},
|
||||
"count": {},
|
||||
"implement": {},
|
||||
"criminal": {},
|
||||
"bankrupt": {}
|
||||
},
|
||||
"sxbzxr": [{}],
|
||||
"xgbzxr": []
|
||||
},
|
||||
"pcode": "P_004_0271",
|
||||
"param": null,
|
||||
"time": "1744593480538",
|
||||
"message": "查询成功"
|
||||
}
|
||||
data 节点说明
|
||||
ss:涉诉案件(民事 / 刑事 / 执行 / 行政 / 破产等)
|
||||
sxbzxr:失信被执行人
|
||||
xgbzxr:限制高消费
|
||||
4. 状态码说明
|
||||
表格
|
||||
状态码 描述
|
||||
100 查询成功
|
||||
101 参数错误
|
||||
103 账户不存在
|
||||
104 IP 限制
|
||||
105 账号已过期
|
||||
107 服务不存在
|
||||
108 产品通道已关闭
|
||||
109 账户资金不足
|
||||
110 查询成功,无数据
|
||||
500 未知请求错误
|
||||
要不要我帮你把这份接口直接写成可上线的小程序请求代码(含加密、header、异常捕获、状态码统一处理)?
|
||||
83
internal/infrastructure/external/huibo/crypto.go
vendored
Normal file
83
internal/infrastructure/external/huibo/crypto.go
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
package huibo
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/hmac"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// MD5Encrypt 使用 AppKey 进行 MD5 加密
|
||||
func MD5Encrypt(data, appKey string) string {
|
||||
h := md5.New()
|
||||
h.Write([]byte(data + appKey))
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
// HMACSHA256Base64 使用 HMAC-SHA256 算法生成签名
|
||||
func HMACSHA256Base64(data, secret string) string {
|
||||
m := hmac.New(sha256.New, []byte(secret))
|
||||
_, _ = m.Write([]byte(data))
|
||||
return base64.StdEncoding.EncodeToString(m.Sum(nil))
|
||||
}
|
||||
|
||||
// EncryptAESGCMBase64 使用 AES-GCM 算法加密数据
|
||||
func EncryptAESGCMBase64(plainText, base64Key string) (string, error) {
|
||||
key, err := base64.StdEncoding.DecodeString(base64Key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
gcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
iv := make([]byte, 12)
|
||||
if _, err = io.ReadFull(rand.Reader, iv); err != nil {
|
||||
return "", err
|
||||
}
|
||||
ciphertext := gcm.Seal(nil, iv, []byte(plainText), nil)
|
||||
out := append(iv, ciphertext...)
|
||||
return base64.StdEncoding.EncodeToString(out), nil
|
||||
}
|
||||
|
||||
// DecryptAESGCMBase64 使用 AES-GCM 算法解密数据
|
||||
func DecryptAESGCMBase64(encryptedBase64, base64Key string) (string, error) {
|
||||
key, err := base64.StdEncoding.DecodeString(base64Key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
raw, err := base64.StdEncoding.DecodeString(encryptedBase64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(raw) < 13 {
|
||||
return "", errors.New("密文长度非法")
|
||||
}
|
||||
|
||||
iv := raw[:12]
|
||||
ciphertext := raw[12:]
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
gcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
plain, err := gcm.Open(nil, iv, ciphertext, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(plain), nil
|
||||
}
|
||||
59
internal/infrastructure/external/huibo/curl_helper.go
vendored
Normal file
59
internal/infrastructure/external/huibo/curl_helper.go
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
package huibo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// generateCurlCommand 从 HTTP 请求生成 curl 命令
|
||||
func generateCurlCommand(req *http.Request) string {
|
||||
var cmd strings.Builder
|
||||
cmd.WriteString("curl -X ")
|
||||
cmd.WriteString(req.Method)
|
||||
cmd.WriteString(" '")
|
||||
cmd.WriteString(req.URL.String())
|
||||
cmd.WriteString("'")
|
||||
|
||||
// 添加请求头
|
||||
for key, values := range req.Header {
|
||||
for _, value := range values {
|
||||
cmd.WriteString(" \\\n -H '")
|
||||
cmd.WriteString(key)
|
||||
cmd.WriteString(": ")
|
||||
cmd.WriteString(value)
|
||||
cmd.WriteString("'")
|
||||
}
|
||||
}
|
||||
|
||||
return cmd.String()
|
||||
}
|
||||
|
||||
// generateCurlCommandWithBody 生成包含请求体的 curl 命令
|
||||
func generateCurlCommandWithBody(method, url string, headers map[string]string, body string) string {
|
||||
var cmd strings.Builder
|
||||
cmd.WriteString("curl -X ")
|
||||
cmd.WriteString(method)
|
||||
cmd.WriteString(" '")
|
||||
cmd.WriteString(url)
|
||||
cmd.WriteString("'")
|
||||
|
||||
// 添加请求头
|
||||
for key, value := range headers {
|
||||
cmd.WriteString(" \\\n -H '")
|
||||
cmd.WriteString(key)
|
||||
cmd.WriteString(": ")
|
||||
cmd.WriteString(value)
|
||||
cmd.WriteString("'")
|
||||
}
|
||||
|
||||
// 添加请求体
|
||||
if body != "" {
|
||||
cmd.WriteString(" \\\n -d '")
|
||||
cmd.WriteString(body)
|
||||
cmd.WriteString("'")
|
||||
}
|
||||
|
||||
cmd.WriteString(" \\\n --compressed")
|
||||
|
||||
return cmd.String()
|
||||
}
|
||||
@@ -39,6 +39,8 @@ func NewHuiboServiceWithConfig(cfg *config.Config) (*HuiboService, error) {
|
||||
AESKey: cfg.Huibo.AESKey,
|
||||
WorkOrderCode: cfg.Huibo.WorkOrderCode,
|
||||
ProductCode: cfg.Huibo.ProductCode,
|
||||
BaseURL2: cfg.Huibo.BaseURL2,
|
||||
AppCode2: cfg.Huibo.AppCode2,
|
||||
}, logger)
|
||||
|
||||
return service, nil
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/hmac"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
@@ -85,6 +86,8 @@ type HuiboConfig struct {
|
||||
AESKey string
|
||||
WorkOrderCode string
|
||||
ProductCode string
|
||||
BaseURL2 string // CallAPI2 使用的 URL
|
||||
AppCode2 string // CallAPI2 使用的 AppCode
|
||||
}
|
||||
|
||||
type HuiboService struct {
|
||||
@@ -101,10 +104,22 @@ type responseWrapper struct {
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
// CallAPI2Response CallAPI2 的响应结构体
|
||||
type CallAPI2Response struct {
|
||||
Code string `json:"code"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
func NewHuiboService(config HuiboConfig, logger *external_logger.ExternalServiceLogger) *HuiboService {
|
||||
return &HuiboService{config: config, logger: logger}
|
||||
}
|
||||
|
||||
// GetConfig 获取汇博配置
|
||||
func (s *HuiboService) GetConfig() HuiboConfig {
|
||||
return s.config
|
||||
}
|
||||
|
||||
// CallEducationBackgroundDetailed 教育背景(详细)查询
|
||||
func (s *HuiboService) CallEducationBackgroundDetailed(ctx context.Context, name, idCard, authPDFBase64 string) ([]byte, error) {
|
||||
requestID := s.generateRequestID()
|
||||
@@ -440,3 +455,158 @@ func randomDigits(n int) string {
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// MD5Encrypt 使用配置的 AppKey 进行 MD5 加密
|
||||
func (s *HuiboService) MD5Encrypt(data string) string {
|
||||
h := md5.New()
|
||||
h.Write([]byte(data + s.config.AppKey))
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
// CallAPI2 通用 HTTP 调用方法,返回原始响应 JSON
|
||||
func (s *HuiboService) CallAPI2(ctx context.Context, pcode string, requestData map[string]interface{}) ([]byte, error) {
|
||||
startTime := time.Now()
|
||||
transactionID := ""
|
||||
if v, ok := ctx.Value("transaction_id").(string); ok {
|
||||
transactionID = v
|
||||
}
|
||||
|
||||
if s.logger != nil {
|
||||
s.logger.LogRequest("", transactionID, "huibo_callapi2", s.config.BaseURL2)
|
||||
}
|
||||
|
||||
if strings.TrimSpace(s.config.BaseURL2) == "" {
|
||||
return nil, errors.Join(ErrSystem, errors.New("汇博配置不完整:BaseURL2为空"))
|
||||
}
|
||||
|
||||
if strings.TrimSpace(s.config.AppCode2) == "" {
|
||||
return nil, errors.Join(ErrSystem, errors.New("汇博配置不完整:AppCode2为空"))
|
||||
}
|
||||
|
||||
reqJSON, err := json.Marshal(requestData)
|
||||
if err != nil {
|
||||
return nil, errors.Join(ErrSystem, fmt.Errorf("请求参数序列化失败: %w", err))
|
||||
}
|
||||
|
||||
// 构建 curl 命令的 headers
|
||||
headers := map[string]string{
|
||||
"AppCode": s.config.AppCode2,
|
||||
"pcode": pcode,
|
||||
"Content-Type": "application/json",
|
||||
"X-ORDER-CODE": s.config.XOrderCode,
|
||||
}
|
||||
|
||||
// 生成包含请求体的 curl 命令用于日志记录
|
||||
curlCmd := generateCurlCommandWithBody("POST", s.config.BaseURL2, headers, string(reqJSON))
|
||||
|
||||
// 创建 HTTP 请求
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, s.config.BaseURL2, bytes.NewBuffer(reqJSON))
|
||||
if err != nil {
|
||||
return nil, errors.Join(ErrSystem, fmt.Errorf("创建HTTP请求失败: %w", err))
|
||||
}
|
||||
|
||||
// req.Header.Set(headerAuthorization, s.config.AppID+"::"+s.config.AppKey)
|
||||
// req.Header.Set(headerWorkOrderCode, s.config.WorkOrderCode)
|
||||
// req.Header.Set(headerOrderCode, s.config.XOrderCode)
|
||||
// req.Header.Set(headerSecretIDHdr, s.config.SecretID)
|
||||
// req.Header.Set(headerAESKeyHdr, s.config.AESKey)
|
||||
// req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
|
||||
// 设置请求头
|
||||
req.Header.Set("AppCode", s.config.AppCode2)
|
||||
req.Header.Set("pcode", pcode)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("X-ORDER-CODE", s.config.XOrderCode)
|
||||
|
||||
client := &http.Client{Timeout: 60 * time.Second}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
if s.logger != nil {
|
||||
s.logger.LogErrorWithFields("汇博 CallAPI2 HTTP 请求失败",
|
||||
zap.String("url", s.config.BaseURL2),
|
||||
zap.String("pcode", pcode),
|
||||
zap.String("curl", curlCmd),
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
return nil, errors.Join(ErrDatasource, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
if s.logger != nil {
|
||||
s.logger.LogErrorWithFields("汇博 CallAPI2 读取响应体失败",
|
||||
zap.String("url", s.config.BaseURL2),
|
||||
zap.Int("http_status", resp.StatusCode),
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
return nil, errors.Join(ErrSystem, fmt.Errorf("读取响应体失败: %w", err))
|
||||
}
|
||||
|
||||
// 解析响应以检查业务状态码
|
||||
var response CallAPI2Response
|
||||
if err := json.Unmarshal(respBody, &response); err != nil {
|
||||
if s.logger != nil {
|
||||
s.logger.LogErrorWithFields("汇博 CallAPI2 响应解析失败",
|
||||
zap.String("url", s.config.BaseURL2),
|
||||
zap.String("pcode", pcode),
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
return nil, errors.Join(ErrDatasource, fmt.Errorf("响应解析失败: %w", err))
|
||||
}
|
||||
|
||||
// 根据业务状态码进行处理
|
||||
switch response.Code {
|
||||
case CallAPI2StatusSuccess:
|
||||
// 查询成功
|
||||
if s.logger != nil {
|
||||
s.logger.LogInfo(
|
||||
"汇博 CallAPI2 查询成功",
|
||||
zap.String("pcode", pcode),
|
||||
zap.String("code", response.Code),
|
||||
zap.String("transaction_id", transactionID),
|
||||
)
|
||||
}
|
||||
case CallAPI2StatusNoData:
|
||||
// 查询成功,无数据
|
||||
if s.logger != nil {
|
||||
s.logger.LogInfo(
|
||||
"汇博 CallAPI2 查询成功但无数据",
|
||||
zap.String("pcode", pcode),
|
||||
zap.String("code", response.Code),
|
||||
zap.String("transaction_id", transactionID),
|
||||
)
|
||||
}
|
||||
default:
|
||||
// 其他错误状态码
|
||||
message := GetCallAPI2StatusMessage(response.Code)
|
||||
if s.logger != nil {
|
||||
s.logger.LogErrorWithFields("汇博 CallAPI2 业务状态异常",
|
||||
zap.String("url", s.config.BaseURL2),
|
||||
zap.String("pcode", pcode),
|
||||
zap.String("code", response.Code),
|
||||
zap.String("message", message),
|
||||
)
|
||||
}
|
||||
return nil, errors.Join(ErrDatasource, fmt.Errorf("业务状态异常(code=%s,msg=%s)", response.Code, message))
|
||||
}
|
||||
|
||||
// 记录 curl 命令和响应
|
||||
if s.logger != nil {
|
||||
s.logger.LogInfo(
|
||||
"汇博 CallAPI2 请求响应",
|
||||
zap.String("curl", curlCmd),
|
||||
zap.String("response_body", string(respBody)),
|
||||
zap.String("transaction_id", transactionID),
|
||||
)
|
||||
}
|
||||
|
||||
if s.logger != nil {
|
||||
s.logger.LogResponse("", transactionID, "huibo_callapi2", http.StatusOK, time.Since(startTime))
|
||||
}
|
||||
|
||||
return respBody, nil
|
||||
}
|
||||
|
||||
52
internal/infrastructure/external/huibo/status_codes.go
vendored
Normal file
52
internal/infrastructure/external/huibo/status_codes.go
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
package huibo
|
||||
|
||||
// CallAPI2 状态码常量
|
||||
const (
|
||||
CallAPI2StatusSuccess = "100" // 查询成功
|
||||
CallAPI2StatusNoData = "110" // 查询成功,无数据
|
||||
CallAPI2StatusParamError = "101" // 参数错误
|
||||
CallAPI2StatusAccountError = "103" // 账户不存在
|
||||
CallAPI2StatusIPError = "104" // IP 限制
|
||||
CallAPI2StatusExpired = "105" // 账号已过期
|
||||
CallAPI2StatusServiceError = "107" // 服务不存在
|
||||
CallAPI2StatusChannelError = "108" // 产品通道已关闭
|
||||
CallAPI2StatusBalanceError = "109" // 账户资金不足
|
||||
CallAPI2StatusUnknownError = "500" // 未知请求错误
|
||||
)
|
||||
|
||||
// CallAPI2 状态码对应的错误信息
|
||||
var CallAPI2StatusMessages = map[string]string{
|
||||
CallAPI2StatusSuccess: "查询成功",
|
||||
CallAPI2StatusNoData: "查询成功,无数据",
|
||||
CallAPI2StatusParamError: "参数错误",
|
||||
CallAPI2StatusAccountError: "账户不存在",
|
||||
CallAPI2StatusIPError: "IP 限制",
|
||||
CallAPI2StatusExpired: "账号已过期",
|
||||
CallAPI2StatusServiceError: "服务不存在",
|
||||
CallAPI2StatusChannelError: "产品通道已关闭",
|
||||
CallAPI2StatusBalanceError: "账户资金不足",
|
||||
CallAPI2StatusUnknownError: "未知请求错误",
|
||||
}
|
||||
|
||||
// IsCallAPI2Success 判断 CallAPI2 状态码是否为成功(需要扣费)
|
||||
func IsCallAPI2Success(code string) bool {
|
||||
return code == CallAPI2StatusSuccess
|
||||
}
|
||||
|
||||
// IsCallAPI2NoData 判断 CallAPI2 状态码是否为无数据(需要扣费)
|
||||
func IsCallAPI2NoData(code string) bool {
|
||||
return code == CallAPI2StatusNoData
|
||||
}
|
||||
|
||||
// IsCallAPI2Billable 判断 CallAPI2 状态码是否需要扣费
|
||||
func IsCallAPI2Billable(code string) bool {
|
||||
return IsCallAPI2Success(code) || IsCallAPI2NoData(code)
|
||||
}
|
||||
|
||||
// GetCallAPI2StatusMessage 获取 CallAPI2 状态码对应的错误信息
|
||||
func GetCallAPI2StatusMessage(code string) string {
|
||||
if msg, ok := CallAPI2StatusMessages[code]; ok {
|
||||
return msg
|
||||
}
|
||||
return "未知状态码: " + code
|
||||
}
|
||||
Reference in New Issue
Block a user