package core import ( "reflect" "strings" ) // ConfigMeta 配置元信息 type ConfigMeta struct { Name string `json:"name"` // 配置名称,如 "consul" Desc string `json:"desc"` // 配置描述 Fields map[string]FieldMeta `json:"fields"` // 字段信息 } // FieldMeta 字段元信息 type FieldMeta struct { Type string `json:"type"` // 字段类型,如 "string" YamlName string `json:"yamlName"` // YAML标签,如 "address" Desc string `json:"desc"` // 字段描述 } // GetAllConfigsMeta 获取所有配置的元信息 func GetAllConfigsMeta() map[string]*ConfigMeta { // 获取所有配置实例 allConfigs := GetAllConfigs() result := make(map[string]*ConfigMeta, len(allConfigs)) // 遍历所有配置 for name, config := range allConfigs { meta := getConfigMeta(name, config) result[name] = meta } return result } // GetConfigMeta 获取单个配置的元信息 func GetConfigMeta(name string) (*ConfigMeta, error) { config := GetConfig(name) if config == nil { return nil, nil } return getConfigMeta(name, config), nil } // getConfigMeta 内部方法:获取配置元信息 func getConfigMeta(name string, config ConfigLoader) *ConfigMeta { meta := &ConfigMeta{ Name: name, Desc: config.Description(), Fields: make(map[string]FieldMeta), } // 使用反射获取类型信息 t := reflect.TypeOf(config) // 如果是指针类型,获取其指向的类型 if t.Kind() == reflect.Ptr { t = t.Elem() } // 遍历所有字段 for i := 0; i < t.NumField(); i++ { field := t.Field(i) yamlTag := field.Tag.Get("yaml") // 跳过BaseConfig这种匿名字段(除非是inline) if field.Anonymous && !strings.Contains(yamlTag, "inline") { continue } // 处理inline字段 if strings.Contains(yamlTag, "inline") { // 获取字段类型 fieldType := field.Type // 如果是map类型,提取map值的结构体信息 if fieldType.Kind() == reflect.Map { // 获取map的值类型 valueType := fieldType.Elem() // 如果是指针类型,获取指向的类型 if valueType.Kind() == reflect.Ptr { valueType = valueType.Elem() } // 如果值类型是结构体,提取其字段 if valueType.Kind() == reflect.Struct { // 创建FieldMeta fieldMeta := FieldMeta{ Type: field.Type.String(), YamlName: yamlTag, Desc: field.Tag.Get("desc"), } // 提取结构体字段 valueFields := make(map[string]FieldMeta) extractStructFields(valueType, valueFields) // 这里可以添加一个子字段信息,或者直接合并到主字段 // 为了简单,我们直接合并 for name, fm := range valueFields { meta.Fields[name] = fm } // 同时保留map字段本身 meta.Fields[field.Name] = fieldMeta } else { // 不是结构体类型,只显示map本身 meta.Fields[field.Name] = FieldMeta{ Type: field.Type.String(), YamlName: yamlTag, Desc: field.Tag.Get("desc"), } } } else if fieldType.Kind() == reflect.Struct || (fieldType.Kind() == reflect.Ptr && fieldType.Elem().Kind() == reflect.Struct) { // 对于结构体类型(或指向结构体的指针),递归提取内联结构体的字段 if fieldType.Kind() == reflect.Ptr { fieldType = fieldType.Elem() } extractInlineFields(fieldType, meta.Fields) } else { // 其他类型 meta.Fields[field.Name] = FieldMeta{ Type: field.Type.String(), YamlName: yamlTag, Desc: field.Tag.Get("desc"), } } continue } // 处理普通字段 meta.Fields[field.Name] = FieldMeta{ Type: field.Type.String(), YamlName: yamlTag, Desc: field.Tag.Get("desc"), } } return meta } // extractInlineFields 提取内联结构体的字段 func extractInlineFields(t reflect.Type, fields map[string]FieldMeta) { // 遍历结构体的字段 for i := 0; i < t.NumField(); i++ { field := t.Field(i) // 跳过匿名字段 if field.Anonymous { continue } fields[field.Name] = FieldMeta{ Type: field.Type.String(), YamlName: field.Tag.Get("yaml"), Desc: field.Tag.Get("desc"), } } } // extractStructFields 提取结构体字段 func extractStructFields(t reflect.Type, fields map[string]FieldMeta) { // 遍历结构体的字段 for i := 0; i < t.NumField(); i++ { field := t.Field(i) // 跳过匿名字段 if field.Anonymous { continue } fields[field.Name] = FieldMeta{ Type: field.Type.String(), YamlName: field.Tag.Get("yaml"), Desc: field.Tag.Get("desc"), } } }