package config import ( "encoding/json" "os" "path/filepath" "sync" ) // Config 全局配置结构 type Config struct { mu sync.RWMutex FTP FTPConfig `json:"ftp"` Web WebConfig `json:"web"` Admin AdminConfig `json:"admin"` Database DBConfig `json:"database"` } type FTPConfig struct { Host string `json:"host"` Port int `json:"port"` PassivePortMin int `json:"passive_port_min"` PassivePortMax int `json:"passive_port_max"` RootDir string `json:"root_dir"` EnableAnonymous bool `json:"enable_anonymous"` MaxConnections int `json:"max_connections"` IdleTimeout int `json:"idle_timeout"` // 秒 } type WebConfig struct { Host string `json:"host"` Port int `json:"port"` } type AdminConfig struct { Username string `json:"username"` Password string `json:"password"` } type DBConfig struct { Path string `json:"path"` } // DefaultConfig 返回默认配置 func DefaultConfig() *Config { return &Config{ FTP: FTPConfig{ Host: "0.0.0.0", Port: 2121, PassivePortMin: 50000, PassivePortMax: 50100, RootDir: "./ftp_root", EnableAnonymous: false, MaxConnections: 50, IdleTimeout: 300, }, Web: WebConfig{ Host: "0.0.0.0", Port: 8080, }, Admin: AdminConfig{ Username: "admin", Password: "admin123", }, Database: DBConfig{ Path: "./data/ftp.db", }, } } // Load 从文件加载配置 func Load(path string) (*Config, error) { data, err := os.ReadFile(path) if err != nil { if os.IsNotExist(err) { cfg := DefaultConfig() if err := cfg.Save(path); err != nil { return nil, err } return cfg, nil } return nil, err } var cfg Config if err := json.Unmarshal(data, &cfg); err != nil { return nil, err } return &cfg, nil } // Save 保存配置到文件 func (c *Config) Save(path string) error { c.mu.RLock() defer c.mu.RUnlock() dir := filepath.Dir(path) if err := os.MkdirAll(dir, 0755); err != nil { return err } data, err := json.MarshalIndent(c, "", " ") if err != nil { return err } return os.WriteFile(path, data, 0644) } // Get 安全获取配置副本 func (c *Config) Get() Config { c.mu.RLock() defer c.mu.RUnlock() return *c } // Update 安全更新配置 func (c *Config) Update(fn func(cfg *Config)) { c.mu.Lock() defer c.mu.Unlock() fn(c) }