package config import ( "fmt" "os" "gopkg.in/yaml.v3" ) type Config struct { Server struct { Port int `yaml:"port"` Key string `yaml:"key"` } `yaml:"server"` Database struct { Path string `yaml:"path"` } `yaml:"database"` Telegram struct { Enabled bool `yaml:"enabled"` Token string `yaml:"token"` } `yaml:"telegram"` QQBot struct { Enabled bool `yaml:"enabled"` AppID string `yaml:"appid"` Secret string `yaml:"secret"` } `yaml:"qqbot"` Admin struct { Username string `yaml:"username"` Password string `yaml:"password"` } `yaml:"admin"` } func LoadConfig(path string) (*Config, error) { cfg := &Config{} file, err := os.Open(path) if err != nil { return nil, fmt.Errorf("打开配置文件失败: %w", err) } defer file.Close() d := yaml.NewDecoder(file) if err := d.Decode(&cfg); err != nil { return nil, fmt.Errorf("解析配置文件失败: %w", err) } if err := cfg.Validate(); err != nil { return nil, fmt.Errorf("配置验证失败: %w", err) } return cfg, nil } func (c *Config) Validate() error { if c.Database.Path == "" { return fmt.Errorf("database.path 不能为空") } if c.Server.Port <= 0 || c.Server.Port > 65535 { return fmt.Errorf("server.port 必须在 1-65535 之间,当前值: %d", c.Server.Port) } if c.Server.Key == "" { return fmt.Errorf("server.key 不能为空(用于会话签名)") } if c.Admin.Username == "" || c.Admin.Password == "" { return fmt.Errorf("admin.username 和 admin.password 不能为空") } if c.Telegram.Enabled && c.Telegram.Token == "" { return fmt.Errorf("telegram 已启用但 token 为空") } if c.QQBot.Enabled { if c.QQBot.AppID == "" || c.QQBot.Secret == "" { return fmt.Errorf("qqbot 已启用但 appid 或 secret 为空") } } return nil }