221 lines
7.5 KiB
Go
221 lines
7.5 KiB
Go
// Package config 配置加载模块,基于 Viper 读取 YAML 配置并提供默认值
|
||
package config
|
||
|
||
import (
|
||
"errors"
|
||
"strings"
|
||
|
||
"github.com/spf13/viper"
|
||
)
|
||
|
||
const (
|
||
DefaultAdminPath = "/admin" // 默认后台管理路径
|
||
DefaultMaxLoginAttempts = 5 // 默认最大登录尝试次数
|
||
DefaultLockoutDuration = 15 // 默认锁定时长(分钟)
|
||
DefaultServerHost = "0.0.0.0" // 默认服务监听地址
|
||
DefaultServerPort = 8090 // 默认服务端口
|
||
DefaultServerMode = "release" // 默认运行模式
|
||
DefaultDatabaseType = "sqlite" // 默认数据库类型
|
||
DefaultDatabasePath = "./data/resume.db" // 默认数据库文件路径
|
||
DefaultLogLevel = "info" // 默认日志级别
|
||
DefaultTemplateDefault = "modern" // 默认简历模板
|
||
)
|
||
|
||
// Config 全局配置结构体
|
||
type Config struct {
|
||
Server ServerConfig `mapstructure:"server"` // 服务配置
|
||
Database DatabaseConfig `mapstructure:"database"` // 数据库配置
|
||
Auth AuthConfig `mapstructure:"auth"` // 认证配置
|
||
Template TemplateConfig `mapstructure:"template"` // 模板配置
|
||
Log LogConfig `mapstructure:"log"` // 日志配置
|
||
AI AIConfig `mapstructure:"ai"` // AI配置
|
||
}
|
||
|
||
// ServerConfig 服务配置
|
||
type ServerConfig struct {
|
||
Host string `mapstructure:"host"` // 监听地址
|
||
Port int `mapstructure:"port"` // 监听端口
|
||
Mode string `mapstructure:"mode"` // 运行模式(debug/release)
|
||
Debug bool `mapstructure:"debug"` // 是否开启调试
|
||
}
|
||
|
||
// DatabaseConfig 数据库配置
|
||
type DatabaseConfig struct {
|
||
Type string `mapstructure:"type"` // 数据库类型
|
||
Path string `mapstructure:"path"` // 数据库文件路径
|
||
Password string `mapstructure:"password"` // 数据库加密密码
|
||
}
|
||
|
||
// AuthConfig 认证配置
|
||
type AuthConfig struct {
|
||
Enabled bool `mapstructure:"enabled"` // 是否启用认证
|
||
Username string `mapstructure:"username"` // 管理员用户名
|
||
Password string `mapstructure:"password"` // 管理员密码
|
||
AdminPath string `mapstructure:"admin_path"` // 后台路径
|
||
MaxLoginAttempts int `mapstructure:"max_login_attempts"` // 最大登录尝试
|
||
LockoutDuration int `mapstructure:"lockout_duration"` // 锁定时长(分钟)
|
||
}
|
||
|
||
// TemplateConfig 模板配置
|
||
type TemplateConfig struct {
|
||
Default string `mapstructure:"default"` // 默认模板名称
|
||
}
|
||
|
||
// LogConfig 日志配置
|
||
type LogConfig struct {
|
||
Level string `mapstructure:"level"` // 日志级别
|
||
Output string `mapstructure:"output"` // 输出文件路径
|
||
}
|
||
|
||
// AIConfig AI 大模型配置
|
||
type AIConfig struct {
|
||
Provider string `mapstructure:"provider"` // 默认供应商
|
||
Enabled bool `mapstructure:"enabled"` // 是否启用
|
||
Spark SparkConfig `mapstructure:"spark"` // 讯飞星火配置
|
||
Tongyi TongyiConfig `mapstructure:"tongyi"` // 通义千问配置
|
||
Doubao DoubaoConfig `mapstructure:"doubao"` // 豆包配置
|
||
DeepSeek DeepSeekConfig `mapstructure:"deepseek"` // DeepSeek配置
|
||
}
|
||
|
||
// SparkConfig 讯飞星火配置
|
||
type SparkConfig struct {
|
||
APPID string `mapstructure:"app_id"` // APP ID
|
||
APIKey string `mapstructure:"api_key"` // API Key
|
||
APISecret string `mapstructure:"api_secret"` // API Secret
|
||
APIPassword string `mapstructure:"api_password"` // API 密码(HTTP接口使用)
|
||
BaseURL string `mapstructure:"base_url"` // 接口地址
|
||
Model string `mapstructure:"model"` // 模型版本
|
||
MaxTokens int `mapstructure:"max_tokens"` // 最大token数
|
||
Timeout int `mapstructure:"timeout"` // 超时时间(秒)
|
||
WebSearch bool `mapstructure:"web_search"` // 是否启用联网搜索
|
||
ShowRefLabel bool `mapstructure:"show_ref_label"` // 是否显示引用标签
|
||
}
|
||
|
||
// TongyiConfig 通义千问配置
|
||
type TongyiConfig struct {
|
||
APIKey string `mapstructure:"api_key"` // API Key
|
||
BaseURL string `mapstructure:"base_url"` // 接口地址
|
||
Model string `mapstructure:"model"` // 模型名称
|
||
MaxTokens int `mapstructure:"max_tokens"` // 最大token数
|
||
Timeout int `mapstructure:"timeout"` // 超时时间(秒)
|
||
}
|
||
|
||
// DoubaoConfig 豆包配置
|
||
type DoubaoConfig struct {
|
||
APIKey string `mapstructure:"api_key"` // API Key
|
||
BaseURL string `mapstructure:"base_url"` // 接口地址
|
||
Model string `mapstructure:"model"` // 模型名称
|
||
MaxTokens int `mapstructure:"max_tokens"` // 最大token数
|
||
Timeout int `mapstructure:"timeout"` // 超时时间(秒)
|
||
}
|
||
|
||
// DeepSeekConfig DeepSeek 配置
|
||
type DeepSeekConfig struct {
|
||
APIKey string `mapstructure:"api_key"` // API Key
|
||
BaseURL string `mapstructure:"base_url"` // 接口地址
|
||
Model string `mapstructure:"model"` // 模型名称
|
||
MaxTokens int `mapstructure:"max_tokens"` // 最大token数
|
||
Timeout int `mapstructure:"timeout"` // 超时时间(秒)
|
||
}
|
||
|
||
// setDefaults 设置 Viper 默认值
|
||
// @author sunct
|
||
func setDefaults() {
|
||
viper.SetDefault("server.host", DefaultServerHost)
|
||
viper.SetDefault("server.port", DefaultServerPort)
|
||
viper.SetDefault("server.mode", DefaultServerMode)
|
||
viper.SetDefault("server.debug", false)
|
||
|
||
viper.SetDefault("database.type", DefaultDatabaseType)
|
||
viper.SetDefault("database.path", DefaultDatabasePath)
|
||
|
||
viper.SetDefault("auth.enabled", true)
|
||
viper.SetDefault("auth.admin_path", DefaultAdminPath)
|
||
viper.SetDefault("auth.max_login_attempts", DefaultMaxLoginAttempts)
|
||
viper.SetDefault("auth.lockout_duration", DefaultLockoutDuration)
|
||
|
||
viper.SetDefault("template.default", DefaultTemplateDefault)
|
||
|
||
viper.SetDefault("log.level", DefaultLogLevel)
|
||
}
|
||
|
||
// LoadConfig 加载并解析配置文件,支持多路径查找
|
||
// @return *Config 配置实例
|
||
// @return error 加载错误
|
||
// @author sunct
|
||
func LoadConfig() (*Config, error) {
|
||
setDefaults()
|
||
|
||
viper.SetConfigName("config")
|
||
viper.SetConfigType("yaml")
|
||
|
||
viper.AddConfigPath("./config")
|
||
viper.AddConfigPath(".")
|
||
viper.AddConfigPath("../config")
|
||
viper.AddConfigPath("../")
|
||
|
||
if err := viper.ReadInConfig(); err != nil {
|
||
var configFileNotFoundError viper.ConfigFileNotFoundError
|
||
if !errors.As(err, &configFileNotFoundError) {
|
||
return nil, err
|
||
}
|
||
}
|
||
|
||
var cfg Config
|
||
if err := viper.Unmarshal(&cfg); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
if err := validateAndNormalize(&cfg); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return &cfg, nil
|
||
}
|
||
|
||
// validateAndNormalize 校验并规范化配置,补全默认值
|
||
// @param cfg 配置实例
|
||
// @return error 校验错误
|
||
// @author sunct
|
||
func validateAndNormalize(cfg *Config) error {
|
||
if cfg.Server.Port <= 0 || cfg.Server.Port > 65535 {
|
||
cfg.Server.Port = DefaultServerPort
|
||
}
|
||
if cfg.Server.Host == "" {
|
||
cfg.Server.Host = DefaultServerHost
|
||
}
|
||
if cfg.Server.Mode == "" {
|
||
cfg.Server.Mode = DefaultServerMode
|
||
}
|
||
|
||
if cfg.Database.Type == "" {
|
||
cfg.Database.Type = DefaultDatabaseType
|
||
}
|
||
if cfg.Database.Path == "" {
|
||
cfg.Database.Path = DefaultDatabasePath
|
||
}
|
||
|
||
if !strings.HasPrefix(cfg.Auth.AdminPath, "/") {
|
||
cfg.Auth.AdminPath = "/" + cfg.Auth.AdminPath
|
||
}
|
||
if cfg.Auth.AdminPath == "/" {
|
||
cfg.Auth.AdminPath = DefaultAdminPath
|
||
}
|
||
if cfg.Auth.MaxLoginAttempts <= 0 {
|
||
cfg.Auth.MaxLoginAttempts = DefaultMaxLoginAttempts
|
||
}
|
||
if cfg.Auth.LockoutDuration <= 0 {
|
||
cfg.Auth.LockoutDuration = DefaultLockoutDuration
|
||
}
|
||
|
||
if cfg.Template.Default == "" {
|
||
cfg.Template.Default = DefaultTemplateDefault
|
||
}
|
||
|
||
if cfg.Log.Level == "" {
|
||
cfg.Log.Level = DefaultLogLevel
|
||
}
|
||
|
||
return nil
|
||
}
|