From 239c9c446d15b2daf2af6ce402bc6ed3e798c8b4 Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Wed, 13 May 2026 19:58:19 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9B=91=E6=8E=A7=E9=A1=B5=E9=9D=A2=E5=A2=9E?= =?UTF-8?q?=E5=BC=BA=EF=BC=9A=E6=B8=A9=E5=BA=A6=E5=8F=98=E5=8C=96=E9=97=AA?= =?UTF-8?q?=E7=BB=BF=E5=85=89=E3=80=81=E8=A7=82=E6=B5=8BN=E5=88=86?= =?UTF-8?q?=E9=92=9F=E5=89=8D=E3=80=81=E6=9B=B4=E6=96=B0=E6=88=B3=E5=8F=AF?= =?UTF-8?q?=E8=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 每张卡片加"观测 X 分钟前"时间感知 - 温度值变化时卡片边框闪绿光(HTMX afterSwap 事件) - 更新时间戳移入 HTMX 局部刷新区,30s 刷新可见 - CSS 加 obs-age 样式 --- monitoring-web/src/db.rs | 4 ++- monitoring-web/src/main.rs | 13 ++++++++++ monitoring-web/src/model.rs | 1 + monitoring-web/static/style.css | 3 +++ monitoring-web/templates/monitor.html | 36 ++++++++++++++++++++++++++- 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/monitoring-web/src/db.rs b/monitoring-web/src/db.rs index 92f7db3b..af0126b1 100644 --- a/monitoring-web/src/db.rs +++ b/monitoring-web/src/db.rs @@ -5,6 +5,7 @@ pub struct ObsRow { pub temp_c: Option, #[allow(dead_code)] pub obs_time: Option, + pub created_at: Option, } /// Get recent temperature observations for an ICAO station. @@ -14,7 +15,7 @@ pub fn get_recent_obs(db_path: &str, icao: &str, minutes: i32, limit: usize) -> Err(_) => return vec![], }; let sql = format!( - "SELECT temp_c, obs_time FROM airport_obs_log \ + "SELECT temp_c, obs_time, created_at FROM airport_obs_log \ WHERE icao = ?1 AND created_at > datetime('now', '{} minutes') \ ORDER BY created_at DESC LIMIT ?2", -minutes @@ -28,6 +29,7 @@ pub fn get_recent_obs(db_path: &str, icao: &str, minutes: i32, limit: usize) -> Ok(ObsRow { temp_c: row.get(0)?, obs_time: row.get(1)?, + created_at: row.get(2)?, }) }) .ok() diff --git a/monitoring-web/src/main.rs b/monitoring-web/src/main.rs index 886914e3..b1550a3a 100644 --- a/monitoring-web/src/main.rs +++ b/monitoring-web/src/main.rs @@ -59,6 +59,18 @@ fn load_city_snapshot(db_path: &str, (key, display, icao, airport, tz, thresh): let temps: Vec = obs.iter().filter_map(|o| o.temp_c).collect(); let current_temp = temps.first().copied(); + // Age of most recent observation + let obs_age_min = obs.first().and_then(|o| { + o.created_at.as_ref().and_then(|ts| { + chrono::NaiveDateTime::parse_from_str(ts, "%Y-%m-%d %H:%M:%S") + .ok() + .map(|dt| { + let obs_utc = dt.and_utc(); + (now_utc - obs_utc).num_minutes().max(0) + }) + }) + }); + // Trend from last 6 points let trend_data: Vec = temps.iter().take(6).copied().collect(); let trend = trend::calc_trend(&trend_data); @@ -94,6 +106,7 @@ fn load_city_snapshot(db_path: &str, (key, display, icao, airport, tz, thresh): temp_ok: false, trend_ok: false, in_window: false, + obs_age_min, } } diff --git a/monitoring-web/src/model.rs b/monitoring-web/src/model.rs index 6d9df98d..63c2beeb 100644 --- a/monitoring-web/src/model.rs +++ b/monitoring-web/src/model.rs @@ -19,6 +19,7 @@ pub struct CitySnapshot { pub temp_ok: bool, pub trend_ok: bool, pub in_window: bool, + pub obs_age_min: Option, } #[derive(Debug, Clone, Copy, Serialize)] diff --git a/monitoring-web/static/style.css b/monitoring-web/static/style.css index 465d5896..1e2fa95d 100644 --- a/monitoring-web/static/style.css +++ b/monitoring-web/static/style.css @@ -172,6 +172,9 @@ body { .runway-label { color: #4a5160; } .runway-temp { color: #7a8290; font-variant-numeric: tabular-nums; } +/* ── obs age ── */ +.obs-age { font-size: 12px; color: #5a6170; } + /* ── HTMX indicator ── */ .htmx-indicator { text-align: center; diff --git a/monitoring-web/templates/monitor.html b/monitoring-web/templates/monitor.html index 798118c3..4eadf021 100644 --- a/monitoring-web/templates/monitor.html +++ b/monitoring-web/templates/monitor.html @@ -12,12 +12,14 @@

🔥 市场监控

- 更新 {{ generated_at }} + 更新中…
{% endif %}
+ + {{ generated_at }} {% for c in cities %}
@@ -52,6 +54,15 @@ 趋势 {{ c.trend.symbol() }}
+
+ 观测 + {% match c.obs_age_min %} + {% when Some with (m) %} + {{ m }} 分钟前 + {% when None %} + -- + {% endmatch %} +
{% if !c.runway_pairs.is_empty() %} @@ -73,6 +84,29 @@ {% if full_page %} +