Files
oil/mobile-uniapp/pages/station/index.vue
T
2026-09-01 22:15:50 +08:00

384 lines
9.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>