监控页面布局对齐文档:时区后缀、暖色高温、新高紫光、趋势同行

- 当地时间加时区缩写(KST/JST/HKT 等)
- 温度 >= 30°C 暖橙色高亮
- 新高标记:紫色边框 + 紫色温度数字
- "今日最高" 与趋势箭头同行,对齐 docs 卡片布局
- CSS: temp-value.warm, new-high-card/high-val 样式
This commit is contained in:
2569718930@qq.com
2026-05-13 20:03:18 +08:00
parent 239c9c446d
commit ded09df749
4 changed files with 34 additions and 34 deletions
+16 -15
View File
@@ -17,19 +17,19 @@ use tower_http::services::ServeDir;
use tracing_subscriber;
// ── city config ──
// (city_key, display_name, icao, airport_en, utc_offset_hours, threshold)
const CITIES: &[(&str, &str, &str, &str, i32, f64)] = &[
("seoul", "首尔", "RKSI", "Incheon", 9, 3.0),
("busan", "釜山", "RKPK", "Gimhae", 9, 2.0),
("tokyo", "东京", "44166", "Haneda", 9, 2.0),
("ankara", "安卡拉", "17128", "Esenboğa", 3, 3.0),
("helsinki", "赫尔辛基", "EFHK", "Vantaa", 3, 2.0),
("amsterdam","阿姆斯特丹","EHAM","Schiphol",2,2.0),
("istanbul","伊斯坦布尔","17058","Airport",3,3.0),
("paris", "巴黎", "LFPB", "Le Bourget", 2, 3.0),
("hong kong","香港","HKO","Observatory",8,1.5),
("lau fau shan","流浮山","LFS","Lau Fau Shan",8,1.5),
("taipei", "台北", "466920", "Songshan", 8, 1.5),
// (city_key, display_name, icao, airport_en, utc_offset_hours, threshold, tz_abbr)
const CITIES: &[(&str, &str, &str, &str, i32, f64, &str)] = &[
("seoul", "首尔", "RKSI", "Incheon", 9, 3.0, "KST"),
("busan", "釜山", "RKPK", "Gimhae", 9, 2.0, "KST"),
("tokyo", "东京", "44166", "Haneda", 9, 2.0, "JST"),
("ankara", "安卡拉", "17128", "Esenboğa", 3, 3.0, "TRT"),
("helsinki", "赫尔辛基", "EFHK", "Vantaa", 3, 2.0, "EEST"),
("amsterdam","阿姆斯特丹","EHAM","Schiphol",2,2.0,"CEST"),
("istanbul","伊斯坦布尔","17058","Airport",3,3.0,"TRT"),
("paris", "巴黎", "LFPB", "Le Bourget", 2, 3.0, "CEST"),
("hong kong","香港","HKO","Observatory",8,1.5,"HKT"),
("lau fau shan","流浮山","LFS","Lau Fau Shan",8,1.5,"HKT"),
("taipei", "台北", "466920", "Songshan", 8, 1.5, "TST"),
];
// ── app state ──
@@ -49,10 +49,10 @@ struct MonitorTemplate {
// ── data loading ──
fn load_city_snapshot(db_path: &str, (key, display, icao, airport, tz, thresh): &(&str, &str, &str, &str, i32, f64)) -> CitySnapshot {
fn load_city_snapshot(db_path: &str, (key, display, icao, airport, tz, thresh, tz_abbr): &(&str, &str, &str, &str, i32, f64, &str)) -> CitySnapshot {
let now_utc = Utc::now();
let local = now_utc + chrono::Duration::hours(*tz as i64);
let local_time = local.format("%H:%M").to_string();
let local_time = format!("{} {}", local.format("%H:%M"), tz_abbr);
// Recent obs for temp + trend
let obs = db::get_recent_obs(db_path, icao, 120, 12);
@@ -107,6 +107,7 @@ fn load_city_snapshot(db_path: &str, (key, display, icao, airport, tz, thresh):
trend_ok: false,
in_window: false,
obs_age_min,
temp_warm: current_temp.map_or(false, |t| t >= 30.0),
}
}
+1
View File
@@ -20,6 +20,7 @@ pub struct CitySnapshot {
pub trend_ok: bool,
pub in_window: bool,
pub obs_age_min: Option<i64>,
pub temp_warm: bool,
}
#[derive(Debug, Clone, Copy, Serialize)]
+14 -1
View File
@@ -95,6 +95,9 @@ body {
background: rgba(124, 58, 237, 0.18);
color: #a78bfa;
}
.new-high-card {
border-color: rgba(124, 58, 237, 0.25);
}
/* ── temp ── */
.card-temp {
@@ -113,6 +116,12 @@ body {
color: #3a4050;
font-size: 28px;
}
.temp-value.warm {
color: #f59e0b;
}
.temp-value.new-high-val {
color: #c084fc;
}
.temp-unit {
font-size: 18px;
@@ -130,7 +139,8 @@ body {
.meta-row {
display: flex;
justify-content: space-between;
align-items: baseline;
gap: 6px;
font-size: 13px;
}
@@ -146,6 +156,9 @@ body {
.meta-row .value.na {
color: #3a4050;
}
.meta-row .trend {
margin-left: auto;
}
/* ── trend ── */
.trend { font-size: 15px; font-weight: 600; }
+3 -18
View File
@@ -21,7 +21,7 @@
<span id="update-time" class="updated" style="display:block;grid-column:1/-1;text-align:right;margin-bottom:2px">
{{ generated_at }}</span>
{% for c in cities %}
<div class="card">
<div class="card{% if c.new_high %} new-high-card{% endif %}">
<div class="card-top">
<span class="city-name">{{ c.display_name }}</span>
<span class="airport">/ {{ c.airport }}</span>
@@ -34,7 +34,7 @@
<div class="card-temp">
{% match c.current_temp %}
{% when Some with (t) %}
<span class="temp-value">{{ "{:.1}"|format(t) }}</span><span class="temp-unit">°C</span>
<span class="temp-value{% if c.temp_warm %} warm{% endif %}{% if c.new_high %} new-high-val{% endif %}">{{ "{:.1}"|format(t) }}</span><span class="temp-unit">°C</span>
{% when None %}
<span class="temp-value na">--</span>
{% endmatch %}
@@ -49,10 +49,7 @@
{% when None %}
<span class="value na">--</span>
{% endmatch %}
</div>
<div class="meta-row">
<span class="label">趋势</span>
<span class="value trend {{ c.trend.css_class() }}">{{ c.trend.symbol() }}</span>
<span class="trend {{ c.trend.css_class() }}">{{ c.trend.symbol() }}</span>
</div>
<div class="meta-row">
<span class="label">观测</span>
@@ -64,18 +61,6 @@
{% endmatch %}
</div>
</div>
{% if !c.runway_pairs.is_empty() %}
<div class="card-runway">
<div class="runway-divider"></div>
{% for (pair, temp) in c.runway_pairs %}
<div class="runway-row">
<span class="runway-label">{{ pair }}</span>
<span class="runway-temp">{{ "{:.1}"|format(temp) }}°C</span>
</div>
{% endfor %}
</div>
{% endif %}
</div>
{% endfor %}
</div>