has($cacheKey)) { return Cache::store('redis')->get($cacheKey); } //查询市级名称 $data = Db::name('dev_region') ->order('id', 'asc') ->field('id,parent_id,name') ->where('level',1) ->select(); if ($data) { Cache::store('redis')->set($cacheKey, $data); } return $data; } /** * 根据经纬度获取所在城市 * @param float $lat 纬度 * @param float $lng 经度 * @return array */ public function getCityByLocation($lat, $lng) { // 参数验证 if (empty($lat) || empty($lng)) { return [ 'success' => false, 'msg' => '经纬度参数不能为空', 'data' => null ]; } // 验证经纬度范围 if (!is_numeric($lat) || !is_numeric($lng)) { return [ 'success' => false, 'msg' => '经纬度格式错误', 'data' => null ]; } $lat = floatval($lat); $lng = floatval($lng); if ($lat < -90 || $lat > 90 || $lng < -180 || $lng > 180) { return [ 'success' => false, 'msg' => '经纬度范围错误', 'data' => null ]; } // 生成缓存key $cacheKey = 'city_location_' . md5($lat . '_' . $lng); // 尝试从缓存获取 if (Cache::store('redis')->has($cacheKey)) { $cachedData = Cache::store('redis')->get($cacheKey); return [ 'success' => true, 'msg' => '获取成功', 'data' => $cachedData ]; } // 调用腾讯地图逆地理编码API $apiUrl = 'https://apis.map.qq.com/ws/geocoder/v1/'; $params = [ 'location' => $lat . ',' . $lng, 'key' => $this->tencentMapKey, 'get_poi' => 0 ]; $url = $apiUrl . '?' . http_build_query($params); // 使用curl请求 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $error = curl_error($ch); curl_close($ch); if ($error) { return [ 'success' => false, 'msg' => '请求失败:' . $error, 'data' => null ]; } if ($httpCode !== 200) { return [ 'success' => false, 'msg' => 'API请求失败,HTTP状态码:' . $httpCode, 'data' => null ]; } $result = json_decode($response, true); if (empty($result) || $result['status'] !== 0) { return [ 'success' => false, 'msg' => isset($result['message']) ? $result['message'] : '获取城市信息失败', 'data' => null ]; } // 解析返回数据 $addressComponent = $result['result']['address_component'] ?? []; $cityName = $addressComponent['city'] ?? ''; $provinceName = $addressComponent['province'] ?? ''; $districtName = $addressComponent['district'] ?? ''; $adcode = $addressComponent['adcode'] ?? ''; // 如果城市名称为空,尝试使用区县名称 if (empty($cityName) && !empty($districtName)) { $cityName = $districtName; } // 查询数据库中的城市ID $cityId = null; $cityInfo = null; if (!empty($cityName)) { // 先尝试精确匹配 $cityInfo = Db::name('dev_region') ->where('name', $cityName) ->where('level', 2) // 市级 ->find(); // 如果精确匹配失败,尝试模糊匹配 if (empty($cityInfo)) { $cityInfo = Db::name('dev_region') ->where('name', 'like', '%' . $cityName . '%') ->where('level', 2) ->find(); } if ($cityInfo) { $cityId = $cityInfo['id']; } } $data = [ 'city_name' => $cityName, 'province_name' => $provinceName, 'district_name' => $districtName, 'adcode' => $adcode, 'city_id' => $cityId, 'city_info' => $cityInfo, 'formatted_address' => $result['result']['formatted_addresses']['recommend'] ?? '', 'location' => [ 'lat' => $lat, 'lng' => $lng ] ]; // 缓存结果(缓存1小时) Cache::store('redis')->set($cacheKey, $data, 3600); return [ 'success' => true, 'msg' => '获取成功', 'data' => $data ]; } }