| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- 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"),
- }
- }
- }
|