From fe3f48f255e4cc07e83d46d7f747c803a5bb631d Mon Sep 17 00:00:00 2001
From: "2569718930@qq.com" <2569718930@qq.com>
Date: Sun, 10 May 2026 18:30:59 +0800
Subject: [PATCH] =?UTF-8?q?=E5=9F=8E=E5=B8=82=E5=86=B3=E7=AD=96=E5=8D=A1?=
=?UTF-8?q?=E6=96=B0=E5=A2=9E=20AMOS=20=E8=B7=91=E9=81=93=E6=B8=A9?=
=?UTF-8?q?=E5=BA=A6=E9=9D=A2=E6=9D=BF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 新增 AmosRunwayPanel 组件:展示每条跑道的温度/露点/能见度/RVR/风速
- 跑道卡片网格布局 (auto-fit minmax 160px)
- 每条跑道独立显示:跑道编号、温度(含露点)、能见度、RVR、风速范围
- 官方 METAR 标签 vs 跑道中位数标签
- CityDetail 类型新增 AmosData 接口
- 暗色/浅色主题均已适配
- 仅首尔/釜山(有 AMOS 数据)时显示
---
.../dashboard/ScanTerminalCard.module.css | 64 ++++++++++++++
.../ScanTerminalLightTheme.module.css | 28 ++++++
.../scan-terminal/AiPinnedCityCard.tsx | 9 ++
.../scan-terminal/AmosRunwayPanel.tsx | 86 +++++++++++++++++++
frontend/lib/dashboard-types.ts | 30 +++++++
grep.exe.stackdump | 15 ++++
6 files changed, 232 insertions(+)
create mode 100644 frontend/components/dashboard/scan-terminal/AmosRunwayPanel.tsx
create mode 100644 grep.exe.stackdump
diff --git a/frontend/components/dashboard/ScanTerminalCard.module.css b/frontend/components/dashboard/ScanTerminalCard.module.css
index 847f910a..7abedcc0 100644
--- a/frontend/components/dashboard/ScanTerminalCard.module.css
+++ b/frontend/components/dashboard/ScanTerminalCard.module.css
@@ -1225,3 +1225,67 @@
font-weight: 800;
line-height: 1.5;
}
+
+/* ── AMOS runway observation panel ── */
+.root :global(.scan-amos-runway-panel) {
+ margin-top: 14px;
+ border: 1px solid rgba(77, 163, 255, 0.12);
+ border-radius: 16px;
+ background: rgba(11, 18, 32, 0.24);
+ padding: 14px;
+}
+
+.root :global(.scan-amos-source-tag) {
+ display: inline-block;
+ margin-left: 8px;
+ padding: 1px 7px;
+ border-radius: 999px;
+ background: rgba(77, 163, 255, 0.12);
+ color: var(--color-accent-secondary);
+ font-size: 10px;
+ font-weight: 700;
+}
+
+.root :global(.scan-amos-runway-grid) {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
+ gap: 10px;
+ margin-top: 10px;
+}
+
+.root :global(.scan-amos-runway-card) {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ padding: 10px 12px;
+ border: 1px solid rgba(77, 163, 255, 0.08);
+ border-radius: 12px;
+ background: rgba(11, 18, 32, 0.38);
+}
+
+.root :global(.scan-amos-runway-label) {
+ font-size: 11px;
+ font-weight: 700;
+ color: var(--color-accent-secondary);
+ letter-spacing: 0.02em;
+}
+
+.root :global(.scan-amos-runway-temp) {
+ font-size: 20px;
+ font-weight: 800;
+ font-variant-numeric: tabular-nums;
+ color: var(--color-text-primary);
+ line-height: 1.15;
+}
+
+.root :global(.scan-amos-runway-temp small) {
+ font-size: 11px;
+ font-weight: 600;
+ color: var(--color-text-muted);
+}
+
+.root :global(.scan-amos-runway-detail) {
+ font-size: 11px;
+ font-weight: 600;
+ color: var(--color-text-muted);
+}
diff --git a/frontend/components/dashboard/ScanTerminalLightTheme.module.css b/frontend/components/dashboard/ScanTerminalLightTheme.module.css
index 5c2ef36c..d9422462 100644
--- a/frontend/components/dashboard/ScanTerminalLightTheme.module.css
+++ b/frontend/components/dashboard/ScanTerminalLightTheme.module.css
@@ -982,3 +982,31 @@ html.light .root :global(.scan-terminal.light .scan-retry-button) {
html.light .root :global(.scan-terminal.light .scan-retry-button:hover) {
background: rgba(37, 99, 235, 0.14);
}
+
+/* ── AMOS runway panel light overrides ── */
+html.light .root :global(.scan-terminal.light .scan-amos-runway-panel) {
+ background: rgba(37, 99, 235, 0.03);
+ border-color: rgba(37, 99, 235, 0.12);
+}
+
+html.light .root :global(.scan-terminal.light .scan-amos-runway-card) {
+ background: #ffffff;
+ border-color: rgba(37, 99, 235, 0.08);
+}
+
+html.light .root :global(.scan-terminal.light .scan-amos-runway-label) {
+ color: #2563EB;
+}
+
+html.light .root :global(.scan-terminal.light .scan-amos-runway-temp) {
+ color: #0F172A;
+}
+
+html.light .root :global(.scan-terminal.light .scan-amos-source-tag) {
+ background: rgba(37, 99, 235, 0.08);
+ color: #2563EB;
+}
+
+html.light .root :global(.scan-terminal.light .scan-amos-runway-detail) {
+ color: #64748B;
+}
diff --git a/frontend/components/dashboard/scan-terminal/AiPinnedCityCard.tsx b/frontend/components/dashboard/scan-terminal/AiPinnedCityCard.tsx
index 16c589db..0aaa23d0 100644
--- a/frontend/components/dashboard/scan-terminal/AiPinnedCityCard.tsx
+++ b/frontend/components/dashboard/scan-terminal/AiPinnedCityCard.tsx
@@ -5,6 +5,7 @@ import type { MouseEvent } from "react";
import { useEffect, useState } from "react";
import { AiCityTemperatureChart } from "@/components/dashboard/scan-terminal/AiCityTemperatureChart";
import { AiEvidencePanel } from "@/components/dashboard/scan-terminal/AiEvidencePanel";
+import { AmosRunwayPanel } from "@/components/dashboard/scan-terminal/AmosRunwayPanel";
import { CityCardHeader } from "@/components/dashboard/scan-terminal/CityCardHeader";
import { MobileDecisionCard } from "@/components/dashboard/scan-terminal/MobileDecisionCard";
import { ModelEvidencePanel } from "@/components/dashboard/scan-terminal/ModelEvidencePanel";
@@ -650,6 +651,14 @@ export function AiPinnedCityCard({
/>
+ {detail?.amos ? (
+