Files
2026-01-12 11:33:43 +08:00

253 lines
6.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package config
import (
"fmt"
"os"
"time"
"gopkg.in/yaml.v3"
)
// Config 应用配置
type Config struct {
Server ServerConfig `yaml:"server"`
City CityConfig `yaml:"city"`
LLM LLMConfig `yaml:"llm"`
Amap AmapConfig `yaml:"amap"`
JobAPI JobAPIConfig `yaml:"job_api"`
OCR OCRConfig `yaml:"ocr"`
Policy PolicyConfig `yaml:"policy"`
Logging LoggingConfig `yaml:"logging"`
Performance PerformanceConfig `yaml:"performance"`
}
// CityConfig 城市配置
type CityConfig struct {
Name string `yaml:"name"` // 城市名称,如:青岛
SystemName string `yaml:"system_name"` // 系统名称,如:青岛岗位匹配系统
AreaCodes map[string]string `yaml:"area_codes"` // 区域代码映射,如:市南区:0, 市北区:1
Landmarks []string `yaml:"landmarks"` // 地标示例,如:五四广场、青岛啤酒博物馆
Abbreviations map[string]string `yaml:"abbreviations"` // 简称映射,如:青啤:青岛啤酒
}
// ServerConfig 服务器配置
type ServerConfig struct {
Port int `yaml:"port"`
Host string `yaml:"host"`
ReadTimeout time.Duration `yaml:"read_timeout"`
WriteTimeout time.Duration `yaml:"write_timeout"`
}
// LLMConfig LLM配置
type LLMConfig struct {
BaseURL string `yaml:"base_url"`
APIKey string `yaml:"api_key"`
Model string `yaml:"model"`
Timeout time.Duration `yaml:"timeout"`
MaxRetries int `yaml:"max_retries"`
}
// AmapConfig 高德地图配置
type AmapConfig struct {
APIKey string `yaml:"api_key"`
BaseURL string `yaml:"base_url"`
Timeout time.Duration `yaml:"timeout"`
}
// JobAPIConfig 岗位API配置
type JobAPIConfig struct {
BaseURL string `yaml:"base_url"`
Timeout time.Duration `yaml:"timeout"`
}
// OCRConfig OCR服务配置
type OCRConfig struct {
BaseURL string `yaml:"base_url"`
Timeout time.Duration `yaml:"timeout"`
}
// PolicyConfig 政策大模型配置
type PolicyConfig struct {
BaseURL string `yaml:"base_url"`
LoginName string `yaml:"login_name"`
UserKey string `yaml:"user_key"`
ServiceID string `yaml:"service_id"`
Timeout time.Duration `yaml:"timeout"`
}
// LoggingConfig 日志配置
type LoggingConfig struct {
Level string `yaml:"level"`
Format string `yaml:"format"`
}
// PerformanceConfig 性能配置
type PerformanceConfig struct {
MaxGoroutines int `yaml:"max_goroutines"`
GoroutinePoolSize int `yaml:"goroutine_pool_size"`
TaskQueueSize int `yaml:"task_queue_size"`
EnablePprof *bool `yaml:"enable_pprof"`
EnableMetrics *bool `yaml:"enable_metrics"`
GCPercent int `yaml:"gc_percent"`
}
var globalConfig *Config
// Load 从文件加载配置
func Load(configPath string) (*Config, error) {
data, err := os.ReadFile(configPath)
if err != nil {
return nil, fmt.Errorf("读取配置文件失败: %w", err)
}
var cfg Config
if err := yaml.Unmarshal(data, &cfg); err != nil {
return nil, fmt.Errorf("解析配置文件失败: %w", err)
}
// 环境变量覆盖(用于生产环境,避免密钥泄露)
if v := os.Getenv("LLM_API_KEY"); v != "" {
cfg.LLM.APIKey = v
}
if v := os.Getenv("LLM_BASE_URL"); v != "" {
cfg.LLM.BaseURL = v
}
if v := os.Getenv("AMAP_API_KEY"); v != "" {
cfg.Amap.APIKey = v
}
if v := os.Getenv("OCR_BASE_URL"); v != "" {
cfg.OCR.BaseURL = v
}
if v := os.Getenv("POLICY_LOGIN_NAME"); v != "" {
cfg.Policy.LoginName = v
}
if v := os.Getenv("POLICY_USER_KEY"); v != "" {
cfg.Policy.UserKey = v
}
if v := os.Getenv("POLICY_SERVICE_ID"); v != "" {
cfg.Policy.ServiceID = v
}
if v := os.Getenv("SERVER_PORT"); v != "" {
fmt.Sscanf(v, "%d", &cfg.Server.Port)
}
// 设置默认值
if cfg.Server.Port == 0 {
cfg.Server.Port = 8080
}
if cfg.Server.Host == "" {
cfg.Server.Host = "0.0.0.0"
}
if cfg.LLM.MaxRetries == 0 {
cfg.LLM.MaxRetries = 3
}
if cfg.Server.ReadTimeout == 0 {
cfg.Server.ReadTimeout = 30 * time.Second
}
if cfg.Server.WriteTimeout == 0 {
cfg.Server.WriteTimeout = 300 * time.Second
}
// 城市配置默认值
if cfg.City.Name == "" {
cfg.City.Name = "青岛"
}
if cfg.City.SystemName == "" {
cfg.City.SystemName = cfg.City.Name + "岗位匹配系统"
}
if len(cfg.City.AreaCodes) == 0 {
cfg.City.AreaCodes = map[string]string{
"市南区": "0", "市北区": "1", "李沧区": "2", "崂山区": "3", "黄岛区": "4",
"城阳区": "5", "即墨区": "6", "胶州市": "7", "平度市": "8", "莱西市": "9",
}
}
if len(cfg.City.Landmarks) == 0 {
cfg.City.Landmarks = []string{"五四广场", "青岛啤酒博物馆"}
}
if len(cfg.City.Abbreviations) == 0 {
cfg.City.Abbreviations = map[string]string{"青啤": "青岛啤酒"}
}
// 性能配置默认值
if cfg.Performance.MaxGoroutines == 0 {
cfg.Performance.MaxGoroutines = 10000
}
if cfg.Performance.GoroutinePoolSize == 0 {
cfg.Performance.GoroutinePoolSize = 5000
}
if cfg.Performance.TaskQueueSize == 0 {
cfg.Performance.TaskQueueSize = 10000
}
if cfg.Performance.GCPercent == 0 {
cfg.Performance.GCPercent = 100
}
// pprof和metrics默认启用允许在配置文件中显式关闭
if cfg.Performance.EnablePprof == nil {
v := true
cfg.Performance.EnablePprof = &v
}
if cfg.Performance.EnableMetrics == nil {
v := true
cfg.Performance.EnableMetrics = &v
}
globalConfig = &cfg
return &cfg, nil
}
// Get 获取全局配置
func Get() *Config {
return globalConfig
}
// GetAreaCodesDescription 获取区域代码描述字符串
func (c *CityConfig) GetAreaCodesDescription() string {
if len(c.AreaCodes) == 0 {
return ""
}
// 按代码排序输出
result := ""
for i := 0; i <= 9; i++ {
for name, code := range c.AreaCodes {
if code == fmt.Sprintf("%d", i) {
if result != "" {
result += ", "
}
result += fmt.Sprintf("%s(%s)", name, code)
break
}
}
}
return result
}
// GetLandmarksExample 获取地标示例字符串
func (c *CityConfig) GetLandmarksExample() string {
if len(c.Landmarks) == 0 {
return ""
}
result := ""
for i, landmark := range c.Landmarks {
if i > 0 {
result += "、"
}
result += landmark
}
return result
}
// GetAbbreviationsDescription 获取简称映射描述
func (c *CityConfig) GetAbbreviationsDescription() string {
if len(c.Abbreviations) == 0 {
return ""
}
result := ""
for abbr, full := range c.Abbreviations {
if result != "" {
result += "、"
}
result += fmt.Sprintf("\"%s\"指\"%s\"", abbr, full)
}
return result
}