説明なし
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

core_create_meta.go 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package core
  2. import (
  3. "reflect"
  4. "strings"
  5. )
  6. // ConfigMeta 配置元信息
  7. type ConfigMeta struct {
  8. Name string `json:"name"` // 配置名称,如 "consul"
  9. Desc string `json:"desc"` // 配置描述
  10. Fields map[string]FieldMeta `json:"fields"` // 字段信息
  11. }
  12. // FieldMeta 字段元信息
  13. type FieldMeta struct {
  14. Type string `json:"type"` // 字段类型,如 "string"
  15. YamlName string `json:"yamlName"` // YAML标签,如 "address"
  16. Desc string `json:"desc"` // 字段描述
  17. }
  18. // GetAllConfigsMeta 获取所有配置的元信息
  19. func GetAllConfigsMeta() map[string]*ConfigMeta {
  20. // 获取所有配置实例
  21. allConfigs := GetAllConfigs()
  22. result := make(map[string]*ConfigMeta, len(allConfigs))
  23. // 遍历所有配置
  24. for name, config := range allConfigs {
  25. meta := getConfigMeta(name, config)
  26. result[name] = meta
  27. }
  28. return result
  29. }
  30. // GetConfigMeta 获取单个配置的元信息
  31. func GetConfigMeta(name string) (*ConfigMeta, error) {
  32. config := GetConfig(name)
  33. if config == nil {
  34. return nil, nil
  35. }
  36. return getConfigMeta(name, config), nil
  37. }
  38. // getConfigMeta 内部方法:获取配置元信息
  39. func getConfigMeta(name string, config ConfigLoader) *ConfigMeta {
  40. meta := &ConfigMeta{
  41. Name: name,
  42. Desc: config.Description(),
  43. Fields: make(map[string]FieldMeta),
  44. }
  45. // 使用反射获取类型信息
  46. t := reflect.TypeOf(config)
  47. // 如果是指针类型,获取其指向的类型
  48. if t.Kind() == reflect.Ptr {
  49. t = t.Elem()
  50. }
  51. // 遍历所有字段
  52. for i := 0; i < t.NumField(); i++ {
  53. field := t.Field(i)
  54. yamlTag := field.Tag.Get("yaml")
  55. // 跳过BaseConfig这种匿名字段(除非是inline)
  56. if field.Anonymous && !strings.Contains(yamlTag, "inline") {
  57. continue
  58. }
  59. // 处理inline字段
  60. if strings.Contains(yamlTag, "inline") {
  61. // 获取字段类型
  62. fieldType := field.Type
  63. // 如果是map类型,提取map值的结构体信息
  64. if fieldType.Kind() == reflect.Map {
  65. // 获取map的值类型
  66. valueType := fieldType.Elem()
  67. // 如果是指针类型,获取指向的类型
  68. if valueType.Kind() == reflect.Ptr {
  69. valueType = valueType.Elem()
  70. }
  71. // 如果值类型是结构体,提取其字段
  72. if valueType.Kind() == reflect.Struct {
  73. // 创建FieldMeta
  74. fieldMeta := FieldMeta{
  75. Type: field.Type.String(),
  76. YamlName: yamlTag,
  77. Desc: field.Tag.Get("desc"),
  78. }
  79. // 提取结构体字段
  80. valueFields := make(map[string]FieldMeta)
  81. extractStructFields(valueType, valueFields)
  82. // 这里可以添加一个子字段信息,或者直接合并到主字段
  83. // 为了简单,我们直接合并
  84. for name, fm := range valueFields {
  85. meta.Fields[name] = fm
  86. }
  87. // 同时保留map字段本身
  88. meta.Fields[field.Name] = fieldMeta
  89. } else {
  90. // 不是结构体类型,只显示map本身
  91. meta.Fields[field.Name] = FieldMeta{
  92. Type: field.Type.String(),
  93. YamlName: yamlTag,
  94. Desc: field.Tag.Get("desc"),
  95. }
  96. }
  97. } else if fieldType.Kind() == reflect.Struct ||
  98. (fieldType.Kind() == reflect.Ptr && fieldType.Elem().Kind() == reflect.Struct) {
  99. // 对于结构体类型(或指向结构体的指针),递归提取内联结构体的字段
  100. if fieldType.Kind() == reflect.Ptr {
  101. fieldType = fieldType.Elem()
  102. }
  103. extractInlineFields(fieldType, meta.Fields)
  104. } else {
  105. // 其他类型
  106. meta.Fields[field.Name] = FieldMeta{
  107. Type: field.Type.String(),
  108. YamlName: yamlTag,
  109. Desc: field.Tag.Get("desc"),
  110. }
  111. }
  112. continue
  113. }
  114. // 处理普通字段
  115. meta.Fields[field.Name] = FieldMeta{
  116. Type: field.Type.String(),
  117. YamlName: yamlTag,
  118. Desc: field.Tag.Get("desc"),
  119. }
  120. }
  121. return meta
  122. }
  123. // extractInlineFields 提取内联结构体的字段
  124. func extractInlineFields(t reflect.Type, fields map[string]FieldMeta) {
  125. // 遍历结构体的字段
  126. for i := 0; i < t.NumField(); i++ {
  127. field := t.Field(i)
  128. // 跳过匿名字段
  129. if field.Anonymous {
  130. continue
  131. }
  132. fields[field.Name] = FieldMeta{
  133. Type: field.Type.String(),
  134. YamlName: field.Tag.Get("yaml"),
  135. Desc: field.Tag.Get("desc"),
  136. }
  137. }
  138. }
  139. // extractStructFields 提取结构体字段
  140. func extractStructFields(t reflect.Type, fields map[string]FieldMeta) {
  141. // 遍历结构体的字段
  142. for i := 0; i < t.NumField(); i++ {
  143. field := t.Field(i)
  144. // 跳过匿名字段
  145. if field.Anonymous {
  146. continue
  147. }
  148. fields[field.Name] = FieldMeta{
  149. Type: field.Type.String(),
  150. YamlName: field.Tag.Get("yaml"),
  151. Desc: field.Tag.Get("desc"),
  152. }
  153. }
  154. }