feat:完善功能

This commit is contained in:
zjc
2025-02-20 15:27:03 +08:00
parent 99860f9b50
commit a96998dacd
3 changed files with 152 additions and 89 deletions

View File

@@ -0,0 +1,331 @@
<template>
<div class="dialog">
<el-dialog v-model="modelValue" align-center :modal="false" :show-close="false">
<div id="big-car-ship" class="big-car-ship" />
<img class="close" src="@/assets/images/close.png" @click="modelValue = false" />
</el-dialog>
</div>
</template>
<script setup>
import closeIcon from '@/assets/images/close.png'
import carIcon from '@/assets/images/car.png'
import shipIcon from '@/assets/images/ship.png'
import icon13 from '@/assets/images/icon-13.png'
import icon14 from '@/assets/images/icon-14.png'
import icon15 from '@/assets/images/icon-15.png'
import icon16 from '@/assets/images/icon-16.png'
import icon17 from '@/assets/images/icon-17.png'
import icon18 from '@/assets/images/icon-18.png'
import icon19 from '@/assets/images/icon-19.png'
import icon20 from '@/assets/images/icon-20.png'
import { useMap } from '@/hooks/map'
let modelValue = defineModel()
const { map, marker, initMap, addMarker } = useMap()
let props = defineProps({
carList: {
type: Array,
default: () => []
},
shipList: {
type: Array,
default: () => []
}
})
let lat = ref('')
let lng = ref('')
let scenicChange = null
let carOverlays = ref([])
let shipOverlays = ref([])
let lastInfoBox = ref()
let infoBox = ref()
let currentMarker = ref()
watch(
() => modelValue.value,
(val) => {
if (val) {
setTimeout(() => {
initMap('big-car-ship', lng.value, lat.value, 15)
}, 1000)
}
},
{ immediate: true }
)
watch(
() => [map.value, props.carList, props.shipList],
(val) => {
if (val[0]) {
// 109.645729,31.041203
if (carOverlays.value.length > 0) {
// 更新车辆marker位置
let flag = false
for (let i = 0; i < carOverlays.value.length; i++) {
if (flag) break
for (let j = 0; j < props.carList.length; j++) {
if (carOverlays.value[i].sim == props.carList[j].sim) {
carOverlays.value[i].setPosition({
lng: props.carList[j].lng,
lat: props.carList[j].lat
})
flag = true
break
}
}
}
// 更新车辆infobox位置和内容
for (let i = 0; i < props.carList.length; i++) {
if (
currentMarker.value &&
infoBox.value &&
props.carList[i].sim == currentMarker.value.target.sim
) {
infoBox.value.setContent(setHtml(props.carList[i]))
infoBox.value.setPosition({
lng: props.carList[i].lng,
lat: props.carList[i].lat
})
break
}
}
} else {
props.carList.map((item, i) => {
if (item.lng && item.lat) {
addMarker(carIcon, [item.lng, item.lat], [36, 50])
marker.value.addEventListener('click', (e) => {
currentMarker.value = e
let obj = props.carList.find((item) => item.sim == e.target.sim)
setInfoBox(e.latLng, obj)
})
marker.value.sim = item.sim
carOverlays.value[i] = marker.value
}
})
}
if (shipOverlays.value.length > 0) {
// 更新船只marker位置
let flag = false
for (let i = 0; i < shipOverlays.value.length; i++) {
if (flag) break
for (let j = 0; j < props.shipList.length; j++) {
if (shipOverlays.value[i].sim == props.shipList[j].sim) {
shipOverlays.value[i].setPosition({
lng: props.shipList[j].lng,
lat: props.shipList[j].lat
})
flag = true
break
}
}
}
// 更新船只infobox位置和内容
for (let i = 0; i < props.shipList.length; i++) {
if (
currentMarker.value &&
infoBox.value &&
props.shipList[i].sim == currentMarker.value.target.sim
) {
infoBox.value.setContent(setHtml(props.shipList[i]))
infoBox.value.setPosition({
lng: props.shipList[i].lng,
lat: props.shipList[i].lat
})
break
}
}
} else {
props.shipList.map((item, i) => {
if (item.lng && item.lat) {
addMarker(shipIcon, [item.lng, item.lat], [36, 50])
marker.value.addEventListener('click', (e) => {
currentMarker.value = e
let obj = props.shipList.find((item) => item.sim == e.target.sim)
setInfoBox(e.latLng, obj)
})
marker.value.sim = item.sim
shipOverlays.value[i] = marker.value
}
})
}
}
},
{ immediate: true }
)
const setHtml = (data) => {
console.log(data, 'data')
let html = `<div class='marker-box'>
<p class='marker-title'> ${data?.license_number} </p>
<div class='marker-header'>
<span class='marker-sim'> ${data?.imei} </span>
<div class='marker-tag'> <div></div> ${data.status} (${data.status_time_desc})</div>
</div>
<div class='marker-line'> </div>
<div class='marker-row'>
<div class='marker-col'> <img src='${icon13}' /> <p> 王明 </p> </div>
<div class='marker-col'> <img src='${icon14}' /> <p> 18723232323 </p> </div>
</div>
<div class='marker-row'>
<div class='marker-col'> <img src='${icon15}' /> <p> 王明 </p> </div>
<div class='marker-col'> <img src='${icon16}' /> <p> 18723232323 </p> </div>
</div>
<div class='marker-row'>
<div class='marker-col'> <img src='${icon17}' /> <p> 222KM </p> </div>
<div class='marker-col'> <img src='${icon18}' /> <p> 3.01KM </p> </div>
</div>
<div class='marker-row'>
<div class='marker-col'> <img src='${icon19}' /> <p> ${data.lng},${data.lat} </p> </div>
</div>
<div class='marker-row'>
<div class='marker-col'> <img src='${icon20}' /> <p> 重庆市奉节县(重庆市奉节县白帝城.瞿塘峡景区内.白帝城东南218米 </p> </div>
</div>
</div>`
return html
}
const setInfoBox = (e, data) => {
if (!infoBox.value) {
infoBox.value = new BMapGLLib.InfoBox(map.value, setHtml(data), {
boxStyle: {},
closeIconMargin: '',
closeIconUrl: closeIcon,
enableAutoPan: true,
align: INFOBOX_AT_TOP,
offset: new BMapGL.Size(0, 20)
})
} else {
if (lastInfoBox.value) lastInfoBox.value?.close()
infoBox.value.setContent(setHtml(data))
lastInfoBox.value = infoBox.value
}
infoBox.value.open(e)
}
onMounted(() => {
scenicChange = PubSub.subscribe('scenicChange', (msg, data) => {
lat.value = data.lat
lng.value = data.lng
})
})
onUnmounted(() => {
PubSub.unsubscribe(scenicChange)
})
</script>
<style lang="scss">
.infoBox {
> img {
width: vw(40) !important;
height: auto;
z-index: 9999;
}
}
.marker {
&-box {
position: relative;
width: 316px;
border: 1px solid #0096ff;
background: linear-gradient(180deg, #0a4190 0%, #0e51b1 100%);
}
&-close {
position: absolute;
right: vw(20);
top: vh(10);
width: vw(30);
height: auto;
}
&-title {
width: 100%;
height: vh(36);
padding-left: vw(16);
font-weight: 600;
font-size: vw(16);
color: #ffffff;
display: flex;
align-items: center;
background-image: url('@/assets/images/marker-title.png');
background-size: 100% 100%;
}
&-header {
padding: vh(12) vw(14);
display: flex;
align-items: center;
justify-content: space-between;
}
&-sim {
font-weight: 600;
font-size: vw(16);
color: #ffffff;
}
&-tag {
padding: vh(5) vw(8);
font-weight: 400;
font-size: vw(13);
color: #0096ff;
background: #0b4599;
border-radius: vw(23);
border: vw(1) solid #0096ff;
}
&-line {
width: 100%;
height: vw(1);
background-color: #134fa4;
}
&-row {
padding: vh(10) vw(16);
display: flex;
align-items: center;
border-bottom: 1px solid #134fa4;
}
&-col {
flex: 1;
display: flex;
align-items: flex-start;
> img {
width: vw(32);
height: vw(32);
margin-right: vw(10);
}
> p {
flex: 1;
font-weight: 400;
font-size: vw(24);
color: #ffffff;
line-height: vh(20);
}
}
}
</style>
<style scoped lang="scss">
:deep(.BMap_cpyCtrl) {
display: none;
}
:deep(.anchorBL) {
display: none;
}
.dialog {
:deep(.el-dialog) {
width: vw(2540);
height: vh(900);
padding: vh(40) vw(40);
}
:deep(.el-dialog__header) {
padding-bottom: 0 !important;
}
}
.big-car-ship {
width: 100%;
height: vh(820);
}
.close {
cursor: pointer;
position: absolute;
right: vw(20);
top: vh(20);
width: vw(60);
z-index: 9999;
}
</style>