323 lines
9.4 KiB
Go
323 lines
9.4 KiB
Go
package config
|
||
|
||
import (
|
||
"fmt"
|
||
"sync"
|
||
"time"
|
||
|
||
"github.com/spf13/viper"
|
||
"gorm.io/driver/mysql"
|
||
)
|
||
|
||
// DatabaseConfig 数据库配置
|
||
type DatabaseConfig struct {
|
||
DSN string `mapstructure:"dsn"`
|
||
MaxIdleConns int `mapstructure:"maxIdleConns"`
|
||
MaxOpenConns int `mapstructure:"maxOpenConns"`
|
||
LogLevel string `mapstructure:"logLevel"`
|
||
}
|
||
|
||
// ServerConfig 服务器配置
|
||
type ServerConfig struct {
|
||
Addr string `mapstructure:"addr"`
|
||
Port int `mapstructure:"port"`
|
||
}
|
||
|
||
// GatewayConfig 网关配置
|
||
type GatewayConfig struct {
|
||
BaseURL string `mapstructure:"base_url"`
|
||
Timeout int `mapstructure:"timeout"`
|
||
Auth GatewayAuthConfig `mapstructure:"auth"`
|
||
}
|
||
|
||
// GatewayAuthConfig 网关鉴权配置
|
||
type GatewayAuthConfig struct {
|
||
LoginURL string `mapstructure:"login_url"`
|
||
Key string `mapstructure:"key"`
|
||
}
|
||
|
||
// SSOConfig SSO配置
|
||
type SSOConfig struct {
|
||
SSOServerURL string `mapstructure:"sso_server_url"`
|
||
ClientID string `mapstructure:"client_id"`
|
||
ClientSecret string `mapstructure:"client_secret"`
|
||
RedirectURI string `mapstructure:"redirect_uri"`
|
||
Scope string `mapstructure:"scope"`
|
||
ResourceAud string `mapstructure:"resource_aud"`
|
||
AdminToken string `mapstructure:"admin_token"`
|
||
Timeout time.Duration `mapstructure:"timeout"`
|
||
}
|
||
|
||
// MessagePushConfig 消息推送配置
|
||
type MessagePushConfig struct {
|
||
GoalfyMaxBaseURL string `mapstructure:"goalfymax_base_url"`
|
||
Timeout int `mapstructure:"timeout"`
|
||
RetryCount int `mapstructure:"retry_count"`
|
||
RetryInterval int `mapstructure:"retry_interval"`
|
||
}
|
||
|
||
// AlertConfig 告警配置
|
||
type AlertConfig struct {
|
||
DingTalk DingTalkConfig `mapstructure:"dingtalk"`
|
||
}
|
||
|
||
// DingTalkConfig 钉钉配置
|
||
type DingTalkConfig struct {
|
||
Enabled bool `mapstructure:"enabled"`
|
||
Webhook string `mapstructure:"webhook"`
|
||
Secret string `mapstructure:"secret"`
|
||
TimeoutSeconds int `mapstructure:"timeout_seconds"`
|
||
Keyword string `mapstructure:"keyword"`
|
||
}
|
||
|
||
// PayConfig 支付服务配置
|
||
type PayConfig struct {
|
||
BaseURL string `mapstructure:"base_url"`
|
||
Timeout int `mapstructure:"timeout"`
|
||
}
|
||
|
||
// OssConfig 对象存储(S3兼容)配置
|
||
type OssConfig struct {
|
||
Endpoint string `mapstructure:"endpoint"`
|
||
Region string `mapstructure:"region"`
|
||
AccessKeyID string `mapstructure:"access_key_id"`
|
||
AccessKeySecret string `mapstructure:"access_key_secret"`
|
||
Bucket string `mapstructure:"bucket"`
|
||
AssumeRoleArn string `mapstructure:"assume_role_arn"`
|
||
PresignUrlExpire time.Duration `mapstructure:"presign_url_expire"`
|
||
}
|
||
|
||
// RedisConfig Redis配置
|
||
type RedisConfig struct {
|
||
Addr string `mapstructure:"addr"`
|
||
Password string `mapstructure:"password"`
|
||
DB int `mapstructure:"db"`
|
||
}
|
||
|
||
// EmailConfig 邮件配置
|
||
type EmailConfig struct {
|
||
Sender string `mapstructure:"sender"`
|
||
Host string `mapstructure:"host"`
|
||
Port int `mapstructure:"port"`
|
||
Username string `mapstructure:"username"`
|
||
Password string `mapstructure:"password"`
|
||
InviteURLPrefix string `mapstructure:"invite_url_prefix"`
|
||
}
|
||
|
||
// Config 定义总配置结构
|
||
type Config struct {
|
||
Server ServerConfig `mapstructure:"server"`
|
||
Database DatabaseConfig `mapstructure:"database"`
|
||
Gateway GatewayConfig `mapstructure:"gateway"`
|
||
SSO SSOConfig `mapstructure:"sso"`
|
||
MessagePush MessagePushConfig `mapstructure:"message_push"`
|
||
Alert AlertConfig `mapstructure:"alert"`
|
||
Oss OssConfig `mapstructure:"oss"`
|
||
Redis RedisConfig `mapstructure:"redis"`
|
||
Email EmailConfig `mapstructure:"email"`
|
||
Log LogConfig `mapstructure:"log"`
|
||
Client ClientConfig `mapstructure:"client"`
|
||
PostgreSQL PostgreSQLConfig `mapstructure:"postgresql"`
|
||
Pay PayConfig `mapstructure:"pay"`
|
||
Jobs JobsConfig `mapstructure:"jobs"`
|
||
}
|
||
|
||
// LogConfig 日志配置
|
||
type LogConfig struct {
|
||
Level string `mapstructure:"level"`
|
||
Format string `mapstructure:"format"`
|
||
Output string `mapstructure:"output"`
|
||
}
|
||
|
||
// ClientOption 客户端选项
|
||
type ClientOption struct {
|
||
Key string `mapstructure:"key" json:"key"`
|
||
Value string `mapstructure:"value" json:"value"`
|
||
Label string `json:"label"` // 用于前端展示,格式:key+value
|
||
}
|
||
|
||
// ClientConfig 客户端配置
|
||
type ClientConfig struct {
|
||
Options []ClientOption `mapstructure:"options"`
|
||
}
|
||
|
||
// PostgreSQLConfig PG配置
|
||
type PostgreSQLConfig struct {
|
||
DSN string `mapstructure:"dsn"`
|
||
Host string `mapstructure:"host"`
|
||
Port int `mapstructure:"port"`
|
||
User string `mapstructure:"user"`
|
||
Password string `mapstructure:"password"`
|
||
DBName string `mapstructure:"dbname"`
|
||
SSLMode string `mapstructure:"sslmode"`
|
||
MaxOpenConns int `mapstructure:"max_open_conns"`
|
||
MaxIdleConns int `mapstructure:"max_idle_conns"`
|
||
ConnMaxLifetime time.Duration `mapstructure:"conn_max_lifetime"`
|
||
ConnMaxIdleTime time.Duration `mapstructure:"conn_max_idle_time"`
|
||
}
|
||
|
||
type JobsConfig struct {
|
||
McpUsageBalance McpUsageBalanceJobConfig `mapstructure:"mcp_usage_balance"`
|
||
ModelTokenBalance ModelTokenBalanceJobConfig `mapstructure:"model_token_balance"`
|
||
}
|
||
|
||
type McpUsageBalanceJobConfig struct {
|
||
Enabled bool `mapstructure:"enabled"`
|
||
RunOnStartup bool `mapstructure:"run_on_startup"`
|
||
DelayMinutes int `mapstructure:"delay_minutes"`
|
||
}
|
||
|
||
type ModelTokenBalanceJobConfig struct {
|
||
Enabled bool `mapstructure:"enabled"`
|
||
RunOnStartup bool `mapstructure:"run_on_startup"`
|
||
DelayMinutes int `mapstructure:"delay_minutes"`
|
||
}
|
||
|
||
func (j JobsConfig) IsMcpUsageEnabled() bool {
|
||
return j.McpUsageBalance.Enabled
|
||
}
|
||
|
||
var (
|
||
config *Config
|
||
configLock sync.RWMutex
|
||
)
|
||
|
||
// LoadConfig 从文件加载配置
|
||
func LoadConfig(path string) error {
|
||
fmt.Printf("Loading config from %s\n", path)
|
||
viper.SetConfigFile(path)
|
||
err := viper.ReadInConfig()
|
||
if err != nil {
|
||
return fmt.Errorf("读取配置文件失败: %w", err)
|
||
}
|
||
|
||
if err := viper.Unmarshal(&config); err != nil {
|
||
return fmt.Errorf("解析配置文件失败: %w", err)
|
||
}
|
||
|
||
// 设置默认值
|
||
if config.Server.Addr == "" {
|
||
config.Server.Addr = "0.0.0.0"
|
||
}
|
||
if config.Server.Port == 0 {
|
||
config.Server.Port = 8080
|
||
}
|
||
if config.Database.MaxIdleConns == 0 {
|
||
config.Database.MaxIdleConns = 10
|
||
}
|
||
if config.Database.MaxOpenConns == 0 {
|
||
config.Database.MaxOpenConns = 100
|
||
}
|
||
if config.Database.LogLevel == "" {
|
||
config.Database.LogLevel = "info"
|
||
}
|
||
if config.Log.Level == "" {
|
||
config.Log.Level = "info"
|
||
}
|
||
if config.Log.Format == "" {
|
||
config.Log.Format = "json"
|
||
}
|
||
if config.Log.Output == "" {
|
||
config.Log.Output = "stdout"
|
||
}
|
||
if config.Jobs.McpUsageBalance.DelayMinutes <= 0 {
|
||
config.Jobs.McpUsageBalance.DelayMinutes = 5
|
||
}
|
||
if config.Jobs.ModelTokenBalance.DelayMinutes <= 0 {
|
||
config.Jobs.ModelTokenBalance.DelayMinutes = 5
|
||
}
|
||
if config.Gateway.BaseURL == "" {
|
||
config.Gateway.BaseURL = "http://localhost:8080"
|
||
}
|
||
if config.Gateway.Timeout == 0 {
|
||
config.Gateway.Timeout = 30
|
||
}
|
||
if config.Gateway.Auth.LoginURL == "" {
|
||
config.Gateway.Auth.LoginURL = "http://44.247.156.94:8080/aigateway-admin/api/login"
|
||
}
|
||
if config.Gateway.Auth.Key == "" {
|
||
config.Gateway.Auth.Key = "Jiahe.123"
|
||
}
|
||
if config.MessagePush.GoalfyMaxBaseURL == "" {
|
||
config.MessagePush.GoalfyMaxBaseURL = "http://goalfymax-backend:8080"
|
||
}
|
||
if config.MessagePush.Timeout == 0 {
|
||
config.MessagePush.Timeout = 30
|
||
}
|
||
if config.MessagePush.RetryCount == 0 {
|
||
config.MessagePush.RetryCount = 3
|
||
}
|
||
if config.MessagePush.RetryInterval == 0 {
|
||
config.MessagePush.RetryInterval = 1000
|
||
}
|
||
if config.Pay.BaseURL == "" {
|
||
config.Pay.BaseURL = "http://goalfy-pay:8080"
|
||
}
|
||
if config.Pay.Timeout == 0 {
|
||
config.Pay.Timeout = 30
|
||
}
|
||
if config.Redis.Addr == "" {
|
||
config.Redis.Addr = "localhost:6379"
|
||
}
|
||
if config.Redis.DB == 0 {
|
||
config.Redis.DB = 0
|
||
}
|
||
|
||
// OSS 预签名默认过期时间
|
||
if config.Oss.PresignUrlExpire == 0 {
|
||
config.Oss.PresignUrlExpire = 10 * time.Minute
|
||
}
|
||
|
||
if config.Alert.DingTalk.TimeoutSeconds <= 0 {
|
||
config.Alert.DingTalk.TimeoutSeconds = 5
|
||
}
|
||
|
||
// 设置客户端默认选项
|
||
if len(config.Client.Options) == 0 {
|
||
config.Client.Options = []ClientOption{
|
||
{Key: "5hNXkkkVPfFWUjRvzVP23w", Value: "https://ob-staging-goalfymax.goalfyai.com/"},
|
||
{Key: "J10f8yxU1XDl1Tn00MXKeA", Value: "https://staging-goalfymax.goalfyai.com/"},
|
||
{Key: "xRpT9mgNpt2YvoY9z4FToA", Value: "https://goalfymax.goalfyai.com/"},
|
||
}
|
||
}
|
||
|
||
// 为每个客户端选项生成 label
|
||
for i := range config.Client.Options {
|
||
config.Client.Options[i].Label = config.Client.Options[i].Key + "+" + config.Client.Options[i].Value
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// GetConfig 获取当前配置
|
||
func GetConfig() *Config {
|
||
configLock.RLock()
|
||
defer configLock.RUnlock()
|
||
return config
|
||
}
|
||
|
||
// GetDatabaseConfig 获取数据库配置
|
||
func GetDatabaseConfig() mysql.Config {
|
||
cfg := GetConfig()
|
||
return mysql.Config{
|
||
DSN: cfg.Database.DSN,
|
||
}
|
||
}
|
||
|
||
// GetClientOptions 获取客户端选项列表
|
||
func GetClientOptions() []ClientOption {
|
||
cfg := GetConfig()
|
||
return cfg.Client.Options
|
||
}
|
||
|
||
// GetClientValue 根据key获取客户端的展示值
|
||
func GetClientValue(key string) string {
|
||
options := GetClientOptions()
|
||
for _, opt := range options {
|
||
if opt.Key == key {
|
||
return opt.Value
|
||
}
|
||
}
|
||
return ""
|
||
}
|