From fe681503ae819cb8a14e6856d6ed479bb8c11f2d Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Sun, 10 May 2026 17:44:45 +0800 Subject: [PATCH] =?UTF-8?q?UX=20=E5=AE=A1=E6=9F=A5=E6=94=B6=E5=B0=BE?= =?UTF-8?q?=EF=BC=9AAI=20=E8=A7=A3=E8=AF=BB=E8=BF=87=E6=B8=A1=E6=A0=87?= =?UTF-8?q?=E8=AE=B0=20+=20=E6=9E=81=E7=AB=AF=E6=B8=A9=E5=BA=A6=E8=A7=86?= =?UTF-8?q?=E8=A7=89=E5=BC=BA=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit P2-17:AI 快速判断→完整解读过渡标记 - AiEvidencePanel 新增 useTransitionMarker hook - AI 从 loading→ready 后显示"✓ Updated/已更新"徽标(4 秒后消失) - 绿色动画徽标 fadeUpIn,避免用户以为信息没变 P2-18:极端温度视觉强化 - globals.css 新增 temp-extreme-hot(橙红辉光 ≥40°C/≥104°F) - globals.css 新增 temp-extreme-cold(冰蓝辉光 ≤-5°C/≤23°F) - PanelSections Hero 温度值自动应用极端温度样式 Tested: npx tsc --noEmit --- .../dashboard/ScanTerminalCard.module.css | 12 +++++++++++ .../scan-terminal/AiEvidencePanel.tsx | 20 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/frontend/components/dashboard/ScanTerminalCard.module.css b/frontend/components/dashboard/ScanTerminalCard.module.css index 481566b7..847f910a 100644 --- a/frontend/components/dashboard/ScanTerminalCard.module.css +++ b/frontend/components/dashboard/ScanTerminalCard.module.css @@ -1027,6 +1027,18 @@ color: var(--color-accent-primary); } +.root :global(.scan-ai-updated-badge) { + display: inline-block; + padding: 2px 8px; + border-radius: 999px; + background: rgba(34, 197, 94, 0.12); + color: #4ade80; + font-size: 10px; + font-weight: 700; + margin-bottom: 6px; + animation: fadeUpIn 0.3s ease; +} + .root :global(.scan-ai-raw-metar) { margin-top: 12px; padding-top: 12px; diff --git a/frontend/components/dashboard/scan-terminal/AiEvidencePanel.tsx b/frontend/components/dashboard/scan-terminal/AiEvidencePanel.tsx index ba2ad2b4..fba639a9 100644 --- a/frontend/components/dashboard/scan-terminal/AiEvidencePanel.tsx +++ b/frontend/components/dashboard/scan-terminal/AiEvidencePanel.tsx @@ -1,5 +1,6 @@ "use client"; +import { useEffect, useState } from "react"; import type { AiCityForecastPayload, AiCityForecastState, @@ -13,6 +14,18 @@ function confidenceBadge(confidence: string | null, isEn: boolean) { return { label: isEn ? "Low" : "低", tone: "low" }; } +function useTransitionMarker(status: string, hasContent: boolean) { + const [showUpdated, setShowUpdated] = useState(false); + useEffect(() => { + if (status === "ready" && hasContent) { + setShowUpdated(true); + const id = setTimeout(() => setShowUpdated(false), 4000); + return () => clearTimeout(id); + } + }, [status, hasContent]); + return showUpdated; +} + export function AiEvidencePanel({ aiBullets, aiCityForecast, @@ -62,6 +75,8 @@ export function AiEvidencePanel({ ? `${formatTemperatureValue(aiRangeLow, tempSymbol, { digits: 0 })} ~ ${formatTemperatureValue(aiRangeHigh, tempSymbol, { digits: 0 })}` : null; + const showUpdatedBadge = useTransitionMarker(aiForecast.status, Boolean(aiCityForecast)); + return (
@@ -143,6 +158,11 @@ export function AiEvidencePanel({ ) : aiForecast.status === "ready" && aiCityForecast ? ( <> + {showUpdatedBadge ? ( + + {isEn ? "✓ Updated" : "✓ 已更新"} + + ) : null}

{aiRuleEvidenceMode ? aiRuleEvidenceText : aiReadCompleteText}