From 2a93d120f117ed59df64371088d30278811238e0 Mon Sep 17 00:00:00 2001 From: liangzai <2440983361@qq.com> Date: Tue, 26 Aug 2025 14:43:27 +0800 Subject: [PATCH] add new api --- internal/domains/api/dto/api_request_dto.go | 116 +++++++++++++ .../api/services/api_request_service.go | 23 +++ .../processors/dwbg/dwbg6a2c_processor.go | 61 +++++++ .../processors/dwbg/dwbg8b4d_processor.go | 61 +++++++ .../processors/flxg/flxg2e8f_processor.go | 61 +++++++ .../processors/flxg/flxg5a3b_processor.go | 57 +++++++ .../processors/flxg/flxg8b4d_processor.go | 104 +++++++++++ .../processors/flxg/flxg9c1d_processor.go | 57 +++++++ .../processors/ivyz/ivyz2a8b_processor.go | 57 +++++++ .../processors/ivyz/ivyz5e3f_processor.go | 57 +++++++ .../processors/ivyz/ivyz7c9d_processor.go | 58 +++++++ .../processors/jrzq/jrzq3c7b_processor.go | 63 +++++++ .../processors/jrzq/jrzq4b6c_processor.go | 63 +++++++ .../processors/jrzq/jrzq5e9f_processor.go | 63 +++++++ .../processors/jrzq/jrzq7f1a_processor.go | 63 +++++++ .../processors/jrzq/jrzq8a2d_processor.go | 63 +++++++ .../processors/yysy/yysy3e7f_processor.go | 50 ++++++ .../processors/yysy/yysy4f2e_processor.go | 63 +++++++ .../processors/yysy/yysy6d9a_processor.go | 50 ++++++ .../processors/yysy/yysy8b1c_processor.go | 50 ++++++ .../validator/authorization_url_test.go | 108 ++++++++++++ .../shared/validator/custom_validators.go | 161 ++++++++++++++---- internal/shared/validator/translations.go | 33 +++- 23 files changed, 1503 insertions(+), 39 deletions(-) create mode 100644 internal/domains/api/services/processors/dwbg/dwbg6a2c_processor.go create mode 100644 internal/domains/api/services/processors/dwbg/dwbg8b4d_processor.go create mode 100644 internal/domains/api/services/processors/flxg/flxg2e8f_processor.go create mode 100644 internal/domains/api/services/processors/flxg/flxg5a3b_processor.go create mode 100644 internal/domains/api/services/processors/flxg/flxg8b4d_processor.go create mode 100644 internal/domains/api/services/processors/flxg/flxg9c1d_processor.go create mode 100644 internal/domains/api/services/processors/ivyz/ivyz2a8b_processor.go create mode 100644 internal/domains/api/services/processors/ivyz/ivyz5e3f_processor.go create mode 100644 internal/domains/api/services/processors/ivyz/ivyz7c9d_processor.go create mode 100644 internal/domains/api/services/processors/jrzq/jrzq3c7b_processor.go create mode 100644 internal/domains/api/services/processors/jrzq/jrzq4b6c_processor.go create mode 100644 internal/domains/api/services/processors/jrzq/jrzq5e9f_processor.go create mode 100644 internal/domains/api/services/processors/jrzq/jrzq7f1a_processor.go create mode 100644 internal/domains/api/services/processors/jrzq/jrzq8a2d_processor.go create mode 100644 internal/domains/api/services/processors/yysy/yysy3e7f_processor.go create mode 100644 internal/domains/api/services/processors/yysy/yysy4f2e_processor.go create mode 100644 internal/domains/api/services/processors/yysy/yysy6d9a_processor.go create mode 100644 internal/domains/api/services/processors/yysy/yysy8b1c_processor.go create mode 100644 internal/shared/validator/authorization_url_test.go diff --git a/internal/domains/api/dto/api_request_dto.go b/internal/domains/api/dto/api_request_dto.go index ca6062d..47ec3e6 100644 --- a/internal/domains/api/dto/api_request_dto.go +++ b/internal/domains/api/dto/api_request_dto.go @@ -251,3 +251,119 @@ type JRZQ1D09Req struct { Name string `json:"name" validate:"required,min=1,validName"` Authorized string `json:"authorized" validate:"required,oneof=0 1"` } + +// 新增的处理器DTO +type IVYZ2A8BReq struct { + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + Authorized string `json:"authorized" validate:"required,oneof=0 1"` +} + +type IVYZ7C9DReq struct { + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + UniqueID string `json:"unique_id" validate:"required,validUniqueID"` + ReturnURL string `json:"return_url" validate:"required,validReturnURL"` +} + +type IVYZ5E3FReq struct { + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + Authorized string `json:"authorized" validate:"required,oneof=0 1"` +} + +type YYSY4F2EReq struct { + MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"` + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + Authorized string `json:"authorized" validate:"required,oneof=0 1"` +} + +type YYSY8B1CReq struct { + MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"` +} + +type YYSY6D9AReq struct { + MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"` + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + Authorized string `json:"authorized" validate:"required,oneof=0 1"`} + +type YYSY3E7FReq struct { + MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"` +} + +type FLXG5A3BReq struct { + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + Authorized string `json:"authorized" validate:"required,oneof=0 1"` +} + +type FLXG9C1DReq struct { + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + Authorized string `json:"authorized" validate:"required,oneof=0 1"` +} + +type FLXG2E8FReq struct { + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"` + AuthorizationURL string `json:"authorization_url" validate:"required,authorization_url"` +} + +type JRZQ3C7BReq struct { + MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"` + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + Authorized string `json:"authorized" validate:"required,oneof=0 1"` +} + +type JRZQ8A2DReq struct { + MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"` + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + Authorized string `json:"authorized" validate:"required,oneof=0 1"` +} + +type JRZQ5E9FReq struct { + MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"` + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + Authorized string `json:"authorized" validate:"required,oneof=0 1"` +} + +type JRZQ4B6CReq struct { + MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"` + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + Authorized string `json:"authorized" validate:"required,oneof=0 1"` +} + +type JRZQ7F1AReq struct { + MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"` + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + Authorized string `json:"authorized" validate:"required,oneof=0 1"` +} + +type DWBG6A2CReq struct { + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"` + AuthorizationURL string `json:"authorization_url" validate:"required,authorization_url"` +} + +type DWBG8B4DReq struct { + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + MobileNo string `json:"mobile_no" validate:"required,min=11,max=11,validMobileNo"` + AuthorizationURL string `json:"authorization_url" validate:"required,authorization_url"` +} + +type FLXG8B4DReq struct { + MobileNo string `json:"mobile_no" validate:"omitempty,min=11,max=11,validMobileNo"` + IDCard string `json:"id_card" validate:"omitempty,validIDCard"` + BankCard string `json:"bank_card" validate:"omitempty,validBankCard"` + Authorized string `json:"authorized" validate:"required,oneof=0 1"` +} diff --git a/internal/domains/api/services/api_request_service.go b/internal/domains/api/services/api_request_service.go index 85b5543..2180795 100644 --- a/internal/domains/api/services/api_request_service.go +++ b/internal/domains/api/services/api_request_service.go @@ -7,6 +7,7 @@ import ( "tyapi-server/internal/application/api/commands" "tyapi-server/internal/domains/api/services/processors" "tyapi-server/internal/domains/api/services/processors/comb" + "tyapi-server/internal/domains/api/services/processors/dwbg" "tyapi-server/internal/domains/api/services/processors/flxg" "tyapi-server/internal/domains/api/services/processors/ivyz" "tyapi-server/internal/domains/api/services/processors/jrzq" @@ -92,6 +93,9 @@ func registerAllProcessors(combService *comb.CombService) { "FLXGBC21": flxg.ProcessFLXGBC21Request, "FLXGDEA8": flxg.ProcessFLXGDEA8Request, "FLXGDEA9": flxg.ProcessFLXGDEA9Request, + "FLXG5A3B": flxg.ProcessFLXG5A3BRequest, + "FLXG9C1D": flxg.ProcessFLXG9C1DRequest, + "FLXG2E8F": flxg.ProcessFLXG2E8FRequest, // JRZQ系列处理器 "JRZQ8203": jrzq.ProcessJRZQ8203Request, @@ -100,6 +104,11 @@ func registerAllProcessors(combService *comb.CombService) { "JRZQDCBE": jrzq.ProcessJRZQDCBERequest, "JRZQ09J8": jrzq.ProcessJRZQ09J8Request, "JRZQ1D09": jrzq.ProcessJRZQ1D09Request, + "JRZQ3C7B": jrzq.ProcessJRZQ3C7BRequest, + "JRZQ8A2D": jrzq.ProcessJRZQ8A2DRequest, + "JRZQ5E9F": jrzq.ProcessJRZQ5E9FRequest, + "JRZQ4B6C": jrzq.ProcessJRZQ4B6CRequest, + "JRZQ7F1A": jrzq.ProcessJRZQ7F1ARequest, // QYGL系列处理器 "QYGL8261": qygl.ProcessQYGL8261Request, @@ -119,6 +128,10 @@ func registerAllProcessors(combService *comb.CombService) { "YYSY6F2E": yysy.ProcessYYSY6F2ERequest, "YYSYBE08": yysy.ProcessYYSYBE08Request, "YYSYF7DB": yysy.ProcessYYSYF7DBRequest, + "YYSY4F2E": yysy.ProcessYYSY4F2ERequest, + "YYSY8B1C": yysy.ProcessYYSY8B1CRequest, + "YYSY6D9A": yysy.ProcessYYSY6D9ARequest, + "YYSY3E7F": yysy.ProcessYYSY3E7FRequest, // IVYZ系列处理器 "IVYZ0B03": ivyz.ProcessIVYZ0B03Request, @@ -132,6 +145,9 @@ func registerAllProcessors(combService *comb.CombService) { "IVYZ4E8B": ivyz.ProcessIVYZ4E8BRequest, "IVYZ1C9D": ivyz.ProcessIVYZ1C9DRequest, "IVYZGZ08": ivyz.ProcessIVYZGZ08Request, + "IVYZ2A8B": ivyz.ProcessIVYZ2A8BRequest, + "IVYZ7C9D": ivyz.ProcessIVYZ7C9DRequest, + "IVYZ5E3F": ivyz.ProcessIVYZ5E3FRequest, // COMB系列处理器 "COMB298Y": comb.ProcessCOMB298YRequest, @@ -139,6 +155,13 @@ func registerAllProcessors(combService *comb.CombService) { // QCXG系列处理器 "QCXG7A2B": qcxg.ProcessQCXG7A2BRequest, + + // DWBG系列处理器 - 多维报告 + "DWBG6A2C": dwbg.ProcessDWBG6A2CRequest, + "DWBG8B4D": dwbg.ProcessDWBG8B4DRequest, + + // FLXG系列处理器 - 风险管控 (包含原FXHY功能) + "FLXG8B4D": flxg.ProcessFLXG8B4DRequest, } // 批量注册到组合包服务 diff --git a/internal/domains/api/services/processors/dwbg/dwbg6a2c_processor.go b/internal/domains/api/services/processors/dwbg/dwbg6a2c_processor.go new file mode 100644 index 0000000..4923e95 --- /dev/null +++ b/internal/domains/api/services/processors/dwbg/dwbg6a2c_processor.go @@ -0,0 +1,61 @@ +package dwbg + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessDWBG6A2CRequest DWBG6A2C API处理方法 - 司南报告 +func ProcessDWBG6A2CRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.DWBG6A2CReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + reqData := map[string]interface{}{ + "name": encryptedName, + "idCard": encryptedIDCard, + "mobileNo": encryptedMobileNo, + "authorizationURL": paramsDto.AuthorizationURL, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI102", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/dwbg/dwbg8b4d_processor.go b/internal/domains/api/services/processors/dwbg/dwbg8b4d_processor.go new file mode 100644 index 0000000..895ac58 --- /dev/null +++ b/internal/domains/api/services/processors/dwbg/dwbg8b4d_processor.go @@ -0,0 +1,61 @@ +package dwbg + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessDWBG8B4DRequest DWBG8B4D API处理方法 - 谛听多维报告 +func ProcessDWBG8B4DRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.DWBG8B4DReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + reqData := map[string]interface{}{ + "name": encryptedName, + "idCard": encryptedIDCard, + "mobileNo": encryptedMobileNo, + "authorizationURL": paramsDto.AuthorizationURL, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI103", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/flxg/flxg2e8f_processor.go b/internal/domains/api/services/processors/flxg/flxg2e8f_processor.go new file mode 100644 index 0000000..46cd1ad --- /dev/null +++ b/internal/domains/api/services/processors/flxg/flxg2e8f_processor.go @@ -0,0 +1,61 @@ +package flxg + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessFLXG2E8FRequest FLXG2E8F API处理方法 - 司法核验报告 +func ProcessFLXG2E8FRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.FLXG2E8FReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + reqData := map[string]interface{}{ + "name": encryptedName, + "idCard": encryptedIDCard, + "mobileNo": encryptedMobileNo, + "authorizationURL": paramsDto.AuthorizationURL, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI101", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/flxg/flxg5a3b_processor.go b/internal/domains/api/services/processors/flxg/flxg5a3b_processor.go new file mode 100644 index 0000000..f4e727d --- /dev/null +++ b/internal/domains/api/services/processors/flxg/flxg5a3b_processor.go @@ -0,0 +1,57 @@ +package flxg + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessFLXG5A3BRequest FLXG5A3B API处理方法 - 个人司法涉诉 +func ProcessFLXG5A3BRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.FLXG5A3BReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + reqData := map[string]interface{}{ + "name": encryptedName, + "idCard": encryptedIDCard, + "authorized": paramsDto.Authorized, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI006", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/flxg/flxg8b4d_processor.go b/internal/domains/api/services/processors/flxg/flxg8b4d_processor.go new file mode 100644 index 0000000..9abdb5f --- /dev/null +++ b/internal/domains/api/services/processors/flxg/flxg8b4d_processor.go @@ -0,0 +1,104 @@ +package flxg + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessFLXG8B4DRequest FLXG8B4D API处理方法 - 涉赌涉诈风险评估 +func ProcessFLXG8B4DRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.FLXG8B4DReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + // 三选一校验:MobileNo、IDCard、BankCard 必须且只能有一个 + var fieldCount int + var selectedField string + var selectedValue string + + if paramsDto.MobileNo != "" { + fieldCount++ + selectedField = "mobile_no" + selectedValue = paramsDto.MobileNo + } + if paramsDto.IDCard != "" { + fieldCount++ + selectedField = "id_card" + selectedValue = paramsDto.IDCard + } + if paramsDto.BankCard != "" { + fieldCount++ + selectedField = "bank_card" + selectedValue = paramsDto.BankCard + } + + if fieldCount == 0 { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, errors.New("必须提供手机号、身份证号或银行卡号中的其中一个")) + } + if fieldCount > 1 { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, errors.New("只能提供手机号、身份证号或银行卡号中的一个,不能同时提供多个")) + } + + // 只对选中的字段进行加密 + var encryptedValue string + var err error + switch selectedField { + case "mobile_no": + encryptedValue, err = deps.ZhichaService.Encrypt(selectedValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + case "id_card": + encryptedValue, err = deps.ZhichaService.Encrypt(selectedValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + case "bank_card": + encryptedValue, err = deps.ZhichaService.Encrypt(selectedValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 构建请求数据,根据选中的字段类型设置对应的参数 + reqData := map[string]interface{}{ + "authorized": paramsDto.Authorized, + } + + switch selectedField { + case "mobile_no": + reqData["phone"] = encryptedValue + case "id_card": + reqData["idCard"] = encryptedValue + case "bank_card": + reqData["name"] = encryptedValue + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI027", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/flxg/flxg9c1d_processor.go b/internal/domains/api/services/processors/flxg/flxg9c1d_processor.go new file mode 100644 index 0000000..3707c6d --- /dev/null +++ b/internal/domains/api/services/processors/flxg/flxg9c1d_processor.go @@ -0,0 +1,57 @@ +package flxg + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessFLXG9C1DRequest FLXG9C1D API处理方法 - 法院信息详情高级版 +func ProcessFLXG9C1DRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.FLXG9C1DReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + reqData := map[string]interface{}{ + "name": encryptedName, + "idCard": encryptedIDCard, + "authorized": paramsDto.Authorized, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI007", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/ivyz/ivyz2a8b_processor.go b/internal/domains/api/services/processors/ivyz/ivyz2a8b_processor.go new file mode 100644 index 0000000..0ac58d7 --- /dev/null +++ b/internal/domains/api/services/processors/ivyz/ivyz2a8b_processor.go @@ -0,0 +1,57 @@ +package ivyz + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessIVYZ2A8BRequest IVYZ2A8B API处理方法 - 身份二要素认证 +func ProcessIVYZ2A8BRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.IVYZ2A8BReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + reqData := map[string]interface{}{ + "name": encryptedName, + "idCard": encryptedIDCard, + "authorized": paramsDto.Authorized, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI001", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/ivyz/ivyz5e3f_processor.go b/internal/domains/api/services/processors/ivyz/ivyz5e3f_processor.go new file mode 100644 index 0000000..4fc91c1 --- /dev/null +++ b/internal/domains/api/services/processors/ivyz/ivyz5e3f_processor.go @@ -0,0 +1,57 @@ +package ivyz + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessIVYZ5E3FRequest IVYZ5E3F API处理方法 - 婚姻评估查询 +func ProcessIVYZ5E3FRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.IVYZ5E3FReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + reqData := map[string]interface{}{ + "name": encryptedName, + "idCard": encryptedIDCard, + "authorized": paramsDto.Authorized, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI029", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/ivyz/ivyz7c9d_processor.go b/internal/domains/api/services/processors/ivyz/ivyz7c9d_processor.go new file mode 100644 index 0000000..f7fc281 --- /dev/null +++ b/internal/domains/api/services/processors/ivyz/ivyz7c9d_processor.go @@ -0,0 +1,58 @@ +package ivyz + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessIVYZ7C9DRequest IVYZ7C9D API处理方法 - 人脸识别 +func ProcessIVYZ7C9DRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.IVYZ7C9DReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + reqData := map[string]interface{}{ + "name": encryptedName, + "idCard": encryptedIDCard, + "returnURL": paramsDto.ReturnURL, + "orderId": paramsDto.UniqueID, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI013", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/jrzq/jrzq3c7b_processor.go b/internal/domains/api/services/processors/jrzq/jrzq3c7b_processor.go new file mode 100644 index 0000000..59889b8 --- /dev/null +++ b/internal/domains/api/services/processors/jrzq/jrzq3c7b_processor.go @@ -0,0 +1,63 @@ +package jrzq + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessJRZQ3C7BRequest JRZQ3C7B API处理方法 - 借贷意向验证 +func ProcessJRZQ3C7BRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.JRZQ3C7BReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + reqData := map[string]interface{}{ + "name": encryptedName, + "idCard": encryptedIDCard, + "phone": encryptedMobileNo, + "authorized": paramsDto.Authorized, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI017", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/jrzq/jrzq4b6c_processor.go b/internal/domains/api/services/processors/jrzq/jrzq4b6c_processor.go new file mode 100644 index 0000000..7711492 --- /dev/null +++ b/internal/domains/api/services/processors/jrzq/jrzq4b6c_processor.go @@ -0,0 +1,63 @@ +package jrzq + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessJRZQ4B6CRequest JRZQ4B6C API处理方法 - 探针C +func ProcessJRZQ4B6CRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.JRZQ4B6CReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + reqData := map[string]interface{}{ + "name": encryptedName, + "idCard": encryptedIDCard, + "phone": encryptedMobileNo, + "authorized": paramsDto.Authorized, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI023", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/jrzq/jrzq5e9f_processor.go b/internal/domains/api/services/processors/jrzq/jrzq5e9f_processor.go new file mode 100644 index 0000000..a54de61 --- /dev/null +++ b/internal/domains/api/services/processors/jrzq/jrzq5e9f_processor.go @@ -0,0 +1,63 @@ +package jrzq + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessJRZQ5E9FRequest JRZQ5E9F API处理方法 - 借选指数 +func ProcessJRZQ5E9FRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.JRZQ5E9FReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + reqData := map[string]interface{}{ + "name": encryptedName, + "idCard": encryptedIDCard, + "phone": encryptedMobileNo, + "authorized": paramsDto.Authorized, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI021", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/jrzq/jrzq7f1a_processor.go b/internal/domains/api/services/processors/jrzq/jrzq7f1a_processor.go new file mode 100644 index 0000000..016821e --- /dev/null +++ b/internal/domains/api/services/processors/jrzq/jrzq7f1a_processor.go @@ -0,0 +1,63 @@ +package jrzq + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessJRZQ7F1ARequest JRZQ7F1A API处理方法 - 全景雷达V4 +func ProcessJRZQ7F1ARequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.JRZQ7F1AReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + reqData := map[string]interface{}{ + "name": encryptedName, + "idCard": encryptedIDCard, + "phone": encryptedMobileNo, + "authorized": paramsDto.Authorized, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI008", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/jrzq/jrzq8a2d_processor.go b/internal/domains/api/services/processors/jrzq/jrzq8a2d_processor.go new file mode 100644 index 0000000..d8a0d6d --- /dev/null +++ b/internal/domains/api/services/processors/jrzq/jrzq8a2d_processor.go @@ -0,0 +1,63 @@ +package jrzq + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessJRZQ8A2DRequest JRZQ8A2D API处理方法 - 特殊名单验证 +func ProcessJRZQ8A2DRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.JRZQ8A2DReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + reqData := map[string]interface{}{ + "name": encryptedName, + "idCard": encryptedIDCard, + "phone": encryptedMobileNo, + "authorized": paramsDto.Authorized, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI018", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/yysy/yysy3e7f_processor.go b/internal/domains/api/services/processors/yysy/yysy3e7f_processor.go new file mode 100644 index 0000000..50fcd66 --- /dev/null +++ b/internal/domains/api/services/processors/yysy/yysy3e7f_processor.go @@ -0,0 +1,50 @@ +package yysy + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessYYSY3E7FRequest YYSY3E7F API处理方法 - 空号检测 +func ProcessYYSY3E7FRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.YYSY3E7FReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + reqData := map[string]interface{}{ + "phone": encryptedMobileNo, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "YYSY3E7F", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/yysy/yysy4f2e_processor.go b/internal/domains/api/services/processors/yysy/yysy4f2e_processor.go new file mode 100644 index 0000000..0034f26 --- /dev/null +++ b/internal/domains/api/services/processors/yysy/yysy4f2e_processor.go @@ -0,0 +1,63 @@ +package yysy + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessYYSY4F2ERequest YYSY4F2E API处理方法 - 运营商三要素验证(详版) +func ProcessYYSY4F2ERequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.YYSY4F2EReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + reqData := map[string]interface{}{ + "name": encryptedName, + "idCard": encryptedIDCard, + "phone": encryptedMobileNo, + "authorized": paramsDto.Authorized, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI002", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/yysy/yysy6d9a_processor.go b/internal/domains/api/services/processors/yysy/yysy6d9a_processor.go new file mode 100644 index 0000000..1ff5bd0 --- /dev/null +++ b/internal/domains/api/services/processors/yysy/yysy6d9a_processor.go @@ -0,0 +1,50 @@ +package yysy + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessYYSY6D9ARequest YYSY6D9A API处理方法 - 全网手机号状态验证A +func ProcessYYSY6D9ARequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.YYSY6D9AReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + reqData := map[string]interface{}{ + "phone": encryptedMobileNo, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI030", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/yysy/yysy8b1c_processor.go b/internal/domains/api/services/processors/yysy/yysy8b1c_processor.go new file mode 100644 index 0000000..592d747 --- /dev/null +++ b/internal/domains/api/services/processors/yysy/yysy8b1c_processor.go @@ -0,0 +1,50 @@ +package yysy + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/zhicha" +) + +// ProcessYYSY8B1CRequest YYSY8B1C API处理方法 - 手机在网时长 +func ProcessYYSY8B1CRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.YYSY8B1CReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrInvalidParam, err) + } + + encryptedMobileNo, err := deps.ZhichaService.Encrypt(paramsDto.MobileNo) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + reqData := map[string]interface{}{ + "phone": encryptedMobileNo, + } + + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI003", reqData) + if err != nil { + if errors.Is(err, zhicha.ErrDatasource) { + return nil, fmt.Errorf("%s: %w", processors.ErrDatasource, err) + } else { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + } + + // 将响应数据转换为JSON字节 + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, fmt.Errorf("%s: %w", processors.ErrSystem, err) + } + + return respBytes, nil +} diff --git a/internal/shared/validator/authorization_url_test.go b/internal/shared/validator/authorization_url_test.go new file mode 100644 index 0000000..39f6ddc --- /dev/null +++ b/internal/shared/validator/authorization_url_test.go @@ -0,0 +1,108 @@ +package validator + +import ( + "testing" + + "github.com/go-playground/validator/v10" +) + +func TestValidateAuthorizationURL(t *testing.T) { + validate := validator.New() + RegisterCustomValidators(validate) + + tests := []struct { + name string + url string + wantErr bool + }{ + { + name: "有效的PDF URL", + url: "https://example.com/document.pdf", + wantErr: false, + }, + { + name: "有效的JPG URL", + url: "https://example.com/image.jpg", + wantErr: false, + }, + { + name: "有效的JPEG URL", + url: "https://example.com/image.jpeg", + wantErr: false, + }, + { + name: "有效的PNG URL", + url: "https://example.com/image.png", + wantErr: false, + }, + { + name: "有效的BMP URL", + url: "https://example.com/image.bmp", + wantErr: false, + }, + { + name: "HTTP协议的PDF URL", + url: "http://example.com/document.pdf", + wantErr: false, + }, + { + name: "带查询参数的PDF URL", + url: "https://example.com/document.pdf?version=1.0", + wantErr: false, + }, + { + name: "带路径的PDF URL", + url: "https://example.com/files/documents/contract.pdf", + wantErr: false, + }, + { + name: "无效的URL格式", + url: "not-a-url", + wantErr: true, + }, + { + name: "不支持的文件类型", + url: "https://example.com/document.doc", + wantErr: true, + }, + { + name: "不支持的文件类型2", + url: "https://example.com/document.txt", + wantErr: true, + }, + { + name: "没有文件扩展名", + url: "https://example.com/document", + wantErr: true, + }, + { + name: "FTP协议(不支持)", + url: "ftp://example.com/document.pdf", + wantErr: true, + }, + { + name: "空字符串", + url: "", + wantErr: true, + }, + { + name: "大写扩展名", + url: "https://example.com/document.PDF", + wantErr: false, + }, + { + name: "混合大小写扩展名", + url: "https://example.com/document.JpG", + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validate.Var(tt.url, "authorization_url") + if (err != nil) != tt.wantErr { + t.Errorf("validateAuthorizationURL() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/shared/validator/custom_validators.go b/internal/shared/validator/custom_validators.go index 45dc35d..9ca7d7a 100644 --- a/internal/shared/validator/custom_validators.go +++ b/internal/shared/validator/custom_validators.go @@ -15,70 +15,79 @@ import ( func RegisterCustomValidators(validate *validator.Validate) { // 手机号验证器 validate.RegisterValidation("phone", validatePhone) - + // 用户名验证器(字母开头,允许字母数字下划线,3-20位) validate.RegisterValidation("username", validateUsername) - + // 强密码验证器(至少8位,包含大小写字母和数字) validate.RegisterValidation("strong_password", validateStrongPassword) - + // 统一社会信用代码验证器 validate.RegisterValidation("social_credit_code", validateSocialCreditCode) - + // 姓名验证器(不能为空字符串,长度1-50字符) validate.RegisterValidation("validName", validateName) - + // 身份证号验证器(兼容两种标签) validate.RegisterValidation("validIDCard", validateIDCard) validate.RegisterValidation("id_card", validateIDCard) - + // 统一社会信用代码验证器 validate.RegisterValidation("validUSCI", validateUSCI) - + // 手机号验证器 validate.RegisterValidation("validMobileNo", validateMobileNo) - + // 手机类型验证器 validate.RegisterValidation("validMobileType", validateMobileType) - + // 日期验证器 validate.RegisterValidation("validDate", validateDate) - + // 时间范围验证器 validate.RegisterValidation("validTimeRange", validateTimeRange) - + // 银行卡验证器 validate.RegisterValidation("validBankCard", validateBankCard) - + // 价格验证器(非负数) validate.RegisterValidation("price", validatePrice) - + // 排序方向验证器 validate.RegisterValidation("sort_order", validateSortOrder) - + // 产品代码验证器(字母数字下划线连字符,3-50位) validate.RegisterValidation("product_code", validateProductCode) - + // UUID验证器 validate.RegisterValidation("uuid", validateUUID) - + // URL验证器 validate.RegisterValidation("url", validateURL) - + // 企业邮箱验证器 validate.RegisterValidation("enterprise_email", validateEnterpriseEmail) - + // 企业地址验证器 validate.RegisterValidation("enterprise_address", validateEnterpriseAddress) - + // IP地址验证器 validate.RegisterValidation("ip", validateIP) - + // 非空字符串验证器(不能为空字符串或只包含空格) validate.RegisterValidation("notEmpty", validateNotEmpty) - + // 授权日期验证器 validate.RegisterValidation("auth_date", validateAuthDate) + + // 授权书URL验证器 + validate.RegisterValidation("authorization_url", validateAuthorizationURL) + + // 唯一标识验证器(小于等于32位字符串) + validate.RegisterValidation("validUniqueID", validateUniqueID) + + // 回调地址验证器 + validate.RegisterValidation("validReturnURL", validateReturnURL) } // validatePhone 手机号验证 @@ -195,7 +204,7 @@ func validateName(fl validator.FieldLevel) bool { // 必须包含至少一个中文字符或英文字母 hasValidChar := regexp.MustCompile(`[\p{Han}a-zA-Z]`).MatchString(trimmedName) return hasValidChar -} +} // validateAuthDate 授权日期验证器 // 格式:YYYYMMDD-YYYYMMDD,之前的日期范围必须包括今天 @@ -267,7 +276,7 @@ func parseYYYYMMDD(dateStr string) (time.Time, error) { // 验证日期有效性 date := time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC) - + // 检查解析后的日期是否与输入一致(防止无效日期如20230230) expectedDateStr := date.Format("20060102") if expectedDateStr != dateStr { @@ -315,7 +324,7 @@ func validateDate(fl validator.FieldLevel) bool { if !matched { return false } - + // 尝试解析日期 _, err := time.Parse("2006-01-02", dateStr) return err == nil @@ -327,29 +336,29 @@ func validateTimeRange(fl validator.FieldLevel) bool { if timeRange == "" { return true // 空值由omitempty标签处理 } - + // 时间范围格式:HH:MM-HH:MM parts := strings.Split(timeRange, "-") if len(parts) != 2 { return false } - + startTime := parts[0] endTime := parts[1] - + // 检查时间格式:HH:MM timePattern := `^([01]?[0-9]|2[0-3]):[0-5][0-9]$` startMatched, _ := regexp.MatchString(timePattern, startTime) endMatched, _ := regexp.MatchString(timePattern, endTime) - + if !startMatched || !endMatched { return false } - + // 检查开始时间不能晚于结束时间 start, _ := time.Parse("15:04", startTime) end, _ := time.Parse("15:04", endTime) - + return start.Before(end) || start.Equal(end) } @@ -369,7 +378,7 @@ func validateBankCard(fl validator.FieldLevel) bool { if !matched { return false } - + // 使用Luhn算法验证银行卡号 return validateLuhn(bankCard) } @@ -378,24 +387,104 @@ func validateBankCard(fl validator.FieldLevel) bool { func validateLuhn(cardNumber string) bool { sum := 0 alternate := false - + // 从右到左遍历 for i := len(cardNumber) - 1; i >= 0; i-- { digit, err := strconv.Atoi(string(cardNumber[i])) if err != nil { return false } - + if alternate { digit *= 2 if digit > 9 { digit = digit%10 + digit/10 } } - + sum += digit alternate = !alternate } - + return sum%10 == 0 -} \ No newline at end of file +} + +// validateAuthorizationURL 授权书URL验证器 +func validateAuthorizationURL(fl validator.FieldLevel) bool { + urlStr := fl.Field().String() + if urlStr == "" { + return true // 空值由required标签处理 + } + + // 解析URL + parsedURL, err := url.Parse(urlStr) + if err != nil { + return false + } + + // 检查协议 + if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" { + return false + } + + // 检查文件扩展名 + path := parsedURL.Path + validExtensions := []string{".pdf", ".jpg", ".jpeg", ".png", ".bmp"} + hasValidExtension := false + for _, ext := range validExtensions { + if strings.HasSuffix(strings.ToLower(path), ext) { + hasValidExtension = true + break + } + } + + return hasValidExtension +} + +// validateUniqueID 唯一标识验证器(小于等于32位字符串) +func validateUniqueID(fl validator.FieldLevel) bool { + uniqueID := fl.Field().String() + if uniqueID == "" { + return true // 空值由required标签处理 + } + + // 检查长度:小于等于32位 + if len(uniqueID) > 32 { + return false + } + + // 检查是否只包含允许的字符:字母、数字、下划线、连字符 + matched, _ := regexp.MatchString(`^[a-zA-Z0-9_-]+$`, uniqueID) + return matched +} + +// validateReturnURL 回调地址验证器 +func validateReturnURL(fl validator.FieldLevel) bool { + returnURL := fl.Field().String() + if returnURL == "" { + return true // 空值由required标签处理 + } + + // 检查长度:不能超过500字符 + if len(returnURL) > 500 { + return false + } + + // 检查URL格式 + parsedURL, err := url.Parse(returnURL) + if err != nil { + return false + } + + // 检查协议:只允许http和https + if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" { + return false + } + + // 检查是否有域名 + if parsedURL.Host == "" { + return false + } + + return true +} diff --git a/internal/shared/validator/translations.go b/internal/shared/validator/translations.go index 504f86d..9122e37 100644 --- a/internal/shared/validator/translations.go +++ b/internal/shared/validator/translations.go @@ -194,6 +194,30 @@ func registerCustomFieldTranslations(validate *validator.Validate, trans ut.Tran t, _ := ut.T("auth_date", getFieldDisplayName(fe.Field())) return t }) + + // 授权书URL翻译 + validate.RegisterTranslation("authorization_url", trans, func(ut ut.Translator) error { + return ut.Add("authorization_url", "{0}必须是有效的URL地址,且文件类型必须是PDF、JPG、JPEG、PNG或BMP格式", true) + }, func(ut ut.Translator, fe validator.FieldError) string { + t, _ := ut.T("authorization_url", getFieldDisplayName(fe.Field())) + return t + }) + + // 唯一标识翻译 + validate.RegisterTranslation("validUniqueID", trans, func(ut ut.Translator) error { + return ut.Add("validUniqueID", "{0}格式不正确,只能包含字母、数字、下划线和连字符,且长度不能超过32位", true) + }, func(ut ut.Translator, fe validator.FieldError) string { + t, _ := ut.T("validUniqueID", getFieldDisplayName(fe.Field())) + return t + }) + + // 回调地址翻译 + validate.RegisterTranslation("validReturnURL", trans, func(ut ut.Translator) error { + return ut.Add("validReturnURL", "{0}必须是有效的URL地址,且长度不能超过500字符", true) + }, func(ut ut.Translator, fe validator.FieldError) string { + t, _ := ut.T("validReturnURL", getFieldDisplayName(fe.Field())) + return t + }) } // getFieldDisplayName 获取字段显示名称(中文) @@ -210,7 +234,10 @@ func getFieldDisplayName(field string) string { "email": "邮箱", "enterprise_email": "企业邮箱", "enterprise_address": "企业地址", - "ip_address": "IP地址", + "ip": "IP地址", + "auth_date": "授权日期", + "unique_id": "唯一标识", + "return_url": "回调地址", "display_name": "显示名称", "scene": "使用场景", "Password": "密码", @@ -252,6 +279,8 @@ func getFieldDisplayName(field string) string { "VerificationCode": "验证码", "contract_url": "合同URL", "ContractURL": "合同URL", + "authorization_url": "授权书地址", + "AuthorizationURL": "授权书地址", "amount": "金额", "Amount": "金额", "balance": "余额", @@ -279,8 +308,6 @@ func getFieldDisplayName(field string) string { "ID": "ID", "ids": "ID列表", "IDs": "ID列表", - "auth_date": "授权日期", - "AuthDate": "授权日期", "id_card": "身份证号", "IDCard": "身份证号", }