You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

501 lines
12 KiB

<template>
<view class="container">
<HeaderCustom title="选择位置" :showBack="true"></HeaderCustom>
<!-- 搜索栏 -->
<view class="search-bar">
<view class="search-input" @click="addNewAddress">
<uv-icon name="search" color="#999" size="16"></uv-icon>
<text class="placeholder">请输入地址</text>
</view>
</view>
<!-- 当前地址 -->
<view class="section">
<view class="section-header">
<uv-icon name="map" color="#AAAAAA" size="18"></uv-icon>
<text class="section-title">当前地址</text>
</view>
<view class="current-location">
<text class="location-name">{{ useUserStore().adressInfo?.adress }}</text>
<view class="relocate-btn" @click="relocate">
<uv-icon name="reload" color="#4080FF" size="16"></uv-icon>
<text class="relocate-text">重新定位</text>
</view>
</view>
</view>
<!-- 我的服务地址 -->
<view class="section">
<view class="section-header">
<uv-icon name="home" color="#AAAAAA" size="18"></uv-icon>
<text class="section-title">我的服务地址</text>
</view>
<view class="address-list">
<view class="address-item" v-for="(item, index) in myAdress" :key="index" @click="selectAddress(item)">
<view class="address-icon">
<uv-icon name="map-fill" color="#CCCCCC" size="20"></uv-icon>
</view>
<view class="address-info">
<view class="address-name">{{ item.name }}</view>
<view class="address-detail">{{ item.address }}</view>
</view>
<div class="delBox" @click.stop="delAdress(item)">删除</div>
<!-- <view class="address-distance">{{ item.distance }}</view> -->
</view>
</view>
<view class="address-item add-address" @click="addNewAddress('add')">
<text class="add-text">新增地址</text>
<uv-icon name="arrow-right" color="#CCCCCC" size="16"></uv-icon>
</view>
</view>
<!-- 附近地址 -->
<!-- <view class="section">
<view class="section-header">
<uv-icon name="map" color="#AAAAAA" size="18"></uv-icon>
<text class="section-title">附近地址</text>
</view>
<view class="address-list">
<view class="address-item" v-for="(item, index) in nearbyAddresses" :key="index"
@click="selectAddress(item)">
<view class="address-icon">
<uv-icon name="map-fill" color="#CCCCCC" size="20"></uv-icon>
</view>
<view class="address-info">
<view class="address-name">{{ item.name }}</view>
<view class="address-detail">{{ item.address }}</view>
</view>
<view class="address-distance">{{ item.distance }}</view>
</view>
</view>
</view> -->
</view>
</template>
<script setup>
import {
ref,
onMounted
} from "vue";
import {
onShow,
onPageScroll
} from "@dcloudio/uni-app";
import {
useUserStore
} from "@/store";
import HeaderCustom from '/components/HeaderCustom/HeaderCustom.vue'
import RPC from "@/utils/request";
// 当前位置
// const currentLocation = ref(useUserStore().adressInfo.address);
// 附近地址列表
const nearbyAddresses = ref([{
"name": "三江半岛",
"address": "四川省绵阳市涪城区滨河北路东段298号",
latitude: 31.45467,
longitude: 104.767,
"distance": '942m'
}, {
"name": "建设街1号院",
"address": "四川省绵阳市涪城区建设街1号",
latitude: 31.454278,
longitude: 104.756637,
"distance": '88m'
}, {
"name": "四川省绵阳第一中学",
"address": "四川省绵阳市涪城区警钟街78号",
latitude: 31.457096,
longitude: 104.758555,
"distance": '174m'
}]);
const myAdress = ref([])
// 重新定位
function relocate() {
uni.showLoading({
title: "定位中...",
});
uni.getLocation({
type: "wgs84",
isHighAccuracy: true,
success: function(res) {
console.log("当前位置的经度:" + res.longitude);
console.log("当前位置的纬度:" + res.latitude);
// 调用腾讯地图API进行逆地址解析
uni.request({
url: `https://apis.map.qq.com/ws/geocoder/v1/`,
method: "GET",
data: {
location: `${res.latitude},${res.longitude}`,
key: "N6LBZ-JLDCT-SQNXQ-LQUWR-6PQX7-TQBQN",
},
success: (res1) => {
uni.hideLoading();
if (res1.data.status === 0) {
const addressComponent = res1.data.result.address_component;
// 更新用户存储的地址信息
useUserStore().setAdressInfo({
latitude: res.latitude,
longitude: res.longitude,
adress: addressComponent.street_number || addressComponent
.street,
});
// 获取附近地址
getNearbyAddresses(res.latitude, res.longitude);
} else {
uni.showToast({
title: "定位失败",
icon: "none",
});
console.error("逆解析失败", res1.data.message);
}
},
fail: (err) => {
uni.hideLoading();
uni.showToast({
title: "网络错误",
icon: "none",
});
console.error("网络错误", err);
},
});
},
fail: function(err) {
uni.hideLoading();
uni.showToast({
title: "定位失败,请检查定位权限",
icon: "none",
});
console.error("定位失败", err);
},
});
}
// 获取附近地址
function getNearbyAddresses(latitude, longitude) {
// 这里可以调用地图API获取附近的地址
console.log("获取附近地址:", latitude, longitude);
// 模拟获取附近地址
// 实际应用中应该调用地图POI搜索API
uni.request({
url: 'https://apis.map.qq.com/ws/place/v1/explore',
method: 'GET',
data: {
key: 'N6LBZ-JLDCT-SQNXQ-LQUWR-6PQX7-TQBQN',
boundary: `nearby(${latitude},${longitude},1000,1)`,
},
success: (res) => {
if (res.data.status === 0) {
const pois = res.data.data
console.log('附近地点列表:', res)
nearbyAddresses.value = res?.data?.data?.map(item => {
return {
name: item.title,
address: item.address,
distance: item._distance + 'm',
latitude: item.location.lat,
longitude: item.location.lng
}
})
// pois 是一个包含附近地点的数组
} else {
console.error('搜索失败', res.data.message)
}
},
fail: (err) => {
console.error('请求失败', err)
}
})
}
// 选择地址
function selectAddress(item) {
// 将选择的地址保存到store
// useUserStore().setAdressInfo({
// adress: address.name,
// addressDetail: address.address,
// // 这里应该有经纬度信息,示例中省略
// });
// console.log(item)
useUserStore().setAdressInfo({
latitude: item.latitude,
longitude: item.longitude,
adress: item.name,
});
// // 返回上一页
uni.navigateBack();
}
const getMyAdress = () => {
RPC.post('/address/list',{limit:-1}).then(res => {
myAdress.value = res.rows || []
})
}
getMyAdress()
const delAdress = item => {
RPC.post('/address/delete',{id:item.id}).then(res => {
uni.showToast({
title:"删除成功"
})
getMyAdress()
})
}
// 添加新地址
function addNewAddress(type) {
uni.chooseLocation({
success: (res) => {
console.log('选择位置成功:', res);
if (type === 'add') {
const params = {
"name": res.name,
"address": res.address,
latitude: res.latitude,
longitude: res.longitude,
}
RPC.post('/address/create',params).then(() => {
getMyAdress()
})
} else {
useUserStore().setAdressInfo({
latitude: res.latitude,
longitude: res.longitude,
adress: res.name,
});
}
},
fail: (err) => {
console.error('选择位置失败:', err);
// 检查是否是因为权限问题
if (err.errMsg.includes('auth deny')) {
uni.showModal({
title: '提示',
content: '需要您授权使用位置信息',
confirmText: '去设置',
success: (res) => {
if (res.confirm) {
uni.openSetting({
success: (settingRes) => {
console.log('设置结果:', settingRes);
}
});
}
}
});
} else {
uni.showToast({
title: '选择位置失败',
icon: 'none'
});
}
}
});
}
// 跳转到搜索页面
function goToSearch() {
uni.navigateTo({
url: "/pagesA/search-address/search-address",
});
}
// 页面加载时获取当前位置
onShow(() => {
const adressInfo = useUserStore().adressInfo;
console.log("onShow adressInfo:", adressInfo);
if (!adressInfo?.adress) {
relocate();
} else {
if (nearbyAddresses.value.length <= 0) {
getNearbyAddresses(adressInfo.latitude, adressInfo.longitude)
}
}
});
</script>
<style lang="scss" scoped>
.container {
font-size: 14px;
min-height: 100vh;
background-color: #f8f8f8;
padding-bottom: 30rpx;
box-sizing: border-box;
}
.search-bar {
background-color: #eeeeee;
padding: 20rpx 30rpx;
display: flex;
align-items: center;
border-radius: 40rpx;
margin: 20rpx;
.city-selector {
display: flex;
align-items: center;
padding-right: 20rpx;
border-right: 1px solid #dddddd;
margin-right: 20rpx;
text {
font-size: 28rpx;
color: #333333;
margin-right: 10rpx;
}
.arrow-down {
width: 0;
height: 0;
border-left: 10rpx solid transparent;
border-right: 10rpx solid transparent;
border-top: 10rpx solid #666666;
}
}
.search-input {
flex: 1;
display: flex;
align-items: center;
.placeholder {
color: #999999;
margin-left: 10rpx;
font-size: 28rpx;
}
}
}
.section {
background-color: #ffffff;
margin-bottom: 20rpx;
.section-header {
display: flex;
align-items: center;
padding: 20rpx 30rpx;
border-bottom: 1px solid #f5f5f5;
.section-title {
color: #999999;
margin-left: 10rpx;
font-size: 28rpx;
}
}
.current-location {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
.location-name {
font-size: 32rpx;
font-weight: bold;
color: #333333;
}
.relocate-btn {
display: flex;
align-items: center;
color: #4080ff;
.relocate-text {
margin-left: 10rpx;
font-size: 28rpx;
}
}
}
.address-item {
display: flex;
align-items: center;
padding: 30rpx;
border-bottom: 1px solid #f5f5f5;
&.add-address {
color: #4080ff;
justify-content: space-between;
.add-text {
font-size: 30rpx;
}
}
.address-icon {
margin-right: 20rpx;
}
.address-info {
flex: 1;
.address-name {
font-size: 30rpx;
color: #333333;
margin-bottom: 10rpx;
}
.address-detail {
font-size: 26rpx;
color: #999999;
}
}
.delBox {
color: #f12323;
font-size: 26rpx;
}
.address-distance {
color: #999999;
font-size: 26rpx;
}
}
}
.city-picker {
background-color: #ffffff;
border-radius: 20rpx 20rpx 0 0;
padding-bottom: 30rpx;
.city-picker-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-bottom: 1px solid #f5f5f5;
text {
font-size: 32rpx;
font-weight: bold;
}
}
.city-list {
padding: 20rpx;
display: flex;
flex-wrap: wrap;
.city-item {
width: 25%;
text-align: center;
padding: 20rpx 0;
font-size: 28rpx;
}
}
}
</style>