package config import ( "crypto/rsa" "crypto/tls" "fmt" "os" "strings" "sync" "time" "gitee.com/xuyiping_admin/pkg/di" ) var ( Module = di.Provide(Options) options *AppConfig appEnv string initOnce sync.Once ) // AppConfig store all configuration options type AppConfig struct { FarmName string `yaml:"farm_name"` AppName string `yaml:"app_name"` AppEnv string `yaml:"app_environment"` Debug bool `yaml:"debug"` HTTPServerAddr string `yaml:"http_server_addr"` NeckRingLimit int32 `yaml:"neck_ring_limit"` // 数据库配置 额外加载文件部分 database.yaml StoreSetting StoreSetting `json:"storeSetting" yaml:"store"` // redis 配置 RedisSetting RedisSetting `json:"RedisSetting" yaml:"redis_setting"` JwtSecret string `json:"jwtSecret" yaml:"jwt_secret"` ExcelSetting ExcelSetting `json:"excelSetting" yaml:"excel_setting"` WechatSetting WechatSetting `json:"wechatSetting" yaml:"wechat_setting"` JwtTokenKeyConfig JwtTokenKeyConfig `json:"jwtTokenKeyConfig"` JwtExpireTime int `json:"jwtExpireTime" yaml:"jwt_expire_time"` // asynq 相关配置 SideWorkSetting SideWorkSetting `yaml:"side_work_setting"` CronSetting CronSetting `json:"cron_setting" yaml:"cron"` Mqtt MqttSetting `json:"mqtt"` } type CronSetting struct { // 是否启动任务时先跑一次 CrontabStartRun bool `yaml:"crontab_start_run"` // CRONTAB 表达式 UpdateCowInfo string `yaml:"update_cow_info"` // 更新牛只信息 Indicators string `yaml:"indicators"` // 牛只指标 GenerateWorkOrder string `yaml:"generate_work_order"` // 生成工作单 ImmunizationPlan string `yaml:"immunization_plan"` // 免疫计划 SameTimePlan string `yaml:"same_time_plan"` // 同期 UpdateSameTime string `yaml:"update_same_time"` // 更新同期 SystemBasicCrontab string `yaml:"system_basic_crontab"` // 系统基础定时任务 DeleteOldOriginal string `yaml:"delete_old_original"` // 删除脖环历史数据 CowPregnant string `yaml:"cow_pregnant"` // 月度牛只怀孕清单 UpdateActiveHabit string `yaml:"update_active_habit"` // 脖环2小时数据重新整合 NeckRingEstrus string `yaml:"neck_ring_estrus"` // 脖环牛只发情 NeckRingMerge string `yaml:"neck_ring_merge"` // 脖环原始数据合并 NeckRingCalculate string `yaml:"neck_ring_calculate"` // 脖环数据计算 } type JwtTokenKeyConfig struct { PrivateKey *rsa.PrivateKey `json:"privateKey"` PublicKey *rsa.PublicKey `json:"publicKey"` } type WechatSetting struct { Appid string `yaml:"appid"` Secret string `yaml:"secret"` } type ExcelSetting struct { SheetName string `yaml:"sheet_name"` // = "Sheet1" //默认Sheet名称 Height float64 `yaml:"height"` // = 25.0 //默认行高度 } // StoreSetting 数据库配置 type StoreSetting struct { // 开启 SyDb SQL 记录 DriverName string `yaml:"driver_name" json:"driver_name"` ShowSQL bool `yaml:"show_sql" json:"show_sql"` KptRW string `yaml:"kpt_rw" json:"kpt_rw"` KptMigr string `yaml:"kpt_migr" json:"kpt_migr"` KptMqtt string `yaml:"kpt_mqtt" json:"kpt_mqtt"` } type RedisSetting struct { // sso 配置 CacheRedis CacheRedisDB `json:"cache_redis" yaml:"cache_redis"` } type CacheRedisDB struct { Addr string `json:"addr" yaml:"addr"` DB int `json:"db" yaml:"db"` Requirepass string `json:"requirepass" yaml:"requirepass"` Expiry int `json:"expiry" yaml:"expiry"` } type SideWorkSetting struct { // Asynq 配置 AsynqSetting AsynqSetting `json:"asynq_setting,omitempty" yaml:"asynq_setting"` } type AsynqSetting struct { Redis AsynqRedisSetting `json:"redis" yaml:"redis"` Queues map[string]int `json:"queues,omitempty" yaml:"queues"` Concurrency int `json:"concurrency,omitempty" yaml:"concurrency"` LogLevel int32 `json:"log_level,omitempty" yaml:"log_level"` } type AsynqRedisSetting struct { // Network type to use, either tcp or unix. // Default is tcp. Network string `json:"network,omitempty" yaml:"network"` // Redis server address in "host:port" format. Addr string `json:"addr,omitempty" yaml:"addr"` // Username to authenticate the current connection when Redis ACLs are used. // See: https://redis.io/commands/auth. Username string `json:"username,omitempty" yaml:"username"` // Password to authenticate the current connection. // See: https://redis.io/commands/auth. Password string `json:"password,omitempty" yaml:"password"` // Redis DB to select after connecting to a server. // See: https://redis.io/commands/select. DB int `json:"db,omitempty" yaml:"db"` // Dial timeout for establishing new connections. // Default is 5 seconds. DialTimeout time.Duration `json:"dialTimeout,omitempty" yaml:"dial_timeout"` // Timeout for socket reads. // If timeout is reached, read commands will fail with a timeout error // instead of blocking. // // Use value -1 for no timeout and 0 for default. // Default is 3 seconds. ReadTimeout time.Duration `json:"readTimeout,omitempty" yaml:"read_timeout"` // Timeout for socket writes. // If timeout is reached, write commands will fail with a timeout error // instead of blocking. // // Use value -1 for no timeout and 0 for default. // Default is ReadTimout. WriteTimeout time.Duration `json:"writeTimeout,omitempty" yaml:"write_timeout"` // Maximum number of socket connections. // Default is 10 connections per every CPU as reported by runtime.NumCPU. PoolSize int `json:"poolSize,omitempty" yaml:"pool_size"` // TLS Config used to connect to a server. // TLS will be negotiated only if this field is set. TLSConfig *tls.Config `json:"tlsConfig,omitempty" yaml:"tls_config"` } type MqttSetting struct { Broker string `json:"broker" yaml:"broker"` UserName string `json:"username" yaml:"username"` Password string `json:"password" yaml:"password"` SubTopic string `json:"sub_topic" yaml:"sub_topic"` Retain bool `json:"retain" yaml:"retain"` Qos int `json:"qos" yaml:"qos"` KeepAlive int `json:"keepAlive" yaml:"keep_alive"` ConnectTimeout int `json:"connectTimeout" yaml:"connect_timeout"` AutoReconnect bool `json:"autoReconnect" yaml:"auto_reconnect"` ReconnectInterval int `json:"reconnectInterval" yaml:"reconnect_interval"` WorkNumber int `json:"workNumber" yaml:"work_number"` MergeDataTicker int `json:"mergeDataTicker" yaml:"merge_data_ticker"` } func (a *AppConfig) Name() string { return fmt.Sprintf("%s-%s", a.AppName, a.AppEnv) } // CacheNameSpace 作为 Key 的前缀,用来区分不同环境,不同 APP 下的 Key,防止缓存干扰 // 踩坑记录: // // 如果使用 fmt.Sprintf("%s-%s-%s", a.AppName, a.AppRole, a.AppEnv),例如 sayam-http-production, sayam-consumer-production // 会导致 从 role http 写入的 key,从 role consumer 中取不出来,反之亦然 // 支持更多的key空间, 可以更灵活的定义ns func (a *AppConfig) CacheNameSpace() string { cacheKeySpace := "" if a.FarmName != "" { cacheKeySpace = fmt.Sprintf("%s-%s-%s", a.AppName, a.AppEnv, a.FarmName) } else { cacheKeySpace = fmt.Sprintf("%s-%s", a.AppName, a.AppEnv) } return cacheKeySpace } func Options() *AppConfig { return options } func init() { appEnv = strings.ToLower(os.Getenv("APP_ENVIRONMENT")) cfg := &AppConfig{} var err error initOnce.Do(func() { switch appEnv { case "test": err = Initialize("app.test.yaml", cfg) case "development": err = Initialize("app.develop.yaml", cfg) case "production": err = Initialize("app.production.yaml", cfg) default: panic("err confing") } if err != nil { panic(err) } cfg.JwtTokenKeyConfig = openPrivateKey() options = cfg }) }