model = new SysArea(); } /** * 获取地区信息 * @param int $pid //上级pid * @return mixed * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function getListByPid(int $pid = 0) { $cache_name = self::$cache_tag_name . '_api_pid_' . $pid; return cache_remember( $cache_name, function() use ($pid) { return $this->model->where([ [ 'pid', '=', $pid ] ])->field('id, name')->select()->toArray(); }, [ self::$cache_tag_name ] ); } /** * 查询地区树列表 * @param int $level //层级1,2,3 * @return mixed * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function getAreaTree(int $level = 3) { $cache_name = self::$cache_tag_name . '_api_tree_' . $level; return cache_remember( $cache_name, function() use ($level) { $list = $this->model->where([ [ 'level', '<=', $level ] ])->field('id, pid, name')->select()->toArray(); return list_to_tree($list); }, [ self::$cache_tag_name ] ); } public function getAreaByAreaCode($id) { $cache_name = self::$cache_tag_name . '_api_area_' . $id; return cache_remember( $cache_name, function() use ($id) { $level = [ 1 => 'province', 2 => 'city', 3 => 'district' ]; $tree = []; $area = $this->model->where([ [ 'id', '=', $id ] ])->field('id,level,pid,name')->findOrEmpty(); if (!$area->isEmpty()) { $tree[ $level[ $area[ 'level' ] ] ] = $area->toArray(); while ($area[ 'level' ] > 1) { $area = $this->model->where([ [ 'id', '=', $area[ 'pid' ] ] ])->field('id,level,pid,name')->findOrEmpty(); $tree[ $level[ $area[ 'level' ] ] ] = $area->toArray(); } } return $tree; }, [ self::$cache_tag_name ] ); } /** * 通过经纬度查询地址 * @param $params * @return array */ public function getAddressByLatlng($params) { $map = ( new ConfigService() )->getMap(); $map_type = $map['map_type'] ?? 'tianditu'; if ($map_type == 'tencent') { $map_service = new \app\service\core\map\CoreQqMap(); $res = $map_service->locationToDetail(['location' => $params['latlng']]); } else { $map_service = new \app\service\core\map\CoreTiandituMap(); $loc_arr = explode(',', $params['latlng']); $lat = $loc_arr[0] ?? ''; $lon = $loc_arr[1] ?? ''; $res = $map_service->locationToDetail(['lat' => $lat, 'lon' => $lon]); } if (is_string($res)) { $res = json_decode($res, true); } if ($res) { if ($res[ 'status' ] == 0) { $return_array = $res[ 'result' ][ 'address_component' ] ?? []; // 地址部件,address不满足需求时可自行拼接 $address_reference = $res[ 'result' ][ 'address_reference' ] ?? []; $address = $return_array[ 'street_number' ] ?? ''; // 门牌,可能为空字串 if (empty($address)) { $address = $return_array[ 'street' ] ?? ''; // 道路,可能为空字串 } $town = $address_reference[ 'town' ] ?? []; $landmark_l1 = $address_reference[ 'landmark_l1' ] ?? []; $landmark_l2 = $address_reference[ 'landmark_l2' ] ?? []; $community = ''; if (!empty($landmark_l2[ 'title' ])) { $community = $landmark_l2[ 'title' ]; // 二级地标,较一级地标更为精确,规模更小 } elseif (!empty($landmark_l1[ 'title' ])) { $community = $landmark_l1[ 'title' ]; // 一级地标,可识别性较强、规模较大的地点、小区等 } elseif (!empty($town[ 'title' ])) { $community = $town[ 'title' ]; // 乡镇/街道(四级行政区划) } $address_data = array( 'province' => $return_array[ 'province' ] ?? '', // 省 'city' => $return_array[ 'city' ] ?? '', // 市 'district' => $return_array[ 'district' ] ?? '', // 区 'community' => $community, 'address' => $address, 'full_address' => $res[ 'result' ][ 'address' ] ?? '', 'formatted_addresses' => $res[ 'result' ][ 'formatted_addresses' ] ?? [] ); $province = ''; if ($address_data[ 'province' ]) { $province = str_replace('省', '', $address_data[ 'province' ]); $province = str_replace('市', '', $province); } $city = $address_data[ 'city' ] ?? ''; $district = $address_data[ 'district' ] ?? ''; $province_info = $this->model->where([ [ 'name', 'like', '%' . $province . '%' ], [ 'level', '=', 1 ] ])->field('id,name')->select()->toArray()[ 0 ] ?? []; $province_id = 0; $province_name = $address_data[ 'province' ]; $city_id = 0; $city_name = $address_data[ 'city' ]; $district_id = 0; $district_name = $address_data[ 'district' ]; if (!empty($province_info)) { $province_id = $province_info[ 'id' ]; $province_name = $province_info[ 'name' ]; } if ($province_id > 0) { $city_info = $this->model->where([ [ 'name', 'like', '%' . $city . '%' ], [ 'level', '=', 2 ], [ 'pid', '=', $province_id ] ])->field('id,name')->select()->toArray()[ 0 ] ?? []; if (!empty($city_info)) { $city_id = $city_info[ 'id' ]; $city_name = $city_info[ 'name' ]; } } if ($city_id > 0 && $province_id > 0) { $district_info = $this->model->where([ [ 'name', 'like', '%' . $district . '%' ], [ 'level', '=', 3 ], [ 'pid', '=', $city_id ] ])->field('id,name')->select()->toArray()[ 0 ] ?? []; if (!empty($district_info)) { $district_id = $district_info[ 'id' ]; $district_name = $district_info[ 'name' ]; } } return [ 'province_id' => $province_id, 'province' => $province_name, 'city_id' => $city_id, 'city' => $city_name, 'district_id' => $district_id, 'district' => $district_name, 'community' => $address_data[ 'community' ], 'full_address' => $address_data[ 'full_address' ], 'formatted_addresses' => $address_data[ 'formatted_addresses' ] ]; } else { throw new ApiException('请检查地图配置:'.$res[ 'message' ]); } } else { throw new ApiException('地图接口请求失败'); } } }