This commit is contained in:
Mrx
2026-05-26 16:17:09 +08:00
parent 760c5812ee
commit f10c5dd626
20 changed files with 598 additions and 10 deletions

View File

@@ -654,6 +654,8 @@ huibo:
aes_key: "NQYN3YO+pb/GEcCBNX0ptMb7cUlnXSPvcX7VvNofBkc=" aes_key: "NQYN3YO+pb/GEcCBNX0ptMb7cUlnXSPvcX7VvNofBkc="
work_order_code: "gd219219725093" work_order_code: "gd219219725093"
product_code: "22089" product_code: "22089"
baseUrl2: "https://napi.zhixin.net:9000/api/data"
app_code2: "1508795945301708800"
logging: logging:
enabled: true enabled: true

View File

@@ -682,6 +682,8 @@ type HuiboConfig struct {
AESKey string `mapstructure:"aes_key"` AESKey string `mapstructure:"aes_key"`
WorkOrderCode string `mapstructure:"work_order_code"` WorkOrderCode string `mapstructure:"work_order_code"`
ProductCode string `mapstructure:"product_code"` ProductCode string `mapstructure:"product_code"`
BaseURL2 string `mapstructure:"baseUrl2"`
AppCode2 string `mapstructure:"app_code2"`
Logging HuiboLoggingConfig `mapstructure:"logging"` Logging HuiboLoggingConfig `mapstructure:"logging"`
} }

View File

@@ -534,6 +534,12 @@ type IVYZ4Y27Req struct {
IDCard string `json:"id_card" validate:"required,validIDCard"` IDCard string `json:"id_card" validate:"required,validIDCard"`
AuthAuthorizeFileBase64 string `json:"auth_authorize_file_base64" validate:"required,validBase64PDF"` 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 { type IVYZP2Q6Req struct {
Name string `json:"name" validate:"required,min=1,validName"` Name string `json:"name" validate:"required,min=1,validName"`
IDCard string `json:"id_card" validate:"required,validIDCard"` IDCard string `json:"id_card" validate:"required,validIDCard"`
@@ -572,6 +578,10 @@ type QYGL5A3CReq struct {
PageNum int64 `json:"page_num" validate:"omitempty,min=1"` 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 { type QYGL2naoReq struct {
EntCode string `json:"ent_code" validate:"required,validUSCI"` EntCode string `json:"ent_code" validate:"required,validUSCI"`
PageSize int64 `json:"page_size" validate:"omitempty,min=1,max=100"` PageSize int64 `json:"page_size" validate:"omitempty,min=1,max=100"`

View File

@@ -186,6 +186,7 @@ func registerAllProcessors(combService *comb.CombService) {
"FLXG3A9B": flxg.ProcessFLXG3A9BRequest, "FLXG3A9B": flxg.ProcessFLXG3A9BRequest,
"FLXGK5D2": flxg.ProcessFLXGK5D2Request, "FLXGK5D2": flxg.ProcessFLXGK5D2Request,
"FLXGDJG3": flxg.ProcessFLXGDJG3Request, //董监高司法综合信息核验 "FLXGDJG3": flxg.ProcessFLXGDJG3Request, //董监高司法综合信息核验
"FLXGHB4F": flxg.ProcessFLXGHB4FRequest, //个人涉诉案件查询汇博
// JRZQ系列处理器 // JRZQ系列处理器
"JRZQ8203": jrzq.ProcessJRZQ8203Request, "JRZQ8203": jrzq.ProcessJRZQ8203Request,
"JRZQ0A03": jrzq.ProcessJRZQ0A03Request, "JRZQ0A03": jrzq.ProcessJRZQ0A03Request,
@@ -254,6 +255,7 @@ func registerAllProcessors(combService *comb.CombService) {
"QYGLDJ12": qygl.ProcessQYGLDJ12Request, //企业年报信息核验 "QYGLDJ12": qygl.ProcessQYGLDJ12Request, //企业年报信息核验
"QYGL8848": qygl.ProcessQYGL8848Request, //企业税收违法核查 "QYGL8848": qygl.ProcessQYGL8848Request, //企业税收违法核查
"QYGLDJ33": qygl.ProcessQYGLDJ33Request, //企业年报信息核验 "QYGLDJ33": qygl.ProcessQYGLDJ33Request, //企业年报信息核验
"QYGLBH7Y": qygl.ProcessQYGLBH7YRequest, //企业涉诉案件查询汇博
// YYSY系列处理器 // YYSY系列处理器
"YYSY35TA": yysy.ProcessYYSY35TARequest, //运营商归属地数卖 "YYSY35TA": yysy.ProcessYYSY35TARequest, //运营商归属地数卖

View File

@@ -281,6 +281,8 @@ func (s *FormConfigServiceImpl) getDTOStruct(ctx context.Context, apiCode string
"IVYZRAX1": &dto.IVYZRAX1Req{}, //融安信用分 "IVYZRAX1": &dto.IVYZRAX1Req{}, //融安信用分
"IVYZRAX2": &dto.IVYZRAX1Req{}, //融御反欺诈 "IVYZRAX2": &dto.IVYZRAX1Req{}, //融御反欺诈
"IVYZ2MN7": &dto.IVYZ2MN6Req{}, //学历Bzhicha "IVYZ2MN7": &dto.IVYZ2MN6Req{}, //学历Bzhicha
"FLXGHB4F": &dto.FLXGHB4FReq{}, //个人涉诉案件查询汇博
"QYGLBH7Y": &dto.QYGLBH7YReq{}, //企业涉诉案件查询汇博
} }
// 优先返回已配置的DTO // 优先返回已配置的DTO

View File

@@ -25,7 +25,7 @@ func ProcessFLXG0V4BRequest(ctx context.Context, params []byte, deps *processors
return nil, errors.Join(processors.ErrInvalidParam, err) 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("查询为空")) return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
} }
encryptedName, err := deps.WestDexService.Encrypt(paramsDto.Name) encryptedName, err := deps.WestDexService.Encrypt(paramsDto.Name)

View File

@@ -20,7 +20,7 @@ func ProcessFLXG5A3BRequest(ctx context.Context, params []byte, deps *processors
if err := deps.Validator.ValidateStruct(paramsDto); err != nil { if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err) 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("查询为空")) return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
} }

View File

@@ -20,7 +20,7 @@ func ProcessFLXG7E8FRequest(ctx context.Context, params []byte, deps *processors
if err := deps.Validator.ValidateStruct(paramsDto); err != nil { if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err) 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("查询为空")) return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
} }

View File

@@ -20,7 +20,7 @@ func ProcessFLXGCA3DRequest(ctx context.Context, params []byte, deps *processors
if err := deps.Validator.ValidateStruct(paramsDto); err != nil { if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
return nil, errors.Join(processors.ErrInvalidParam, err) 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("查询为空")) return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
} }
encryptedName, err := deps.WestDexService.Encrypt(paramsDto.Name) encryptedName, err := deps.WestDexService.Encrypt(paramsDto.Name)

View File

@@ -21,7 +21,7 @@ func ProcessFLXGDEA8Request(ctx context.Context, params []byte, deps *processors
return nil, errors.Join(processors.ErrInvalidParam, err) 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("查询为空")) return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
} }

View File

@@ -25,7 +25,7 @@ func ProcessFLXGDEA9Request(ctx context.Context, params []byte, deps *processors
if err != nil { if err != nil {
return nil, errors.Join(processors.ErrSystem, err) 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("查询为空")) return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
} }
encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard)

View File

@@ -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, &paramsDto); 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))
}
}

View File

@@ -37,9 +37,9 @@ func ProcessJRZQ2F8ARequest(ctx context.Context, params []byte, deps *processors
} }
reqData := map[string]interface{}{ reqData := map[string]interface{}{
"name": encryptedName, "name": encryptedName,
"idCard": encryptedIDCard, "idCard": encryptedIDCard,
"phone": encryptedMobileNo, "phone": encryptedMobileNo,
"authorized": paramsDto.Authorized, "authorized": paramsDto.Authorized,
} }
@@ -60,4 +60,3 @@ func ProcessJRZQ2F8ARequest(ctx context.Context, params []byte, deps *processors
return respBytes, nil return respBytes, nil
} }

View File

@@ -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, &paramsDto); 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))
}
}

View 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、异常捕获、状态码统一处理

View 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
}

View 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()
}

View File

@@ -39,6 +39,8 @@ func NewHuiboServiceWithConfig(cfg *config.Config) (*HuiboService, error) {
AESKey: cfg.Huibo.AESKey, AESKey: cfg.Huibo.AESKey,
WorkOrderCode: cfg.Huibo.WorkOrderCode, WorkOrderCode: cfg.Huibo.WorkOrderCode,
ProductCode: cfg.Huibo.ProductCode, ProductCode: cfg.Huibo.ProductCode,
BaseURL2: cfg.Huibo.BaseURL2,
AppCode2: cfg.Huibo.AppCode2,
}, logger) }, logger)
return service, nil return service, nil

View File

@@ -6,6 +6,7 @@ import (
"crypto/aes" "crypto/aes"
"crypto/cipher" "crypto/cipher"
"crypto/hmac" "crypto/hmac"
"crypto/md5"
"crypto/rand" "crypto/rand"
"crypto/sha256" "crypto/sha256"
"encoding/base64" "encoding/base64"
@@ -85,6 +86,8 @@ type HuiboConfig struct {
AESKey string AESKey string
WorkOrderCode string WorkOrderCode string
ProductCode string ProductCode string
BaseURL2 string // CallAPI2 使用的 URL
AppCode2 string // CallAPI2 使用的 AppCode
} }
type HuiboService struct { type HuiboService struct {
@@ -101,10 +104,22 @@ type responseWrapper struct {
} `json:"data"` } `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 { func NewHuiboService(config HuiboConfig, logger *external_logger.ExternalServiceLogger) *HuiboService {
return &HuiboService{config: config, logger: logger} return &HuiboService{config: config, logger: logger}
} }
// GetConfig 获取汇博配置
func (s *HuiboService) GetConfig() HuiboConfig {
return s.config
}
// CallEducationBackgroundDetailed 教育背景(详细)查询 // CallEducationBackgroundDetailed 教育背景(详细)查询
func (s *HuiboService) CallEducationBackgroundDetailed(ctx context.Context, name, idCard, authPDFBase64 string) ([]byte, error) { func (s *HuiboService) CallEducationBackgroundDetailed(ctx context.Context, name, idCard, authPDFBase64 string) ([]byte, error) {
requestID := s.generateRequestID() requestID := s.generateRequestID()
@@ -440,3 +455,158 @@ func randomDigits(n int) string {
} }
return string(b) 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
}

View 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
}