453 lines
14 KiB
Go
453 lines
14 KiB
Go
package services
|
||
|
||
import (
|
||
"reflect"
|
||
"strings"
|
||
"tyapi-server/internal/domains/api/dto"
|
||
)
|
||
|
||
// FormField 表单字段配置
|
||
type FormField struct {
|
||
Name string `json:"name"`
|
||
Label string `json:"label"`
|
||
Type string `json:"type"`
|
||
Required bool `json:"required"`
|
||
Validation string `json:"validation"`
|
||
Description string `json:"description"`
|
||
Example string `json:"example"`
|
||
Placeholder string `json:"placeholder"`
|
||
}
|
||
|
||
// FormConfig 表单配置
|
||
type FormConfig struct {
|
||
ApiCode string `json:"api_code"`
|
||
Fields []FormField `json:"fields"`
|
||
}
|
||
|
||
// FormConfigService 表单配置服务接口
|
||
type FormConfigService interface {
|
||
GetFormConfig(apiCode string) (*FormConfig, error)
|
||
}
|
||
|
||
// FormConfigServiceImpl 表单配置服务实现
|
||
type FormConfigServiceImpl struct{}
|
||
|
||
// NewFormConfigService 创建表单配置服务
|
||
func NewFormConfigService() FormConfigService {
|
||
return &FormConfigServiceImpl{}
|
||
}
|
||
|
||
// GetFormConfig 获取指定API的表单配置
|
||
func (s *FormConfigServiceImpl) GetFormConfig(apiCode string) (*FormConfig, error) {
|
||
// 根据API代码获取对应的DTO结构体
|
||
dtoStruct := s.getDTOStruct(apiCode)
|
||
if dtoStruct == nil {
|
||
return nil, nil
|
||
}
|
||
|
||
// 通过反射解析结构体字段
|
||
fields := s.parseDTOFields(dtoStruct)
|
||
|
||
config := &FormConfig{
|
||
ApiCode: apiCode,
|
||
Fields: fields,
|
||
}
|
||
|
||
return config, nil
|
||
}
|
||
|
||
// getDTOStruct 根据API代码获取对应的DTO结构体
|
||
func (s *FormConfigServiceImpl) getDTOStruct(apiCode string) interface{} {
|
||
// 建立API代码到DTO结构体的映射
|
||
dtoMap := map[string]interface{}{
|
||
"IVYZ9363": &dto.IVYZ9363Req{},
|
||
"IVYZ385E": &dto.IVYZ385EReq{},
|
||
"IVYZ5733": &dto.IVYZ5733Req{},
|
||
"FLXG3D56": &dto.FLXG3D56Req{},
|
||
"FLXG75FE": &dto.FLXG75FEReq{},
|
||
"FLXG0V3B": &dto.FLXG0V3BReq{},
|
||
"FLXG0V4B": &dto.FLXG0V4BReq{},
|
||
"FLXG54F5": &dto.FLXG54F5Req{},
|
||
"FLXG162A": &dto.FLXG162AReq{},
|
||
"FLXG0687": &dto.FLXG0687Req{},
|
||
"FLXGBC21": &dto.FLXGBC21Req{},
|
||
"FLXG970F": &dto.FLXG970FReq{},
|
||
"FLXG5876": &dto.FLXG5876Req{},
|
||
"FLXG9687": &dto.FLXG9687Req{},
|
||
"FLXGC9D1": &dto.FLXGC9D1Req{},
|
||
"FLXGCA3D": &dto.FLXGCA3DReq{},
|
||
"FLXGDEC7": &dto.FLXGDEC7Req{},
|
||
"JRZQ0A03": &dto.JRZQ0A03Req{},
|
||
"JRZQ4AA8": &dto.JRZQ4AA8Req{},
|
||
"JRZQ8203": &dto.JRZQ8203Req{},
|
||
"JRZQDBCE": &dto.JRZQDBCEReq{},
|
||
"QYGL2ACD": &dto.QYGL2ACDReq{},
|
||
"QYGL6F2D": &dto.QYGL6F2DReq{},
|
||
"QYGL45BD": &dto.QYGL45BDReq{},
|
||
"QYGL8261": &dto.QYGL8261Req{},
|
||
"QYGL8271": &dto.QYGL8271Req{},
|
||
"QYGLB4C0": &dto.QYGLB4C0Req{},
|
||
"QYGL23T7": &dto.QYGL23T7Req{},
|
||
"QYGL5A3C": &dto.QYGL5A3CReq{},
|
||
"QYGL8B4D": &dto.QYGL8B4DReq{},
|
||
"QYGL9E2F": &dto.QYGL9E2FReq{},
|
||
"QYGL7C1A": &dto.QYGL7C1AReq{},
|
||
"QYGL3F8E": &dto.QYGL3F8EReq{},
|
||
"YYSY4B37": &dto.YYSY4B37Req{},
|
||
"YYSY4B21": &dto.YYSY4B21Req{},
|
||
"YYSY6F2E": &dto.YYSY6F2EReq{},
|
||
"YYSY09CD": &dto.YYSY09CDReq{},
|
||
"IVYZ0b03": &dto.IVYZ0b03Req{},
|
||
"YYSYBE08": &dto.YYSYBE08Req{},
|
||
"YYSYD50F": &dto.YYSYD50FReq{},
|
||
"YYSYF7DB": &dto.YYSYF7DBReq{},
|
||
"IVYZ9A2B": &dto.IVYZ9A2BReq{},
|
||
"IVYZ7F2A": &dto.IVYZ7F2AReq{},
|
||
"IVYZ4E8B": &dto.IVYZ4E8BReq{},
|
||
"IVYZ1C9D": &dto.IVYZ1C9DReq{},
|
||
"IVYZGZ08": &dto.IVYZGZ08Req{},
|
||
"FLXG8A3F": &dto.FLXG8A3FReq{},
|
||
"FLXG5B2E": &dto.FLXG5B2EReq{},
|
||
"COMB298Y": &dto.COMB298YReq{},
|
||
"COMB86PM": &dto.COMB86PMReq{},
|
||
"QCXG7A2B": &dto.QCXG7A2BReq{},
|
||
"COMENT01": &dto.COMENT01Req{},
|
||
"JRZQ09J8": &dto.JRZQ09J8Req{},
|
||
"FLXGDEA8": &dto.FLXGDEA8Req{},
|
||
"FLXGDEA9": &dto.FLXGDEA9Req{},
|
||
"JRZQ1D09": &dto.JRZQ1D09Req{},
|
||
"IVYZ2A8B": &dto.IVYZ2A8BReq{},
|
||
"IVYZ7C9D": &dto.IVYZ7C9DReq{},
|
||
"IVYZ5E3F": &dto.IVYZ5E3FReq{},
|
||
"YYSY4F2E": &dto.YYSY4F2EReq{},
|
||
"YYSY8B1C": &dto.YYSY8B1CReq{},
|
||
"YYSY6D9A": &dto.YYSY6D9AReq{},
|
||
"YYSY3E7F": &dto.YYSY3E7FReq{},
|
||
"FLXG5A3B": &dto.FLXG5A3BReq{},
|
||
"FLXG9C1D": &dto.FLXG9C1DReq{},
|
||
"FLXG2E8F": &dto.FLXG2E8FReq{},
|
||
"JRZQ3C7B": &dto.JRZQ3C7BReq{},
|
||
"JRZQ8A2D": &dto.JRZQ8A2DReq{},
|
||
"JRZQ5E9F": &dto.JRZQ5E9FReq{},
|
||
"JRZQ4B6C": &dto.JRZQ4B6CReq{},
|
||
"JRZQ7F1A": &dto.JRZQ7F1AReq{},
|
||
"DWBG6A2C": &dto.DWBG6A2CReq{},
|
||
"DWBG8B4D": &dto.DWBG8B4DReq{},
|
||
"FLXG8B4D": &dto.FLXG8B4DReq{},
|
||
"IVYZ81NC": &dto.IVYZ81NCReq{},
|
||
"IVYZ7F3A": &dto.IVYZ7F3AReq{},
|
||
"IVYZ3A7F": &dto.IVYZ3A7FReq{},
|
||
"IVYZ9D2E": &dto.IVYZ9D2EReq{},
|
||
"DWBG7F3A": &dto.DWBG7F3AReq{},
|
||
"YYSY8F3A": &dto.YYSY8F3AReq{},
|
||
"QCXG9P1C": &dto.QCXG9P1CReq{},
|
||
"JRZQ9E2A": &dto.JRZQ9E2AReq{},
|
||
"YYSY9A1B": &dto.YYSY9A1BReq{},
|
||
"YYSY8C2D": &dto.YYSY8C2DReq{},
|
||
"YYSY7D3E": &dto.YYSY7D3EReq{},
|
||
"YYSY9E4A": &dto.YYSY9E4AReq{},
|
||
"JRZQ6F2A": &dto.JRZQ6F2AReq{},
|
||
"JRZQ8B3C": &dto.JRZQ8B3CReq{},
|
||
"JRZQ9D4E": &dto.JRZQ9D4EReq{},
|
||
"FLXG7E8F": &dto.FLXG7E8FReq{},
|
||
"QYGL5F6A": &dto.QYGL5F6AReq{},
|
||
"IVYZ6G7H": &dto.IVYZ6G7HReq{},
|
||
"IVYZ8I9J": &dto.IVYZ8I9JReq{},
|
||
}
|
||
|
||
// 优先返回已配置的DTO
|
||
if dto, exists := dtoMap[apiCode]; exists {
|
||
return dto
|
||
}
|
||
|
||
// 检查是否为通用组合包(COMB开头且未单独配置)
|
||
if len(apiCode) >= 4 && apiCode[:4] == "COMB" {
|
||
// 对于通用组合包,返回一个通用的空结构体,表示无需特定参数验证
|
||
// 因为组合包的参数验证由各个子处理器负责
|
||
return &struct{}{}
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// parseDTOFields 通过反射解析DTO结构体字段
|
||
func (s *FormConfigServiceImpl) parseDTOFields(dtoStruct interface{}) []FormField {
|
||
var fields []FormField
|
||
|
||
t := reflect.TypeOf(dtoStruct).Elem()
|
||
|
||
for i := 0; i < t.NumField(); i++ {
|
||
field := t.Field(i)
|
||
|
||
// 获取JSON标签
|
||
jsonTag := field.Tag.Get("json")
|
||
if jsonTag == "" {
|
||
continue
|
||
}
|
||
|
||
// 获取验证标签
|
||
validateTag := field.Tag.Get("validate")
|
||
|
||
// 解析验证规则
|
||
required := strings.Contains(validateTag, "required")
|
||
validation := s.parseValidationRules(validateTag)
|
||
|
||
// 根据字段类型和验证规则生成前端字段类型
|
||
fieldType := s.getFieldType(field.Type, validation)
|
||
|
||
// 生成字段标签(将下划线转换为中文)
|
||
label := s.generateFieldLabel(jsonTag)
|
||
|
||
// 生成示例值
|
||
example := s.generateExampleValue(field.Type, jsonTag)
|
||
|
||
// 生成占位符
|
||
placeholder := s.generatePlaceholder(jsonTag, fieldType)
|
||
|
||
// 生成字段描述
|
||
description := s.generateDescription(jsonTag, validation)
|
||
|
||
formField := FormField{
|
||
Name: jsonTag,
|
||
Label: label,
|
||
Type: fieldType,
|
||
Required: required,
|
||
Validation: validation,
|
||
Description: description,
|
||
Example: example,
|
||
Placeholder: placeholder,
|
||
}
|
||
|
||
fields = append(fields, formField)
|
||
}
|
||
|
||
return fields
|
||
}
|
||
|
||
// parseValidationRules 解析验证规则
|
||
func (s *FormConfigServiceImpl) parseValidationRules(validateTag string) string {
|
||
if validateTag == "" {
|
||
return ""
|
||
}
|
||
|
||
// 将验证规则转换为前端可理解的格式
|
||
rules := strings.Split(validateTag, ",")
|
||
var frontendRules []string
|
||
|
||
for _, rule := range rules {
|
||
rule = strings.TrimSpace(rule)
|
||
switch {
|
||
case rule == "required":
|
||
frontendRules = append(frontendRules, "必填")
|
||
case strings.HasPrefix(rule, "min="):
|
||
min := strings.TrimPrefix(rule, "min=")
|
||
frontendRules = append(frontendRules, "最小长度"+min)
|
||
case strings.HasPrefix(rule, "max="):
|
||
max := strings.TrimPrefix(rule, "max=")
|
||
frontendRules = append(frontendRules, "最大长度"+max)
|
||
case rule == "validMobileNo":
|
||
frontendRules = append(frontendRules, "手机号格式")
|
||
case rule == "validIDCard":
|
||
frontendRules = append(frontendRules, "身份证格式")
|
||
case rule == "validName":
|
||
frontendRules = append(frontendRules, "姓名格式")
|
||
case rule == "validUSCI":
|
||
frontendRules = append(frontendRules, "统一社会信用代码格式")
|
||
case rule == "validBankCard":
|
||
frontendRules = append(frontendRules, "银行卡号格式")
|
||
case rule == "validDate":
|
||
frontendRules = append(frontendRules, "日期格式")
|
||
case rule == "validAuthDate":
|
||
frontendRules = append(frontendRules, "授权日期格式")
|
||
case rule == "validTimeRange":
|
||
frontendRules = append(frontendRules, "时间范围格式")
|
||
case rule == "validMobileType":
|
||
frontendRules = append(frontendRules, "手机类型")
|
||
case rule == "validUniqueID":
|
||
frontendRules = append(frontendRules, "唯一标识格式")
|
||
case rule == "validReturnURL":
|
||
frontendRules = append(frontendRules, "返回链接格式")
|
||
case rule == "validAuthorizationURL":
|
||
frontendRules = append(frontendRules, "授权链接格式")
|
||
case strings.HasPrefix(rule, "oneof="):
|
||
values := strings.TrimPrefix(rule, "oneof=")
|
||
frontendRules = append(frontendRules, "可选值: "+values)
|
||
}
|
||
}
|
||
|
||
return strings.Join(frontendRules, "、")
|
||
}
|
||
|
||
// getFieldType 根据字段类型和验证规则确定前端字段类型
|
||
func (s *FormConfigServiceImpl) getFieldType(fieldType reflect.Type, validation string) string {
|
||
switch fieldType.Kind() {
|
||
case reflect.String:
|
||
if strings.Contains(validation, "手机号") {
|
||
return "tel"
|
||
} else if strings.Contains(validation, "身份证") {
|
||
return "text"
|
||
} else if strings.Contains(validation, "姓名") {
|
||
return "text"
|
||
} else if strings.Contains(validation, "日期") {
|
||
return "date"
|
||
} else if strings.Contains(validation, "链接") {
|
||
return "url"
|
||
} else if strings.Contains(validation, "可选值") {
|
||
return "select"
|
||
}
|
||
return "text"
|
||
case reflect.Int64:
|
||
return "number"
|
||
case reflect.Bool:
|
||
return "checkbox"
|
||
default:
|
||
return "text"
|
||
}
|
||
}
|
||
|
||
// generateFieldLabel 生成字段标签
|
||
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": "企业代码",
|
||
"auth_date": "授权日期",
|
||
"time_range": "时间范围",
|
||
"authorized": "是否授权",
|
||
"authorization_url": "授权链接",
|
||
"unique_id": "唯一标识",
|
||
"return_url": "返回链接",
|
||
"mobile_type": "手机类型",
|
||
"start_date": "开始日期",
|
||
"years": "年数",
|
||
"bank_card": "银行卡号",
|
||
}
|
||
|
||
if label, exists := labelMap[jsonTag]; exists {
|
||
return label
|
||
}
|
||
|
||
// 如果没有预定义,尝试自动转换
|
||
return strings.ReplaceAll(jsonTag, "_", " ")
|
||
}
|
||
|
||
// 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",
|
||
"auth_date": "2024-01-01",
|
||
"time_range": "2024-01-01至2024-12-31",
|
||
"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/auth",
|
||
}
|
||
|
||
if example, exists := exampleMap[jsonTag]; exists {
|
||
return example
|
||
}
|
||
|
||
// 根据字段类型生成默认示例
|
||
switch fieldType.Kind() {
|
||
case reflect.String:
|
||
return "示例值"
|
||
case reflect.Int64:
|
||
return "123"
|
||
case reflect.Bool:
|
||
return "true"
|
||
default:
|
||
return "示例值"
|
||
}
|
||
}
|
||
|
||
// 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": "请输入统一社会信用代码",
|
||
"auth_date": "请选择授权日期",
|
||
"time_range": "请输入查询时间范围",
|
||
"authorized": "请选择是否授权",
|
||
"years": "请输入查询年数(0-100)",
|
||
"bank_card": "请输入银行卡号",
|
||
"mobile_type": "请选择手机类型",
|
||
"start_date": "请选择开始日期",
|
||
"unique_id": "请输入唯一标识",
|
||
"return_url": "请输入返回链接",
|
||
"authorization_url": "请输入授权链接",
|
||
}
|
||
|
||
if placeholder, exists := placeholderMap[jsonTag]; exists {
|
||
return placeholder
|
||
}
|
||
|
||
// 根据字段类型生成默认占位符
|
||
switch fieldType {
|
||
case "tel":
|
||
return "请输入电话号码"
|
||
case "date":
|
||
return "请选择日期"
|
||
case "url":
|
||
return "请输入链接地址"
|
||
case "number":
|
||
return "请输入数字"
|
||
default:
|
||
return "请输入" + s.generateFieldLabel(jsonTag)
|
||
}
|
||
}
|
||
|
||
// 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": "请输入统一社会信用代码",
|
||
"auth_date": "请输入授权日期,格式:YYYY-MM-DD",
|
||
"time_range": "请输入查询时间范围",
|
||
"authorized": "请输入是否授权:0-未授权,1-已授权",
|
||
"years": "请输入查询年数(0-100)",
|
||
"bank_card": "请输入银行卡号",
|
||
"mobile_type": "请选择手机类型",
|
||
"start_date": "请选择开始日期",
|
||
"unique_id": "请输入唯一标识",
|
||
"return_url": "请输入返回链接",
|
||
"authorization_url": "请输入授权链接",
|
||
}
|
||
|
||
if desc, exists := descMap[jsonTag]; exists {
|
||
return desc
|
||
}
|
||
|
||
return "请输入" + s.generateFieldLabel(jsonTag)
|
||
}
|