app.go 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. package config
  2. import (
  3. "crypto/rsa"
  4. "crypto/tls"
  5. "fmt"
  6. "os"
  7. "strings"
  8. "sync"
  9. "time"
  10. "gitee.com/xuyiping_admin/pkg/di"
  11. )
  12. var (
  13. Module = di.Provide(Options)
  14. options *AppConfig
  15. appEnv string
  16. initOnce sync.Once
  17. )
  18. // AppConfig store all configuration options
  19. type AppConfig struct {
  20. FarmName string `yaml:"farm_name"`
  21. AppName string `yaml:"app_name"`
  22. AppEnv string `yaml:"app_environment"`
  23. Debug bool `yaml:"debug"`
  24. HTTPServerAddr string `yaml:"http_server_addr"`
  25. NeckRingLimit int32 `yaml:"neck_ring_limit"`
  26. // 数据库配置 额外加载文件部分 database.yaml
  27. StoreSetting StoreSetting `json:"storeSetting" yaml:"store"`
  28. // redis 配置
  29. RedisSetting RedisSetting `json:"RedisSetting" yaml:"redis_setting"`
  30. JwtSecret string `json:"jwtSecret" yaml:"jwt_secret"`
  31. ExcelSetting ExcelSetting `json:"excelSetting" yaml:"excel_setting"`
  32. WechatSetting WechatSetting `json:"wechatSetting" yaml:"wechat_setting"`
  33. JwtTokenKeyConfig JwtTokenKeyConfig `json:"jwtTokenKeyConfig"`
  34. JwtExpireTime int `json:"jwtExpireTime" yaml:"jwt_expire_time"`
  35. // asynq 相关配置
  36. SideWorkSetting SideWorkSetting `yaml:"side_work_setting"`
  37. CronSetting CronSetting `json:"cron_setting" yaml:"cron"`
  38. Mqtt MqttSetting `json:"mqtt"`
  39. MilkHall MilkHallSetting `json:"milkHall"`
  40. EmailConfig EmailConfig `json:"emailConfig" yaml:"email_config"`
  41. }
  42. type CronSetting struct {
  43. // 是否启动任务时先跑一次
  44. CrontabStartRun bool `yaml:"crontab_start_run"`
  45. // CRONTAB 表达式
  46. UpdateCowInfo string `yaml:"update_cow_info"` // 更新牛只信息
  47. Indicators string `yaml:"indicators"` // 牛只指标
  48. GenerateWorkOrder string `yaml:"generate_work_order"` // 生成工作单
  49. ImmunizationPlan string `yaml:"immunization_plan"` // 免疫计划
  50. SameTimePlan string `yaml:"same_time_plan"` // 同期
  51. UpdateSameTime string `yaml:"update_same_time"` // 更新同期
  52. SystemBasicCrontab string `yaml:"system_basic_crontab"` // 系统基础定时任务
  53. DeleteOldOriginal string `yaml:"delete_old_original"` // 删除脖环历史数据
  54. UpdateDiseaseToCalendar string `yaml:"update_disease_to_calendar"` // 更新每天治疗中牛头数到日历表中
  55. CowPregnant string `yaml:"cow_pregnant"` // 月度牛只怀孕清单
  56. UpdateActiveHabit string `yaml:"update_active_habit"` // 脖环2小时数据重新整合
  57. NeckRingEstrus string `yaml:"neck_ring_estrus"` // 脖环牛只发情
  58. NeckRingMerge string `yaml:"neck_ring_merge"` // 脖环原始数据合并
  59. NeckRingCalculate string `yaml:"neck_ring_calculate"` // 脖环数据计算
  60. NeckRingEstrusWarning string `yaml:"neck_ring_estrus_warning"` // 脖环发情预警
  61. NeckRingHealthWarning string `yaml:"neck_ring_health_warning"` // 脖环健康预警
  62. UpdatePenBehavior string `yaml:"update_pen_behavior"` // 栏舍行为数据
  63. UpdatePenBehaviorDaily string `yaml:"update_pen_behavior_daily"` // 栏舍饲养监测
  64. UpdateMilkOriginal string `yaml:"update_milk_original"` // 奶厅原始数据更新
  65. InsertMilkDaily string `yaml:"insert_milk_daily"` // 牛只每日奶量数据
  66. TwentyOnePregnantRate string `yaml:"twenty_one_pregnant_rate"` // 21怀孕率
  67. CowNeckRingError string `yaml:"cow_neck_ring_error"` // 异常脖环数据
  68. }
  69. type JwtTokenKeyConfig struct {
  70. PrivateKey *rsa.PrivateKey `json:"privateKey"`
  71. PublicKey *rsa.PublicKey `json:"publicKey"`
  72. }
  73. type WechatSetting struct {
  74. Appid string `yaml:"appid"`
  75. Secret string `yaml:"secret"`
  76. }
  77. type ExcelSetting struct {
  78. SheetName string `yaml:"sheet_name"` // = "Sheet1" //默认Sheet名称
  79. Height float64 `yaml:"height"` // = 25.0 //默认行高度
  80. }
  81. // StoreSetting 数据库配置
  82. type StoreSetting struct {
  83. // 开启 SyDb SQL 记录
  84. DriverName string `yaml:"driver_name" json:"driver_name"`
  85. ShowSQL bool `yaml:"show_sql" json:"show_sql"`
  86. KptRW string `yaml:"kpt_rw" json:"kpt_rw"`
  87. KptMigr string `yaml:"kpt_migr" json:"kpt_migr"`
  88. KptMqtt string `yaml:"kpt_mqtt" json:"kpt_mqtt"`
  89. }
  90. type RedisSetting struct {
  91. // sso 配置
  92. CacheRedis CacheRedisDB `json:"cache_redis" yaml:"cache_redis"`
  93. }
  94. type CacheRedisDB struct {
  95. Addr string `json:"addr" yaml:"addr"`
  96. DB int `json:"db" yaml:"db"`
  97. Requirepass string `json:"requirepass" yaml:"requirepass"`
  98. Expiry int `json:"expiry" yaml:"expiry"`
  99. }
  100. type SideWorkSetting struct {
  101. // Asynq 配置
  102. AsynqSetting AsynqSetting `json:"asynq_setting,omitempty" yaml:"asynq_setting"`
  103. }
  104. type AsynqSetting struct {
  105. Redis AsynqRedisSetting `json:"redis" yaml:"redis"`
  106. Queues map[string]int `json:"queues,omitempty" yaml:"queues"`
  107. Concurrency int `json:"concurrency,omitempty" yaml:"concurrency"`
  108. LogLevel int32 `json:"log_level,omitempty" yaml:"log_level"`
  109. }
  110. type AsynqRedisSetting struct {
  111. // Network type to use, either tcp or unix.
  112. // Default is tcp.
  113. Network string `json:"network,omitempty" yaml:"network"`
  114. // Redis server address in "host:port" format.
  115. Addr string `json:"addr,omitempty" yaml:"addr"`
  116. // Username to authenticate the current connection when Redis ACLs are used.
  117. // See: https://redis.io/commands/auth.
  118. Username string `json:"username,omitempty" yaml:"username"`
  119. // Password to authenticate the current connection.
  120. // See: https://redis.io/commands/auth.
  121. Password string `json:"password,omitempty" yaml:"password"`
  122. // Redis DB to select after connecting to a server.
  123. // See: https://redis.io/commands/select.
  124. DB int `json:"db,omitempty" yaml:"db"`
  125. // Dial timeout for establishing new connections.
  126. // Default is 5 seconds.
  127. DialTimeout time.Duration `json:"dialTimeout,omitempty" yaml:"dial_timeout"`
  128. // Timeout for socket reads.
  129. // If timeout is reached, read commands will fail with a timeout error
  130. // instead of blocking.
  131. //
  132. // Use value -1 for no timeout and 0 for default.
  133. // Default is 3 seconds.
  134. ReadTimeout time.Duration `json:"readTimeout,omitempty" yaml:"read_timeout"`
  135. // Timeout for socket writes.
  136. // If timeout is reached, write commands will fail with a timeout error
  137. // instead of blocking.
  138. //
  139. // Use value -1 for no timeout and 0 for default.
  140. // Default is ReadTimout.
  141. WriteTimeout time.Duration `json:"writeTimeout,omitempty" yaml:"write_timeout"`
  142. // Maximum number of socket connections.
  143. // Default is 10 connections per every CPU as reported by runtime.NumCPU.
  144. PoolSize int `json:"poolSize,omitempty" yaml:"pool_size"`
  145. // TLS Config used to connect to a server.
  146. // TLS will be negotiated only if this field is set.
  147. TLSConfig *tls.Config `json:"tlsConfig,omitempty" yaml:"tls_config"`
  148. }
  149. type MqttSetting struct {
  150. Broker string `json:"broker" yaml:"broker"`
  151. UserName string `json:"username" yaml:"username"`
  152. Password string `json:"password" yaml:"password"`
  153. SubTopic string `json:"sub_topic" yaml:"sub_topic"`
  154. Retain bool `json:"retain" yaml:"retain"`
  155. Qos int `json:"qos" yaml:"qos"`
  156. KeepAlive int `json:"keepAlive" yaml:"keep_alive"`
  157. ConnectTimeout int `json:"connectTimeout" yaml:"connect_timeout"`
  158. AutoReconnect bool `json:"autoReconnect" yaml:"auto_reconnect"`
  159. ReconnectInterval int `json:"reconnectInterval" yaml:"reconnect_interval"`
  160. WorkNumber int `json:"workNumber" yaml:"work_number"`
  161. MergeDataTicker int `json:"mergeDataTicker" yaml:"merge_data_ticker"`
  162. }
  163. type MilkHallSetting struct {
  164. BasePath string `yaml:"base_path"`
  165. FilePath []string `yaml:"file_path"`
  166. BackPath string `json:"back_path"`
  167. UrlPath string `yaml:"url_path"`
  168. Brand string `yaml:"brand"`
  169. FarmId string `yaml:"farm_id"`
  170. MilkHallNumber string `yaml:"milk_hall_number"`
  171. }
  172. // EmailConfig 邮件配置
  173. type EmailConfig struct {
  174. Host string `yaml:"host"` // SMTP服务器地址
  175. Port int `json:"port"` // SMTP服务器端口
  176. Username string `yaml:"username"` // 发件人邮箱
  177. Password string `json:"password"` // 发件人密码
  178. From string `yaml:"from"` // 发件人名称
  179. To []string `yaml:"to"` // 收件人列表
  180. }
  181. func (a *AppConfig) Name() string {
  182. return fmt.Sprintf("%s-%s", a.AppName, a.AppEnv)
  183. }
  184. // CacheNameSpace 作为 Key 的前缀,用来区分不同环境,不同 APP 下的 Key,防止缓存干扰
  185. // 踩坑记录:
  186. //
  187. // 如果使用 fmt.Sprintf("%s-%s-%s", a.AppName, a.AppRole, a.AppEnv),例如 sayam-http-production, sayam-consumer-production
  188. // 会导致 从 role http 写入的 key,从 role consumer 中取不出来,反之亦然
  189. // 支持更多的key空间, 可以更灵活的定义ns
  190. func (a *AppConfig) CacheNameSpace() string {
  191. cacheKeySpace := ""
  192. if a.FarmName != "" {
  193. cacheKeySpace = fmt.Sprintf("%s-%s-%s", a.AppName, a.AppEnv, a.FarmName)
  194. } else {
  195. cacheKeySpace = fmt.Sprintf("%s-%s", a.AppName, a.AppEnv)
  196. }
  197. return cacheKeySpace
  198. }
  199. func Options() *AppConfig {
  200. return options
  201. }
  202. func init() {
  203. appEnv = strings.ToLower(os.Getenv("APP_ENVIRONMENT"))
  204. cfg := &AppConfig{}
  205. var err error
  206. initOnce.Do(func() {
  207. switch appEnv {
  208. case "test":
  209. err = Initialize("app.test.yaml", cfg)
  210. case "development", "develop":
  211. err = Initialize("app.develop.yaml", cfg)
  212. case "production":
  213. err = Initialize("app.production.yaml", cfg)
  214. default:
  215. panic("err confing")
  216. }
  217. if err != nil {
  218. panic(err)
  219. }
  220. cfg.JwtTokenKeyConfig = openPrivateKey()
  221. options = cfg
  222. })
  223. }