From 012715ee81167b9184ed25063de5f97b3aa8256f Mon Sep 17 00:00:00 2001 From: LIRUI <298977887@qq.com> Date: Fri, 28 Feb 2025 23:49:57 +0800 Subject: [PATCH] 0228.6 --- src/app/api/sun/route.ts | 55 +++++++++++++------ src/app/api/weather/route.ts | 2 +- src/app/page.tsx | 2 +- src/components/WeatherSection.tsx | 87 ++++++++++++++++--------------- 4 files changed, 86 insertions(+), 60 deletions(-) diff --git a/src/app/api/sun/route.ts b/src/app/api/sun/route.ts index c8acbde..baa5220 100644 --- a/src/app/api/sun/route.ts +++ b/src/app/api/sun/route.ts @@ -1,33 +1,48 @@ +// src/app/api/sun/route.ts import { NextResponse } from 'next/server'; export async function GET() { const apiKey = process.env.QWEATHER_API_KEY; - // 使用北京坐标(示例) const [longitude, latitude] = [116.3974, 39.9093]; const today = new Date(); try { - // 获取未来6天日出日落数据 + // 生成包含今天在内的未来6天日期 const datePromises = Array.from({ length: 6 }).map((_, i) => { const date = new Date(today); date.setDate(today.getDate() + i); - return date.toISOString().split('T')[0].replace(/-/g, ''); // 格式化为yyyyMMdd + return date; }); const responses = await Promise.all( - datePromises.map(date => - fetch(`https://devapi.qweather.com/v7/astronomy/sun?location=${longitude},${latitude}&date=${date}&key=${apiKey}`) - ) + datePromises.map(date => { + const formattedDate = date.toISOString().split('T')[0].replace(/-/g, ''); + return fetch( + `https://devapi.qweather.com/v7/astronomy/sun?` + + `location=${longitude},${latitude}&date=${formattedDate}&key=${apiKey}` + ); + }) ); + // 增强的错误处理 + const errors = responses.filter(res => !res.ok); + if (errors.length > 0) { + throw new Error(`API请求失败: ${errors.map(e => e.statusText).join(', ')}`); + } + const sunData = await Promise.all(responses.map(res => res.json())); - // 格式化数据 - const formattedData = sunData.map((item, index) => ({ - date: new Date(today.getTime() + index * 86400000).toISOString().split('T')[0], - sunrise: formatSunTime(item.sunrise), - sunset: formatSunTime(item.sunset) - })); + // 数据格式化和验证 + const formattedData = sunData.map((item, index) => { + const targetDate = new Date(today); + targetDate.setDate(today.getDate() + index); + + return { + date: targetDate.toISOString().split('T')[0], + sunrise: safeFormatTime(item.sunrise), + sunset: safeFormatTime(item.sunset) + }; + }); return NextResponse.json(formattedData, { headers: { @@ -39,22 +54,28 @@ export async function GET() { } catch (error) { console.error('日出日落数据获取失败:', error); return NextResponse.json( - { error: "日出日落数据获取失败" }, + { error: "数据获取失败,请稍后重试" }, { status: 500 } ); } } -// 时间格式化函数 -function formatSunTime(isoTime: string) { +// 健壮的时间格式化方法 +function safeFormatTime(timeStr: string) { + // 直接匹配HH:mm格式 + const directMatch = timeStr.match(/(\d{2}:\d{2})/); + if (directMatch) return directMatch[1]; + + // 处理ISO格式 try { - const date = new Date(isoTime); + const date = new Date(timeStr); return date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit', hour12: false }); } catch { - return isoTime.split('T')[1]?.substring(0, 5) || '--:--'; + // 最终处理非常规格式 + return timeStr.split('T')[1]?.substring(0, 5) || '--:--'; } } \ No newline at end of file diff --git a/src/app/api/weather/route.ts b/src/app/api/weather/route.ts index a601f02..c0699ac 100644 --- a/src/app/api/weather/route.ts +++ b/src/app/api/weather/route.ts @@ -77,7 +77,7 @@ function translateSkycon(skycon: string) { "SAND": "沙尘", "WIND": "大风" }; - return skyconMap[skycon] || "未知天气"; + return skyconMap[skycon] || "未知"; } // 风向转换(根据官方文档说明) diff --git a/src/app/page.tsx b/src/app/page.tsx index d33cf59..bfa90fa 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,7 +1,7 @@ "use client"; /** - * 魔镜主页面 + * 魔镜主页面src\app\page.tsx * 集成所有子组件并管理主要状态 */ diff --git a/src/components/WeatherSection.tsx b/src/components/WeatherSection.tsx index 760bbe7..1782a4f 100644 --- a/src/components/WeatherSection.tsx +++ b/src/components/WeatherSection.tsx @@ -1,11 +1,4 @@ -"use client"; - -/** - * 天气信息组件 - * 包含当前天气和天气预报展示 - * 支持加载状态处理和API数据格式转换 - */ - +// src/components/WeatherSection.tsx import { FC } from "react"; import { WeatherData } from "../types/magic-mirror"; import CircularProgress from "@mui/material/CircularProgress"; @@ -15,7 +8,6 @@ interface WeatherSectionProps { } const WeatherSection: FC = ({ data }) => { - // 处理加载状态 if (!data) { return (
@@ -25,21 +17,7 @@ const WeatherSection: FC = ({ data }) => { ); } - // 日出日落时间格式化(安全访问) - const formatTime = (isoTime?: string) => { - if (!isoTime) return "--:--"; - try { - return new Date(isoTime).toLocaleTimeString("zh-CN", { - hour: "2-digit", - minute: "2-digit", - hour12: false, - }); - } catch { - return isoTime.split("T")[1]?.slice(0, 5) || "--:--"; - } - }; - - // 获取天气图标(带默认值) + // 获取天气图标 const getWeatherIcon = (condition?: string) => { const iconMap: Record = { 晴: "☀️", @@ -53,12 +31,8 @@ const WeatherSection: FC = ({ data }) => { return condition ? iconMap[condition] || "🌤️" : "🌤️"; }; - // 安全获取天气预报数据 - const forecastData = data.forecast?.slice(0, 5) || []; - return ( <> - {/* 当前天气模块 */}
@@ -70,10 +44,11 @@ const WeatherSection: FC = ({ data }) => {
日出/日落
- {formatTime(data.sunrise)} / {formatTime(data.sunset)} + {data.sunrise || "--:--"} / {data.sunset || "--:--"}
+
{getWeatherIcon(data.condition)}
@@ -83,33 +58,63 @@ const WeatherSection: FC = ({ data }) => {
+
紫外线指数
{data.uvIndex || "--"}
- {/* 天气预报模块(安全渲染) */} - {forecastData.length > 0 && ( -
- {forecastData.map((day, index) => ( + {/* 天气预报模块 */} +
+
+ 未来5天预报 +
+
+ {data.forecast.slice(0, 5).map((day, index) => (
-
{day.day || "未知"}
-
- {getWeatherIcon(day.condition)} + {/* 日期 */} +
+ {day.day || "未知"}
-
- {day.low ?? "--"}° - {day.high ?? "--"}° + + {/* 天气图标 +
+ {getWeatherIcon(day.condition)} +
*/} + + {/* 天气图标和名称 */} +
+
+ {getWeatherIcon(day.condition)} +
+
+ {day.condition || "未知"} +
+
+ + {/* 温度范围 */} +
+ + {day.low ?? "--"}° + +
+ + {day.high ?? "--"}° +
))}
- )} +
+ + + + ); };