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.

502 lines
12 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="section">
<!-- <view class="cu-bar search bg-white searchIn">
<view class="search-form round"><text class="cuIcon-search"></text>
<input type="text" placeholder="搜索目的地" confirm-type="search" @input="inputSearch"
v-model="stationName" />
</view>
</view> -->
<view class="map">
<map style="width: 100%; height:100%; z-index: 0;" show-location='true' ref="map" id="map"
:latitude="latitude" :longitude="longitude" :markers="marker.markers" :scale="scale"
@markertap="callouttap" @callouttap='callouttap'>
<!-- <view class="" v-if="showSearch">
<scroll-view scroll-y="true" class="scrollView">
<view class="cu-bar bg-white solid-bottom" v-for="item in searchData.searchList" :key="item.id"
@click="goMap(item)">
<view class="action text-lg">{{item.stationName}}</view>
<view class="action text-df text-gray">{{item.distance}}km</view>
</view>
</scroll-view>
</view> -->
</map>
<view class="goToast" v-if="showToast">
<view class=" cu-card bg-white margin-sm card-border">
<view class="cu-item shadow">
<view class="flex padding-tb-sm">
<view class="flex">
<view class="titleState">营业中</view>
</view>
<view class="name">{{searchStationName}}</view>
</view>
<view class="flex padding-tb-sm justify-between">
<view class="flex">
<view class="lg text-gray cuIcon-location"></view>
<view class="titleFont text-df text-gray">{{searchAreaName}}</view>
</view>
<view class="searchDistance text-df">{{searchDistance.toFixed(2)}}km</view>
</view>
<view class="flex padding-tb-xs justify-center">
<view class="flex">
<view class="goDetail" @click="goDetail">查询详情</view>
</view>
</view>
</view>
</view>
</view>
</view>
<uv-notify ref="errornotify" message="当前无操作权限,请审核通过后再试" type="error"></uv-notify>
<uv-popup ref="bottom_popup" round="30" :overlay="false">
<view style="position: relative;">
<view class="line_tops" @click="handle_close_popup"></view>
<view class="position_right_tops" @click.stop="goMap_address(address.longitude,address.latitude)">
<uv-icon name="arrow-up-fill" size="21" color="#fff"></uv-icon>
<view class="" style="font-size: 12px;">
导航
</view>
</view>
<view style="padding: 0 20rpx;">
<view class="cu-item shadow">
<view class="flex padding-tb-sm">
<view class="flex">
<view class="titleState">营业中</view>
</view>
<view class="name">{{searchStationName}}</view>
</view>
<view class="flex padding-tb-sm justify-between">
<view class="flex">
<view class="lg text-gray cuIcon-location"></view>
<view class="titleFont text-df text-gray">{{searchAreaName}}</view>
</view>
<view class="searchDistance text-df">
{{searchDistance == null? '--': searchDistance.toFixed(2) }}km
</view>
</view>
<view class="flex padding-tb-xs justify-center">
<view class="flex">
<view class="goDetail" @click="goDetail"></view>
</view>
</view>
</view>
</view>
</view>
</uv-popup>
</view>
</template>
<script setup>
import config from '@/common/config/config.js';
import piniaPro from '@/stores/piniaPro.js';
import {
globalStore
} from "@/stores/globalData.js";
const globalData = globalStore(piniaPro);
import {
reactive,
ref,
} from "vue";
import {
onLoad,
onShow,
} from "@dcloudio/uni-app";
let id = ref(0) // 使用 marker点击事件 需要填写id
let latitude = ref()
let longitude = ref()
let scale = ref(12)
let marker = reactive({
markers: []
})
const popup_mean = ref(null)
const bottom_popup = ref(false)
const bdlongitude = ref()
const bdlatitude = ref()
const stationName = ref()
const searchData = reactive({
searchList: []
})
const showSearch = ref(false)
const showToast = ref(false)
const searchStationName = ref()
const searchAreaName = ref()
const searchDistance = ref(null)
const showPoints = reactive({
pointList: []
})
const searchNo = ref()
const searchID = ref()
const pointsList = ref()
const realNameAuthFlag = reactive(uni.getStorageSync("realNameAuthFlag"))
const errornotify = ref(null)
const address = ref({
longitude: null,
latitude: null,
stationName: null,
stationLocation: null,
})
onLoad(() => {
})
onShow(() => {
// console.log(globalData.isLogin,'调用了')
// if (globalData.isLogin) {
// setTimeout(() => {
// localtion_map()
// }, 500)
// }
localtion_map()
})
const localtion_map = () => {
// let location = uni.getStorageSync('location');
// let longitude = ''
// let latitude = ''
uni.getLocation({
type: 'gcj02',
geocode: true,
success: (res) => {
// console.log(res, 'res');
address.value = res
uni.setStorageSync('location', res)
longitude.value = res.longitude
latitude.value = res.latitude
handle_maps_now()
},
fail: (err) => {
// console.log(err, 'uni.getLocation解析失败');
},
});
}
const handle_close_popup = () => {
bottom_popup.value.close()
}
const goMap_address = (longitude, latitude) => {
uni.openLocation({
latitude: Number(latitude),
longitude: Number(longitude),
name: undefined, //企业名称
address: undefined, //详细地址
success: function() {
console.log('success');
},
fail: (err) => {
console.log(err, 'err');
}
});
}
const handle_maps_now = async () => {
let data = {
latitude: latitude.value,
longitude: longitude.value,
distance: 4000
}
// console.log(data, 'data');
await uni.$request({
url: config.baseUrl + "app-api/cloud/op/nearbyStation",
method: 'POST',
data: data,
}).then((res) => {
// console.log(res, '地址');
if (res.data.data.list.length > 0) {
let copy = JSON.parse(JSON.stringify(res.data.data.list))
pointsList.value = copy
showPoints.pointList = copy
setMarkersAndCluster(showPoints.pointList) // 3、调用聚合功能
}
})
}
const setMarkersAndCluster = (markerList) => {
let mapContext = uni.createMapContext('map')
// 1.组装数据之后并赋值给地图上的marker
const allMarkers = Array.from(markerList).map((e, i) => {
// console.log(e,'e')
return {
id: e.id,
longitude: e.longitude,
latitude: e.latitude,
iconPath: '../../static/home/marker.png',
rotate: 0, // 旋转度数
width: 50, //宽
height: 50, //高
alpha: 1, //透明
joinCluster: true, //参与点聚合
callout: {
content: e.stationName,
color: '#000',
fontSize: 16,
display: 'ALWAYS',
padding: 8,
bgColor: "#fff",
borderRadius: 5
},
}
});
marker.markers = allMarkers
mapContext.moveToLocation({
longitude: Number(marker.markers[0].longitude),
latitude: Number(marker.markers[0].latitude)
})
// 2.初始化点聚合的配置,未调用时采用默认配置
mapContext.initMarkerCluster({
enableDefaultStyle: false, // 是否启用默认的聚合样式(是否用自定义图标)
zoomOnClick: true,
gridSize: 60,
complete(res) {
// console.log('initMarkerCluster', res)
}
});
// 3.发生聚合时给聚合点设置marker标签
mapContext.on('markerClusterCreate', res => {
// console.log('clusterCreate', res)
const clusters = res.clusters
const markers = clusters.map(cluster => {
const {
center,
clusterId,
markerIds
} = cluster
return {
...center,
width: 0,
height: 0,
clusterId, // 必须
label: {
content: markerIds.length + '',
fontSize: 12,
color: '#fff',
width: 50,
height: 50,
bgColor: '#4C91FF',
borderRadius: 10,
textAlign: 'center',
anchorX: 0,
anchorY: -50,
}
}
})
// 4. 添加聚合簇标签
mapContext.addMarkers({
markers,
clear: false,
complete(res) {
// console.log('clusterCreate addMarkers', res)
}
})
})
}
const goMap = (e) => {
showSearch.value = false //关闭搜索展示列表
showToast.value = true
// console.log(e, 'eeeeeeeeeee');
searchStationName.value = e.stationName
searchAreaName.value = e.areaName
searchDistance.value = e.distance
searchNo.value = e.stationNo
let flag = marker.markers.some((item) => {
item.longitude == e.longitude
item.latitude == e.latitude
})
if (flag) {
uni.createMapContext('map').moveToLocation({
longitude: Number(e.longitude),
latitude: Number(e.latitude)
})
} else {
// 展示点位
let posArr = [{
id: e.id,
longitude: e.longitude,
latitude: e.latitude,
iconPath: '../../../static/home/marker.png',
rotate: 0, // 旋转度数
width: 50, //宽
height: 50, //高
alpha: 1, //透明
callout: {
content: e.stationName,
color: '#000',
fontSize: 16,
display: 'ALWAYS',
padding: 8,
bgColor: "#fff",
borderRadius: 5
}
}]
marker.markers.push(...posArr)
// console.log(marker.markers, 'marker');
uni.createMapContext('map').moveToLocation({
longitude: Number(e.longitude),
latitude: Number(e.latitude)
})
}
}
const emit = defineEmits(['handle_errornotify']);
const goDetail = () => {
if (!uni.getStorageSync("userInfo")) {
uni.showToast({
title: '请先完成登录',
duration: 2000,
icon: 'error'
});
return;
}
// else if (uni.getStorageSync("realNameAuthFlag") != 1) {
// emit('handle_errornotify')
// return
// }
else {
if (searchNo.value) {
let station = searchNo.value
uni.navigateTo({
url: '/pages/index/stationDetails/stationDetails?station=' + JSON.stringify(station) +
'&distance=' +
JSON.parse(searchDistance.value) + '&searchID=' + JSON.parse(searchID.value)
})
}
}
}
const callouttap = (e) => {
let showInf = pointsList.value.filter((item) => {
return item.id == e.detail.markerId
})
searchStationName.value = showInf[0].stationName
searchAreaName.value = showInf[0].areaName
searchDistance.value = showInf[0].distance
searchNo.value = showInf[0].stationNo
searchID.value = showInf[0].id
bottom_popup.value.open('bottom')
// showToast.value = !showToast.value
}
const handle_open = (showInf) => {
for (let item of pointsList.value) {
if (showInf.id == item.id) {
// console.log(item,'平移了');
uni.createMapContext('map').moveToLocation({
longitude: item.longitude,
latitude: item.latitude
})
}
}
// console.log(showInf,'showInf');
// console.log(pointsList.value,'pointsList.value');
}
defineExpose({
handle_open
})
</script>
<style lang="scss">
.section {
width: 100%;
height: 100%;
border-radius: 16rpx;
overflow: hidden;
// height: 100vh;
position: relative;
}
.searchIn {
height: 100rpx;
}
.map {
width: 100%;
height: 100%;
// height: calc(100% - 100rpx);
// overflow: hidden;
// overflow-y: auto;
}
.goToast {
width: 100%;
position: absolute;
bottom: 1%;
z-index: 99;
}
.card-border {
border-radius: 8px;
}
.titleState {
padding: 8rpx 16rpx;
border: 1px solid #4C91FF;
border-radius: 5px;
background-color: #4C91FF;
color: #fff;
}
.name {
font-size: 36rpx;
padding: 8rpx 16rpx;
}
.goDetail {
border: 1px solid #4C91FF;
padding: 8rpx 32rpx;
color: #4C91FF;
border-radius: 20px;
}
.goMap {
width: 24rpx;
height: 24rpx;
color: #4C91FF;
background: url('/static/home/goMap.svg') no-repeat;
background-size: 100% 100%;
}
.searchDistance {
color: #4C91FF;
}
.scrollView {
height: calc(100vh - 100rpx);
}
.line_tops {
width: 20%;
height: 10rpx;
margin: 20rpx auto;
background: #e5e5e5;
border-radius: 5rpx;
}
.position_right_tops {
width: 100rpx;
height: 100rpx;
background: #2bbd69;
border-radius: 50%;
position: absolute;
right: 20rpx;
top: 10rpx;
color: #fff;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
}
</style>