package utils import ( "fmt" "gpt-load/internal/models" "gpt-load/internal/types" "io" "os" "path/filepath" "reflect" "strconv" "strings" "github.com/sirupsen/logrus" ) // GenerateSettingsMetadata 使用反射从 SystemSettings 结构体动态生成元数据 func GenerateSettingsMetadata(s *types.SystemSettings) []models.SystemSettingInfo { var settingsInfo []models.SystemSettingInfo v := reflect.ValueOf(s).Elem() t := v.Type() for i := range t.NumField() { field := t.Field(i) fieldValue := v.Field(i) jsonTag := field.Tag.Get("json") if jsonTag == "" { continue } nameTag := field.Tag.Get("name") descTag := field.Tag.Get("desc") defaultTag := field.Tag.Get("default") validateTag := field.Tag.Get("validate") categoryTag := field.Tag.Get("category") var minValue *int if strings.HasPrefix(validateTag, "min=") { valStr := strings.TrimPrefix(validateTag, "min=") if val, err := strconv.Atoi(valStr); err == nil { minValue = &val } } info := models.SystemSettingInfo{ Key: jsonTag, Name: nameTag, Value: fieldValue.Interface(), Type: field.Type.String(), DefaultValue: defaultTag, Description: descTag, Category: categoryTag, MinValue: minValue, } settingsInfo = append(settingsInfo, info) } return settingsInfo } // DefaultSystemSettings 返回默认的系统配置 func DefaultSystemSettings() types.SystemSettings { s := types.SystemSettings{} v := reflect.ValueOf(&s).Elem() t := v.Type() for i := range t.NumField() { field := t.Field(i) defaultTag := field.Tag.Get("default") if defaultTag == "" { continue } fieldValue := v.Field(i) if fieldValue.CanSet() { if err := SetFieldFromString(fieldValue, defaultTag); err != nil { logrus.Warnf("Failed to set default value for field %s: %v", field.Name, err) } } } return s } // SetFieldFromString sets a struct field's value from a string, based on the field's kind. func SetFieldFromString(fieldValue reflect.Value, value string) error { if !fieldValue.CanSet() { return fmt.Errorf("field cannot be set") } switch fieldValue.Kind() { case reflect.Int: intVal, err := strconv.ParseInt(value, 10, 64) if err != nil { return fmt.Errorf("invalid integer value '%s': %w", value, err) } fieldValue.SetInt(int64(intVal)) case reflect.Bool: boolVal, err := strconv.ParseBool(value) if err != nil { return fmt.Errorf("invalid boolean value '%s': %w", value, err) } fieldValue.SetBool(boolVal) case reflect.String: fieldValue.SetString(value) default: return fmt.Errorf("unsupported field kind: %s", fieldValue.Kind()) } return nil } // ParseInteger parses integer environment variable func ParseInteger(value string, defaultValue int) int { if value == "" { return defaultValue } if parsed, err := strconv.Atoi(value); err == nil { return parsed } return defaultValue } // ParseBoolean parses boolean environment variable func ParseBoolean(value string, defaultValue bool) bool { if value == "" { return defaultValue } lowerValue := strings.ToLower(value) switch lowerValue { case "true", "1", "yes", "on": return true case "false", "0", "no", "off": return false default: return defaultValue } } // ParseArray parses array environment variable (comma-separated) func ParseArray(value string, defaultValue []string) []string { if value == "" { return defaultValue } parts := strings.Split(value, ",") result := make([]string, 0, len(parts)) for _, part := range parts { if trimmed := strings.TrimSpace(part); trimmed != "" { result = append(result, trimmed) } } if len(result) == 0 { return defaultValue } return result } // GetEnvOrDefault gets environment variable or default value func GetEnvOrDefault(key, defaultValue string) string { if value := os.Getenv(key); value != "" { return value } return defaultValue } // SetupLogger configures the logging system based on the provided configuration. func SetupLogger(configManager types.ConfigManager) { logConfig := configManager.GetLogConfig() // Set log level level, err := logrus.ParseLevel(logConfig.Level) if err != nil { logrus.Warn("Invalid log level, using info") level = logrus.InfoLevel } logrus.SetLevel(level) // Set log format if logConfig.Format == "json" { logrus.SetFormatter(&logrus.JSONFormatter{ TimestampFormat: "2006-01-02T15:04:05.000Z07:00", // ISO 8601 format }) } else { logrus.SetFormatter(&logrus.TextFormatter{ ForceColors: true, FullTimestamp: true, TimestampFormat: "2006-01-02 15:04:05", }) } // Setup file logging if enabled if logConfig.EnableFile { logDir := filepath.Dir(logConfig.FilePath) if err := os.MkdirAll(logDir, 0755); err != nil { logrus.Warnf("Failed to create log directory: %v", err) } else { logFile, err := os.OpenFile(logConfig.FilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { logrus.Warnf("Failed to open log file: %v", err) } else { logrus.SetOutput(io.MultiWriter(os.Stdout, logFile)) } } } }