- Implemented all core features from Python version - Fixed int64/int type compatibility in template functions - Added login authentication, SMS receiving, statistics, logs - Independent database: sms_receiver_go.db - Fixed frontend display issues for message list and statistics
143 lines
3.6 KiB
Go
143 lines
3.6 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
type Config struct {
|
|
App AppConfig `mapstructure:"app"`
|
|
Server ServerConfig `mapstructure:"server"`
|
|
Security SecurityConfig `mapstructure:"security"`
|
|
SMS SMSConfig `mapstructure:"sms"`
|
|
Database DatabaseConfig `mapstructure:"database"`
|
|
Timezone string `mapstructure:"timezone"`
|
|
APITokens []APIToken `mapstructure:"api_tokens"`
|
|
}
|
|
|
|
type AppConfig struct {
|
|
Name string `mapstructure:"name"`
|
|
Version string `mapstructure:"version"`
|
|
}
|
|
|
|
type ServerConfig struct {
|
|
Host string `mapstructure:"host"`
|
|
Port int `mapstructure:"port"`
|
|
Debug bool `mapstructure:"debug"`
|
|
}
|
|
|
|
type SecurityConfig struct {
|
|
Enabled bool `mapstructure:"enabled"`
|
|
Username string `mapstructure:"username"`
|
|
Password string `mapstructure:"password"`
|
|
SessionLifetime int `mapstructure:"session_lifetime"`
|
|
SecretKey string `mapstructure:"secret_key"`
|
|
SignVerify bool `mapstructure:"sign_verify"`
|
|
SignMaxAge int64 `mapstructure:"sign_max_age"`
|
|
}
|
|
|
|
type SMSConfig struct {
|
|
MaxMessages int `mapstructure:"max_messages"`
|
|
AutoCleanup bool `mapstructure:"auto_cleanup"`
|
|
CleanupDays int `mapstructure:"cleanup_days"`
|
|
}
|
|
|
|
type DatabaseConfig struct {
|
|
Path string `mapstructure:"path"`
|
|
}
|
|
|
|
type APIToken struct {
|
|
Name string `mapstructure:"name"`
|
|
Token string `mapstructure:"token"`
|
|
Secret string `mapstructure:"secret"`
|
|
Enabled bool `mapstructure:"enabled"`
|
|
}
|
|
|
|
var cfg *Config
|
|
|
|
func Load(configPath string) (*Config, error) {
|
|
viper.SetConfigFile(configPath)
|
|
viper.SetConfigType("yaml")
|
|
|
|
// 允许环境变量覆盖
|
|
viper.AutomaticEnv()
|
|
|
|
if err := viper.ReadInConfig(); err != nil {
|
|
return nil, fmt.Errorf("读取配置文件失败: %w", err)
|
|
}
|
|
|
|
cfg = &Config{}
|
|
if err := viper.Unmarshal(cfg); err != nil {
|
|
return nil, fmt.Errorf("解析配置文件失败: %w", err)
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
func Get() *Config {
|
|
return cfg
|
|
}
|
|
|
|
// GetSessionLifetimeDuration 返回会话 lifetime 为 duration
|
|
func (c *Config) GetSessionLifetimeDuration() time.Duration {
|
|
return time.Duration(c.Security.SessionLifetime) * time.Second
|
|
}
|
|
|
|
// GetSignMaxAgeDuration 返回签名最大有效期
|
|
func (c *Config) GetSignMaxAgeDuration() time.Duration {
|
|
return time.Duration(c.Security.SignMaxAge) * time.Millisecond
|
|
}
|
|
|
|
// GetServerAddress 返回服务器地址
|
|
func (c *Config) GetServerAddress() string {
|
|
return fmt.Sprintf("%s:%d", c.Server.Host, c.Server.Port)
|
|
}
|
|
|
|
// GetTokenByName 根据名称获取 Token 配置
|
|
func (c *Config) GetTokenByName(name string) *APIToken {
|
|
for i := range c.APITokens {
|
|
if c.APITokens[i].Name == name && c.APITokens[i].Enabled {
|
|
return &c.APITokens[i]
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetTokenByValue 根据 token 值获取配置
|
|
func (c *Config) GetTokenByValue(token string) *APIToken {
|
|
for i := range c.APITokens {
|
|
if c.APITokens[i].Token == token && c.APITokens[i].Enabled {
|
|
return &c.APITokens[i]
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Save 保存配置到文件
|
|
func (c *Config) Save(path string) error {
|
|
viper.Set("app", c.App)
|
|
viper.Set("server", c.Server)
|
|
viper.Set("security", c.Security)
|
|
viper.Set("sms", c.SMS)
|
|
viper.Set("database", c.Database)
|
|
viper.Set("timezone", c.Timezone)
|
|
viper.Set("api_tokens", c.APITokens)
|
|
|
|
return viper.WriteConfigAs(path)
|
|
}
|
|
|
|
// LoadDefault 加载默认配置文件
|
|
func LoadDefault() (*Config, error) {
|
|
configPath := "config.yaml"
|
|
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
|
// 尝试查找上层目录
|
|
if _, err := os.Stat("../config.yaml"); err == nil {
|
|
configPath = "../config.yaml"
|
|
}
|
|
}
|
|
return Load(configPath)
|
|
}
|