250 lines
9.6 KiB
Vue
250 lines
9.6 KiB
Vue
<template>
|
||
<view class="community-list-container">
|
||
<view class="community-list">
|
||
<view class="community-item-box" v-for="(item, index) in communityList" :key="index">
|
||
<view class="community-item">
|
||
<view class="community-image">
|
||
<image :src="item.pic" mode="aspectFill"></image>
|
||
</view>
|
||
<view class="community-info">
|
||
<view class="community-name">{{ item.name }}</view>
|
||
<view class="community-property">物业公司:{{ item.property || '-' }}</view>
|
||
<view class="community-distance">距我当前:{{ item.distance || '未知' }}</view>
|
||
<view class="community-buttons">
|
||
<view class="community-action-btn" @tap="navigate(item)">
|
||
<uni-icons type="paperplane-filled" size="18"></uni-icons>
|
||
<text class="btn-text">导航</text>
|
||
</view>
|
||
<view class="community-action-btn" @tap="callPhone(item)">
|
||
<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>
|
||
</view>
|
||
<view class="community-address">
|
||
<image id="local"
|
||
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_localIcon.png"
|
||
mode="aspectFill"></image>
|
||
<view class="community-address-text">{{ item.addr }}</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<nav-footer :current="0" />
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
request,
|
||
picUrl,
|
||
uniqueByField,
|
||
menuButtonInfo,
|
||
NavgateTo,
|
||
} from "../../../utils";
|
||
import { apiArr } from "../../../api/community";
|
||
|
||
export default {
|
||
name: 'CommunityList',
|
||
data() {
|
||
return {
|
||
communityList: [], // 用于显示的列表
|
||
allCommunityList: [], // 存储所有数据的列表
|
||
currentPage: 1,
|
||
pageSize: 16,
|
||
hasMoreData: true,
|
||
isLoading: false
|
||
};
|
||
},
|
||
methods: {
|
||
async getCommunityList() {
|
||
// 如果正在加载中,则不再请求
|
||
if (this.isLoading) {
|
||
return;
|
||
}
|
||
|
||
// 显示加载中提示
|
||
uni.showLoading({
|
||
title: '加载中...'
|
||
});
|
||
|
||
this.isLoading = true;
|
||
|
||
try {
|
||
const res = await request(apiArr.getAllList, "POST", {
|
||
page_num: 1,
|
||
page_size: 9999
|
||
});
|
||
|
||
if (res && res.rows) {
|
||
let processedList = res.rows.map(item => {
|
||
// 处理图片路径
|
||
if (item.pic) {
|
||
item.pic = picUrl + item.pic;
|
||
}
|
||
|
||
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 && 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';
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error('计算距离失败:', error);
|
||
}
|
||
|
||
return item;
|
||
});
|
||
|
||
// 根据距离排序
|
||
processedList.sort((a, b) => {
|
||
const distanceA = parseFloat(String(a.distance).trim());
|
||
const distanceB = parseFloat(String(b.distance).trim());
|
||
|
||
// 如果是 NaN,则视为 Infinity
|
||
const valueA = isNaN(distanceA) ? Infinity : distanceA;
|
||
const valueB = isNaN(distanceB) ? Infinity : distanceB;
|
||
|
||
return valueA - valueB;
|
||
});
|
||
|
||
|
||
// 保存所有数据到allCommunityList
|
||
this.allCommunityList = processedList;
|
||
|
||
this.currentPage = 1;
|
||
this.updateDisplayList();
|
||
}
|
||
} catch (error) {
|
||
console.error('获取社区列表失败:', error);
|
||
uni.showToast({
|
||
title: '获取数据失败',
|
||
icon: 'none',
|
||
duration: 1500
|
||
});
|
||
} finally {
|
||
this.isLoading = false;
|
||
// 隐藏加载中提示
|
||
uni.hideLoading();
|
||
}
|
||
},
|
||
|
||
// 更新显示的列表数据
|
||
updateDisplayList() {
|
||
const startIndex = 0;
|
||
const endIndex = this.currentPage * this.pageSize;
|
||
this.communityList = this.allCommunityList.slice(startIndex, endIndex);
|
||
this.hasMoreData = endIndex < this.allCommunityList.length;
|
||
},
|
||
navigate(item) {
|
||
// 实现导航功能
|
||
if (item.lat && item.lng) {
|
||
// 确保经纬度是有效的数字
|
||
const latitude = parseFloat(item.lat);
|
||
const longitude = parseFloat(item.lng);
|
||
|
||
if (!isNaN(latitude) && !isNaN(longitude)) {
|
||
uni.openLocation({
|
||
latitude: latitude,
|
||
longitude: longitude,
|
||
name: item.name || '未知小区',
|
||
address: item.addr || '',
|
||
scale: 18,
|
||
success: () => {
|
||
console.log('打开地图成功:', item.name);
|
||
},
|
||
fail: (error) => {
|
||
console.error('打开地图失败:', error);
|
||
}
|
||
});
|
||
} else {
|
||
uni.showToast({
|
||
title: '位置信息无效',
|
||
icon: 'none',
|
||
duration: 1500
|
||
});
|
||
}
|
||
} else {
|
||
uni.showToast({
|
||
title: '暂无位置信息',
|
||
icon: 'none',
|
||
duration: 1500
|
||
});
|
||
}
|
||
},
|
||
callPhone(item) {
|
||
if (item.property_server_phone) {
|
||
uni.makePhoneCall({
|
||
phoneNumber: item.property_server_phone,
|
||
success: () => {
|
||
},
|
||
fail: (error) => {
|
||
console.error('拨打电话失败:', error);
|
||
}
|
||
});
|
||
} else {
|
||
uni.showToast({
|
||
title: '暂无联系电话',
|
||
icon: 'none',
|
||
duration: 1500
|
||
});
|
||
}
|
||
},
|
||
enterCommunity(item) {
|
||
NavgateTo("/packages/community/index/index?item=" + encodeURIComponent(JSON.stringify(item)));
|
||
},
|
||
// 下拉加载更多
|
||
loadMore() {
|
||
if (this.hasMoreData && !this.isLoading) {
|
||
this.currentPage += 1;
|
||
this.updateDisplayList();
|
||
// if (!this.hasMoreData) {
|
||
// uni.showToast({
|
||
// title: '没有更多了',
|
||
// icon: 'none',
|
||
// duration: 1500
|
||
// });
|
||
// }
|
||
}
|
||
}
|
||
},
|
||
onLoad() {
|
||
this.getCommunityList();
|
||
},
|
||
// 监听页面滚动到底部
|
||
onReachBottom() {
|
||
this.loadMore();
|
||
},
|
||
// 下拉刷新
|
||
onPullDownRefresh() {
|
||
this.currentPage = 1;
|
||
this.hasMoreData = true;
|
||
this.getCommunityList().then(() => {
|
||
uni.stopPullDownRefresh();
|
||
});
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style>
|
||
@import url("./index.css");
|
||
</style> |