This commit is contained in:
Mrx
2026-03-20 16:23:08 +08:00
parent c27b15af18
commit a6f309e472
8 changed files with 451 additions and 209 deletions

View File

@@ -620,6 +620,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"`
}
type FLXGDJG3Req struct {
IDCard string `json:"id_card" validate:"required,validIDCard"`

View File

@@ -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

View File

@@ -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"
@@ -491,6 +497,8 @@ func (s *FormConfigServiceImpl) generateFieldLabel(jsonTag string) string {
"first_registrationdate": "首次登记日期",
"color": "颜色",
"plate_color": "车牌颜色",
"marital_type": "婚姻状况类型",
"auth_authorize_file_base64": "PDF授权文件Base64编码5MB以内",
}
if label, exists := labelMap[jsonTag]; exists {
@@ -553,7 +561,9 @@ func (s *FormConfigServiceImpl) generateExampleValue(fieldType reflect.Type, jso
"vehicle_location": "车辆所在地,示例:北京",
"first_registrationdate": "初登日期示例2020-05",
"color": "示例:白色",
"plate_color": "车牌颜色0蓝色1黄色2黑色3白色4渐变绿色5黄绿双拼色6蓝白渐变色7临时牌照11绿色12红色默认标准车牌查蓝色新能源车牌查绿色",
"plate_color": "0",
"marital_type": "10",
"auth_authorize_file_base64": "JVBERi0xLjQKJcTl8uXr...示例PDF的Base64编码",
}
if example, exists := exampleMap[jsonTag]; exists {
@@ -626,6 +636,8 @@ func (s *FormConfigServiceImpl) generatePlaceholder(jsonTag string, fieldType st
"first_registrationdate": "请输入首次登记日期格式YYYY-MM",
"color": "请输入颜色",
"plate_color": "请输入车牌颜色",
"marital_type": "请选择婚姻状况类型",
"auth_authorize_file_base64": "请输入PDF文件的Base64编码字符串",
}
if placeholder, exists := placeholderMap[jsonTag]; exists {
@@ -700,6 +712,8 @@ func (s *FormConfigServiceImpl) generateDescription(jsonTag string, validation s
"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 {

View File

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

View File

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

View File

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

View File

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

View File

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