更新
This commit is contained in:
1
api/tq/counter.dat
Normal file
1
api/tq/counter.dat
Normal file
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
199
api/tq/index.php
199
api/tq/index.php
@@ -44,105 +44,29 @@ if (!preg_match('/^[\u4e00-\u9fff\w\s\-]+$/u', $city) || strlen($city) > 50) {
|
|||||||
$result = null;
|
$result = null;
|
||||||
$error = null;
|
$error = null;
|
||||||
|
|
||||||
// 方案1: wttr.in 天气服务 (支持中文)
|
// 方案1: 心知天气 API (国内数据源,优先使用)
|
||||||
// 方案2: 使用中国天气网数据源
|
// 方案2: 和风天气 API (国内数据源)
|
||||||
|
// 方案3: wttr.in (备选)
|
||||||
|
|
||||||
// 尝试方案1: wttr.in 天气服务 (支持中文)
|
// 尝试方案1: 心知天气 API (中国天气网数据)
|
||||||
$url = "https://wttr.in/" . urlencode($city) . "?format=j1&lang=" . ($lang === 'en' ? 'en' : 'zh-CN');
|
$url1 = "https://api.seniverse.com/v1/now.json?location=" . urlencode($city) . "&language=" . ($lang === 'en' ? 'en' : 'zh-Hans');
|
||||||
|
|
||||||
$ch = curl_init();
|
$ch1 = curl_init();
|
||||||
curl_setopt($ch, CURLOPT_URL, $url);
|
curl_setopt($ch1, CURLOPT_URL, $url1);
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
|
||||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
curl_setopt($ch1, CURLOPT_TIMEOUT, 8);
|
||||||
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) QuickAPI/1.0');
|
curl_setopt($ch1, CURLOPT_USERAGENT, 'Mozilla/5.0 QuickAPI/1.0');
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
|
||||||
|
|
||||||
$response = curl_exec($ch);
|
$response1 = curl_exec($ch1);
|
||||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
$http_code1 = curl_getinfo($ch1, CURLINFO_HTTP_CODE);
|
||||||
curl_close($ch);
|
curl_close($ch1);
|
||||||
|
|
||||||
if ($http_code == 200 && $response) {
|
if ($http_code1 == 200 && $response1) {
|
||||||
$data = json_decode($response, true);
|
$data1 = json_decode($response1, true);
|
||||||
|
|
||||||
if ($data && isset($data['current_condition'])) {
|
if ($data1 && isset($data1['results']) && count($data1['results']) > 0) {
|
||||||
$current = $data['current_condition'][0];
|
$results = $data1['results'][0];
|
||||||
$desc = $current['desc'] ?? [];
|
|
||||||
|
|
||||||
$result = [
|
|
||||||
'status' => 'success',
|
|
||||||
'code' => 200,
|
|
||||||
'city' => $city,
|
|
||||||
'current' => [
|
|
||||||
'temperature' => (float)$current['temp_C'] ?? null,
|
|
||||||
'temperature_f' => (float)$current['temp_F'] ?? null,
|
|
||||||
'feels_like' => (float)$current['FeelsLikeC'] ?? null,
|
|
||||||
'condition' => is_array($desc) ? ($desc[$lang === 'en' ? 'en' : 'zh-CN'] ?? $desc[0] ?? 'Unknown') : 'Unknown',
|
|
||||||
'humidity' => (int)$current['humidity'] ?? null,
|
|
||||||
'wind_speed' => (float)$current['windspeedKmph'] ?? null,
|
|
||||||
'wind_speed_ms' => (float)$current['windspeedKmph'] / 3.6 ?? null,
|
|
||||||
'wind_direction' => $current['winddir16Point'] ?? null,
|
|
||||||
'pressure' => (int)$current['pressure'] ?? null,
|
|
||||||
'precipitation' => (float)$current['precipMM'] ?? null,
|
|
||||||
'visibility' => (float)$current['visibility'] ?? null,
|
|
||||||
'uv_index' => (int)$current['uvIndex'] ?? null,
|
|
||||||
'cloud_cover' => (int)$current['cloudcover'] ?? null
|
|
||||||
],
|
|
||||||
'forecast' => [],
|
|
||||||
'source' => 'wttr.in',
|
|
||||||
'updated_at' => date('Y-m-d H:i:s')
|
|
||||||
];
|
|
||||||
|
|
||||||
// 添加预报数据 (如果可用)
|
|
||||||
if (isset($data['weather']) && is_array($data['weather'])) {
|
|
||||||
foreach ($data['weather'] as $day_idx => $day) {
|
|
||||||
if ($day_idx >= 3) break; // 只显示3天预报
|
|
||||||
|
|
||||||
$forecast_avg = $day['avgtemp_c'] ?? null;
|
|
||||||
$forecast_max = $day['maxtemp_c'] ?? null;
|
|
||||||
$forecast_min = $day['mintemp_c'] ?? null;
|
|
||||||
$forecast_desc = $day['hourly'][0]['desc'] ?? [];
|
|
||||||
|
|
||||||
$result['forecast'][] = [
|
|
||||||
'date' => $day['date'] ?? null,
|
|
||||||
'avg_temp' => (float)$forecast_avg,
|
|
||||||
'max_temp' => (float)$forecast_max,
|
|
||||||
'min_temp' => (float)$forecast_min,
|
|
||||||
'condition' => is_array($forecast_desc) ? ($forecast_desc[$lang === 'en' ? 'en' : 'zh-CN'] ?? $forecast_desc[0] ?? 'Unknown') : 'Unknown',
|
|
||||||
'avg_humidity' => (int)$day['avghumidity'] ?? null,
|
|
||||||
'total_snow' => (float)$day['totalSnow_cm'] ?? null,
|
|
||||||
'uv_index' => (int)$day['uvIndex'] ?? null
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$error = '无法解析天气数据';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$error = '无法连接到天气服务或城市不存在';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果主方案失败,尝试方案2: 心知天气 API (中国天气网数据)
|
|
||||||
if (!$result) {
|
|
||||||
// 心知天气免费API - 无需key即可使用基础功能
|
|
||||||
$url2 = "https://api.seniverse.com/v1/now.json?location=" . urlencode($city) . "&language=" . ($lang === 'en' ? 'en' : 'zh-Hans');
|
|
||||||
|
|
||||||
$ch2 = curl_init();
|
|
||||||
curl_setopt($ch2, CURLOPT_URL, $url2);
|
|
||||||
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch2, CURLOPT_TIMEOUT, 10);
|
|
||||||
curl_setopt($ch2, CURLOPT_USERAGENT, 'Mozilla/5.0 QuickAPI/1.0');
|
|
||||||
curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, false);
|
|
||||||
|
|
||||||
$response2 = curl_exec($ch2);
|
|
||||||
$http_code2 = curl_getinfo($ch2, CURLINFO_HTTP_CODE);
|
|
||||||
curl_close($ch2);
|
|
||||||
|
|
||||||
if ($http_code2 == 200 && $response2) {
|
|
||||||
$data2 = json_decode($response2, true);
|
|
||||||
|
|
||||||
if ($data2 && isset($data2['results']) && count($data2['results']) > 0) {
|
|
||||||
$results = $data2['results'][0];
|
|
||||||
$location = $results['location'];
|
$location = $results['location'];
|
||||||
$now = $results['now'];
|
$now = $results['now'];
|
||||||
|
|
||||||
@@ -168,39 +92,37 @@ if (!$result) {
|
|||||||
'visibility' => (float)$now['visibility'] ?? null,
|
'visibility' => (float)$now['visibility'] ?? null,
|
||||||
'pressure' => (int)$now['pressure'] ?? null
|
'pressure' => (int)$now['pressure'] ?? null
|
||||||
],
|
],
|
||||||
'source' => '心知天气(中国天气数据)',
|
'source' => '心知天气',
|
||||||
'updated_at' => date('Y-m-d H:i:s')
|
'updated_at' => date('Y-m-d H:i:s')
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果仍未获得数据,尝试方案3: 和风天气 API
|
// 如果方案1失败,尝试方案2: 和风天气 API
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
// 和风天气免费API
|
$url2 = "https://devapi.qweather.com/v7/weather/now?location=" . urlencode($city) . "&lang=" . ($lang === 'en' ? 'en' : 'zh');
|
||||||
$url3 = "https://devapi.qweather.com/v7/weather/now?location=" . urlencode($city) . "&lang=" . ($lang === 'en' ? 'en' : 'zh');
|
|
||||||
|
|
||||||
$ch3 = curl_init();
|
$ch2 = curl_init();
|
||||||
curl_setopt($ch3, CURLOPT_URL, $url3);
|
curl_setopt($ch2, CURLOPT_URL, $url2);
|
||||||
curl_setopt($ch3, CURLOPT_RETURNTRANSFER, true);
|
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
|
||||||
curl_setopt($ch3, CURLOPT_TIMEOUT, 10);
|
curl_setopt($ch2, CURLOPT_TIMEOUT, 8);
|
||||||
curl_setopt($ch3, CURLOPT_USERAGENT, 'Mozilla/5.0 QuickAPI/1.0');
|
curl_setopt($ch2, CURLOPT_USERAGENT, 'Mozilla/5.0 QuickAPI/1.0');
|
||||||
curl_setopt($ch3, CURLOPT_SSL_VERIFYPEER, false);
|
curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
|
||||||
$response3 = curl_exec($ch3);
|
$response2 = curl_exec($ch2);
|
||||||
$http_code3 = curl_getinfo($ch3, CURLINFO_HTTP_CODE);
|
$http_code2 = curl_getinfo($ch2, CURLINFO_HTTP_CODE);
|
||||||
curl_close($ch3);
|
curl_close($ch2);
|
||||||
|
|
||||||
if ($http_code3 == 200 && $response3) {
|
if ($http_code2 == 200 && $response2) {
|
||||||
$data3 = json_decode($response3, true);
|
$data2 = json_decode($response2, true);
|
||||||
|
|
||||||
if ($data3 && isset($data3['now'])) {
|
if ($data2 && isset($data2['now'])) {
|
||||||
$now = $data3['now'];
|
$now = $data2['now'];
|
||||||
|
|
||||||
$result = [
|
$result = [
|
||||||
'status' => 'success',
|
'status' => 'success',
|
||||||
'code' => 200,
|
'code' => 200,
|
||||||
'city' => $data3['fxLink'] ? substr($data3['fxLink'], strrpos($data3['fxLink'], '/') + 1) : $city,
|
'city' => $city,
|
||||||
'current' => [
|
'current' => [
|
||||||
'temperature' => (int)$now['temp'] ?? null,
|
'temperature' => (int)$now['temp'] ?? null,
|
||||||
'feels_like' => (int)$now['feelsLike'] ?? null,
|
'feels_like' => (int)$now['feelsLike'] ?? null,
|
||||||
@@ -214,7 +136,56 @@ if (!$result) {
|
|||||||
'visibility' => (int)$now['vis'] ?? null,
|
'visibility' => (int)$now['vis'] ?? null,
|
||||||
'dew_point' => (int)$now['dewPoint'] ?? null
|
'dew_point' => (int)$now['dewPoint'] ?? null
|
||||||
],
|
],
|
||||||
'source' => '和风天气(中国天气数据)',
|
'source' => '和风天气',
|
||||||
|
'updated_at' => date('Y-m-d H:i:s')
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果国内方案都失败,尝试方案3: wttr.in (备选)
|
||||||
|
if (!$result) {
|
||||||
|
$url3 = "https://wttr.in/" . urlencode($city) . "?format=j1&lang=" . ($lang === 'en' ? 'en' : 'zh-CN');
|
||||||
|
|
||||||
|
$ch3 = curl_init();
|
||||||
|
curl_setopt($ch3, CURLOPT_URL, $url3);
|
||||||
|
curl_setopt($ch3, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch3, CURLOPT_TIMEOUT, 8);
|
||||||
|
curl_setopt($ch3, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) QuickAPI/1.0');
|
||||||
|
curl_setopt($ch3, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
curl_setopt($ch3, CURLOPT_SSL_VERIFYHOST, false);
|
||||||
|
|
||||||
|
$response3 = curl_exec($ch3);
|
||||||
|
$http_code3 = curl_getinfo($ch3, CURLINFO_HTTP_CODE);
|
||||||
|
curl_close($ch3);
|
||||||
|
|
||||||
|
if ($http_code3 == 200 && $response3) {
|
||||||
|
$data3 = json_decode($response3, true);
|
||||||
|
|
||||||
|
if ($data3 && isset($data3['current_condition'])) {
|
||||||
|
$current = $data3['current_condition'][0];
|
||||||
|
$desc = $current['desc'] ?? [];
|
||||||
|
|
||||||
|
$result = [
|
||||||
|
'status' => 'success',
|
||||||
|
'code' => 200,
|
||||||
|
'city' => $city,
|
||||||
|
'current' => [
|
||||||
|
'temperature' => (float)$current['temp_C'] ?? null,
|
||||||
|
'temperature_f' => (float)$current['temp_F'] ?? null,
|
||||||
|
'feels_like' => (float)$current['FeelsLikeC'] ?? null,
|
||||||
|
'condition' => is_array($desc) ? ($desc[$lang === 'en' ? 'en' : 'zh-CN'] ?? $desc[0] ?? 'Unknown') : 'Unknown',
|
||||||
|
'humidity' => (int)$current['humidity'] ?? null,
|
||||||
|
'wind_speed' => (float)$current['windspeedKmph'] ?? null,
|
||||||
|
'wind_speed_ms' => (float)$current['windspeedKmph'] / 3.6 ?? null,
|
||||||
|
'wind_direction' => $current['winddir16Point'] ?? null,
|
||||||
|
'pressure' => (int)$current['pressure'] ?? null,
|
||||||
|
'precipitation' => (float)$current['precipMM'] ?? null,
|
||||||
|
'visibility' => (float)$current['visibility'] ?? null,
|
||||||
|
'uv_index' => (int)$current['uvIndex'] ?? null,
|
||||||
|
'cloud_cover' => (int)$current['cloudcover'] ?? null
|
||||||
|
],
|
||||||
|
'source' => 'wttr.in',
|
||||||
'updated_at' => date('Y-m-d H:i:s')
|
'updated_at' => date('Y-m-d H:i:s')
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user