mirror of
https://git.beihong.wang/wangbeihong/blog-source.git
synced 2026-04-24 02:53:05 +08:00
112 lines
4.6 KiB
PHP
112 lines
4.6 KiB
PHP
<?php
|
||
|
||
/**
|
||
* 天气小部件
|
||
*
|
||
* @author 星语社长
|
||
* @link https://biibii.cn
|
||
* @update 2026-03-03
|
||
*/
|
||
if ( ! defined('__TYPECHO_ROOT_DIR__')) {
|
||
exit;
|
||
}
|
||
// 只有在侧边栏开启且不是文章页面时显示
|
||
if ( ! empty($this->options->sidebarBlock) && in_array('ShowSidebarWeather', $this->options->sidebarBlock) && ! $this->is('post')): ?>
|
||
<?php
|
||
// 获取配置信息
|
||
$city = trim($this->options->weatherCity ?: 'Beijing');
|
||
$apiKey = trim($this->options->weatherApiKey ?: '');
|
||
$cacheFile = dirname(__DIR__, 2) . '/assets/weather_cache.json';
|
||
|
||
// 缓存机制:记录城市和时间,过期 1 小时,城市变更时自动失效
|
||
function hh_fetch_weather($city, $apiKey, $cacheFile) {
|
||
if (file_exists($cacheFile)) {
|
||
$raw = @file_get_contents($cacheFile);
|
||
$cached = $raw ? json_decode($raw, true) : null;
|
||
// 缓存结构:{"city":"xxx","timestamp":12345678,"data":{…}}
|
||
if ($cached && isset($cached['city'], $cached['timestamp'], $cached['data'])) {
|
||
if ($cached['city'] === $city && time() - $cached['timestamp'] < 3600) {
|
||
return $cached['data'];
|
||
}
|
||
}
|
||
}
|
||
|
||
if (empty($apiKey) || empty($city)) {
|
||
return null;
|
||
}
|
||
|
||
$url = 'https://api.openweathermap.org/data/2.5/weather?q=' . urlencode($city)
|
||
. '&appid=' . $apiKey . '&units=metric&lang=zh_cn';
|
||
$json = @file_get_contents($url);
|
||
if ($json) {
|
||
$payload = json_encode([
|
||
'city' => $city,
|
||
'timestamp' => time(),
|
||
'data' => json_decode($json, true),
|
||
]);
|
||
@file_put_contents($cacheFile, $payload);
|
||
return json_decode($json, true);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
$weather = hh_fetch_weather($city, $apiKey, $cacheFile);
|
||
// 用于调试:在 HTML 注释中输出参数和值,方便查看
|
||
$reqUrl = 'https://api.openweathermap.org/data/2.5/weather?q=' . urlencode($city)
|
||
. '&appid=' . $apiKey . '&units=metric&lang=zh_cn';
|
||
?>
|
||
|
||
<!-- weather widget debug: city=<?php echo htmlspecialchars($city, ENT_QUOTES); ?>, key_len=<?php echo strlen($apiKey); ?>, url=<?php echo htmlspecialchars($reqUrl, ENT_QUOTES); ?>, allow_url_fopen=<?php echo ini_get('allow_url_fopen') ? 'on' : 'off'; ?>, last_err=<?php $e = error_get_last(); echo $e ? htmlspecialchars($e['message'], ENT_QUOTES) : 'none'; ?> -->
|
||
|
||
<div class="hh-widget mt-3 weather-widget" style="font-size:0.9rem;line-height:1.4;">
|
||
<?php if ($weather && isset($weather['weather'][0])): ?>
|
||
<?php
|
||
// 语言友好的城市显示(中英文互译)
|
||
function hh_display_city($inputCity, $weather) {
|
||
static $map = [
|
||
'Beijing' => '北京',
|
||
'Guangzhou' => '广州',
|
||
'Shenzhen' => '深圳',
|
||
'Shanghai' => '上海',
|
||
'Chengdu' => '成都',
|
||
// 可根据需要继续添加
|
||
];
|
||
if (isset($map[$inputCity])) {
|
||
return $map[$inputCity];
|
||
}
|
||
if (isset($map[$weather['name']])) {
|
||
return $map[$weather['name']];
|
||
}
|
||
return $weather['name'];
|
||
}
|
||
$displayCity = hh_display_city($city, $weather);
|
||
$w = $weather['weather'][0];
|
||
$m = $weather['main'];
|
||
$wind = $weather['wind'] ?? [];
|
||
$iconUrl = 'https://openweathermap.org/img/wn/' . $w['icon'] . '@2x.png';
|
||
?>
|
||
<div class="weather-header" style="display:flex;align-items:center;justify-content:center;">
|
||
<img src="<?php echo $iconUrl; ?>"
|
||
alt="<?php echo htmlspecialchars($w['description'], ENT_QUOTES); ?>"
|
||
style="width:48px;height:48px;margin-right:8px;">
|
||
<div style="text-align:left;">
|
||
<p style="margin:0;font-weight:bold;line-height:1;"><?php echo $displayCity; ?></p>
|
||
<p style="margin:0;line-height:1;"><?php echo $w['description']; ?> <?php echo $m['temp']; ?>°C</p>
|
||
</div>
|
||
</div>
|
||
<div class="weather-details" style="font-size:0.85rem;color:#555;text-align:center;margin-top:4px;">
|
||
<p style="margin:0;">体感:<?php echo $m['feels_like']; ?>°C;湿度:<?php echo $m['humidity']; ?>%;气压:<?php echo $m['pressure']; ?> hPa</p>
|
||
<?php if (!empty($wind)): ?>
|
||
<p style="margin:0;">风速:<?php echo $wind['speed']; ?> m/s<?php
|
||
if (isset($wind['deg'])) echo ',方向:' . $wind['deg'] . '°'; ?></p>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php elseif ($weather && isset($weather['cod']) && $weather['cod'] != 200): ?>
|
||
<p>天气接口错误:<?php echo htmlspecialchars($weather['message'] ?? '未知', ENT_QUOTES); ?></p>
|
||
<?php else: ?>
|
||
<p>天气获取失败</p>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<?php endif; ?>
|