<script lang="ts" setup name="Map"> import type { Ref } from 'vue' import { getCurrentInstance, ref } from 'vue' import dayjs from 'dayjs' import L from 'leaflet' // import aMap from '@/components/aMap/aMap.vue' import { getDataHisList, getDevInfo, getDevMap } from '@/api/ptz/dev' import useWebsocketStore from '@/store/modules/websocket' import type { lineDataI } from '@/components/Echart/echart-interface' import 'leaflet/dist/leaflet.css' import 'leaflet.label' import {getDevListPage} from "@/api/ycjg/dev"; const { proxy } = getCurrentInstance() const websocket = useWebsocketStore() const toParentsMap = ref({ lat: '', lng: '', }) const map: any = ref(null) const baseLayer = ref([]) const keyword = ref('') const refreshMarker = ref(false) const isRightShow = ref(false) const pointList: Ref<any[]> = ref([]) const currentName = ref('') const monitorId = ref('') const deviceIp = ref('') const device = ref({}) const devCH4Loading = ref(false) const devCH4XData: Ref<string[]> = ref([]) const devCH4Data: Ref<lineDataI[]> = ref([]) const devCH4YDataMax = ref() const webRtcServer = ref(null) const amap = ref() // 组件 function search() { refreshMarker.value = false map.value.eachLayer((layer: any) => { if (layer !== baseLayer.value[0]) { layer.remove() } }) getDevListPage({ keyword: keyword.value, devType: '', offset: 1, limit: 1000, }).then((res) => { res.data.rows.forEach((item: any) => { let icon let color switch (item.deviceStatus) { case 0: icon = './marker/gray.png' color = 'gray' break case 1: icon = './marker/green.png' color = 'green' break } const Icon = L.icon({ iconUrl: icon, iconSize: [30, 30], }) const message = `<div style="padding: 10px;width: 230px;font-size: 16px;"> <div style="font-weight: bold;margin-bottom: 10px">${item.monitorName || ''}</div> <div style="color: ` + `${color}` + `"><span style="color: black">设备状态:</span>${item.deviceStatusName || ''}</div> <div style="word-break: break-all; "><span>密级:</span>${item.secretLevelName || ''}</div> <div style="word-break: break-all; "><span>详细位置:</span>${item.location || ''}</div> </div>` const popup = L.popup().setContent(message) const divIcon = L.divIcon({ html: `<div> <image src="${icon}" width="30" height="30" style="margin-bottom: -3px"> <div style="margin-left: calc(-50% - 5px);border-radius:5px;display: inline-block;white-space: nowrap;background: rgb(255,255,255);text-align: left;height: 20px;padding: 0 4px">${item.monitorName || ''}</div> </div>`, className: 'my-div-icon', iconSize: [30, 30], }) const marker = L.marker([item.latitude, item.longitude], { icon: divIcon }).addTo(map.value).bindPopup(popup) }) refreshMarker.value = true // 定位 if (res.data.length > 0) { map.value.setView({ lat: res.data[0].latitude, lng: res.data[0].longitude }) } }) } onBeforeMount(() => { toParentsMap.value.lat = proxy.$position.lat toParentsMap.value.lng = proxy.$position.lng }) onMounted(() => { map.value = L.map('map', { minZoom: Number(proxy.$zoom.minZoom), maxZoom: Number(proxy.$zoom.maxZoom), center: [toParentsMap.value.lat, toParentsMap.value.lng], zoom: Number(proxy.$zoom.zoom), zoomControl: false, attributionControl: false, crs: L.CRS.EPSG3857, }) const str = '/static/tiles/{z}/{x}/{y}.png' baseLayer.value.push(L.tileLayer(str).addTo(map.value)) search() }) onBeforeUnmount(() => { }) </script> <template> <div id="map" style="height: calc(100vh - 110px)" /> <div class="input"> <el-input v-model="keyword" type="text" placeholder="设备名称关键字" clearable style="width: 200px;" /> <el-button type="primary" style="margin-left: 5px;" @click="search"> 查询 </el-button> </div> <div class="cover"> <div class="green" /> <div class="gray" /> <div class="item"> 正常 </div> <div class="item"> 离线 </div> </div> <div v-if="isRightShow" class="right"> </div> </template> <style lang="scss"> .leaflet-popup { margin-bottom: 35px !important; } </style> <style lang="scss" scoped> .map { width: 100%; height: 100%; } .right { z-index: 1000 !important; position: absolute; right: 20px; top: 10px; width: 350px; height: calc(100vh - var(--g-topbar-height) - var(--g-header-height) - 20px); background: #faefe0; border-radius: 10px; padding: 20px 0; .devName { padding-left: 10px; margin-bottom: 10px; font-size: 19px; font-weight: bold; } .title { font-size: 17px; font-weight: bold; margin: 10px 0; color: #464646; } .close { width: 20px; height: 20px; position: absolute; right: 10px; top: 20px; } } .input { position: absolute; top: 20px; left: 20px; width: 280px; height: 34px; display: flex; z-index: 11111111111111; } .cover { position: absolute; bottom: 25px; left: 5px; width: 120px; height: 120px; border-radius: 10px; background: #faefe0; z-index: 1111; display: flex; flex-flow: column wrap; justify-content: space-evenly; align-items: center; .item { width: 50px; height: 45px; padding-top: 10px; font-weight: bold; color: #5f5f5f; } .green { background: url("../../assets/images/marker/green.png") no-repeat center / cover; width: 45px; height: 45px; } .red { background: url("../../assets/images/marker/red.png") no-repeat center / cover; width: 45px; height: 45px; } .gray { background: url("../../assets/images/marker/gray.png") no-repeat center / cover; width: 45px; height: 45px; } } </style> <style> .my-div-icon { color: black; font-size: 14px; text-align: center; pointer-events: none; /* Prevent mouse events from firing */ } </style>