Merge branch 'main' of http://1.117.67.95:3000/team/tyapi-server
This commit is contained in:
@@ -249,7 +249,8 @@ type IVYZZQT3Req struct {
|
||||
type IVYZZQ3BReq struct {
|
||||
Name string `json:"name" validate:"required,min=1,validName"`
|
||||
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||
ImageUrl string `json:"image_url" validate:"required,url"`
|
||||
PhotoData string `json:"photo_data" validate:"omitempty,validBase64Image"`
|
||||
ImageUrl string `json:"image_url" validate:"omitempty,url"`
|
||||
Authorized string `json:"authorized" validate:"required,oneof=0 1"`
|
||||
}
|
||||
|
||||
@@ -357,6 +358,11 @@ type QCXGGB2QReq struct {
|
||||
Name string `json:"name" validate:"required,min=1,validName"`
|
||||
CarPlateType string `json:"carplate_type" validate:"required"`
|
||||
}
|
||||
|
||||
type QCXGM4CLReq struct {
|
||||
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||
}
|
||||
|
||||
type QCXGJJ2AReq struct {
|
||||
VinCode string `json:"vin_code" validate:"required"`
|
||||
EngineNumber string `json:"engine_number" validate:"omitempty"`
|
||||
@@ -487,6 +493,30 @@ type IVYZ2A8BReq struct {
|
||||
Authorized string `json:"authorized" validate:"required,oneof=0 1"`
|
||||
}
|
||||
|
||||
type QYGL4YABReq struct {
|
||||
EntName string `json:"ent_name" validate:"required,min=1,validEnterpriseName"`
|
||||
LegalPerson string `json:"legal_person" validate:"required,min=1,validName"`
|
||||
EntCode string `json:"ent_code" validate:"required,validUSCI"`
|
||||
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||
}
|
||||
|
||||
type QYGL3YSBReq struct {
|
||||
EntName string `json:"ent_name" validate:"required,min=1,validEnterpriseName"`
|
||||
LegalPerson string `json:"legal_person" validate:"required,min=1,validName"`
|
||||
EntCode string `json:"ent_code" validate:"required,validUSCI"`
|
||||
}
|
||||
|
||||
type QYGL2YSBReq struct {
|
||||
LegalPerson string `json:"legal_person" validate:"required,min=1,validName"`
|
||||
EntCode string `json:"ent_code" validate:"required,validUSCI"`
|
||||
}
|
||||
|
||||
type QYGLDG77Req struct {
|
||||
EntName string `json:"ent_name" validate:"required,min=1,validEnterpriseName"`
|
||||
AccountNo string `json:"account_no" validate:"required,min=1,"`
|
||||
AccountBank string `json:"account_bank" validate:"required,min=1,"`
|
||||
}
|
||||
|
||||
type IVYZ7C9DReq struct {
|
||||
IDCard string `json:"id_card" validate:"required,validIDCard"`
|
||||
Name string `json:"name" validate:"required,min=1,validName"`
|
||||
@@ -533,6 +563,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"`
|
||||
@@ -571,6 +607,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"`
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"tyapi-server/internal/infrastructure/external/huibo"
|
||||
"tyapi-server/internal/infrastructure/external/jiguang"
|
||||
"tyapi-server/internal/infrastructure/external/muzi"
|
||||
"tyapi-server/internal/infrastructure/external/nuoer"
|
||||
"tyapi-server/internal/infrastructure/external/shujubao"
|
||||
"tyapi-server/internal/infrastructure/external/shumai"
|
||||
"tyapi-server/internal/infrastructure/external/tianyancha"
|
||||
@@ -68,6 +69,7 @@ func NewApiRequestService(
|
||||
jiguangService *jiguang.JiguangService,
|
||||
shumaiService *shumai.ShumaiService,
|
||||
huiboService *huibo.HuiboService,
|
||||
nuoerService *nuoer.NuoerService,
|
||||
validator interfaces.RequestValidator,
|
||||
productManagementService *services.ProductManagementService,
|
||||
cfg *appconfig.Config,
|
||||
@@ -84,6 +86,7 @@ func NewApiRequestService(
|
||||
jiguangService,
|
||||
shumaiService,
|
||||
huiboService,
|
||||
nuoerService,
|
||||
validator,
|
||||
productManagementService,
|
||||
cfg,
|
||||
@@ -105,6 +108,7 @@ func NewApiRequestServiceWithRepos(
|
||||
jiguangService *jiguang.JiguangService,
|
||||
shumaiService *shumai.ShumaiService,
|
||||
huiboService *huibo.HuiboService,
|
||||
nuoerService *nuoer.NuoerService,
|
||||
validator interfaces.RequestValidator,
|
||||
productManagementService *services.ProductManagementService,
|
||||
cfg *appconfig.Config,
|
||||
@@ -132,6 +136,7 @@ func NewApiRequestServiceWithRepos(
|
||||
jiguangService,
|
||||
shumaiService,
|
||||
huiboService,
|
||||
nuoerService,
|
||||
validator,
|
||||
combService,
|
||||
reportRepo,
|
||||
@@ -186,6 +191,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,7 +260,11 @@ func registerAllProcessors(combService *comb.CombService) {
|
||||
"QYGLDJ12": qygl.ProcessQYGLDJ12Request, //企业年报信息核验
|
||||
"QYGL8848": qygl.ProcessQYGL8848Request, //企业税收违法核查
|
||||
"QYGLDJ33": qygl.ProcessQYGLDJ33Request, //企业年报信息核验
|
||||
|
||||
"QYGLBH7Y": qygl.ProcessQYGLBH7YRequest, //企业涉诉案件查询汇博
|
||||
"QYGL4YAB": qygl.ProcessQYGL4YABRequest, //企业四要素认证shumai
|
||||
"QYGL3YSB": qygl.ProcessQYGL3YSBRequest, //企业三要素认证shumai
|
||||
"QYGL2YSB": qygl.ProcessQYGL2YSBRequest, //企业二要素认证shumai
|
||||
"QYGLDG77": qygl.ProcessQYGLDG77Request, //企业对公打款认证shumai
|
||||
// YYSY系列处理器
|
||||
"YYSY35TA": yysy.ProcessYYSY35TARequest, //运营商归属地数卖
|
||||
"YYSYD50F": yysy.ProcessYYSYD50FRequest,
|
||||
@@ -373,7 +383,7 @@ func registerAllProcessors(combService *comb.CombService) {
|
||||
"QCXG5U0Z": qcxg.ProcessQCXG5U0ZRequest, // 车辆静态信息查询 10479
|
||||
"QCXGY7F2": qcxg.ProcessQCXGY7F2Request, // 二手车VIN估值 10443
|
||||
"QCXG3M7Z": qcxg.ProcessQCXG3M7ZRequest, //人车关系核验(ETC)10093 月更
|
||||
|
||||
"QCXGM4CL": qcxg.ProcessQCXGM4CLRequest, //名下车辆诺尔
|
||||
// DWBG系列处理器 - 多维报告
|
||||
"DWBG6A2C": dwbg.ProcessDWBG6A2CRequest,
|
||||
"DWBG8B4D": dwbg.ProcessDWBG8B4DRequest,
|
||||
|
||||
@@ -281,6 +281,13 @@ 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{}, //企业涉诉案件查询汇博
|
||||
"QYGL4YAB": &dto.QYGL4YABReq{}, //企业四要素认证shumai
|
||||
"QYGL3YSB": &dto.QYGL3YSBReq{}, //企业三要素认证shumai
|
||||
"QYGL2YSB": &dto.QYGL2YSBReq{}, //企业二要素认证shumai
|
||||
"QYGLDG77": &dto.QYGLDG77Req{}, //企业对公打款认证shumai
|
||||
"QCXGM4CL": &dto.QCXGM4CLReq{}, //名下车辆诺尔
|
||||
}
|
||||
|
||||
// 优先返回已配置的DTO
|
||||
@@ -513,6 +520,8 @@ func (s *FormConfigServiceImpl) generateFieldLabel(jsonTag string) string {
|
||||
"plate_color": "车牌颜色",
|
||||
"marital_type": "婚姻状况类型",
|
||||
"auth_authorize_file_base64": "PDF授权文件Base64编码(≤500KB,仅PDF)",
|
||||
"account_no": "企业账户",
|
||||
"account_bank": "开户行",
|
||||
}
|
||||
|
||||
if label, exists := labelMap[jsonTag]; exists {
|
||||
@@ -579,6 +588,8 @@ func (s *FormConfigServiceImpl) generateExampleValue(fieldType reflect.Type, jso
|
||||
"plate_color": "0",
|
||||
"marital_type": "10",
|
||||
"auth_authorize_file_base64": "JVBERi0xLjQKJcTl8uXr...(示例PDF的Base64编码)",
|
||||
"account_no": "6222021234567890123",
|
||||
"account_bank": "中国工商银行",
|
||||
}
|
||||
|
||||
if example, exists := exampleMap[jsonTag]; exists {
|
||||
@@ -654,6 +665,8 @@ func (s *FormConfigServiceImpl) generatePlaceholder(jsonTag string, fieldType st
|
||||
"plate_color": "请输入车牌颜色",
|
||||
"marital_type": "请选择婚姻状况类型",
|
||||
"auth_authorize_file_base64": "请输入PDF文件的Base64编码字符串",
|
||||
"account_no": "请输入企业账户",
|
||||
"account_bank": "请输入开户行",
|
||||
}
|
||||
|
||||
if placeholder, exists := placeholderMap[jsonTag]; exists {
|
||||
@@ -731,6 +744,8 @@ func (s *FormConfigServiceImpl) generateDescription(jsonTag string, validation s
|
||||
"plate_color": "车牌颜色",
|
||||
"marital_type": "婚姻状况类型:10-未登记(无登记记录),20-已婚,30-丧偶,40-离异",
|
||||
"auth_authorize_file_base64": "请输入PDF文件的Base64编码字符串",
|
||||
"account_no": "请输入企业账户",
|
||||
"account_bank": "请输入开户行",
|
||||
}
|
||||
|
||||
if desc, exists := descMap[jsonTag]; exists {
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"tyapi-server/internal/infrastructure/external/huibo"
|
||||
"tyapi-server/internal/infrastructure/external/jiguang"
|
||||
"tyapi-server/internal/infrastructure/external/muzi"
|
||||
"tyapi-server/internal/infrastructure/external/nuoer"
|
||||
"tyapi-server/internal/infrastructure/external/shujubao"
|
||||
"tyapi-server/internal/infrastructure/external/shumai"
|
||||
"tyapi-server/internal/infrastructure/external/tianyancha"
|
||||
@@ -42,6 +43,7 @@ type ProcessorDependencies struct {
|
||||
JiguangService *jiguang.JiguangService
|
||||
ShumaiService *shumai.ShumaiService
|
||||
HuiboService *huibo.HuiboService
|
||||
NuoerService *nuoer.NuoerService
|
||||
Validator interfaces.RequestValidator
|
||||
CombService CombServiceInterface // Changed to interface to break import cycle
|
||||
Options *commands.ApiCallOptions // 添加Options支持
|
||||
@@ -70,6 +72,7 @@ func NewProcessorDependencies(
|
||||
jiguangService *jiguang.JiguangService,
|
||||
shumaiService *shumai.ShumaiService,
|
||||
huiboService *huibo.HuiboService,
|
||||
nuoerService *nuoer.NuoerService,
|
||||
validator interfaces.RequestValidator,
|
||||
combService CombServiceInterface, // Changed to interface
|
||||
reportRepo repositories.ReportRepository,
|
||||
@@ -88,6 +91,7 @@ func NewProcessorDependencies(
|
||||
JiguangService: jiguangService,
|
||||
ShumaiService: shumaiService,
|
||||
HuiboService: huiboService,
|
||||
NuoerService: nuoerService,
|
||||
Validator: validator,
|
||||
CombService: combService,
|
||||
Options: nil, // 初始化为nil,在调用时设置
|
||||
|
||||
@@ -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 == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" {
|
||||
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" || paramsDto.IDCard == "13032319930128263X" {
|
||||
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
|
||||
}
|
||||
encryptedName, err := deps.WestDexService.Encrypt(paramsDto.Name)
|
||||
|
||||
@@ -20,9 +20,10 @@ 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 == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" {
|
||||
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" || paramsDto.IDCard == "13032319930128263X" {
|
||||
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
|
||||
}
|
||||
|
||||
encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
|
||||
@@ -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 == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" {
|
||||
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" || paramsDto.IDCard == "13032319930128263X" {
|
||||
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 == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" {
|
||||
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" || paramsDto.IDCard == "13032319930128263X" {
|
||||
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
|
||||
}
|
||||
encryptedName, err := deps.WestDexService.Encrypt(paramsDto.Name)
|
||||
|
||||
@@ -20,6 +20,10 @@ func ProcessFLXGDEA8Request(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 == "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" || paramsDto.IDCard == "13032319930128263X" {
|
||||
return nil, errors.Join(processors.ErrNotFound, errors.New("查询为空"))
|
||||
}
|
||||
|
||||
encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name)
|
||||
if err != nil {
|
||||
|
||||
@@ -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 == "622301200006250550" || paramsDto.IDCard == "320682198910134998" || paramsDto.IDCard == "640102198708020925" || paramsDto.IDCard == "420624197310234034" || paramsDto.IDCard == "350104198501184416" || paramsDto.IDCard == "410521198606018056" || paramsDto.IDCard == "410482198504029333" || paramsDto.IDCard == "370982199012037272" {
|
||||
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" || paramsDto.IDCard == "13032319930128263X" {
|
||||
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": paramsDto.Name,
|
||||
"idCard": paramsDto.IDCard,
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -30,19 +31,20 @@ func ProcessIVYZZQ3BRequest(ctx context.Context, params []byte, deps *processors
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
encryptedImageUrl, err := deps.ZhichaService.Encrypt(paramsDto.ImageUrl)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
reqData := map[string]interface{}{
|
||||
"idCard": encryptedIDCard,
|
||||
"name": encryptedName,
|
||||
"imageId": encryptedImageUrl,
|
||||
"authorized": paramsDto.Authorized,
|
||||
}
|
||||
|
||||
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI062", reqData)
|
||||
if paramsDto.ImageUrl != "" {
|
||||
reqData["url"] = paramsDto.ImageUrl
|
||||
} else {
|
||||
reqData["image"] = paramsDto.PhotoData
|
||||
}
|
||||
|
||||
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI1001", reqData)
|
||||
if err != nil {
|
||||
if errors.Is(err, zhicha.ErrDatasource) {
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
@@ -56,7 +58,7 @@ func ProcessIVYZZQ3BRequest(ctx context.Context, params []byte, deps *processors
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
outBytes, err := mapZCI062RespToIVYZZQ3B(respBytes)
|
||||
outBytes, err := mapZCI1001RespToIVYZZQ3B(respBytes)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
@@ -69,44 +71,118 @@ type IVYZZQ3BOut struct {
|
||||
}
|
||||
|
||||
type IVYZZQ3BOutResultData struct {
|
||||
// VerificationResult 审核校验结果:valid 身份审核通过;invalid 身份审核不通过(与 similarity 区间联动,见 mapVerificationResultFromSimilarity)
|
||||
// VerificationCode 审核校验编码,透传上游 incorrect
|
||||
VerificationCode string `json:"verification_code"`
|
||||
// VerificationResult 审核校验结果:valid 身份审核通过;invalid 身份审核不通过(score >= 0.45 为 valid)
|
||||
VerificationResult string `json:"verification_result"`
|
||||
// Similarity 照片相似度分数字符串(0–1000)。区间说明:(0,600)不同人;(600,700)不能确定是否同人;(700,1000)同人。数值为上游 score(0~1)×1000。
|
||||
// VerificationMessage 审核校验信息,透传上游 msg
|
||||
VerificationMessage string `json:"verification_message"`
|
||||
// Similarity 照片相似度分数字符串(0–1000)。区间说明:(0,600)不同人;(600,700)不能确定是否同人;(700,1000)同人。
|
||||
Similarity string `json:"similarity"`
|
||||
}
|
||||
|
||||
// zci062UpstreamResp 智查 ZCI062 成功返回体中的分数字段(分值越大相似度越高)
|
||||
type zci062UpstreamResp struct {
|
||||
Score interface{} `json:"score"`
|
||||
// zci1001UpstreamResp 智查 ZCI1001 成功返回体中的字段
|
||||
type zci1001UpstreamResp struct {
|
||||
Score interface{} `json:"score"`
|
||||
Msg string `json:"msg"`
|
||||
Incorrect interface{} `json:"incorrect"`
|
||||
}
|
||||
|
||||
func mapZCI062RespToIVYZZQ3B(respBytes []byte) ([]byte, error) {
|
||||
var r zci062UpstreamResp
|
||||
func mapZCI1001RespToIVYZZQ3B(respBytes []byte) ([]byte, error) {
|
||||
var r zci1001UpstreamResp
|
||||
if err := json.Unmarshal(respBytes, &r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
score := parseScoreToFloat64(r.Score)
|
||||
similarityVal := score * 1000
|
||||
score := parseScoreZCI1001ToFloat64(r.Score)
|
||||
similarityVal := mapScoreToZCI001Similarity(score)
|
||||
similarity := strconv.FormatFloat(similarityVal, 'f', 2, 64)
|
||||
verificationResult := mapVerificationResultFromSimilarity(similarityVal)
|
||||
verificationResult := buildToStringmapZCI1001RespToIVYZZQ3B(score)
|
||||
|
||||
out := IVYZZQ3BOut{
|
||||
HandleTime: time.Now().Format("2006-01-02 15:04:05"),
|
||||
ResultData: IVYZZQ3BOutResultData{
|
||||
VerificationResult: verificationResult,
|
||||
Similarity: similarity,
|
||||
VerificationCode: valueZCI001ToString(r.Incorrect),
|
||||
VerificationResult: verificationResult,
|
||||
VerificationMessage: r.Msg,
|
||||
Similarity: similarity,
|
||||
},
|
||||
}
|
||||
|
||||
return json.Marshal(out)
|
||||
}
|
||||
|
||||
// mapVerificationResultFromSimilarity 与 similarity(0–1000)区间说明对齐:
|
||||
// (700,1000】系统判断为同一人 → 身份审核通过 valid;其余 → invalid。
|
||||
func mapVerificationResultFromSimilarity(similarity float64) string {
|
||||
if similarity >= 700 {
|
||||
// buildToStringmapZCI1001RespToIVYZZQ3B 审核判定逻辑:score >= 0.45 为 valid,否则为 invalid
|
||||
func buildToStringmapZCI1001RespToIVYZZQ3B(score float64) string {
|
||||
if score >= 0.45 {
|
||||
return "valid"
|
||||
}
|
||||
return "invalid"
|
||||
}
|
||||
|
||||
// mapScoreToZCI001Similarity 将 score(0~1) 分段映射到 similarity(0~1000):
|
||||
// 0.40 -> 600,0.45 -> 700
|
||||
func mapScoreToZCI001Similarity(score float64) float64 {
|
||||
if score <= 0 {
|
||||
return 0
|
||||
}
|
||||
if score >= 1 {
|
||||
return 1000
|
||||
}
|
||||
if score < 0.40 {
|
||||
// [0, 0.40) -> [0, 600)
|
||||
return (score / 0.40) * 600
|
||||
}
|
||||
if score < 0.45 {
|
||||
// [0.40, 0.45) -> [600, 700)
|
||||
return 600 + ((score-0.40)/0.05)*100
|
||||
}
|
||||
// [0.45, 1] -> [700, 1000]
|
||||
return 700 + ((score-0.45)/0.55)*300
|
||||
}
|
||||
|
||||
func parseScoreZCI1001ToFloat64(v interface{}) float64 {
|
||||
switch t := v.(type) {
|
||||
case float64:
|
||||
return t
|
||||
case float32:
|
||||
return float64(t)
|
||||
case int:
|
||||
return float64(t)
|
||||
case int32:
|
||||
return float64(t)
|
||||
case int64:
|
||||
return float64(t)
|
||||
case json.Number:
|
||||
if f, err := t.Float64(); err == nil {
|
||||
return f
|
||||
}
|
||||
case string:
|
||||
if f, err := strconv.ParseFloat(t, 64); err == nil {
|
||||
return f
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func valueZCI001ToString(v interface{}) string {
|
||||
if v == nil {
|
||||
return ""
|
||||
}
|
||||
switch t := v.(type) {
|
||||
case string:
|
||||
return t
|
||||
case int:
|
||||
return strconv.Itoa(t)
|
||||
case int32:
|
||||
return strconv.FormatInt(int64(t), 10)
|
||||
case int64:
|
||||
return strconv.FormatInt(t, 10)
|
||||
case float64:
|
||||
return strconv.FormatFloat(t, 'f', -1, 64)
|
||||
case float32:
|
||||
return strconv.FormatFloat(float64(t), 'f', -1, 64)
|
||||
default:
|
||||
return fmt.Sprintf("%v", v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,9 +37,9 @@ func ProcessJRZQ1E7BRequest(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,
|
||||
}
|
||||
|
||||
@@ -55,9 +55,9 @@ func ProcessJRZQ1E7BRequest(ctx context.Context, params []byte, deps *processors
|
||||
// 将响应数据转换为 JSON 字节
|
||||
respBytes, err := json.Marshal(respData)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
// return nil, errors.Join(processors.ErrSystem, err)
|
||||
return json.Marshal(map[string]interface{}{})
|
||||
}
|
||||
|
||||
return respBytes, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ func ProcessJRZQ3P01Request(ctx context.Context, params []byte, deps *processors
|
||||
respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI109", 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)
|
||||
|
||||
@@ -7,10 +7,9 @@ import (
|
||||
|
||||
"tyapi-server/internal/domains/api/dto"
|
||||
"tyapi-server/internal/domains/api/services/processors"
|
||||
"tyapi-server/internal/infrastructure/external/jiguang"
|
||||
)
|
||||
|
||||
// ProcessQCXG4D2ERequest QCXG4D2E API处理方法 - 极光名下车辆数量查询
|
||||
// ProcessQCXG4D2ERequest QCXG4D2E API处理方法 - 名下车辆数量(委托诺尔 QCXGM4CL)
|
||||
func ProcessQCXG4D2ERequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.QCXG4D2EReq
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
@@ -21,27 +20,15 @@ func ProcessQCXG4D2ERequest(ctx context.Context, params []byte, deps *processors
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
|
||||
// 构建请求参数
|
||||
reqData := map[string]interface{}{
|
||||
"idNum": paramsDto.IDCard,
|
||||
"userType": paramsDto.UserType,
|
||||
}
|
||||
|
||||
// 调用极光API
|
||||
// apiCode: vehicle-inquiry-under-name (用于请求头)
|
||||
// apiPath: vehicle/inquiry-under-name (用于URL路径)
|
||||
respBytes, err := deps.JiguangService.CallAPI(ctx, "vehicle-inquiry-under-name", "vehicle/inquiry-under-name", reqData)
|
||||
m4clParams, err := json.Marshal(dto.QCXGM4CLReq{IDCard: paramsDto.IDCard})
|
||||
if err != nil {
|
||||
// 根据错误类型返回相应的错误
|
||||
if errors.Is(err, jiguang.ErrNotFound) {
|
||||
return nil, errors.Join(processors.ErrNotFound, err)
|
||||
} else if errors.Is(err, jiguang.ErrDatasource) {
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
} else {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
// 极光服务已经返回了 data 字段的 JSON,直接返回即可
|
||||
return respBytes, nil
|
||||
raw, err := ProcessQCXGM4CLRequest(ctx, m4clParams, deps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformQCXG5F3AResponse(raw)
|
||||
}
|
||||
|
||||
@@ -4,13 +4,15 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"tyapi-server/internal/domains/api/dto"
|
||||
"tyapi-server/internal/domains/api/services/processors"
|
||||
"tyapi-server/internal/infrastructure/external/jiguang"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
// ProcessQCXG5F3ARequest QCXG5F3A API处理方法 - 极光名下车辆车牌查询
|
||||
// ProcessQCXG5F3ARequest QCXG5F3A API处理方法 - 名下车辆(委托诺尔 QCXGM4CL,响应格式兼容极光)
|
||||
func ProcessQCXG5F3ARequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.QCXG5F3AReq
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
@@ -21,32 +23,53 @@ func ProcessQCXG5F3ARequest(ctx context.Context, params []byte, deps *processors
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
|
||||
null := ""
|
||||
// 构建请求参数
|
||||
reqData := map[string]interface{}{
|
||||
"id_card": paramsDto.IDCard,
|
||||
"name": paramsDto.Name,
|
||||
"userType": null,
|
||||
"vehicleType": null,
|
||||
"encryptionType": null,
|
||||
"encryptionContent": null,
|
||||
}
|
||||
|
||||
// 调用极光API
|
||||
// apiCode: vehicle-person-vehicles (用于请求头)
|
||||
// apiPath: vehicle/person-vehicles (用于URL路径)
|
||||
respBytes, err := deps.JiguangService.CallAPI(ctx, "vehicle-person-vehicles", "vehicle/person-vehicles", reqData)
|
||||
m4clParams, err := json.Marshal(dto.QCXGM4CLReq{IDCard: paramsDto.IDCard})
|
||||
if err != nil {
|
||||
// 根据错误类型返回相应的错误
|
||||
if errors.Is(err, jiguang.ErrNotFound) {
|
||||
return nil, errors.Join(processors.ErrNotFound, err)
|
||||
} else if errors.Is(err, jiguang.ErrDatasource) {
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
} else {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
// 极光服务已经返回了 data 字段的 JSON,直接返回即可
|
||||
return respBytes, nil
|
||||
raw, err := ProcessQCXGM4CLRequest(ctx, m4clParams, deps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformQCXG5F3AResponse(raw)
|
||||
}
|
||||
|
||||
// transformQCXG5F3AResponse 将诺尔响应转为 QCXG5F3A 对外格式:去掉 busiCode/busiMsg,展开 result,vehicleCount 为字符串
|
||||
func transformQCXG5F3AResponse(raw []byte) ([]byte, error) {
|
||||
base := gjson.GetBytes(raw, "result")
|
||||
if !base.Exists() {
|
||||
base = gjson.ParseBytes(raw)
|
||||
}
|
||||
|
||||
list := base.Get("list").Value()
|
||||
if list == nil {
|
||||
list = []interface{}{}
|
||||
}
|
||||
|
||||
countStr, err := formatVehicleCountAsString(base.Get("vehicleCount"))
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
out := map[string]interface{}{
|
||||
"vehicleCount": countStr,
|
||||
"list": list,
|
||||
}
|
||||
return json.Marshal(out)
|
||||
}
|
||||
|
||||
func formatVehicleCountAsString(v gjson.Result) (string, error) {
|
||||
if !v.Exists() {
|
||||
return "0", nil
|
||||
}
|
||||
switch v.Type {
|
||||
case gjson.String:
|
||||
return v.String(), nil
|
||||
case gjson.Number:
|
||||
return strconv.FormatInt(v.Int(), 10), nil
|
||||
default:
|
||||
return "", errors.New("vehicleCount 类型无效")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,11 @@ import (
|
||||
|
||||
"tyapi-server/internal/domains/api/dto"
|
||||
"tyapi-server/internal/domains/api/services/processors"
|
||||
"tyapi-server/internal/infrastructure/external/jiguang"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
// ProcessQCXG9P1CRequest QCXG9P1C API处理方法 兼容旧版 极光名下车牌查询数量
|
||||
// ProcessQCXG9P1CRequest QCXG9P1C API处理方法 - 名下车辆详版(委托诺尔 QCXGM4CL)
|
||||
func ProcessQCXG9P1CRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.QCXG9P1CReq
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
@@ -24,54 +23,53 @@ func ProcessQCXG9P1CRequest(ctx context.Context, params []byte, deps *processors
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
|
||||
null := ""
|
||||
// 构建请求参数
|
||||
reqData := map[string]interface{}{
|
||||
"id_card": paramsDto.IDCard,
|
||||
"name": null,
|
||||
"userType": null,
|
||||
"vehicleType": null,
|
||||
"encryptionType": null,
|
||||
"encryptionContent": null,
|
||||
}
|
||||
|
||||
// 调用极光API
|
||||
// apiCode: vehicle-person-vehicles (用于请求头)
|
||||
// apiPath: vehicle/person-vehicles (用于URL路径)
|
||||
respBytes, err := deps.JiguangService.CallAPI(ctx, "vehicle-person-vehicles", "vehicle/person-vehicles", reqData)
|
||||
m4clParams, err := json.Marshal(dto.QCXGM4CLReq{IDCard: paramsDto.IDCard})
|
||||
if err != nil {
|
||||
// 根据错误类型返回相应的错误
|
||||
if errors.Is(err, jiguang.ErrNotFound) {
|
||||
return nil, errors.Join(processors.ErrNotFound, err)
|
||||
} else if errors.Is(err, jiguang.ErrDatasource) {
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
} else {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
// 使用 gjson 检查并转换 vehicleCount 字段
|
||||
vehicleCountResult := gjson.GetBytes(respBytes, "vehicleCount")
|
||||
if vehicleCountResult.Exists() && vehicleCountResult.Type == gjson.String {
|
||||
// 如果是字符串类型,转换为整数
|
||||
vehicleCountInt, err := strconv.Atoi(vehicleCountResult.String())
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
// 解析 JSON 并修改 vehicleCount 字段
|
||||
var respData map[string]interface{}
|
||||
if err := json.Unmarshal(respBytes, &respData); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
respData["vehicleCount"] = vehicleCountInt
|
||||
// 重新序列化为JSON并返回
|
||||
resultBytes, err := json.Marshal(respData)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
return resultBytes, nil
|
||||
raw, err := ProcessQCXGM4CLRequest(ctx, m4clParams, deps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 如果 vehicleCount 不存在或不是字符串,直接返回原始响应
|
||||
return respBytes, nil
|
||||
return transformQCXG9P1CResponse(raw)
|
||||
}
|
||||
|
||||
// transformQCXG9P1CResponse 将诺尔响应转为 QCXG9P1C 对外格式:去掉 busiCode/busiMsg,展开 result,vehicleCount 为整数
|
||||
func transformQCXG9P1CResponse(raw []byte) ([]byte, error) {
|
||||
base := gjson.GetBytes(raw, "result")
|
||||
if !base.Exists() {
|
||||
base = gjson.ParseBytes(raw)
|
||||
}
|
||||
|
||||
list := base.Get("list").Value()
|
||||
if list == nil {
|
||||
list = []interface{}{}
|
||||
}
|
||||
|
||||
countInt, err := formatVehicleCountAsInt(base.Get("vehicleCount"))
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
out := map[string]interface{}{
|
||||
"vehicleCount": countInt,
|
||||
"list": list,
|
||||
}
|
||||
return json.Marshal(out)
|
||||
}
|
||||
|
||||
func formatVehicleCountAsInt(v gjson.Result) (int, error) {
|
||||
if !v.Exists() {
|
||||
return 0, nil
|
||||
}
|
||||
switch v.Type {
|
||||
case gjson.String:
|
||||
return strconv.Atoi(v.String())
|
||||
case gjson.Number:
|
||||
return int(v.Int()), nil
|
||||
default:
|
||||
return 0, errors.New("vehicleCount 类型无效")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package qcxg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"tyapi-server/internal/domains/api/dto"
|
||||
"tyapi-server/internal/domains/api/services/processors"
|
||||
"tyapi-server/internal/infrastructure/external/nuoer"
|
||||
)
|
||||
|
||||
// ProcessQCXGM4CLRequest QCXGM4CL API处理方法 - 名下车辆诺尔
|
||||
func ProcessQCXGM4CLRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.QCXGM4CLReq
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
|
||||
body := map[string]string{
|
||||
"idCard": paramsDto.IDCard,
|
||||
}
|
||||
|
||||
nuoerDoCheckAPIKey := "id_vehicle_query_102"
|
||||
ApiPath := "/v1/doCheck"
|
||||
|
||||
resp, err := deps.NuoerService.CallAPI(ctx, nuoerDoCheckAPIKey, ApiPath, body)
|
||||
if err != nil {
|
||||
if errors.Is(err, nuoer.ErrNotFound) {
|
||||
return nil, errors.Join(processors.ErrNotFound, err)
|
||||
}
|
||||
if errors.Is(err, nuoer.ErrDatasource) {
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
}
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
respBytes, err := json.Marshal(resp.Data)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
return respBytes, nil
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
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/shumai"
|
||||
)
|
||||
|
||||
// ProcessQYGL2YSBRequest QYGL2YSB API处理方法 - 企业二要素认证
|
||||
func ProcessQYGL2YSBRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.QYGL2YSBReq
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"legalPerson": paramsDto.LegalPerson,
|
||||
"creditNo": paramsDto.EntCode,
|
||||
}
|
||||
apiPath := "/v4/company/two/check" // 接口路径,根据数脉文档填写(如 v4/xxx)
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
if errors.Is(err, shumai.ErrDatasource) {
|
||||
// 数据源错误
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
} else if errors.Is(err, shumai.ErrSystem) {
|
||||
// 系统错误
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
} else if errors.Is(err, shumai.ErrNotFound) {
|
||||
// 查无记录
|
||||
return nil, errors.Join(processors.ErrNotFound, err)
|
||||
} else {
|
||||
// 其他未知错误
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
}
|
||||
return respBytes, nil
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
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/shumai"
|
||||
)
|
||||
|
||||
// ProcessQYGL3YSBRequest QYGL3YSB API处理方法 - 企业三要素认证
|
||||
func ProcessQYGL3YSBRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.QYGL3YSBReq
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"legalPerson": paramsDto.LegalPerson,
|
||||
"companyName": paramsDto.EntName,
|
||||
"creditNo": paramsDto.EntCode,
|
||||
}
|
||||
apiPath := "/v4/company-three/check" // 接口路径,根据数脉文档填写(如 v4/xxx)
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
if errors.Is(err, shumai.ErrDatasource) {
|
||||
// 数据源错误
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
} else if errors.Is(err, shumai.ErrSystem) {
|
||||
// 系统错误
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
} else if errors.Is(err, shumai.ErrNotFound) {
|
||||
// 查无记录
|
||||
return nil, errors.Join(processors.ErrNotFound, err)
|
||||
} else {
|
||||
// 其他未知错误
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
}
|
||||
return respBytes, nil
|
||||
|
||||
}
|
||||
@@ -8,10 +8,31 @@ import (
|
||||
|
||||
"tyapi-server/internal/domains/api/dto"
|
||||
"tyapi-server/internal/domains/api/services/processors"
|
||||
"tyapi-server/internal/infrastructure/external/shujubao"
|
||||
)
|
||||
|
||||
// QYGL4B2EItem 返回列表项
|
||||
type QYGL4B2EItem struct {
|
||||
PublishTime string `json:"publish_time"`
|
||||
CaseType string `json:"case_type"`
|
||||
ID int64 `json:"id"`
|
||||
Department string `json:"department"`
|
||||
TaxpayerName string `json:"taxpayer_name"`
|
||||
}
|
||||
|
||||
// QYGL4B2EResponse 最终返回结构
|
||||
type QYGL4B2EResponse struct {
|
||||
Total int64 `json:"total"`
|
||||
Items []QYGL4B2EItem `json:"items"`
|
||||
}
|
||||
|
||||
// ProcessQYGL4B2ERequest QYGL4B2E API处理方法 - 税收违法
|
||||
func ProcessQYGL4B2ERequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
func ProcessQYGL4B2ERequest(
|
||||
ctx context.Context,
|
||||
params []byte,
|
||||
deps *processors.ProcessorDependencies,
|
||||
) ([]byte, error) {
|
||||
|
||||
var paramsDto dto.QYGL5A3CReq
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
@@ -21,39 +42,90 @@ func ProcessQYGL4B2ERequest(ctx context.Context, params []byte, deps *processors
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
|
||||
// 设置默认值
|
||||
// 默认值
|
||||
pageSize := paramsDto.PageSize
|
||||
if pageSize == 0 {
|
||||
pageSize = int64(20)
|
||||
pageSize = 20
|
||||
}
|
||||
pageNum := paramsDto.PageNum
|
||||
if pageNum == 0 {
|
||||
pageNum = int64(1)
|
||||
pageNum = 1
|
||||
}
|
||||
|
||||
// 构建API调用参数
|
||||
apiParams := map[string]string{
|
||||
"keyword": paramsDto.EntCode,
|
||||
"pageSize": strconv.FormatInt(pageSize, 10),
|
||||
"pageNum": strconv.FormatInt(pageNum, 10),
|
||||
// 调用外部接口
|
||||
reqParams := map[string]interface{}{
|
||||
"key": "c67673dd2e92deb2d2ec91b87bb0a81c",
|
||||
"creditCode": paramsDto.EntCode,
|
||||
}
|
||||
|
||||
// 调用天眼查API - 税收违法
|
||||
response, err := deps.TianYanChaService.CallAPI(ctx, "TaxContravention", apiParams)
|
||||
apiPath := "/communication/personal/10233"
|
||||
data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams)
|
||||
if err != nil {
|
||||
return nil, convertTianYanChaError(err)
|
||||
if errors.Is(err, shujubao.ErrDatasource) {
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
}
|
||||
if errors.Is(err, shujubao.ErrQueryEmpty) {
|
||||
data = map[string]interface{}{}
|
||||
} else {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 检查天眼查API调用是否成功
|
||||
if !response.Success {
|
||||
return nil, errors.Join(processors.ErrDatasource, errors.New(response.Message))
|
||||
// 原始返回结构处理 - data 是 map[string]interface{} 类型
|
||||
dataMap, ok := data.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, errors.Join(processors.ErrSystem, errors.New("data不是map类型"))
|
||||
}
|
||||
|
||||
// 返回天眼查响应数据
|
||||
respBytes, err := json.Marshal(response.Data)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
// 提取 total
|
||||
total := int64(0)
|
||||
if v, ok := dataMap["total"]; ok {
|
||||
switch val := v.(type) {
|
||||
case float64:
|
||||
total = int64(val)
|
||||
case int:
|
||||
total = int64(val)
|
||||
case string:
|
||||
total, _ = strconv.ParseInt(val, 10, 64)
|
||||
}
|
||||
}
|
||||
|
||||
return respBytes, nil
|
||||
// 提取 items 数组
|
||||
srcItems := make([]map[string]interface{}, 0)
|
||||
if v, ok := dataMap["items"]; ok {
|
||||
if arr, ok := v.([]interface{}); ok {
|
||||
for _, item := range arr {
|
||||
if itemMap, ok := item.(map[string]interface{}); ok {
|
||||
srcItems = append(srcItems, itemMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 构造返回数据
|
||||
resp := QYGL4B2EResponse{
|
||||
Total: total,
|
||||
Items: make([]QYGL4B2EItem, 0, len(srcItems)),
|
||||
}
|
||||
|
||||
getString := func(item map[string]interface{}, key string) string {
|
||||
if v, ok := item[key]; ok {
|
||||
if str, ok := v.(string); ok {
|
||||
return str
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
for i, v := range srcItems {
|
||||
resp.Items = append(resp.Items, QYGL4B2EItem{
|
||||
ID: int64(i + 1),
|
||||
TaxpayerName: getString(v, "entityName"),
|
||||
Department: getString(v, "belongDepartment"),
|
||||
CaseType: getString(v, "caseType"),
|
||||
PublishTime: getString(v, "illegalTime"),
|
||||
})
|
||||
}
|
||||
|
||||
return json.Marshal(resp)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
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/shumai"
|
||||
)
|
||||
|
||||
// ProcessQYGL4YABRequest QYGL4YAB API处理方法 - 企业四要素认证
|
||||
func ProcessQYGL4YABRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.QYGL4YABReq
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"idCard": paramsDto.IDCard,
|
||||
"legalPerson": paramsDto.LegalPerson,
|
||||
"companyName": paramsDto.EntName,
|
||||
"creditNo": paramsDto.EntCode,
|
||||
}
|
||||
apiPath := "/v4/company-four/check" // 接口路径,根据数脉文档填写(如 v4/xxx)
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
if errors.Is(err, shumai.ErrDatasource) {
|
||||
// 数据源错误
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
} else if errors.Is(err, shumai.ErrSystem) {
|
||||
// 系统错误
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
} else if errors.Is(err, shumai.ErrNotFound) {
|
||||
// 查无记录
|
||||
return nil, errors.Join(processors.ErrNotFound, err)
|
||||
} else {
|
||||
// 其他未知错误
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
}
|
||||
return respBytes, nil
|
||||
|
||||
}
|
||||
@@ -38,8 +38,10 @@ func ProcessQYGL6S1BRequest(ctx context.Context, params []byte, deps *processors
|
||||
}
|
||||
if errors.Is(err, shujubao.ErrQueryEmpty) {
|
||||
return nil, errors.Join(processors.ErrNotFound, err)
|
||||
// data = map[string]interface{}{}
|
||||
} else {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
// 解析响应中的 JSON 字符串(使用 RecursiveParse)
|
||||
|
||||
@@ -8,8 +8,59 @@ import (
|
||||
|
||||
"tyapi-server/internal/domains/api/dto"
|
||||
"tyapi-server/internal/domains/api/services/processors"
|
||||
"tyapi-server/internal/infrastructure/external/shujubao"
|
||||
)
|
||||
|
||||
/*
|
||||
## 返回字段说明
|
||||
|
||||
| 返回值字段 | 字段类型 | 字段说明 | 备注 |
|
||||
|------------|----------|----------|------|
|
||||
| total | Number | int(11) | 总数 |
|
||||
| items | Array | | |
|
||||
| _child | Object | | |
|
||||
| taxIdNumber | String | varchar(150) | 纳税人识别号 |
|
||||
| newOwnTaxBalance | String | varchar(20) | 当前新发生欠税余额 |
|
||||
| ownTaxAmount | String | varchar(50) | 欠税金额 |
|
||||
| publishDate | String | 日期 | 发布时间 |
|
||||
| ownTaxBalance | String | varchar(20) | 欠税余额 |
|
||||
| type | String | varchar(10) | 税务类型 |
|
||||
| personIdNumber | String | varchar(150) | 证件号码 |
|
||||
| taxCategory | String | varchar(255) | 欠税税种 |
|
||||
| taxpayerType | String | varchar(10) | 纳税人类型 |
|
||||
| personIdName | String | varchar(50) | 法人证件名称 |
|
||||
| name | String | varchar(255) | 纳税人名称 |
|
||||
| location | String | varchar(150) | 经营地点 |
|
||||
| department | String | varchar(200) | 税务机关 |
|
||||
| regType | String | varchar(50) | 注册类型 |
|
||||
| legalpersonName | String | varchar(150) | 法人或负责人名称 |
|
||||
*/
|
||||
|
||||
// QYGL7D9AItem 返回列表项
|
||||
type QYGL7D9AItem struct {
|
||||
TaxIdNumber string `json:"taxIdNumber"`
|
||||
NewOwnTaxBalance string `json:"newOwnTaxBalance"`
|
||||
OwnTaxAmount string `json:"ownTaxAmount"`
|
||||
PublishDate string `json:"publishDate"`
|
||||
OwnTaxBalance string `json:"ownTaxBalance"`
|
||||
Type string `json:"type"`
|
||||
PersonIdNumber string `json:"personIdNumber"`
|
||||
TaxCategory string `json:"taxCategory"`
|
||||
TaxpayerType string `json:"taxpayerType"`
|
||||
PersonIdName string `json:"personIdName"`
|
||||
Name string `json:"name"`
|
||||
Location string `json:"location"`
|
||||
Department string `json:"department"`
|
||||
RegType string `json:"regType"`
|
||||
LegalpersonName string `json:"legalpersonName"`
|
||||
}
|
||||
|
||||
// QYGL7D9AResponse 最终返回结构
|
||||
type QYGL7D9AResponse struct {
|
||||
Total int64 `json:"total"`
|
||||
Items []QYGL7D9AItem `json:"items"`
|
||||
}
|
||||
|
||||
// ProcessQYGL7D9ARequest QYGL7D9A API处理方法 - 欠税公告
|
||||
func ProcessQYGL7D9ARequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.QYGL5A3CReq
|
||||
@@ -21,39 +72,100 @@ func ProcessQYGL7D9ARequest(ctx context.Context, params []byte, deps *processors
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
|
||||
// 设置默认值
|
||||
// 默认值
|
||||
pageSize := paramsDto.PageSize
|
||||
if pageSize == 0 {
|
||||
pageSize = int64(20)
|
||||
pageSize = 20
|
||||
}
|
||||
pageNum := paramsDto.PageNum
|
||||
if pageNum == 0 {
|
||||
pageNum = int64(1)
|
||||
pageNum = 1
|
||||
}
|
||||
|
||||
// 构建API调用参数
|
||||
apiParams := map[string]string{
|
||||
"keyword": paramsDto.EntCode,
|
||||
"pageSize": strconv.FormatInt(pageSize, 10),
|
||||
"pageNum": strconv.FormatInt(pageNum, 10),
|
||||
// 调用外部接口
|
||||
reqParams := map[string]interface{}{
|
||||
"key": "9ad1365cb0580863a239b0255649fb1a",
|
||||
"creditCode": paramsDto.EntCode,
|
||||
}
|
||||
|
||||
// 调用天眼查API - 欠税公告
|
||||
response, err := deps.TianYanChaService.CallAPI(ctx, "OwnTax", apiParams)
|
||||
apiPath := "/communication/personal/10235"
|
||||
data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams)
|
||||
if err != nil {
|
||||
return nil, convertTianYanChaError(err)
|
||||
if errors.Is(err, shujubao.ErrDatasource) {
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
}
|
||||
if errors.Is(err, shujubao.ErrQueryEmpty) {
|
||||
data = map[string]interface{}{}
|
||||
} else {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 检查天眼查API调用是否成功
|
||||
if !response.Success {
|
||||
return nil, errors.Join(processors.ErrDatasource, errors.New(response.Message))
|
||||
// 原始返回结构处理 - data 是 map[string]interface{} 类型
|
||||
dataMap, ok := data.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, errors.Join(processors.ErrSystem, errors.New("data不是map类型"))
|
||||
}
|
||||
|
||||
// 返回天眼查响应数据
|
||||
respBytes, err := json.Marshal(response.Data)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
// 提取 total
|
||||
totalStr := ""
|
||||
if v, ok := dataMap["total"]; ok {
|
||||
if str, ok := v.(string); ok {
|
||||
totalStr = str
|
||||
}
|
||||
}
|
||||
|
||||
return respBytes, nil
|
||||
// 提取 items 数组
|
||||
srcItems := make([]map[string]interface{}, 0)
|
||||
if v, ok := dataMap["items"]; ok {
|
||||
if arr, ok := v.([]interface{}); ok {
|
||||
for _, item := range arr {
|
||||
if itemMap, ok := item.(map[string]interface{}); ok {
|
||||
srcItems = append(srcItems, itemMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 构造返回数据(缺失字段留空字符串)
|
||||
resp := QYGL7D9AResponse{
|
||||
Total: 0,
|
||||
Items: make([]QYGL7D9AItem, 0, len(srcItems)),
|
||||
}
|
||||
|
||||
getString := func(item map[string]interface{}, key string) string {
|
||||
if v, ok := item[key]; ok {
|
||||
if str, ok := v.(string); ok {
|
||||
return str
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, v := range srcItems {
|
||||
resp.Items = append(resp.Items, QYGL7D9AItem{
|
||||
TaxIdNumber: getString(v, "taxpayerCode"),
|
||||
NewOwnTaxBalance: getString(v, "thisOwedAmount"),
|
||||
OwnTaxAmount: getString(v, "totalOwedAmount"),
|
||||
PublishDate: getString(v, "publishDate"),
|
||||
OwnTaxBalance: getString(v, "beforeOwedAmount"),
|
||||
Type: getString(v, "taxBureauType"),
|
||||
PersonIdNumber: "",
|
||||
TaxCategory: getString(v, "taxOwedType"),
|
||||
TaxpayerType: "",
|
||||
PersonIdName: "",
|
||||
Name: getString(v, "entityName"),
|
||||
Location: getString(v, "businessAddress"),
|
||||
Department: getString(v, "taxBureauName"),
|
||||
RegType: "",
|
||||
LegalpersonName: getString(v, "legalPerson"),
|
||||
})
|
||||
}
|
||||
|
||||
// total 转 int64
|
||||
if totalStr != "" {
|
||||
resp.Total, _ = strconv.ParseInt(totalStr, 10, 64)
|
||||
}
|
||||
|
||||
return json.Marshal(resp)
|
||||
}
|
||||
|
||||
@@ -8,8 +8,50 @@ import (
|
||||
|
||||
"tyapi-server/internal/domains/api/dto"
|
||||
"tyapi-server/internal/domains/api/services/processors"
|
||||
"tyapi-server/internal/infrastructure/external/shujubao"
|
||||
)
|
||||
|
||||
/*
|
||||
## 返回字段说明
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| items | array | 融资历史记录列表,无记录时为空数组 |
|
||||
| items[].round | string | 融资轮次 |
|
||||
| items[].amount | string | 融资金额 |
|
||||
| items[].date | string | 融资日期,格式:YYYY-MM-DD |
|
||||
| items[].investors | array of string | 投资方列表 |
|
||||
| items[].postValuation | string | 融资后估值 |
|
||||
| items[].preValuation | string | 融资前估值 |
|
||||
| items[].currency | string | 币种 |
|
||||
| items[].intro | string | 项目简介 |
|
||||
| items[].shareRatio | string | 持股比例 |
|
||||
| total | integer | 符合条件的融资记录总数,无记录时为 0 |
|
||||
| pageNum | integer | 当前页码 |
|
||||
| pageSize | integer | 每页记录条数 |
|
||||
*/
|
||||
|
||||
// QYGL8B4DItem 融资历史单项
|
||||
type QYGL8B4DItem struct {
|
||||
Round string `json:"round"`
|
||||
Amount string `json:"amount"`
|
||||
Date string `json:"date"`
|
||||
Investors []string `json:"investors"`
|
||||
PostValuation string `json:"postValuation"`
|
||||
PreValuation string `json:"preValuation"`
|
||||
Currency string `json:"currency"`
|
||||
Intro string `json:"intro"`
|
||||
ShareRatio string `json:"shareRatio"`
|
||||
}
|
||||
|
||||
// QYGL8B4DResponse 融资历史返回结构
|
||||
type QYGL8B4DResponse struct {
|
||||
Items []QYGL8B4DItem `json:"items"`
|
||||
Total int64 `json:"total"`
|
||||
PageNum int64 `json:"pageNum"`
|
||||
PageSize int64 `json:"pageSize"`
|
||||
}
|
||||
|
||||
// ProcessQYGL8B4DRequest QYGL8B4D API处理方法 - 融资历史
|
||||
func ProcessQYGL8B4DRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.QYGL8B4DReq
|
||||
@@ -21,7 +63,7 @@ func ProcessQYGL8B4DRequest(ctx context.Context, params []byte, deps *processors
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
|
||||
// 设置默认值
|
||||
// 默认值
|
||||
pageSize := paramsDto.PageSize
|
||||
if pageSize == 0 {
|
||||
pageSize = int64(20)
|
||||
@@ -31,29 +73,100 @@ func ProcessQYGL8B4DRequest(ctx context.Context, params []byte, deps *processors
|
||||
pageNum = int64(1)
|
||||
}
|
||||
|
||||
// 构建API调用参数
|
||||
apiParams := map[string]string{
|
||||
"keyword": paramsDto.EntCode,
|
||||
"pageSize": strconv.FormatInt(pageSize, 10),
|
||||
"pageNum": strconv.FormatInt(pageNum, 10),
|
||||
// 调用外部接口
|
||||
reqParams := map[string]interface{}{
|
||||
"key": "8887a17748d767b0a1f417171108873f",
|
||||
"creditCode": paramsDto.EntCode,
|
||||
}
|
||||
|
||||
// 调用天眼查API - 融资历史
|
||||
response, err := deps.TianYanChaService.CallAPI(ctx, "FinancingHistory", apiParams)
|
||||
apiPath := "/communication/personal/10435"
|
||||
data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams)
|
||||
if err != nil {
|
||||
return nil, convertTianYanChaError(err)
|
||||
if errors.Is(err, shujubao.ErrDatasource) {
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
}
|
||||
if errors.Is(err, shujubao.ErrQueryEmpty) {
|
||||
data = map[string]interface{}{}
|
||||
} else {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 检查天眼查API调用是否成功
|
||||
if !response.Success {
|
||||
return nil, errors.Join(processors.ErrDatasource, errors.New(response.Message))
|
||||
// 原始返回结构处理 - data 是 map[string]interface{} 类型
|
||||
dataMap, ok := data.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, errors.Join(processors.ErrSystem, errors.New("data不是map类型"))
|
||||
}
|
||||
|
||||
// 返回天眼查响应数据
|
||||
respBytes, err := json.Marshal(response.Data)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
// 提取 page 对象中的 totalRecords
|
||||
totalRecords := ""
|
||||
if page, ok := dataMap["page"].(map[string]interface{}); ok {
|
||||
if v, ok := page["totalRecords"]; ok {
|
||||
if str, ok := v.(string); ok {
|
||||
totalRecords = str
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return respBytes, nil
|
||||
// 提取 records 数组(不是 items)
|
||||
records := make([]map[string]interface{}, 0)
|
||||
if v, ok := dataMap["records"]; ok {
|
||||
if arr, ok := v.([]interface{}); ok {
|
||||
for _, item := range arr {
|
||||
if itemMap, ok := item.(map[string]interface{}); ok {
|
||||
records = append(records, itemMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 构造返回数据
|
||||
resp := QYGL8B4DResponse{
|
||||
Items: make([]QYGL8B4DItem, 0, len(records)),
|
||||
PageNum: pageNum,
|
||||
PageSize: pageSize,
|
||||
}
|
||||
|
||||
for _, item := range records {
|
||||
// 提取字段,使用类型断言
|
||||
getString := func(key string) string {
|
||||
if v, ok := item[key]; ok {
|
||||
if str, ok := v.(string); ok {
|
||||
return str
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
investAmount := getString("investAmount")
|
||||
afterValuation := getString("afterInvestValuation")
|
||||
|
||||
// 计算持股比例:持股比例 = 本轮投资金额 / 投后估值 × 100%
|
||||
shareRatio := ""
|
||||
investAmountFloat, err1 := strconv.ParseFloat(investAmount, 64)
|
||||
afterValuationFloat, err2 := strconv.ParseFloat(afterValuation, 64)
|
||||
if err1 == nil && err2 == nil && afterValuationFloat > 0 {
|
||||
ratio := investAmountFloat / afterValuationFloat * 100
|
||||
shareRatio = strconv.FormatFloat(ratio, 'f', 2, 64) // 保留两位小数
|
||||
}
|
||||
|
||||
resp.Items = append(resp.Items, QYGL8B4DItem{
|
||||
Round: getString("financingRound"),
|
||||
Amount: investAmount,
|
||||
Date: getString("financingDate"),
|
||||
Investors: []string{getString("financingRoundInvestor")},
|
||||
PostValuation: afterValuation,
|
||||
PreValuation: getString("beforeInvestValuation"),
|
||||
Currency: getString("currency"),
|
||||
Intro: "",
|
||||
ShareRatio: shareRatio,
|
||||
})
|
||||
}
|
||||
|
||||
// total
|
||||
if totalRecords != "" {
|
||||
resp.Total, _ = strconv.ParseInt(totalRecords, 10, 64)
|
||||
}
|
||||
|
||||
return json.Marshal(resp)
|
||||
}
|
||||
|
||||
@@ -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{}{
|
||||
"companyName": 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))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
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/shumai"
|
||||
)
|
||||
|
||||
// ProcessQYGLDG77Request QYGLDG77 API处理方法 - 企业打款认证
|
||||
func ProcessQYGLDG77Request(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) {
|
||||
var paramsDto dto.QYGLDG77Req
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
reqFormData := map[string]interface{}{
|
||||
"companyName": paramsDto.EntName,
|
||||
"accountNo": paramsDto.AccountNo,
|
||||
"accountBank": paramsDto.AccountBank,
|
||||
}
|
||||
apiPath := "/v2/company/dkrz/check" // 接口路径,根据数脉文档填写(如 v4/xxx)
|
||||
respBytes, err := deps.ShumaiService.CallAPIForm(ctx, apiPath, reqFormData)
|
||||
if err != nil {
|
||||
if errors.Is(err, shumai.ErrDatasource) {
|
||||
// 数据源错误
|
||||
return nil, errors.Join(processors.ErrDatasource, err)
|
||||
} else if errors.Is(err, shumai.ErrSystem) {
|
||||
// 系统错误
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
} else if errors.Is(err, shumai.ErrNotFound) {
|
||||
// 查无记录
|
||||
return nil, errors.Join(processors.ErrNotFound, err)
|
||||
} else {
|
||||
// 其他未知错误
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
}
|
||||
return respBytes, nil
|
||||
|
||||
}
|
||||
@@ -35,6 +35,8 @@ type Certification struct {
|
||||
EsignFlowID string `gorm:"type:varchar(500)" json:"esign_flow_id,omitempty" comment:"签署流程ID"`
|
||||
ContractURL string `gorm:"type:varchar(500)" json:"contract_url,omitempty" comment:"合同文件访问链接"`
|
||||
ContractSignURL string `gorm:"type:varchar(500)" json:"contract_sign_url,omitempty" comment:"合同签署链接"`
|
||||
// ContractCode 合作协议编号(与电子合同模板控件 xybh 一致,签署完成后写入用户域合同)
|
||||
ContractCode string `gorm:"type:varchar(255)" json:"contract_code,omitempty" comment:"合作协议编号"`
|
||||
|
||||
// === 失败信息 ===
|
||||
FailureReason enums.FailureReason `gorm:"type:varchar(100)" json:"failure_reason,omitempty" comment:"失败原因"`
|
||||
@@ -323,6 +325,11 @@ func (c *Certification) ApplyContract(EsignFlowID string, ContractSignURL string
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetContractCode 设置合作协议编号(首次生成合同时写入,后续换文件复用)
|
||||
func (c *Certification) SetContractCode(code string) {
|
||||
c.ContractCode = code
|
||||
}
|
||||
|
||||
// AddContractFileID 生成合同文件
|
||||
func (c *Certification) AddContractFileID(contractFileID string, contractURL string) error {
|
||||
c.ContractFileID = contractFileID
|
||||
|
||||
@@ -435,3 +435,31 @@ func (s *ProductManagementService) ListProductsWithSubscriptionStatus(ctx contex
|
||||
|
||||
return products, subscriptionStatusMap, total, nil
|
||||
}
|
||||
|
||||
// GetAllProductsForDictionary 获取所有启用且可见的产品(用于导出产品字典)
|
||||
func (s *ProductManagementService) GetAllProductsForDictionary(ctx context.Context) ([]*entities.Product, error) {
|
||||
// 构建查询条件:启用且可见
|
||||
isEnabled := true
|
||||
isVisible := true
|
||||
|
||||
filters := map[string]interface{}{
|
||||
"is_enabled": isEnabled,
|
||||
"is_visible": isVisible,
|
||||
}
|
||||
|
||||
options := interfaces.ListOptions{
|
||||
Page: 1,
|
||||
PageSize: 1000, // 获取所有产品
|
||||
Sort: "id", // 按产品ID排序,避免JOIN问题
|
||||
Order: "asc",
|
||||
}
|
||||
|
||||
// 获取产品列表
|
||||
products, _, err := s.ListProducts(ctx, filters, options)
|
||||
if err != nil {
|
||||
s.logger.Error("获取产品字典数据失败", zap.Error(err))
|
||||
return nil, fmt.Errorf("获取产品字典数据失败: %w", err)
|
||||
}
|
||||
|
||||
return products, nil
|
||||
}
|
||||
|
||||
@@ -119,6 +119,58 @@ func NewContractInfo(enterpriseInfoID, userID, contractName string, contractType
|
||||
return contractInfo, nil
|
||||
}
|
||||
|
||||
// NewContractInfoWithContractCode 使用指定合同编号创建合同信息(与认证阶段生成的编号一致)
|
||||
func NewContractInfoWithContractCode(enterpriseInfoID, userID, contractName string, contractType ContractType, contractFileID, contractFileURL, contractCode string) (*ContractInfo, error) {
|
||||
if enterpriseInfoID == "" {
|
||||
return nil, fmt.Errorf("企业信息ID不能为空")
|
||||
}
|
||||
if userID == "" {
|
||||
return nil, fmt.Errorf("用户ID不能为空")
|
||||
}
|
||||
if contractName == "" {
|
||||
return nil, fmt.Errorf("合同名称不能为空")
|
||||
}
|
||||
if contractType == "" {
|
||||
return nil, fmt.Errorf("合同类型不能为空")
|
||||
}
|
||||
if contractFileID == "" {
|
||||
return nil, fmt.Errorf("合同文件ID不能为空")
|
||||
}
|
||||
if contractFileURL == "" {
|
||||
return nil, fmt.Errorf("合同文件URL不能为空")
|
||||
}
|
||||
if contractCode == "" {
|
||||
return nil, fmt.Errorf("合同编号不能为空")
|
||||
}
|
||||
if !isValidContractType(contractType) {
|
||||
return nil, fmt.Errorf("无效的合同类型: %s", contractType)
|
||||
}
|
||||
|
||||
contractInfo := &ContractInfo{
|
||||
ID: uuid.New().String(),
|
||||
EnterpriseInfoID: enterpriseInfoID,
|
||||
UserID: userID,
|
||||
ContractCode: contractCode,
|
||||
ContractName: contractName,
|
||||
ContractType: contractType,
|
||||
ContractFileID: contractFileID,
|
||||
ContractFileURL: contractFileURL,
|
||||
domainEvents: make([]interface{}, 0),
|
||||
}
|
||||
|
||||
contractInfo.addDomainEvent(&ContractInfoCreatedEvent{
|
||||
ContractInfoID: contractInfo.ID,
|
||||
EnterpriseInfoID: enterpriseInfoID,
|
||||
UserID: userID,
|
||||
ContractCode: contractCode,
|
||||
ContractName: contractName,
|
||||
ContractType: string(contractType),
|
||||
CreatedAt: time.Now(),
|
||||
})
|
||||
|
||||
return contractInfo, nil
|
||||
}
|
||||
|
||||
// ================ 聚合根核心方法 ================
|
||||
|
||||
// UpdateContractInfo 更新合同信息
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
type ContractAggregateService interface {
|
||||
// 聚合根生命周期管理
|
||||
CreateContract(ctx context.Context, enterpriseInfoID, userID, contractName string, contractType entities.ContractType, contractFileID, contractFileURL string) (*entities.ContractInfo, error)
|
||||
CreateContractWithCode(ctx context.Context, enterpriseInfoID, userID, contractName string, contractType entities.ContractType, contractFileID, contractFileURL, contractCode string) (*entities.ContractInfo, error)
|
||||
LoadContract(ctx context.Context, contractID string) (*entities.ContractInfo, error)
|
||||
SaveContract(ctx context.Context, contract *entities.ContractInfo) error
|
||||
DeleteContract(ctx context.Context, contractID string) error
|
||||
@@ -94,6 +95,51 @@ func (s *ContractAggregateServiceImpl) CreateContract(
|
||||
return contract, nil
|
||||
}
|
||||
|
||||
// CreateContractWithCode 使用指定合同编号创建合同信息(与认证合同模板上的编号一致)
|
||||
func (s *ContractAggregateServiceImpl) CreateContractWithCode(
|
||||
ctx context.Context,
|
||||
enterpriseInfoID, userID, contractName string,
|
||||
contractType entities.ContractType,
|
||||
contractFileID, contractFileURL, contractCode string,
|
||||
) (*entities.ContractInfo, error) {
|
||||
s.logger.Debug("创建合同信息(指定编号)",
|
||||
zap.String("enterprise_info_id", enterpriseInfoID),
|
||||
zap.String("user_id", userID),
|
||||
zap.String("contract_name", contractName),
|
||||
zap.String("contract_code", contractCode),
|
||||
zap.String("contract_type", string(contractType)))
|
||||
|
||||
exists, err := s.ExistsByContractFileID(ctx, contractFileID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("检查合同文件ID失败: %w", err)
|
||||
}
|
||||
if exists {
|
||||
return nil, fmt.Errorf("合同文件ID已存在")
|
||||
}
|
||||
|
||||
contract, err := entities.NewContractInfoWithContractCode(enterpriseInfoID, userID, contractName, contractType, contractFileID, contractFileURL, contractCode)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("创建合同信息失败: %w", err)
|
||||
}
|
||||
|
||||
if err := s.ValidateBusinessRules(ctx, contract); err != nil {
|
||||
return nil, fmt.Errorf("业务规则验证失败: %w", err)
|
||||
}
|
||||
|
||||
err = s.SaveContract(ctx, contract)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("保存合同信息失败: %w", err)
|
||||
}
|
||||
|
||||
s.logger.Info("合同信息创建成功",
|
||||
zap.String("contract_id", contract.ID),
|
||||
zap.String("enterprise_info_id", enterpriseInfoID),
|
||||
zap.String("contract_code", contractCode),
|
||||
zap.String("contract_name", contractName))
|
||||
|
||||
return contract, nil
|
||||
}
|
||||
|
||||
// LoadContract 加载合同信息
|
||||
func (s *ContractAggregateServiceImpl) LoadContract(ctx context.Context, contractID string) (*entities.ContractInfo, error) {
|
||||
s.logger.Debug("加载合同信息", zap.String("contract_id", contractID))
|
||||
|
||||
Reference in New Issue
Block a user