From 4d6e41ed1c91e33f6425bbe66a0357ba5785f9bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E6=AF=85?= <1335909236@qq.com> Date: Wed, 17 Sep 2025 15:46:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B9=96=E7=95=94=E7=A4=BE?= =?UTF-8?q?=E5=8C=BA=E9=A1=B5=E9=9D=A2=E7=9A=84=E6=95=B0=E6=8D=AE=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/community/list/index.vue | 219 ++++++++++++++++++++++++------ 1 file changed, 175 insertions(+), 44 deletions(-) diff --git a/packages/community/list/index.vue b/packages/community/list/index.vue index 18046fcc..c1c81a83 100644 --- a/packages/community/list/index.vue +++ b/packages/community/list/index.vue @@ -4,7 +4,9 @@ - + + {{ item.name }} @@ -15,12 +17,12 @@ 导航 - + 电话 - 进入小区 + 进入小区 @@ -42,6 +44,7 @@ import { uniqueByField, menuButtonInfo, NavgateTo, + calculateDistance } from "../../../utils"; import { apiArr } from "../../../api/community"; @@ -54,7 +57,9 @@ export default { currentPage: 1, pageSize: 16, hasMoreData: true, - isLoading: false + isLoading: false, + tencentMapKey: '55NBZ-MUQYW-EAJRL-YIWPA-ZXCR6-4NBPP', // 腾讯地图API Key + defaultCommunityImage: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/community_no_image3.png' // 默认小区图片 }; }, methods: { @@ -72,12 +77,23 @@ export default { this.isLoading = true; try { + // 获取用户当前位置 + const locationData = await this.getUserLocation(); + if (!locationData) { + throw new Error('无法获取用户位置'); + } + + const userLat = parseFloat(locationData.lat); + const userLng = parseFloat(locationData.lng); + + // 获取现有小区列表 const res = await request(apiArr.getAllList, "POST", { page_num: 1, page_size: 9999 }); if (res && res.rows) { + // 处理现有数据,只保留距离1km以内的小区 let processedList = res.rows.map(item => { // 处理图片路径 if (item.pic) { @@ -85,51 +101,80 @@ export default { } try { - let locationData = uni.getStorageSync('location'); - if (locationData) { - // 确保locationData是对象而不是字符串 - const location = typeof locationData === 'string' ? JSON.parse(locationData) : locationData; - const userLat = parseFloat(location.lat) || 0; - const userLng = parseFloat(location.lng) || 0; - const parkLat = parseFloat(item.lat) || 0; - const parkLng = parseFloat(item.lng) || 0; + // 只有当经纬度都有效时才计算距离 + if (userLat && userLng && item.lat && item.lng) { + const parkLat = parseFloat(item.lat); + const parkLng = parseFloat(item.lng); - // 只有当经纬度都有效时才计算距离 - if (userLat && userLng && parkLat && parkLng) { - // 使用Haversine公式计算距离(单位:千米) - const R = 6371; // 地球半径(千米) - const dLat = (parkLat - userLat) * Math.PI / 180; - const dLng = (parkLng - userLng) * Math.PI / 180; - const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + - Math.cos(userLat * Math.PI / 180) * Math.cos(parkLat * Math.PI / 180) * - Math.sin(dLng / 2) * Math.sin(dLng / 2); - const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - const distance = (R * c).toFixed(2); - item.distance = distance + 'km'; - } + // 使用Haversine公式计算距离(单位:千米) + const distance = calculateDistance(userLat, userLng, parkLat, parkLng); + item.distance = distance.toFixed(2) + 'km'; + item.distanceValue = distance; // 保存数值型距离用于排序 } } catch (error) { console.error('计算距离失败:', error); + item.distanceValue = Infinity; } return item; }); + // 过滤出距离1km以内的数据 + processedList = processedList.filter(item => + item.distanceValue && item.distanceValue <= 1 + ); + + // 调用腾讯地图API获取附近1km的小区(包含图片信息) + const nearbyCommunities = await this.getNearbyCommunities(userLat, userLng); + + // 合并现有数据和腾讯地图API返回的数据 + let mergedList = [...processedList]; + + if (nearbyCommunities && nearbyCommunities.length > 0) { + // 处理腾讯地图返回的数据,提取图片信息 + const tencentCommunities = nearbyCommunities.map(item => { + // 计算距离 + const distance = calculateDistance(userLat, userLng, item.lat, item.lng); + + // 提取图片(腾讯地图POI可能包含多张图片) + let communityImage = ''; + if (item.photos && item.photos.length > 0) { + // 取第一张图片 + communityImage = item.photos[0].url; + } + + return { + name: item.title, + addr: item.address, + lat: item.lat, + lng: item.lng, + distance: distance.toFixed(2) + 'km', + distanceValue: distance, + // 补充其他必要字段 + pic: communityImage || this.defaultCommunityImage, // 使用腾讯地图图片或默认图片 + property: item.extension && item.extension.property_company ? item.extension.property_company : '-', + property_server_phone: item.tel || '', + community_id: `tencent_${item.id}` // 为腾讯地图数据设置唯一ID + }; + }); + + // 合并数据 + mergedList = [...processedList, ...tencentCommunities]; + + // 根据community_id去重 + mergedList = uniqueByField(mergedList, 'community_id'); + } + // 根据距离排序 - processedList.sort((a, b) => { - const distanceA = parseFloat(String(a.distance).trim()); - const distanceB = parseFloat(String(b.distance).trim()); + mergedList.sort((a, b) => { + const distanceA = a.distanceValue || Infinity; + const distanceB = b.distanceValue || Infinity; - // 如果是 NaN,则视为 Infinity - const valueA = isNaN(distanceA) ? Infinity : distanceA; - const valueB = isNaN(distanceB) ? Infinity : distanceB; - - return valueA - valueB; + return distanceA - distanceB; }); - // 保存所有数据到allCommunityList - this.allCommunityList = processedList; + this.allCommunityList = mergedList; this.currentPage = 1; this.updateDisplayList(); @@ -148,6 +193,100 @@ export default { } }, + // 获取用户当前位置 + getUserLocation() { + return new Promise((resolve, reject) => { + try { + let locationData = uni.getStorageSync('location'); + if (locationData) { + // 确保locationData是对象而不是字符串 + const location = typeof locationData === 'string' ? JSON.parse(locationData) : locationData; + if (location.lat && location.lng) { + resolve(location); + return; + } + } + } catch (error) { + console.error('从缓存获取位置失败:', error); + } + + // 如果缓存中没有有效位置,则请求新的位置 + uni.getLocation({ + type: 'gcj02', + altitude: true, + success: (res) => { + const location = { + lat: res.latitude, + lng: res.longitude + }; + // 保存到缓存 + uni.setStorageSync('location', location); + resolve(location); + }, + fail: (err) => { + console.error('获取位置失败:', err); + reject(err); + } + }); + }); + }, + + // 调用腾讯地图API获取附近1km的小区(包含图片信息) + async getNearbyCommunities(lat, lng) { + try { + const keyword = '小区'; + const radius = 1000; // 1km范围 + const pageSize = 20; + + // 使用uni.request调用腾讯地图API,增加extensions=all参数获取更多信息 + return new Promise((resolve, reject) => { + uni.request({ + url: 'https://apis.map.qq.com/ws/place/v1/search', + method: 'GET', + data: { + keyword: keyword, + boundary: `nearby(${lat},${lng},${radius})`, + key: this.tencentMapKey, + page_size: pageSize, + extensions: 'all' // 获取详细信息,包括图片 + }, + success: (res) => { + if (res.statusCode === 200 && res.data.status === 0) { + // 提取需要的数据,包括图片信息 + const results = res.data.data.map(item => ({ + id: item.id, + title: item.title, + address: item.address, + lat: item.location.lat, + lng: item.location.lng, + tel: item.tel || '', + photos: item.photos || [], // 提取图片数组 + extension: item.extension || {}, // 提取扩展信息,可能包含物业公司 + is_me: false + })); + resolve(results); + } else { + console.error('腾讯地图API请求失败:', res.data); + resolve([]); + } + }, + fail: (err) => { + console.error('腾讯地图API请求错误:', err); + resolve([]); + } + }); + }); + } catch (error) { + console.error('获取附近小区失败:', error); + return []; + } + }, + + // 图片加载失败时使用默认图片 + handleImageError(item) { + item.pic = this.defaultCommunityImage; + }, + // 更新显示的列表数据 updateDisplayList() { const startIndex = 0; @@ -198,7 +337,6 @@ export default { success: () => { }, fail: (error) => { - console.error('拨打电话失败:', error); } }); } else { @@ -223,13 +361,6 @@ export default { if (this.hasMoreData && !this.isLoading) { this.currentPage += 1; this.updateDisplayList(); - // if (!this.hasMoreData) { - // uni.showToast({ - // title: '没有更多了', - // icon: 'none', - // duration: 1500 - // }); - // } } } }, @@ -253,4 +384,4 @@ export default { \ No newline at end of file +