diff --git a/internal/domains/api/dto/api_request_dto.go b/internal/domains/api/dto/api_request_dto.go index 5d5eca3..3a89048 100644 --- a/internal/domains/api/dto/api_request_dto.go +++ b/internal/domains/api/dto/api_request_dto.go @@ -618,6 +618,30 @@ type QYGLJ0Q1Req struct { } type IVYZ18HYReq struct { + IDCard string `json:"id_card" validate:"required,validIDCard"` + Name string `json:"name" validate:"required,min=1,validName"` + MaritalType string `json:"marital_type" validate:"required"` + AuthAuthorizeFileBase64 string `json:"auth_authorize_file_base64" validate:"required,validBase64"` + AuthAuthorizeFileCode string `json:"auth_authorize_file_code" validate:"required"` + AuthDate string `json:"auth_date" validate:"required"` +} + +type IVYZ38SRReq struct { + ManName string `json:"man_name" validate:"required,min=1,validName"` + ManIDCard string `json:"man_id_card" validate:"required,validIDCard"` + WomanName string `json:"woman_name" validate:"required,min=1,validName"` + WomanIDCard string `json:"woman_id_card" validate:"required,validIDCard"` +} + +type IVYZ48SRReq struct { + ManName string `json:"man_name" validate:"required,min=1,validName"` + ManIDCard string `json:"man_id_card" validate:"required,validIDCard"` + WomanName string `json:"woman_name" validate:"required,min=1,validName"` + WomanIDCard string `json:"woman_id_card" validate:"required,validIDCard"` + MaritalType string `json:"marital_type" validate:"required"` + AuthAuthorizeFileCode string `json:"auth_authorize_file_code" validate:"required"` +} +type IVYZ28HYReq struct { IDCard string `json:"id_card" validate:"required,validIDCard"` Name string `json:"name" validate:"required,min=1,validName"` } diff --git a/internal/domains/api/services/api_request_service.go b/internal/domains/api/services/api_request_service.go index a0b41ac..dbe97dc 100644 --- a/internal/domains/api/services/api_request_service.go +++ b/internal/domains/api/services/api_request_service.go @@ -312,6 +312,10 @@ func registerAllProcessors(combService *comb.CombService) { "IVYZX5Q2": ivyz.ProcessIVYZX5Q2Request, //活体识别步骤二 "IVYZOCR1": ivyz.ProcessIVYZOCR1Request, //身份证OCR "IVYZOCR2": ivyz.ProcessIVYZOCR2Request, //身份证OCR2数卖 + "IVYZ18HY": ivyz.ProcessIVYZ18HYRequest, //婚姻状况核验V2(单人) + "IVYZ28HY": ivyz.ProcessIVYZ28HYRequest, //婚姻状况核验(单人) + "IVYZ38SR": ivyz.ProcessIVYZ38SRRequest, //婚姻状态核验(双人) + "IVYZ48SR": ivyz.ProcessIVYZ48SRRequest, //婚姻状态核验V2(双人) // COMB系列处理器 - 只注册有自定义逻辑的组合包 "COMB86PM": comb.ProcessCOMB86PMRequest, // 有自定义逻辑:重命名ApiCode diff --git a/internal/domains/api/services/form_config_service.go b/internal/domains/api/services/form_config_service.go index 92832e7..39c9860 100644 --- a/internal/domains/api/services/form_config_service.go +++ b/internal/domains/api/services/form_config_service.go @@ -266,6 +266,10 @@ func (s *FormConfigServiceImpl) getDTOStruct(ctx context.Context, apiCode string "QYGLDJ12": &dto.QYGLDJ12Req{}, //企业年报信息核验 "FLXGDJG3": &dto.FLXGDJG3Req{}, //董监高司法综合信息核验 "QYGL8848": &dto.QYGLDJ12Req{}, //企业税收违法核查 + "IVYZ18HY": &dto.IVYZ18HYReq{}, //婚姻状况核验V2(单人) + "IVYZ28HY": &dto.IVYZ28HYReq{}, //婚姻状况核验(单人) + "IVYZ38SR": &dto.IVYZ38SRReq{}, //婚姻状态核验(双人) + "IVYZ48SR": &dto.IVYZ48SRReq{}, //婚姻状态核验V2(双人) } // 优先返回已配置的DTO @@ -387,6 +391,8 @@ func (s *FormConfigServiceImpl) parseValidationRules(validateTag string) string frontendRules = append(frontendRules, "授权链接格式") case rule == "validBase64Image": frontendRules = append(frontendRules, "Base64图片格式(JPG、BMP、PNG)") + case rule == "base64" || rule == "validBase64": + frontendRules = append(frontendRules, "Base64编码格式(支持图片/PDF)") case strings.HasPrefix(rule, "oneof="): values := strings.TrimPrefix(rule, "oneof=") frontendRules = append(frontendRules, "可选值: "+values) @@ -420,7 +426,7 @@ func (s *FormConfigServiceImpl) getFieldType(fieldType reflect.Type, validation return "url" } else if strings.Contains(validation, "可选值") { return "select" - } else if strings.Contains(validation, "Base64图片") || strings.Contains(validation, "base64") { + } else if strings.Contains(validation, "Base64图片") || strings.Contains(validation, "Base64编码") || strings.Contains(validation, "base64") { return "textarea" } else if strings.Contains(validation, "图片地址") { return "url" @@ -439,58 +445,60 @@ func (s *FormConfigServiceImpl) getFieldType(fieldType reflect.Type, validation func (s *FormConfigServiceImpl) generateFieldLabel(jsonTag string) string { // 将下划线命名转换为中文标签 labelMap := map[string]string{ - "mobile_no": "手机号码", - "id_card": "身份证号", - "name": "姓名", - "man_name": "男方姓名", - "woman_name": "女方姓名", - "man_id_card": "男方身份证", - "woman_id_card": "女方身份证", - "ent_name": "企业名称", - "legal_person": "法人姓名", - "ent_code": "企业代码", - "ent_reg_no": "企业注册号", - "auth_date": "授权日期", - "date_range": "日期范围", - "time_range": "时间范围", - "authorized": "是否授权", - "authorization_url": "授权链接", - "unique_id": "唯一标识", - "return_url": "返回链接", - "mobile_type": "手机类型", - "start_date": "开始日期", - "years": "年数", - "bank_card": "银行卡号", - "user_type": "关系类型", - "vehicle_type": "车辆类型", - "page_num": "页码", - "page_size": "每页数量", - "use_scenario": "使用场景", - "auth_authorize_file_code": "授权文件编码", - "plate_no": "车牌号", - "plate_type": "号牌类型", - "vin_code": "车辆识别代号VIN码", - "return_type": "返回类型", - "photo_data": "入参图片base64编码", - "owner_type": "企业主类型", - "type": "查询类型", - "query_reason_id": "查询原因ID", - "flag": "层次", - "dir": "方向", - "min_percent": "股权穿透比例下限", - "max_percent": "股权穿透比例上限", - "engine_number": "发动机号码", - "notice_model": "车辆型号", - "vlphoto_data": "行驶证图片", - "carplate_type": "车辆号牌类型", - "image_url": "入参图片地址", - "reg_url": "车辆登记证图片地址", - "token": "token采集及获取结果时所使用的凭证,有效期2个小时,在此时效内,应用侧可以发起采集请求(重复的采集所触发的结果会被忽略)和结果查询", - "vehicle_name": "车型名称", - "vehicle_location": "车辆所在地", - "first_registrationdate": "首次登记日期", - "color": "颜色", - "plate_color": "车牌颜色", + "mobile_no": "手机号码", + "id_card": "身份证号", + "name": "姓名", + "man_name": "男方姓名", + "woman_name": "女方姓名", + "man_id_card": "男方身份证", + "woman_id_card": "女方身份证", + "ent_name": "企业名称", + "legal_person": "法人姓名", + "ent_code": "企业代码", + "ent_reg_no": "企业注册号", + "auth_date": "授权日期", + "date_range": "日期范围", + "time_range": "时间范围", + "authorized": "是否授权", + "authorization_url": "授权链接", + "unique_id": "唯一标识", + "return_url": "返回链接", + "mobile_type": "手机类型", + "start_date": "开始日期", + "years": "年数", + "bank_card": "银行卡号", + "user_type": "关系类型", + "vehicle_type": "车辆类型", + "page_num": "页码", + "page_size": "每页数量", + "use_scenario": "使用场景", + "auth_authorize_file_code": "授权文件编码", + "plate_no": "车牌号", + "plate_type": "号牌类型", + "vin_code": "车辆识别代号VIN码", + "return_type": "返回类型", + "photo_data": "入参图片base64编码", + "owner_type": "企业主类型", + "type": "查询类型", + "query_reason_id": "查询原因ID", + "flag": "层次", + "dir": "方向", + "min_percent": "股权穿透比例下限", + "max_percent": "股权穿透比例上限", + "engine_number": "发动机号码", + "notice_model": "车辆型号", + "vlphoto_data": "行驶证图片", + "carplate_type": "车辆号牌类型", + "image_url": "入参图片地址", + "reg_url": "车辆登记证图片地址", + "token": "token采集及获取结果时所使用的凭证,有效期2个小时,在此时效内,应用侧可以发起采集请求(重复的采集所触发的结果会被忽略)和结果查询", + "vehicle_name": "车型名称", + "vehicle_location": "车辆所在地", + "first_registrationdate": "首次登记日期", + "color": "颜色", + "plate_color": "车牌颜色", + "marital_type": "婚姻状况类型", + "auth_authorize_file_base64": "PDF授权文件Base64编码(5MB以内)", } if label, exists := labelMap[jsonTag]; exists { @@ -504,56 +512,58 @@ func (s *FormConfigServiceImpl) generateFieldLabel(jsonTag string) string { // generateExampleValue 生成示例值 func (s *FormConfigServiceImpl) generateExampleValue(fieldType reflect.Type, jsonTag string) string { exampleMap := map[string]string{ - "mobile_no": "13800138000", - "id_card": "110101199001011234", - "name": "张三", - "man_name": "张三", - "woman_name": "李四", - "ent_name": "示例企业有限公司", - "legal_person": "王五", - "ent_code": "91110000123456789X", - "ent_reg_no": "110000000123456", - "auth_date": "20240101-20241231", - "date_range": "20240101-20241231", - "time_range": "09:00-18:00", - "authorized": "1", - "years": "5", - "bank_card": "6222021234567890123", - "mobile_type": "移动", - "start_date": "2024-01-01", - "unique_id": "UNIQUE123456", - "return_url": "https://example.com/return", - "authorization_url": "https://example.com/auth20250101.pdf 注意:请不要使用示例链接,示例链接仅作为参考格式。必须为实际的被查询人授权具有法律效益的授权书文件链接,如访问不到或为不实授权书将追究责任。协议必须为http https", - "user_type": "1", - "vehicle_type": "0", - "page_num": "1", - "page_size": "10", - "use_scenario": "1", - "auth_authorize_file_code": "AUTH123456", - "plate_no": "京A12345", - "plate_type": "01", - "vin_code": "LSGBF53M8DS123456", - "return_type": "1", - "photo_data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==", - "ownerType": "1", - "type": "per", - "query_reason_id": "1", - "flag": "4", - "dir": "down", - "min_percent": "0", - "max_percent": "1", - "engine_number": "1234567890", - "notice_model": "1", - "vlphoto_data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==", - "carplate_type": "01", - "image_url": "https://example.com/images/driving_license.jpg", - "reg_url": "https://example.com/images/vehicle_registration.jpg", - "token": "0fc79b80371f45e2ac1c693ef9136b24", - "vehicle_name": "车型名称,示例:凌派 2020款 锐·混动 1.5L 锐·舒适版", - "vehicle_location": "车辆所在地,示例:北京", - "first_registrationdate": "初登日期,示例:2020-05", - "color": "示例:白色", - "plate_color": "车牌颜色(0:蓝色,1:黄色,2:黑色,3:白色,4:渐变绿色,5:黄绿双拼色,6:蓝白渐变色,7:临时牌照,11:绿色,12:红色)默认标准车牌查蓝色,新能源车牌查绿色)", + "mobile_no": "13800138000", + "id_card": "110101199001011234", + "name": "张三", + "man_name": "张三", + "woman_name": "李四", + "ent_name": "示例企业有限公司", + "legal_person": "王五", + "ent_code": "91110000123456789X", + "ent_reg_no": "110000000123456", + "auth_date": "20240101-20241231", + "date_range": "20240101-20241231", + "time_range": "09:00-18:00", + "authorized": "1", + "years": "5", + "bank_card": "6222021234567890123", + "mobile_type": "移动", + "start_date": "2024-01-01", + "unique_id": "UNIQUE123456", + "return_url": "https://example.com/return", + "authorization_url": "https://example.com/auth20250101.pdf 注意:请不要使用示例链接,示例链接仅作为参考格式。必须为实际的被查询人授权具有法律效益的授权书文件链接,如访问不到或为不实授权书将追究责任。协议必须为http https", + "user_type": "1", + "vehicle_type": "0", + "page_num": "1", + "page_size": "10", + "use_scenario": "1", + "auth_authorize_file_code": "AUTH123456", + "plate_no": "京A12345", + "plate_type": "01", + "vin_code": "LSGBF53M8DS123456", + "return_type": "1", + "photo_data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==", + "ownerType": "1", + "type": "per", + "query_reason_id": "1", + "flag": "4", + "dir": "down", + "min_percent": "0", + "max_percent": "1", + "engine_number": "1234567890", + "notice_model": "1", + "vlphoto_data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==", + "carplate_type": "01", + "image_url": "https://example.com/images/driving_license.jpg", + "reg_url": "https://example.com/images/vehicle_registration.jpg", + "token": "0fc79b80371f45e2ac1c693ef9136b24", + "vehicle_name": "车型名称,示例:凌派 2020款 锐·混动 1.5L 锐·舒适版", + "vehicle_location": "车辆所在地,示例:北京", + "first_registrationdate": "初登日期,示例:2020-05", + "color": "示例:白色", + "plate_color": "0", + "marital_type": "10", + "auth_authorize_file_base64": "JVBERi0xLjQKJcTl8uXr...(示例PDF的Base64编码)", } if example, exists := exampleMap[jsonTag]; exists { @@ -576,56 +586,58 @@ func (s *FormConfigServiceImpl) generateExampleValue(fieldType reflect.Type, jso // generatePlaceholder 生成占位符 func (s *FormConfigServiceImpl) generatePlaceholder(jsonTag string, fieldType string) string { placeholderMap := map[string]string{ - "mobile_no": "请输入11位手机号码", - "id_card": "请输入18位身份证号码", - "name": "请输入真实姓名", - "man_name": "请输入男方真实姓名", - "woman_name": "请输入女方真实姓名", - "ent_name": "请输入企业全称", - "legal_person": "请输入法人真实姓名", - "ent_code": "请输入统一社会信用代码", - "ent_reg_no": "请输入企业注册号(统一社会信用代码)", - "auth_date": "请输入授权日期范围(YYYYMMDD-YYYYMMDD)", - "date_range": "请输入日期范围(YYYYMMDD-YYYYMMDD)", - "time_range": "请输入时间范围(HH:MM-HH:MM)", - "authorized": "请选择是否授权", - "years": "请输入查询年数(0-100)", - "bank_card": "请输入银行卡号", - "mobile_type": "请选择手机类型", - "start_date": "请选择开始日期", - "unique_id": "请输入唯一标识", - "return_url": "请输入返回链接", - "authorization_url": "请输入授权链接", - "user_type": "请选择关系类型", - "vehicle_type": "请选择车辆类型", - "page_num": "请输入页码", - "page_size": "请输入每页数量(1-100)", - "use_scenario": "请选择使用场景", - "auth_authorize_file_code": "请输入授权文件编码", - "plate_no": "请输入车牌号", - "plate_type": "请选择号牌类型(01或02)", - "vin_code": "请输入17位车辆识别代号VIN码", - "return_type": "请选择返回类型", - "photo_data": "请输入base64编码的入参图片(支持JPG、BMP、PNG格式)", - "ownerType": "请选择企业主类型", - "type": "请选择查询类型", - "query_reason_id": "请选择查询原因ID", - "flag": "请输入层次(最大4)", - "dir": "请选择方向(up-向上,down-向下)", - "min_percent": "请输入股权穿透比例下限(默认0)", - "max_percent": "请输入股权穿透比例上限(默认1)", - "engine_number": "请输入发动机号码", - "notice_model": "请输入车辆型号", - "vlphoto_data": "请输入行驶证图片", - "carplate_type": "请选择车辆号牌类型(01-大型汽车 02-小型汽车 03-使馆汽车 04-领馆汽车 05-境外汽车 06-外籍汽车 07-普通摩托车 08-轻便摩托车 09-使馆摩托车 10-领馆摩托车 11-境外摩托车 12-外籍摩托车 13-低速车 14-拖拉机 15-挂车 16-教练汽车 17-教练摩托车 20-临时入境汽车 21-临时入境摩托车 22-临时行驶车 23-警用汽车 24-警用摩托 51-新能源大型车 52-新能源小型车)", - "image_url": "请输入行驶证图片地址", - "reg_url": "请输入车辆登记证图片地址", - "token": "请输入token", - "vehicle_name": "请输入车型名称", - "vehicle_location": "请输入车辆所在地", - "first_registrationdate": "请输入首次登记日期,格式:YYYY-MM", - "color": "请输入颜色", - "plate_color": "请输入车牌颜色", + "mobile_no": "请输入11位手机号码", + "id_card": "请输入18位身份证号码", + "name": "请输入真实姓名", + "man_name": "请输入男方真实姓名", + "woman_name": "请输入女方真实姓名", + "ent_name": "请输入企业全称", + "legal_person": "请输入法人真实姓名", + "ent_code": "请输入统一社会信用代码", + "ent_reg_no": "请输入企业注册号(统一社会信用代码)", + "auth_date": "请输入授权日期范围(YYYYMMDD-YYYYMMDD)", + "date_range": "请输入日期范围(YYYYMMDD-YYYYMMDD)", + "time_range": "请输入时间范围(HH:MM-HH:MM)", + "authorized": "请选择是否授权", + "years": "请输入查询年数(0-100)", + "bank_card": "请输入银行卡号", + "mobile_type": "请选择手机类型", + "start_date": "请选择开始日期", + "unique_id": "请输入唯一标识", + "return_url": "请输入返回链接", + "authorization_url": "请输入授权链接", + "user_type": "请选择关系类型", + "vehicle_type": "请选择车辆类型", + "page_num": "请输入页码", + "page_size": "请输入每页数量(1-100)", + "use_scenario": "请选择使用场景", + "auth_authorize_file_code": "请输入授权文件编码", + "plate_no": "请输入车牌号", + "plate_type": "请选择号牌类型(01或02)", + "vin_code": "请输入17位车辆识别代号VIN码", + "return_type": "请选择返回类型", + "photo_data": "请输入base64编码的入参图片(支持JPG、BMP、PNG格式)", + "ownerType": "请选择企业主类型", + "type": "请选择查询类型", + "query_reason_id": "请选择查询原因ID", + "flag": "请输入层次(最大4)", + "dir": "请选择方向(up-向上,down-向下)", + "min_percent": "请输入股权穿透比例下限(默认0)", + "max_percent": "请输入股权穿透比例上限(默认1)", + "engine_number": "请输入发动机号码", + "notice_model": "请输入车辆型号", + "vlphoto_data": "请输入行驶证图片", + "carplate_type": "请选择车辆号牌类型(01-大型汽车 02-小型汽车 03-使馆汽车 04-领馆汽车 05-境外汽车 06-外籍汽车 07-普通摩托车 08-轻便摩托车 09-使馆摩托车 10-领馆摩托车 11-境外摩托车 12-外籍摩托车 13-低速车 14-拖拉机 15-挂车 16-教练汽车 17-教练摩托车 20-临时入境汽车 21-临时入境摩托车 22-临时行驶车 23-警用汽车 24-警用摩托 51-新能源大型车 52-新能源小型车)", + "image_url": "请输入行驶证图片地址", + "reg_url": "请输入车辆登记证图片地址", + "token": "请输入token", + "vehicle_name": "请输入车型名称", + "vehicle_location": "请输入车辆所在地", + "first_registrationdate": "请输入首次登记日期,格式:YYYY-MM", + "color": "请输入颜色", + "plate_color": "请输入车牌颜色", + "marital_type": "请选择婚姻状况类型", + "auth_authorize_file_base64": "请输入PDF文件的Base64编码字符串", } if placeholder, exists := placeholderMap[jsonTag]; exists { @@ -650,56 +662,58 @@ func (s *FormConfigServiceImpl) generatePlaceholder(jsonTag string, fieldType st // generateDescription 生成字段描述 func (s *FormConfigServiceImpl) generateDescription(jsonTag string, validation string) string { descMap := map[string]string{ - "mobile_no": "请输入11位手机号码", - "id_card": "请输入18位身份证号码最后一位如是字母请大写", - "name": "请输入真实姓名", - "man_name": "请输入男方真实姓名", - "woman_name": "请输入女方真实姓名", - "ent_name": "请输入企业全称", - "legal_person": "请输入法人真实姓名", - "ent_code": "请输入统一社会信用代码", - "ent_reg_no": "请输入企业注册号(统一社会信用代码)", - "auth_date": "请输入授权日期范围,格式:YYYYMMDD-YYYYMMDD,且日期范围必须包括今天", - "date_range": "请输入日期范围,格式:YYYYMMDD-YYYYMMDD", - "time_range": "请输入时间范围,格式:HH:MM-HH:MM", - "authorized": "请输入是否授权:0-未授权,1-已授权", - "years": "请输入查询年数(0-100)", - "bank_card": "请输入银行卡号", - "mobile_type": "请选择手机类型", - "start_date": "请选择开始日期", - "unique_id": "请输入唯一标识", - "return_url": "请输入返回链接", - "authorization_url": "请输入授权链接", - "user_type": "关系类型:1-ETC开户人;2-车辆所有人;3-ETC经办人(默认1-ETC开户人)", - "vehicle_type": "车辆类型:0-客车;1-货车;2-全部(默认查全部)", - "page_num": "请输入页码,从1开始", - "page_size": "请输入每页数量,范围1-100", - "use_scenario": "使用场景:1-信贷审核;2-保险评估;3-招聘背景调查;4-其他业务场景;99-其他", - "auth_authorize_file_code": "请输入授权文件编码", - "plate_no": "请输入车牌号", - "plate_type": "号牌类型:01-小型汽车;02-大型汽车(可选)", - "vin_code": "请输入17位车辆识别代号VIN码(Vehicle Identification Number)", - "return_type": "返回类型:1-专业和学校名称数据返回编码形式(默认);2-专业和学校名称数据返回中文名称", - "photo_data": "入参图片:base64编码的图片数据,仅支持JPG、BMP、PNG三种格式", - "owner_type": "企业主类型编码:1-法定代表人;2-主要人员;3-自然人股东;4-法定代表人及自然人股东;5-其他", - "type": "查询类型:per-人员,ent-企业 ", - "query_reason_id": "查询原因ID:1-授信审批;2-贷中管理;3-贷后管理;4-异议处理;5-担保查询;6-租赁资质审查;7-融资租赁审批;8-借贷撮合查询;9-保险审批;10-资质审核;11-风控审核;12-企业背调", - "flag": "层次,最大4", - "dir": "方向:up-向上穿透,down-向下穿透", - "min_percent": "股权穿透比例下限(大于等于),默认为0,支持小数点后两位(以小数指代百分比)", - "max_percent": "股权穿透比例上限(小于等于),默认为1,支持小数点后两位(以小数指代百分比)", - "engine_number": "发动机号码", - "notice_model": "车辆型号", - "vlphoto_data": "行驶证图片:base64编码的图片数据,仅支持JPG、BMP、PNG三种格式", - "carplate_type": "车辆号牌类型:01-大型汽车;02-小型汽车;03-使馆汽车;04-领馆汽车;05-境外汽车;06-外籍汽车;07-普通摩托车;08-轻便摩托车;09-使馆摩托车;10-领馆摩托车;11-境外摩托车;12-外籍摩托车;13-低速车;14-拖拉机;15-挂车;16-教练汽车;17-教练摩托车;20-临时入境汽车;21-临时入境摩托车;22-临时行驶车;23-警用汽车;24-警用摩托;51-新能源大型车;52-新能源小型车", - "image_url": "入参图片url地址", - "reg_url": "车辆登记证图片地址(非必填):请提供车辆登记证的图片URL地址", - "token": "token采集及获取结果时所使用的凭证,有效期2个小时,在此时效内,应用侧可以发起采集请求(重复的采集所触发的结果会被忽略)和结果查询", - "vehicle_name": "车型名称,示例:凌派 2020款 锐·混动 1.5L 锐·舒适版", - "vehicle_location": "车辆所在地", - "first_registrationdate": "首次登记日期,格式:YYYY-MM", - "color": "颜色", - "plate_color": "车牌颜色", + "mobile_no": "请输入11位手机号码", + "id_card": "请输入18位身份证号码最后一位如是字母请大写", + "name": "请输入真实姓名", + "man_name": "请输入男方真实姓名", + "woman_name": "请输入女方真实姓名", + "ent_name": "请输入企业全称", + "legal_person": "请输入法人真实姓名", + "ent_code": "请输入统一社会信用代码", + "ent_reg_no": "请输入企业注册号(统一社会信用代码)", + "auth_date": "请输入授权日期范围,格式:YYYYMMDD-YYYYMMDD,且日期范围必须包括今天", + "date_range": "请输入日期范围,格式:YYYYMMDD-YYYYMMDD", + "time_range": "请输入时间范围,格式:HH:MM-HH:MM", + "authorized": "请输入是否授权:0-未授权,1-已授权", + "years": "请输入查询年数(0-100)", + "bank_card": "请输入银行卡号", + "mobile_type": "请选择手机类型", + "start_date": "请选择开始日期", + "unique_id": "请输入唯一标识", + "return_url": "请输入返回链接", + "authorization_url": "请输入授权链接", + "user_type": "关系类型:1-ETC开户人;2-车辆所有人;3-ETC经办人(默认1-ETC开户人)", + "vehicle_type": "车辆类型:0-客车;1-货车;2-全部(默认查全部)", + "page_num": "请输入页码,从1开始", + "page_size": "请输入每页数量,范围1-100", + "use_scenario": "使用场景:1-信贷审核;2-保险评估;3-招聘背景调查;4-其他业务场景;99-其他", + "auth_authorize_file_code": "请输入授权文件编码", + "plate_no": "请输入车牌号", + "plate_type": "号牌类型:01-小型汽车;02-大型汽车(可选)", + "vin_code": "请输入17位车辆识别代号VIN码(Vehicle Identification Number)", + "return_type": "返回类型:1-专业和学校名称数据返回编码形式(默认);2-专业和学校名称数据返回中文名称", + "photo_data": "入参图片:base64编码的图片数据,仅支持JPG、BMP、PNG三种格式", + "owner_type": "企业主类型编码:1-法定代表人;2-主要人员;3-自然人股东;4-法定代表人及自然人股东;5-其他", + "type": "查询类型:per-人员,ent-企业 ", + "query_reason_id": "查询原因ID:1-授信审批;2-贷中管理;3-贷后管理;4-异议处理;5-担保查询;6-租赁资质审查;7-融资租赁审批;8-借贷撮合查询;9-保险审批;10-资质审核;11-风控审核;12-企业背调", + "flag": "层次,最大4", + "dir": "方向:up-向上穿透,down-向下穿透", + "min_percent": "股权穿透比例下限(大于等于),默认为0,支持小数点后两位(以小数指代百分比)", + "max_percent": "股权穿透比例上限(小于等于),默认为1,支持小数点后两位(以小数指代百分比)", + "engine_number": "发动机号码", + "notice_model": "车辆型号", + "vlphoto_data": "行驶证图片:base64编码的图片数据,仅支持JPG、BMP、PNG三种格式", + "carplate_type": "车辆号牌类型:01-大型汽车;02-小型汽车;03-使馆汽车;04-领馆汽车;05-境外汽车;06-外籍汽车;07-普通摩托车;08-轻便摩托车;09-使馆摩托车;10-领馆摩托车;11-境外摩托车;12-外籍摩托车;13-低速车;14-拖拉机;15-挂车;16-教练汽车;17-教练摩托车;20-临时入境汽车;21-临时入境摩托车;22-临时行驶车;23-警用汽车;24-警用摩托;51-新能源大型车;52-新能源小型车", + "image_url": "入参图片url地址", + "reg_url": "车辆登记证图片地址(非必填):请提供车辆登记证的图片URL地址", + "token": "token采集及获取结果时所使用的凭证,有效期2个小时,在此时效内,应用侧可以发起采集请求(重复的采集所触发的结果会被忽略)和结果查询", + "vehicle_name": "车型名称,示例:凌派 2020款 锐·混动 1.5L 锐·舒适版", + "vehicle_location": "车辆所在地", + "first_registrationdate": "首次登记日期,格式:YYYY-MM", + "color": "颜色", + "plate_color": "车牌颜色", + "marital_type": "婚姻状况类型:10-未登记(无登记记录),20-已婚,30-丧偶,40-离异", + "auth_authorize_file_base64": "请输入PDF文件的Base64编码字符串", } if desc, exists := descMap[jsonTag]; exists { diff --git a/internal/domains/api/services/processors/ivyz/ivyz18hy_processor.go b/internal/domains/api/services/processors/ivyz/ivyz18hy_processor.go index 5542c31..8c872ec 100644 --- a/internal/domains/api/services/processors/ivyz/ivyz18hy_processor.go +++ b/internal/domains/api/services/processors/ivyz/ivyz18hy_processor.go @@ -10,7 +10,7 @@ import ( "tyapi-server/internal/infrastructure/external/shujubao" ) -// ProcessIVYZ2B2TRequest IVYZ2B2T 婚姻状况核验(单人) API 处理方法(使用数据宝服务示例) +// ProcessIVYZ18HYRequest IVYZ18HY 婚姻状况核验V2(单人) API 处理方法(使用数据宝服务示例) func ProcessIVYZ18HYRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { var paramsDto dto.IVYZ18HYReq if err := json.Unmarshal(params, ¶msDto); err != nil { @@ -21,17 +21,32 @@ func ProcessIVYZ18HYRequest(ctx context.Context, params []byte, deps *processors return nil, errors.Join(processors.ErrInvalidParam, err) } - // 构建数据宝入参(sign 外的业务参数可按需 AES 加密后作为 bodyData) + fixedData := map[string]interface{}{"msg": "请联系商务咨询"} + fixedRespBytes, err := json.Marshal(fixedData) + if err != nil { + return nil, errors.Join(processors.ErrSystem, err) + } + return fixedRespBytes, nil + + authDate := "" + if len(paramsDto.AuthDate) >= 8 { + authDate = paramsDto.AuthDate[len(paramsDto.AuthDate)-8:] + } reqParams := map[string]interface{}{ - "key": "", - "certNum": paramsDto.IDCard, - "name": paramsDto.Name, + "key": "", + "idcard": paramsDto.IDCard, + "name": paramsDto.Name, + "maritalType": paramsDto.MaritalType, + "authcode": paramsDto.AuthAuthorizeFileBase64, + "authAuthorizeFileCode": paramsDto.AuthAuthorizeFileCode, + "authDate": authDate, } // 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197 - apiPath := "/communication/personal/10149" + apiPath := "/communication/personal/10333" data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams) if err != nil { + if errors.Is(err, shujubao.ErrDatasource) { return nil, errors.Join(processors.ErrDatasource, err) } diff --git a/internal/domains/api/services/processors/ivyz/ivyz28hy_processor.go b/internal/domains/api/services/processors/ivyz/ivyz28hy_processor.go new file mode 100644 index 0000000..b8cdc57 --- /dev/null +++ b/internal/domains/api/services/processors/ivyz/ivyz28hy_processor.go @@ -0,0 +1,54 @@ +package ivyz + +import ( + "context" + "encoding/json" + "errors" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/shujubao" +) + +// ProcessIVYZ28HYRequest IVYZ28HY 婚姻状况核验单人) API 处理方法(使用数据宝服务示例) +func ProcessIVYZ28HYRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.IVYZ28HYReq + 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) + } + + fixedData := map[string]interface{}{"msg": "请联系商务咨询"} + fixedRespBytes, err := json.Marshal(fixedData) + if err != nil { + return nil, errors.Join(processors.ErrSystem, err) + } + return fixedRespBytes, nil + + reqParams := map[string]interface{}{ + "key": "", + "idcard": paramsDto.IDCard, + "name": paramsDto.Name, + } + + // 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197 + apiPath := "/communication/personal/10149" + data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams) + if err != nil { + if errors.Is(err, shujubao.ErrDatasource) { + return nil, errors.Join(processors.ErrDatasource, err) + } + if errors.Is(err, shujubao.ErrQueryEmpty) { + return nil, errors.Join(processors.ErrNotFound, err) + } + return nil, errors.Join(processors.ErrSystem, err) + } + respBytes, err := json.Marshal(data) + if err != nil { + return nil, errors.Join(processors.ErrSystem, err) + } + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/ivyz/ivyz38sr_processor.go b/internal/domains/api/services/processors/ivyz/ivyz38sr_processor.go new file mode 100644 index 0000000..8067526 --- /dev/null +++ b/internal/domains/api/services/processors/ivyz/ivyz38sr_processor.go @@ -0,0 +1,56 @@ +package ivyz + +import ( + "context" + "encoding/json" + "errors" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/shujubao" +) + +// ProcessIVYZ38SRRequest IVYZ38SR 婚姻状态核验(双人) API 处理方法(使用数据宝服务示例) +func ProcessIVYZ38SRRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.IVYZ38SRReq + 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) + } + + fixedData := map[string]interface{}{"msg": "请联系商务咨询"} + fixedRespBytes, err := json.Marshal(fixedData) + if err != nil { + return nil, errors.Join(processors.ErrSystem, err) + } + return fixedRespBytes, nil + + reqParams := map[string]interface{}{ + "key": "", + "name": paramsDto.ManName, + "idcard": paramsDto.ManIDCard, + "woman_name": paramsDto.WomanName, + "woman_idcard": paramsDto.WomanIDCard, + } + + // 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197 + apiPath := "/communication/personal/10148" + data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams) + if err != nil { + if errors.Is(err, shujubao.ErrDatasource) { + return nil, errors.Join(processors.ErrDatasource, err) + } + if errors.Is(err, shujubao.ErrQueryEmpty) { + return nil, errors.Join(processors.ErrNotFound, err) + } + return nil, errors.Join(processors.ErrSystem, err) + } + respBytes, err := json.Marshal(data) + if err != nil { + return nil, errors.Join(processors.ErrSystem, err) + } + return respBytes, nil +} diff --git a/internal/domains/api/services/processors/ivyz/ivyz48sr_processor.go b/internal/domains/api/services/processors/ivyz/ivyz48sr_processor.go new file mode 100644 index 0000000..8480ec2 --- /dev/null +++ b/internal/domains/api/services/processors/ivyz/ivyz48sr_processor.go @@ -0,0 +1,58 @@ +package ivyz + +import ( + "context" + "encoding/json" + "errors" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/shujubao" +) + +// ProcessIVYZ48SRRequest IVYZ48SR 婚姻状态核验V2(双人) API 处理方法(使用数据宝服务示例) +func ProcessIVYZ48SRRequest(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.IVYZ48SRReq + 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) + } + + fixedData := map[string]interface{}{"msg": "请联系商务咨询"} + fixedRespBytes, err := json.Marshal(fixedData) + if err != nil { + return nil, errors.Join(processors.ErrSystem, err) + } + return fixedRespBytes, nil + + reqParams := map[string]interface{}{ + "key": "", + "name": paramsDto.ManName, + "idcard": paramsDto.ManIDCard, + "woman_name": paramsDto.WomanName, + "woman_idcard": paramsDto.WomanIDCard, + "marital_type": paramsDto.MaritalType, + "auth_authorize_file_code": paramsDto.AuthAuthorizeFileCode, + } + + // 最终请求 URL = https://api.chinadatapay.com/communication + 拼接接口地址值,如 personal/197 + apiPath := "/communication/personal/10332" + data, err := deps.ShujubaoService.CallAPI(ctx, apiPath, reqParams) + if err != nil { + if errors.Is(err, shujubao.ErrDatasource) { + return nil, errors.Join(processors.ErrDatasource, err) + } + if errors.Is(err, shujubao.ErrQueryEmpty) { + return nil, errors.Join(processors.ErrNotFound, err) + } + return nil, errors.Join(processors.ErrSystem, err) + } + respBytes, err := json.Marshal(data) + if err != nil { + return nil, errors.Join(processors.ErrSystem, err) + } + return respBytes, nil +} diff --git a/internal/shared/validator/custom_validators.go b/internal/shared/validator/custom_validators.go index ed1a8e5..34f9d67 100644 --- a/internal/shared/validator/custom_validators.go +++ b/internal/shared/validator/custom_validators.go @@ -100,6 +100,10 @@ func RegisterCustomValidators(validate *validator.Validate) { // Base64图片格式验证器(JPG、BMP、PNG) validate.RegisterValidation("validBase64Image", validateBase64Image) + + // Base64编码格式验证器 + validate.RegisterValidation("base64", validateBase64) + validate.RegisterValidation("validBase64", validateBase64) } // validatePhone 手机号验证 @@ -1020,3 +1024,16 @@ func validateBase64Image(fl validator.FieldLevel) bool { return false } + +// validateBase64 Base64编码格式验证器 +func validateBase64(fl validator.FieldLevel) bool { + base64Str := strings.TrimSpace(fl.Field().String()) + + // 空值由 required/omitempty 处理 + if base64Str == "" { + return true + } + + _, err := base64.StdEncoding.DecodeString(base64Str) + return err == nil +}