Files
tyapi-server/internal/domains/api/services/form_config_service.go
2025-09-20 23:29:49 +08:00

433 lines
13 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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{},
"FLXG21": &dto.FLXG21Req{},
"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{},
"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{},
}
// 优先返回已配置的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)
}