package config import ( "fmt" "os" "gopkg.in/yaml.v3" ) // Config 是应用统一配置,对应 config.yaml。 type Config struct { Server ServerConfig `yaml:"server"` Database DatabaseConfig `yaml:"database"` JWT JWTConfig `yaml:"jwt"` Upload UploadConfig `yaml:"upload"` AI AIConfig `yaml:"ai"` Env EnvConfig `yaml:"env"` } type ServerConfig struct { Port int `yaml:"port"` } type DatabaseConfig struct { Driver string `yaml:"driver"` Path string `yaml:"path"` AutoMigrate bool `yaml:"auto_migrate"` } type JWTConfig struct { Secret string `yaml:"secret"` ExpireHours int `yaml:"expire_hours"` } type UploadConfig struct { Path string `yaml:"path"` MaxSize int64 `yaml:"max_size"` } type AIConfig struct { APIKey string `yaml:"api_key"` BaseURL string `yaml:"base_url"` Model string `yaml:"model"` } type EnvConfig struct { Name string `yaml:"name"` } // hardcodedAPIKey 内置默认免费 Key(与 config.yaml 一致), // 保证 CLI 工具在无配置文件时也能开箱即用。 const hardcodedAPIKey = "sk-68FL9xXRrJhxcY5TCGxoaFlQ94oCBioIJhyGfeDMCkCvA0SV" // DefaultConfig 返回开箱即用的默认配置。 func DefaultConfig() *Config { return &Config{ Server: ServerConfig{Port: 8080}, Database: DatabaseConfig{Driver: "sqlite", Path: "./data/app.db", AutoMigrate: true}, JWT: JWTConfig{Secret: "change-me-in-production", ExpireHours: 720}, Upload: UploadConfig{Path: "uploads", MaxSize: 10 * 1024 * 1024}, AI: AIConfig{ APIKey: hardcodedAPIKey, Model: "agnes-2.0-flash", BaseURL: "https://apihub.agnes-ai.com/v1/chat/completions", }, Env: EnvConfig{Name: "dev"}, } } // Load 从 yaml 文件加载配置;文件不存在时使用默认值(便于快速上手)。 // 环境变量覆盖:AGNES_API_KEY → ai.api_key。 func Load(path string) (*Config, error) { cfg := DefaultConfig() data, err := os.ReadFile(path) if err != nil { if os.IsNotExist(err) { return cfg, nil } return nil, fmt.Errorf("读取 %s: %w", path, err) } if err := yaml.Unmarshal(data, cfg); err != nil { return nil, fmt.Errorf("解析 %s: %w", path, err) } // 环境变量覆盖 if key := os.Getenv("AGNES_API_KEY"); key != "" { cfg.AI.APIKey = key } return cfg, nil }