feat(server-go): 和风天气接入与高发病天气预警规则(#12)

This commit is contained in:
weijuesen
2026-08-12 17:40:24 +08:00
parent fa86542e55
commit c7f18c1381
10 changed files with 464 additions and 0 deletions
+37
View File
@@ -74,6 +74,7 @@ func main() {
transcodeSvc := service.NewTranscodeService(db, s3Svc)
aiSvc := service.NewAIClient(cfg.AIServiceBase)
wechatSvc := service.NewWechatService(cfg.WechatAppID, cfg.WechatSecret)
weatherSvc := service.NewWeatherService(cfg.QWeatherAPIKey, cfg.QWeatherLocation)
// 9. 创建 Gin 引擎
gin.SetMode(gin.ReleaseMode)
@@ -112,6 +113,10 @@ func main() {
handler.RegisterInspectionRoutes(api, db, s3Svc, aiSvc, cfg.S3BucketImages, wechatSvc, cfg.WechatTemplateInspection)
handler.RegisterTrayBatchRoutes(api, db)
handler.RegisterWechatRoutes(api, db, wechatSvc)
handler.RegisterWeatherRoutes(api, db, weatherSvc)
// 启动高发病天气预警定时任务(未配置时跳过)
go startWeatherAlertLoop(db, weatherSvc, time.Duration(cfg.QWeatherIntervalMin)*time.Minute)
// 启动后台设备状态同步(每 30 秒查询 WVP 设备在线状态)
go startDeviceStatusSync(db, mediaSvc)
@@ -179,3 +184,35 @@ func startDeviceStatusSync(db *gorm.DB, media *service.MediaService) {
}
}
}
// startWeatherAlertLoop 定期拉取天气并按规则写入 weather_alerts
func startWeatherAlertLoop(db *gorm.DB, weather *service.WeatherService, interval time.Duration) {
if !weather.Configured() {
slog.Warn("天气服务未配置(QWEATHER_API_KEY/QWEATHER_LOCATION),跳过定时预警")
return
}
run := func() {
ctx := context.Background()
now, err := weather.FetchNow(ctx)
if err != nil {
slog.Warn("天气拉取失败", "err", err)
return
}
daily, err := weather.FetchDaily(ctx)
if err != nil {
slog.Warn("天气预报拉取失败", "err", err)
return
}
for _, a := range service.EvaluateWeatherRules(*now, daily, "") {
if err := db.Create(&a).Error; err != nil {
slog.Warn("天气预警写入失败", "disease", a.Disease, "err", err)
}
}
}
run()
ticker := time.NewTicker(interval)
defer ticker.Stop()
for range ticker.C {
run()
}
}