package config import ( "encoding/json" "one-api/common" "reflect" "strconv" "strings" "sync" ) // ConfigManager 统一管理所有配置 type ConfigManager struct { configs map[string]interface{} mutex sync.RWMutex } var GlobalConfig = NewConfigManager() func NewConfigManager() *ConfigManager { return &ConfigManager{ configs: make(map[string]interface{}), } } // Register 注册一个配置模块 func (cm *ConfigManager) Register(name string, config interface{}) { cm.mutex.Lock() defer cm.mutex.Unlock() cm.configs[name] = config } // Get 获取指定配置模块 func (cm *ConfigManager) Get(name string) interface{} { cm.mutex.RLock() defer cm.mutex.RUnlock() return cm.configs[name] } // LoadFromDB 从数据库加载配置 func (cm *ConfigManager) LoadFromDB(options map[string]string) error { cm.mutex.Lock() defer cm.mutex.Unlock() for name, config := range cm.configs { prefix := name + "." configMap := make(map[string]string) // 收集属于此配置的所有选项 for key, value := range options { if strings.HasPrefix(key, prefix) { configKey := strings.TrimPrefix(key, prefix) configMap[configKey] = value } } // 如果找到配置项,则更新配置 if len(configMap) > 0 { if err := updateConfigFromMap(config, configMap); err != nil { common.SysError("failed to update config " + name + ": " + err.Error()) continue } } } return nil } // SaveToDB 将配置保存到数据库 func (cm *ConfigManager) SaveToDB(updateFunc func(key, value string) error) error { cm.mutex.RLock() defer cm.mutex.RUnlock() for name, config := range cm.configs { configMap, err := configToMap(config) if err != nil { return err } for key, value := range configMap { dbKey := name + "." + key if err := updateFunc(dbKey, value); err != nil { return err } } } return nil } // 辅助函数:将配置对象转换为map func configToMap(config interface{}) (map[string]string, error) { result := make(map[string]string) val := reflect.ValueOf(config) if val.Kind() == reflect.Ptr { val = val.Elem() } if val.Kind() != reflect.Struct { return nil, nil } typ := val.Type() for i := 0; i < val.NumField(); i++ { field := val.Field(i) fieldType := typ.Field(i) // 跳过未导出字段 if !fieldType.IsExported() { continue } // 获取json标签作为键名 key := fieldType.Tag.Get("json") if key == "" || key == "-" { key = fieldType.Name } // 处理不同类型的字段 var strValue string switch field.Kind() { case reflect.String: strValue = field.String() case reflect.Bool: strValue = strconv.FormatBool(field.Bool()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: strValue = strconv.FormatInt(field.Int(), 10) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: strValue = strconv.FormatUint(field.Uint(), 10) case reflect.Float32, reflect.Float64: strValue = strconv.FormatFloat(field.Float(), 'f', -1, 64) case reflect.Map, reflect.Slice, reflect.Struct: // 复杂类型使用JSON序列化 bytes, err := json.Marshal(field.Interface()) if err != nil { return nil, err } strValue = string(bytes) default: // 跳过不支持的类型 continue } result[key] = strValue } return result, nil } // 辅助函数:从map更新配置对象 func updateConfigFromMap(config interface{}, configMap map[string]string) error { val := reflect.ValueOf(config) if val.Kind() != reflect.Ptr { return nil } val = val.Elem() if val.Kind() != reflect.Struct { return nil } typ := val.Type() for i := 0; i < val.NumField(); i++ { field := val.Field(i) fieldType := typ.Field(i) // 跳过未导出字段 if !fieldType.IsExported() { continue } // 获取json标签作为键名 key := fieldType.Tag.Get("json") if key == "" || key == "-" { key = fieldType.Name } // 检查map中是否有对应的值 strValue, ok := configMap[key] if !ok { continue } // 根据字段类型设置值 if !field.CanSet() { continue } switch field.Kind() { case reflect.String: field.SetString(strValue) case reflect.Bool: boolValue, err := strconv.ParseBool(strValue) if err != nil { continue } field.SetBool(boolValue) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: intValue, err := strconv.ParseInt(strValue, 10, 64) if err != nil { continue } field.SetInt(intValue) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: uintValue, err := strconv.ParseUint(strValue, 10, 64) if err != nil { continue } field.SetUint(uintValue) case reflect.Float32, reflect.Float64: floatValue, err := strconv.ParseFloat(strValue, 64) if err != nil { continue } field.SetFloat(floatValue) case reflect.Map, reflect.Slice, reflect.Struct: // 复杂类型使用JSON反序列化 err := json.Unmarshal([]byte(strValue), field.Addr().Interface()) if err != nil { continue } } } return nil } // ConfigToMap 将配置对象转换为map(导出函数) func ConfigToMap(config interface{}) (map[string]string, error) { return configToMap(config) } // UpdateConfigFromMap 从map更新配置对象(导出函数) func UpdateConfigFromMap(config interface{}, configMap map[string]string) error { return updateConfigFromMap(config, configMap) } // ExportAllConfigs 导出所有已注册的配置为扁平结构 func (cm *ConfigManager) ExportAllConfigs() map[string]string { cm.mutex.RLock() defer cm.mutex.RUnlock() result := make(map[string]string) for name, cfg := range cm.configs { configMap, err := ConfigToMap(cfg) if err != nil { continue } // 使用 "模块名.配置项" 的格式添加到结果中 for key, value := range configMap { result[name+"."+key] = value } } return result }