package config import ( "fmt" "strconv" "strings" "github.com/go-kratos/kratos/v2/config" "github.com/go-kratos/kratos/v2/config/env" ) type EnvSource struct { Prefixes []string } func (e *EnvSource) NewSource() (config.Source, error) { source := env.NewSource(e.Prefixes...) return source, nil } func (e *EnvSource) Validate() bool { if len(e.Prefixes) == 0 { return false } return true } func (e *EnvSource) String() string { return fmt.Sprintf("env source prefixes:%v", e.Prefixes) } // buildNestedMap 将环境变量的键值对转换为嵌套的 map 结构 // 例如: "SERVER_PORT" -> "8080" 转换为 {"server": {"port": "8080"}} func buildNestedMap(key, value string) map[string]any { result := make(map[string]any) current := result // 将大写的键名转换为小写,并用下划线分割 parts := strings.Split(strings.ToLower(key), "_") // 构建嵌套结构 for i, part := range parts { if i == len(parts)-1 { // 最后一个部分,设置值 current[part] = convertEnvValue(value) } else { // 中间部分,创建嵌套 map if _, exists := current[part]; !exists { current[part] = make(map[string]any) } current = current[part].(map[string]any) } } return result } // convertEnvValue 尝试将环境变量的字符串值转换为合适的类型 func convertEnvValue(value string) any { // 布尔值转换 if value == "true" { return true } if value == "false" { return false } // 整数转换 if i, err := strconv.Atoi(value); err == nil { return i } // 浮点数转换 if f, err := strconv.ParseFloat(value, 64); err == nil { return f } // 默认返回字符串 return value }