From 46d8ecb3725d3869f0eb29e79fe175d63173c6eb Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Wed, 22 Apr 2026 03:39:11 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=BA=E5=9F=8E=E5=B8=82=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=B7=BB=E5=8A=A0=E6=91=98=E8=A6=81=E5=9B=9E?= =?UTF-8?q?=E9=80=80=E5=93=8D=E5=BA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/app/api/city/[name]/route.ts | 107 ++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/frontend/app/api/city/[name]/route.ts b/frontend/app/api/city/[name]/route.ts index e5d6856c..81d66013 100644 --- a/frontend/app/api/city/[name]/route.ts +++ b/frontend/app/api/city/[name]/route.ts @@ -6,6 +6,97 @@ import { const API_BASE = process.env.POLYWEATHER_API_BASE_URL; +function buildFallbackCityDetail(name: string, depth: string, summary: Record) { + const nowIso = new Date().toISOString(); + return { + detail_depth: depth, + name, + display_name: summary?.display_name || name, + lat: 0, + lon: 0, + utc_offset_seconds: summary?.utc_offset_seconds ?? null, + temp_symbol: summary?.temp_symbol || "°C", + local_time: summary?.local_time || "--:--", + local_date: nowIso.slice(0, 10), + risk: { + level: summary?.risk?.level || "medium", + warning: summary?.risk?.warning || null, + airport: summary?.display_name || name, + icao: summary?.icao || null, + }, + current: { + temp: summary?.current?.temp ?? null, + max_so_far: summary?.current?.temp ?? null, + max_temp_time: summary?.current?.obs_time || null, + wu_settlement: null, + settlement_source: summary?.current?.settlement_source || null, + settlement_source_label: summary?.current?.settlement_source_label || null, + station_code: summary?.icao || null, + station_name: summary?.display_name || name, + obs_time: summary?.current?.obs_time || null, + obs_age_min: null, + observation_status: "missing", + wind_speed_kt: null, + wind_dir: null, + humidity: null, + cloud_desc: null, + clouds_raw: [], + visibility_mi: null, + wx_desc: null, + raw_metar: null, + report_time: null, + receipt_time: null, + obs_time_epoch: null, + }, + deb: { + prediction: summary?.deb?.prediction ?? null, + }, + deviation_monitor: summary?.deviation_monitor || {}, + forecast: { + today_high: null, + daily: [], + sunrise: null, + sunset: null, + sunshine_hours: null, + }, + multi_model: {}, + probabilities: { + mu: null, + distribution: [], + distribution_all: [], + engine: "legacy", + calibration_mode: "legacy", + calibration_version: null, + raw_mu: null, + raw_sigma: null, + calibrated_mu: null, + calibrated_sigma: null, + shadow_distribution: [], + shadow_distribution_all: [], + }, + trend: { + direction: "unknown", + recent: [], + is_cooling: false, + is_dead_market: false, + }, + peak: { + hours: [], + first_h: null, + last_h: null, + status: "unknown", + }, + dynamic_commentary: { + summary: "", + notes: [], + }, + market_scan: null, + intraday_meteorology: null, + updated_at: summary?.updated_at || nowIso, + fallback_source: "summary", + }; +} + export async function GET( req: NextRequest, context: { params: Promise<{ name: string }> }, @@ -33,6 +124,22 @@ export async function GET( }); if (!res.ok) { const raw = await res.text(); + const summaryUrl = `${API_BASE}/api/city/${encodeURIComponent(name)}/summary?force_refresh=${forceRefresh}`; + const summaryRes = await fetch(summaryUrl, { + headers: auth.headers, + cache: "no-store", + }); + if (summaryRes.ok) { + const summaryData = await summaryRes.json(); + const response = NextResponse.json(buildFallbackCityDetail(name, depth, summaryData), { + headers: { + "Cache-Control": "no-store", + "X-PolyWeather-Fallback": "summary", + }, + }); + return applyAuthResponseCookies(response, auth.response); + } + const response = NextResponse.json( { error: `Backend returned ${res.status}`, detail: raw.slice(0, 300) }, { status: 502 },