diff --git a/internal/database/models.go b/internal/database/models.go index 3f6c6e8..e949062 100644 --- a/internal/database/models.go +++ b/internal/database/models.go @@ -131,7 +131,8 @@ func GetSeriesFrom10Min(db *sql.DB, stationID string, startTime, endTime time.Ti ROUND(wind_dir_deg::numeric, 2) AS wind_direction, ROUND(rain_10m_mm_x1000/1000.0, 3) AS rainfall, ROUND(solar_wm2_x100/100.0, 2) AS light, - ROUND(uv_index::numeric, 2) AS uv + ROUND(uv_index::numeric, 2) AS uv, + ROUND(rain_total_mm_x1000/1000.0, 3) AS rain_total FROM rs485_weather_10min WHERE station_id = $1 AND bucket_start >= $2 AND bucket_start <= $3 ORDER BY bucket_start` @@ -156,7 +157,7 @@ func GetSeriesFrom10Min(db *sql.DB, stationID string, startTime, endTime time.Ti var points []types.WeatherPoint for rows.Next() { var p types.WeatherPoint - if err := rows.Scan(&p.DateTime, &p.Temperature, &p.Humidity, &p.Pressure, &p.WindSpeed, &p.WindDir, &p.Rainfall, &p.Light, &p.UV); err != nil { + if err := rows.Scan(&p.DateTime, &p.Temperature, &p.Humidity, &p.Pressure, &p.WindSpeed, &p.WindDir, &p.Rainfall, &p.Light, &p.UV, &p.RainTotal); err != nil { continue } points = append(points, p) @@ -191,7 +192,8 @@ func buildAggFrom10MinQuery(interval string) string { SUM(sin(radians(wind_dir_deg)) * sample_count)::double precision AS sin_sum, SUM(cos(radians(wind_dir_deg)) * sample_count)::double precision AS cos_sum, SUM(rain_10m_mm_x1000) AS rain_sum, - SUM(sample_count) AS n_sum + SUM(sample_count) AS n_sum, + MAX(rain_total_mm_x1000) AS rain_total_max FROM base GROUP BY 1 ) @@ -206,7 +208,8 @@ func buildAggFrom10MinQuery(interval string) string { ELSE degrees(atan2(sin_sum, cos_sum)) END)::numeric, 2) AS wind_direction, ROUND((rain_sum/1000.0)::numeric, 3) AS rainfall, ROUND((w_solar/NULLIF(n_sum,0))/100.0, 2) AS light, - ROUND((w_uv/NULLIF(n_sum,0))::numeric, 2) AS uv + ROUND((w_uv/NULLIF(n_sum,0))::numeric, 2) AS uv, + ROUND((rain_total_max/1000.0)::numeric, 3) AS rain_total FROM g ORDER BY grp` } @@ -415,3 +418,37 @@ func GetForecastData(db *sql.DB, stationID string, startTime, endTime time.Time, return points, nil } + +func GetSeriesRaw(db *sql.DB, stationID string, startTime, endTime time.Time) ([]types.WeatherPoint, error) { + query := ` + SELECT + to_char(timestamp, 'YYYY-MM-DD HH24:MI:SS') AS date_time, + COALESCE(temperature, 0) AS temperature, + COALESCE(humidity, 0) AS humidity, + COALESCE(pressure, 0) AS pressure, + COALESCE(wind_speed, 0) AS wind_speed, + COALESCE(wind_direction, 0) AS wind_direction, + COALESCE(rainfall, 0) AS rainfall, + COALESCE(light, 0) AS light, + COALESCE(uv, 0) AS uv, + COALESCE(rainfall, 0) AS rain_total + FROM rs485_weather_data + WHERE station_id = $1 AND timestamp >= $2 AND timestamp <= $3 + ORDER BY timestamp` + + rows, err := db.Query(query, stationID, startTime, endTime) + if err != nil { + return nil, err + } + defer rows.Close() + + var points []types.WeatherPoint + for rows.Next() { + var p types.WeatherPoint + if err := rows.Scan(&p.DateTime, &p.Temperature, &p.Humidity, &p.Pressure, &p.WindSpeed, &p.WindDir, &p.Rainfall, &p.Light, &p.UV, &p.RainTotal); err != nil { + continue + } + points = append(points, p) + } + return points, nil +} diff --git a/internal/server/gin.go b/internal/server/gin.go index c97a906..00deb56 100644 --- a/internal/server/gin.go +++ b/internal/server/gin.go @@ -126,7 +126,12 @@ func getDataHandler(c *gin.Context) { } // 获取数据(改为基于10分钟聚合表的再聚合) - points, err := database.GetSeriesFrom10Min(database.GetDB(), stationID, start, end, interval) + var points []types.WeatherPoint + if interval == "raw" { + points, err = database.GetSeriesRaw(database.GetDB(), stationID, start, end) + } else { + points, err = database.GetSeriesFrom10Min(database.GetDB(), stationID, start, end, interval) + } if err != nil { log.Printf("查询数据失败: %v", err) // 记录具体错误到服务端日志 c.JSON(http.StatusInternalServerError, gin.H{ diff --git a/pkg/types/types.go b/pkg/types/types.go index b7c8045..0cbaa59 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -24,6 +24,7 @@ type WeatherPoint struct { Rainfall float64 `json:"rainfall"` Light float64 `json:"light"` UV float64 `json:"uv"` + RainTotal float64 `json:"rain_total"` } // PageData 页面数据结构 diff --git a/static/js/weather-chart.js b/static/js/weather-chart.js index 3201943..3c2d07c 100644 --- a/static/js/weather-chart.js +++ b/static/js/weather-chart.js @@ -32,12 +32,20 @@ const WeatherChart = { const item = historyData.find(d => d.date_time === label); return item ? item.rainfall : null; }); + const historyRainTotals = allLabels.map(label => { + const item = historyData.find(d => d.date_time === label); + return item && item.rain_total !== undefined ? item.rain_total : null; + }); // 准备预报数据 const forecastTemperatures = allLabels.map(label => { const item = forecastData.find(d => d.date_time === label); return item && item.temperature !== null ? item.temperature : null; }); + const forecastHumidities = allLabels.map(label => { + const item = forecastData.find(d => d.date_time === label); + return item && item.humidity !== null ? item.humidity : null; + }); const forecastRainfalls = allLabels.map(label => { const item = forecastData.find(d => d.date_time === label); return item && item.rainfall !== null ? item.rainfall : null; @@ -74,6 +82,17 @@ const WeatherChart = { backgroundColor: 'rgba(54, 162, 235, 0.6)', borderColor: 'rgb(54, 162, 235)', yAxisID: 'y-rainfall' + }, + { + label: '累计雨量 (mm) - 实测(10m total)', + data: historyRainTotals, + borderColor: 'rgb(75, 192, 192)', + backgroundColor: 'rgba(75, 192, 192, 0.1)', + yAxisID: 'y-rainfall', + tension: 0.2, + spanGaps: false, + pointRadius: 0, + hidden: true } ]; @@ -88,7 +107,19 @@ const WeatherChart = { borderDash: [5, 5], yAxisID: 'y-temperature', tension: 0.4, - spanGaps: false + spanGaps: false, + hidden: true + }, + { + label: '湿度 (%) - 预报', + data: forecastHumidities, + borderColor: 'rgba(255, 165, 0, 0.8)', + backgroundColor: 'rgba(255, 165, 0, 0.05)', + borderDash: [5, 5], + yAxisID: 'y-humidity', + tension: 0.4, + spanGaps: false, + hidden: false }, { label: '雨量 (mm) - 预报', diff --git a/templates/index.html b/templates/index.html index 5fd207d..23397ce 100644 --- a/templates/index.html +++ b/templates/index.html @@ -489,6 +489,7 @@ +