384 lines
9.8 KiB
Vue
384 lines
9.8 KiB
Vue
<template>
|
||
<view class="container">
|
||
<!-- 地图显示 -->
|
||
<map
|
||
id="map"
|
||
:latitude="userLocation.latitude"
|
||
:longitude="userLocation.longitude"
|
||
:markers="markers"
|
||
show-location
|
||
:scale="scale"
|
||
style="width: 100%; height: 100vh;"
|
||
@markertap="onMarkerTap">
|
||
<cover-image class="img-map1" src="/static/center.png"></cover-image>
|
||
<cover-image class="img-map2" src="/static/locate.png" @click="clickcontrol"></cover-image>
|
||
</map>
|
||
|
||
<!-- 加油站列表 -->
|
||
<view class="station-list">
|
||
<view class="station-item" v-if="now.id != undefined">
|
||
<view class="station-info">
|
||
<text class="station-name">{{ now.name }}</text>
|
||
<view>
|
||
<text class="station-distance">距您 {{ now.distance }}km</text>
|
||
<text class="station-addres">{{ now.address }}</text>
|
||
</view>
|
||
<view class="station-oil">
|
||
<text>0#</text>
|
||
<text>92#</text>
|
||
<text>95#</text>
|
||
</view>
|
||
<view class="station-time-info">
|
||
<view class="time-info-time">00:00-23:59 营业</view>
|
||
<view class="time-info-plan">
|
||
<text>便利点</text>
|
||
<text>卫生间</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="station-action">
|
||
<button class="navigate-button" @click="navigate()">导航加油站</button>
|
||
<button class="navigate-button" @click="oil()">去购券</button>
|
||
</view>
|
||
</view>
|
||
<view class="station-item" v-else>
|
||
<view class="station-info">
|
||
<text class="station-name">您所在的城市,暂无可用加油站</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
|
||
import * as StationApi from '@/api/station'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
userLocation: {
|
||
latitude: 0,
|
||
longitude: 0
|
||
},
|
||
markers: [
|
||
],
|
||
scale: 13,
|
||
now: {}
|
||
};
|
||
},
|
||
mounted() {
|
||
this.getUserLocation();
|
||
},
|
||
methods: {
|
||
// 获取用户当前的位置
|
||
getUserLocation() {
|
||
// let latitude = '25.068413'
|
||
// let longitude = '118.522990'
|
||
// this.userLocation.latitude = latitude;
|
||
// this.userLocation.longitude = longitude;
|
||
// // 存储经纬度到缓存中
|
||
// uni.setStorageSync('latitude', latitude)
|
||
// uni.setStorageSync('longitude', longitude)
|
||
|
||
// uni.setStorageSync('province', '福建省')
|
||
// uni.setStorageSync('city', '泉州市')
|
||
// uni.setStorageSync('district', '南安市')
|
||
// this.mapapiStation()
|
||
let app = this
|
||
// 获取经纬度
|
||
uni.authorize({
|
||
scope: 'scope.userLocation',
|
||
success() {
|
||
uni.getLocation({
|
||
type: 'wgs84',
|
||
success: (res) => {
|
||
app.userLocation.latitude = res.latitude;
|
||
app.userLocation.longitude = res.longitude;
|
||
// 存储经纬度到缓存中
|
||
uni.setStorageSync('latitude', res.latitude)
|
||
uni.setStorageSync('longitude', res.longitude)
|
||
|
||
app.getRegion(res.latitude, res.longitude).then(region => {
|
||
uni.setStorageSync('province', region.province)
|
||
uni.setStorageSync('city', region.city)
|
||
uni.setStorageSync('district', region.district)
|
||
app.mapapiStation(res.latitude, res.longitude)
|
||
}).catch(err => {
|
||
console.error('获取区域信息失败:', err);
|
||
});
|
||
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取位置失败', err);
|
||
}
|
||
});
|
||
},
|
||
fail: (err) => {
|
||
console.error('授权失败', err);
|
||
}
|
||
});
|
||
},
|
||
// 获取加油站点
|
||
mapapiStation(latitude, longitude) {
|
||
let app = this
|
||
let key = '67NBZ-MHUH4-ODCU2-KNPZW-3OGJF-ARBRQ';
|
||
let url = `https://apis.map.qq.com/ws/place/v1/search?key=${key}&keyword=中国石油&boundary=nearby(${latitude},${longitude},1000)&page_size=20`;
|
||
return new Promise((resolve, reject) => {
|
||
uni.request({
|
||
url: url,
|
||
method: 'GET',
|
||
success: (res) => {
|
||
var markers = [] //地图markers标记点
|
||
var arr = res.data.data
|
||
for (var i = 0; i < arr.length; i++) {
|
||
markers.push({
|
||
iconPath: "/static/marker.png",
|
||
id: i,
|
||
name: arr[i].title,
|
||
latitude: arr[i].location.lat,
|
||
longitude: arr[i].location.lng,
|
||
address: arr[i].address,
|
||
distance: (arr[i]._distance/1000).toFixed(2),
|
||
width: 32,
|
||
height: 32
|
||
})
|
||
}
|
||
app.markers = markers
|
||
app.now = markers[0]
|
||
resolve(markers)
|
||
},
|
||
fail: (err) => {
|
||
console.error('请求失败:', err);
|
||
reject(err); // 请求失败处理
|
||
}
|
||
});
|
||
});
|
||
},
|
||
// 逆你解析地址
|
||
getRegion(latitude, longitude) {
|
||
let key = '67NBZ-MHUH4-ODCU2-KNPZW-3OGJF-ARBRQ'; // ETFBZ-F4XCW-YOQRI-RWBQM-BAZIQ-2VFS5
|
||
let url = `https://apis.map.qq.com/ws/geocoder/v1/?location=${latitude},${longitude}&key=${key}`;
|
||
return new Promise((resolve, reject) => {
|
||
uni.request({
|
||
url: url,
|
||
method: 'GET',
|
||
success: (res) => {
|
||
let data = res.data;
|
||
if (data.status === 0) { // 腾讯地图API通常使用0表示成功
|
||
let address = data.result.address; // 完整地址
|
||
let province = data.result.address_component.province; // 省
|
||
let city = data.result.address_component.city; // 市
|
||
let district = data.result.address_component.district; // 区/县
|
||
|
||
let region = {
|
||
address: address,
|
||
province: province,
|
||
city: city,
|
||
district: district,
|
||
};
|
||
resolve(region); // 成功时返回region对象
|
||
} else {
|
||
console.error('逆地理编码失败:', data.message);
|
||
reject(data.message); // 处理失败情况
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('请求失败:', err);
|
||
reject(err); // 请求失败处理
|
||
}
|
||
});
|
||
});
|
||
},
|
||
// 获取站点列表
|
||
getStationList(pageNo = 1) {
|
||
const app = this
|
||
return new Promise((resolve, reject) => {
|
||
StationApi.list({ page: pageNo })
|
||
.then(result => {
|
||
const newList = result.data.list
|
||
app.markers = newList
|
||
app.getRegion(newList[0].latitude, newList[0].longitude).then(region => {
|
||
newList[0].address = region.address
|
||
}).catch(err => {
|
||
console.error('获取区域信息失败:', err);
|
||
});
|
||
app.now = newList[0]
|
||
resolve(newList)
|
||
})
|
||
})
|
||
},
|
||
// 更新每个标记点与用户位置之间的距离
|
||
updateDistances() {
|
||
this.markers = this.markers.map(marker => {
|
||
marker.distance = this.calculateDistance(
|
||
this.userLocation.latitude,
|
||
this.userLocation.longitude,
|
||
marker.latitude,
|
||
marker.longitude
|
||
);
|
||
return marker;
|
||
});
|
||
},
|
||
// 计算两点之间的距离
|
||
calculateDistance(lat1, lon1, lat2, lon2) {
|
||
const radLat1 = this.rad(lat1);
|
||
const radLat2 = this.rad(lat2);
|
||
const a = radLat1 - radLat2;
|
||
const b = this.rad(lon1) - this.rad(lon2);
|
||
let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
|
||
Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
|
||
s = s * 6378.137; // 地球半径(单位:公里)
|
||
s = Math.round(s * 10000) / 10000;
|
||
return s.toFixed(2);
|
||
},
|
||
rad(d) {
|
||
return d * Math.PI / 180.0;
|
||
},
|
||
// 标记点点击事件处理
|
||
onMarkerTap(event) {
|
||
const markerId = event.detail.markerId;
|
||
const marker = this.markers.find(m => m.id === markerId);
|
||
if (marker) {
|
||
// this.getRegion(marker.latitude, marker.longitude).then(region => {
|
||
// marker.address = region.address
|
||
// }).catch(err => {
|
||
// console.error('获取区域信息失败:', err);
|
||
// });
|
||
this.now = marker;
|
||
}
|
||
},
|
||
//右下角定位按钮的点击事件
|
||
clickcontrol(){
|
||
uni.createMapContext("map", this).moveToLocation({ //moveToLocation将地图中心移动到当前定位点,需要配合map组件的show-location使用
|
||
latitude: this.userLocation.latitude,
|
||
longitude: this.userLocation.longitude
|
||
});
|
||
},
|
||
// 导航到标记点
|
||
navigate() {
|
||
uni.openLocation({
|
||
latitude: Number(this.now.latitude),
|
||
longitude: Number(this.now.longitude),
|
||
name: this.now.name,
|
||
address: this.now.address,
|
||
scale: 18
|
||
});
|
||
},
|
||
// 跳转商品详情页
|
||
oil() {
|
||
this.$navTo('pages/goods/list?location=1')
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style>
|
||
.container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
}
|
||
|
||
.station-list {
|
||
width: 100%;
|
||
padding: 20rpx;
|
||
position: fixed;
|
||
bottom: 80rpx;
|
||
height: 300rpx;
|
||
}
|
||
|
||
.station-item {
|
||
padding: 20rpx;
|
||
background-color: #fff;
|
||
margin-bottom: 10rpx;
|
||
border-radius: 12rpx;
|
||
box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1);
|
||
height: 350rpx;
|
||
}
|
||
|
||
.station-info {
|
||
height: 250rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 10rpx;
|
||
}
|
||
|
||
.station-name {
|
||
font-size: 35rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
.station-distance {
|
||
font-size: 26rpx;
|
||
margin-top: 4rpx;
|
||
margin-right: 25rpx;
|
||
}
|
||
|
||
.station-oil {
|
||
display: flex;
|
||
gap: 12rpx;
|
||
}
|
||
.station-oil text{
|
||
background-color: #5983b1;
|
||
color: aliceblue;
|
||
padding: 4rpx 8rpx;
|
||
font-size: 12px;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.station-time-info{
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 20rpx;
|
||
}
|
||
.station-time-info .time-info-time {
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
}
|
||
.station-time-info .time-info-plan {
|
||
font-size: 24rpx;
|
||
display: flex;
|
||
gap: 10rpx;
|
||
}
|
||
.station-time-info .time-info-plan text{
|
||
padding: 4rpx;
|
||
border: 1rpx solid #007aff;
|
||
color: #007aff;
|
||
border-radius: 8rpx;
|
||
}
|
||
.navigate-button {
|
||
padding: 4rpx 14rpx;
|
||
background-color: #007aff;
|
||
color: #fff;
|
||
border: none;
|
||
border-radius: 4rpx;
|
||
font-size: 22rpx;
|
||
width: 150rpx;
|
||
}
|
||
|
||
.navigate-button:active {
|
||
background-color: #005bb5;
|
||
}
|
||
.station-action{
|
||
display: flex;
|
||
}
|
||
.img-map1{
|
||
width: 60rpx;
|
||
height: 60rpx;
|
||
position: fixed;
|
||
bottom: 47%;
|
||
left: 46%;
|
||
}
|
||
.img-map2{
|
||
width: 60rpx;
|
||
height: 60rpx;
|
||
position: fixed;
|
||
bottom: 30vh;
|
||
right: 2vh;
|
||
background-color: #FFFFFF;
|
||
border-radius: 5px;
|
||
}
|
||
</style>
|