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
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> |