Files
dvcp_v2_wxcp_app/src/project/xicheng/AppMerchantMap/AppMerchantMap.vue
yanran200730 54f0d57b37 bug
2022-07-02 15:19:30 +08:00

287 lines
7.4 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>
<div class="AppMerchantMap">
<div class="search">
<image :src="$cdn + 'xincheng/search.png'" />
<input placeholder="请输入姓名、店名、电话" v-model="businessName" @confirm="getList">
</div>
<div class="map-content">
<AiTMap :map.sync="map" :lib.sync="lib" :ops="ops" :libraries="['service', 'tools']"/>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: 'AppMerchantMap',
appName: '商户地图',
data() {
return {
areaId: '',
lib: null,
map: null,
polygons: [],
labels: [],
businessName: '',
markers: [],
ops: {},
markers: [],
MarkerCluster: null
}
},
computed: {...mapState(['user', 'config'])},
created () {
this.areaId = this.user.areaId
this.getList()
},
mounted () {
this.initMap()
},
methods: {
getList () {
this.$http.post('/app/appcompany/list', null, {
params: {
size: 100000,
current: 1,
businessName: this.businessName
}
}).then((res) => {
if (res.code == 0) {
const markers = res.data.records.filter(item => item.lat).map(item => {
return {
title: item.businessName,
lnglat: [item.lon, item.lat],
lat: item.lat,
lng: item.lon,
id: item.id,
name: item.businessName
}
})
this.getMarkerCluster(markers)
}
})
},
getMarkerCluster(points, count = 0) {
let {lib: TMap, map} = this
if (map) {
if (this.markers.length) {
this.markers.forEach(v => {
v.setMap(null)
})
}
class ClusterBubble extends TMap.DOMOverlay {
constructor(options) {
super(options);
}
onInit(options) {
this.content = options.content;
this.position = options.position;
this.customClass = options.customClass
};
onDestroy() {
this.dom.removeEventListener('click', this.onClick);
this.removeAllListeners();
}
createDOM() {
let dom = document.createElement('div');
dom.classList.add(this.customClass || 'marker');
dom.innerText = this.content;
// 监听点击事件实现zoomOnClick
this.onClick = this.onClick.bind(this);
// pc端注册click事件移动端注册touchend事件
dom.addEventListener('click', this.onClick);
dom.addEventListener('touchend', this.onClick);
return dom;
};
updateDOM() {
if (!this.map) {
return;
}
// 经纬度坐标转容器像素坐标
let pixel = this.map.projectToContainer(this.position);
// 使文本框中心点对齐经纬度坐标点
let left = pixel.getX() - this.dom.clientWidth / 2 + 'px';
let top = pixel.getY() - this.dom.clientHeight / 2 + 'px';
this.dom.style.transform = `translate(${left}, ${top})`;
this.emit('dom_updated');
};
onClick() {
this.emit('click');
}
}
this.config.latlng && map.setCenter(this.config.latlng)
this.MarkerCluster = new TMap.MarkerCluster({
map, gridSize: 60,
enableDefaultStyle: false, // 关闭默认样式
geometries: points.map(e => ({
position: new TMap.LatLng(e.lat, e.lng),
id: e.id,
content: `${e.name}`,
properties: {...e}
})) || [],
zoomOnClick: true
})
let cls = []
this.MarkerCluster.on('cluster_changed', () => {
if (this.markers.length) {
this.markers.forEach(function (item) {
item.destroy();
})
}
cls.forEach(e => e.destroy())
cls = []
let clusters = this.MarkerCluster.getClusters()
clusters.forEach((item) => {
if (item.geometries?.length > 1) {
//聚合样式
let clusterBubble = new ClusterBubble({
map,
position: item.center,
content: item.geometries.length,
customClass: 'cluster'
})
clusterBubble.on('click', () => {
map.fitBounds(item.bounds);
});
cls.push(clusterBubble)
} else {
//点标记样式
let {content, id} = item.geometries?.[0] || {},
overlay = new ClusterBubble({map, position: item.center, content})
overlay.on('click', () => {
uni.navigateTo({
url: `../AppMerchantManage/detail?id=${id}`
})
})
this.markers.push(overlay)
}
});
})
return Promise.resolve()
} else {
if (count < 5) {
setTimeout(() => {
return this.getMarkerCluster(points, ++count)
}, 1000)
} else Promise.reject("加载失败")
}
},
initMap (retryTimes = 0) {
this.$nextTick(() => {
let { map, TMap } = this
if (map) {
map.setZoom(15)
} else {
if (retryTimes < 10) {
setTimeout(() => {
this.initMap(++retryTimes)
}, 500)
}
}
})
}
}
}
</script>
<style lang="scss" scoped>
.AppMerchantMap {
height: 100%;
::v-deep.cluster {
color: #fff;
border-radius: 50%;
height: 120px;
width: 120px;
background: radial-gradient(circle, #5088ff 50%, rgba(#5088ff, .4) 100%);
display: flex;
align-items: center;
justify-content: center;
}
::v-deep.marker {
color: #fff;
background: #558BFE;
padding: 0 32px;
width: fit-content;
height: 56px;
border-radius: 52px;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
&:before {
content: " ";
display: block;
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 0;
transform: translate(-50%, 100%);
border: 12px solid transparent;
border-top-color: #558BFE;
}
}
* {
box-sizing: border-box;
}
.search {
display: flex;
position: fixed;
align-items: center;
top: 24px;
left: 50%;
z-index: 11111;
width: 718px;
height: 88px;
padding: 0 16px;
background: #FFFFFF;
box-shadow: 0px 4px 8px 0px rgba(192, 185, 185, 0.5);
border-radius: 16px;
transform: translateX(-50%);
image {
width: 48px;
height: 48px;
margin-right: 16px;
}
input {
flex: 1;
font-size: 28px;
color: #666666;
}
}
.map-content {
width: 100%;
height: 100vh;
map {
width: 100%;
height: 100vh;
}
}
}
</style>