修改湖畔社区页面的数据展示逻辑
This commit is contained in:
parent
9bffd147ba
commit
4d6e41ed1c
@ -4,7 +4,9 @@
|
||||
<view class="community-item-box" v-for="(item, index) in communityList" :key="index">
|
||||
<view class="community-item">
|
||||
<view class="community-image" @tap="enterCommunity(item)">
|
||||
<image :src="item.pic" mode="aspectFill"></image>
|
||||
<!-- 使用默认图片作为 fallback -->
|
||||
<image :src="item.pic || defaultCommunityImage" mode="aspectFill"
|
||||
@error="handleImageError(item)"></image>
|
||||
</view>
|
||||
<view class="community-info">
|
||||
<view class="community-name" @tap="enterCommunity(item)">{{ item.name }}</view>
|
||||
@ -15,12 +17,12 @@
|
||||
<uni-icons type="paperplane-filled" size="18"></uni-icons>
|
||||
<text class="btn-text">导航</text>
|
||||
</view>
|
||||
<view class="community-action-btn" @tap="callPhone(item)">
|
||||
<view class="community-action-btn" @tap="callPhone(item)" v-if="item.property_server_phone">
|
||||
<uni-icons type="phone-filled" size="18"></uni-icons>
|
||||
<view class="btn-text">电话</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="enter-btn" @tap="enterCommunity(item)">进入小区</view>
|
||||
<view v-if="item.is_me" class="enter-btn" @tap="enterCommunity(item)">进入小区</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="community-address">
|
||||
@ -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 {
|
||||
|
||||
<style>
|
||||
@import url("./index.css");
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user