(data: OpenMeteoResponse, locationName: string)
| 417 | const current = data.current!; |
| 418 | const daily = data.daily!; |
| 419 | |
| 420 | // 获取天气图标和描述 |
| 421 | const weatherInfo = weatherCodeMap[current.weather_code] || { icon: "🌤️", description: "未知" }; |
| 422 | |
| 423 | // 风向 |
| 424 | const windDir = calcWindDirection(current.wind_direction_10m); |
| 425 | |
| 426 | // 日出日落时间 |
| 427 | const sunrise = daily.sunrise[0].split('T')[1].substring(0, 5); |
| 428 | const sunset = daily.sunset[0].split('T')[1].substring(0, 5); |
| 429 | |
| 430 | let result = `<b>📍 ${htmlEscape(locationName)}</b>\n\n`; |
| 431 | result += `${weatherInfo.icon} <b>${weatherInfo.description}</b>\n\n`; |
| 432 | result += `🌡️ <b>温度:</b> ${current.temperature_2m}°C\n`; |
| 433 | result += `🤔 <b>体感:</b> ${current.apparent_temperature}°C\n`; |
| 434 | result += `📊 <b>今日最高/最低:</b> ${daily.temperature_2m_max[0]}°C / ${daily.temperature_2m_min[0]}°C\n`; |
| 435 | result += `💧 <b>湿度:</b> ${current.relative_humidity_2m}%\n`; |
| 436 | result += `💨 <b>风速:</b> ${current.wind_speed_10m} km/h (${windDir}风)\n`; |
| 437 | |
| 438 | if (current.wind_gusts_10m > 0) { |
| 439 | result += `🌪️ <b>阵风:</b> ${current.wind_gusts_10m} km/h\n`; |
| 440 | } |
| 441 | |
| 442 | result += `🔵 <b>气压:</b> ${Math.round(current.pressure_msl)} hPa\n`; |
| 443 | result += `☁️ <b>云量:</b> ${current.cloud_cover}%\n`; |
| 444 | |
| 445 | if (current.precipitation > 0) { |
| 446 | result += `🌧️ <b>降水量:</b> ${current.precipitation} mm\n`; |
| 447 | } |
| 448 | if (current.rain > 0) { |
| 449 | result += `☔ <b>降雨量:</b> ${current.rain} mm\n`; |
| 450 | } |
| 451 | if (current.snowfall > 0) { |
| 452 | result += `❄️ <b>降雪量:</b> ${current.snowfall} cm\n`; |
| 453 | } |
| 454 | |
| 455 | result += `🌅 <b>日出:</b> ${sunrise}\n`; |
| 456 | result += `🌇 <b>日落:</b> ${sunset}\n\n`; |
| 457 | |
| 458 | // 天气预警 |
| 459 | const warnings = this.checkWeatherWarnings(current, daily); |
| 460 | if (warnings.length > 0) { |
| 461 | result += `<b>⚠️ 天气提醒</b>\n`; |
| 462 | for (const warning of warnings) { |
| 463 | result += `${warning}\n`; |
| 464 | } |
| 465 | result += `\n`; |
| 466 | } |
| 467 | |
| 468 | result += `<i>数据来源: Open-Meteo (免费API)</i>`; |
| 469 | |
| 470 | return result; |
| 471 | } |
| 472 | |
| 473 | // 检查天气预警 |
| 474 | private checkWeatherWarnings(current: any, daily: any): string[] { |
| 475 | const warnings: string[] = []; |
| 476 |
no test coverage detected