<!-- Description: 综合大屏-布控地图 Author: 李亚光 Date: 2024-07-18 --> <script lang="ts" setup> import allAlarmStatus from '../fullScreen-components/allAlarmStatus.vue' import deptAlarmCount from '../fullScreen-components/deptAlarmCount.vue' import currentAlarm from '../fullScreen-components/currentAlarm.vue' import deviceOnlineMonitor from '../fullScreen-components/deviceOnlineMonitor.vue' import deviceAlarmTrend from '../fullScreen-components/deviceAlarmTrend.vue' import alarmCount from '../fullScreen-components/alarmCount.vue' import detailInfo from './alarmDialog.vue' import { img } from './imgData' import { getAlarmLevelListPage } from '@/api/home/rule/alarm' import { getCurrentAlarmListPage } from '@/api/home/alarm/current' import AMap from '@/components/map/index.vue' // 地图实例 const mapRef = ref() // 图例展示 const legend = ref<string[]>([]) const legendData = ref<any[]>([]) // 双击多边形(行政区或九五示范区)掉起弹窗 const detail = ref() const detailRef = ref() // 绘点标记 const drawMarker = (data: any, style: any, type: string) => { mapRef.value.addMassMarks({ path: data, zIndex: 111, zooms: [0, 100], style, }) // 判断图例设置(没有显示的直接就隐藏) if (!legend.value.includes(type)) { mapRef.value.massMarksAllList.forEach((line: any) => { line.hide() }) } } // 阀门,调压站等点标记点击 const massMarksClick = (data: any) => { // 定义弹窗 detail.value = new mapRef.value.AMap.InfoWindow({ closeWhenClickMap: true, // 是否在鼠标点击地图后关闭信息窗体 autoMove: true, // 是否自动调整窗体到视野内 isCustom: true, // 自定义信息窗体 content: detailRef.value.$el, // 窗体内容(vue组件) offset: new mapRef.value.AMap.Pixel(9, -5), // 偏移 }) // 打开信息窗口 console.log(data.event.data.lnglat, 'data.event.data.lnglat') detail.value.open(data.map, data.event.data.lnglat) // 初始化信息窗口 detailRef.value.initDialog({ overlay: data.event.target, infoWindow: detail.value, info: data.event.data, }) } // 点击图例,显示隐藏对应的点或线 const clickLegend = (data: { name: string; type: string }) => { if (legend.value.includes(data.name)) { // 隐藏 legend.value = legend.value.filter((citem: string) => citem !== data.name) mapRef.value.massMarksAllList.filter((item: any) => item.getData().some((citem: any) => citem.type === data.name)).forEach((marker: any) => { marker.hide() }) } else { // 显示 legend.value.push(data.name) mapRef.value.massMarksAllList.filter((item: any) => item.getData().some((citem: any) => citem.type === data.name)).forEach((marker: any) => { marker.show() }) } } // 获取报警等级 const publicPath = window.location.href.split('#')[0] async function fetchAlarmLevel() { legendData.value = [] const res = await getAlarmLevelListPage({ offset: 1, limit: 9999 }) const colorObj = { 一级: '#f56c6c', 二级: '#ee9611', 三级: '#ffd700', 其他: '#8dc6ea', } as { [key: string]: string } const imgObj = { 一级: `${publicPath}/image/other/one-icon.png`, 二级: `${publicPath}/image/other/two-icon.png`, 三级: `${publicPath}/image/other/three-icon.png`, 其他: `${publicPath}/image/other/other-icon.png`, } as { [key: string]: string } legendData.value = [] legend.value = [] res.data.rows.forEach((element: any) => { legend.value.push(element.alarmLevel) const obj = { name: element.alarmLevel, // img: img.alarm, type: 'marker', color: '', img: '', } for (const i in colorObj) { if (element.alarmLevel.includes(i)) { obj.color = colorObj[i] obj.img = imgObj[i] } } if (!obj.color) { obj.color = colorObj['其他'] obj.img = `${publicPath}/image/other/other-icon.png` } legendData.value.push(obj) }) console.log(legendData.value, 'legendData.value') } // 获取报警 const alarmList = ref<any[]>([]) const fetchAlarm = () => { getCurrentAlarmListPage({ offset: 1, limit: 9999 }).then((res) => { alarmList.value = res.data.rows const style = [ { url: `${publicPath}/image/other/one.png`, anchor: new mapRef.value.AMap.Pixel(4, 4), size: new mapRef.value.AMap.Size(18, 18), zIndex: 99, type: '一级', }, { url: `${publicPath}/image/other/two.png`, anchor: new mapRef.value.AMap.Pixel(4, 4), size: new mapRef.value.AMap.Size(18, 18), zIndex: 99, type: '二级', }, { url: `${publicPath}/image/other/three.png`, anchor: new mapRef.value.AMap.Pixel(4, 4), size: new mapRef.value.AMap.Size(18, 18), zIndex: 99, type: '三级', }, { url: `${publicPath}/image/other/other.png`, anchor: new mapRef.value.AMap.Pixel(4, 4), size: new mapRef.value.AMap.Size(18, 18), zIndex: 99, type: '其他', }, ] legendData.value.forEach((item: any) => { drawMarker( alarmList.value.filter((citem: any) => citem.alarmLevelName === item.name && citem.lngGaode && citem.latGaode).map((citem: any) => ({ lnglat: [citem.lngGaode, citem.latGaode], name: citem.alarmContent, style: style.findIndex(citem => item.name.includes(citem.type)) === -1 ? 3 : style.findIndex(citem => item.name.includes(citem.type)), type: citem.alarmLevelName, id: citem.id, })), style, item.name, ) }) mapRef.value.map.setCenter([alarmList.value[0].lngGaode, alarmList.value[0].latGaode]) mapRef.value.map.setZoom(11) }) } // 获取报警 // 地图挂载完毕执行 const drawBj = async () => { await fetchAlarmLevel() fetchAlarm() } </script> <template> <div class="full-container"> <!-- 左侧 --> <div class="left-container"> <!-- 总体报警情况 --> <all-alarm-status type=" " /> <!-- 各分公司报警统计 --> <dept-alarm-count type=" " style="margin-top: 20px;" /> <!-- 当前报警 --> <current-alarm style="margin-top: 20px;" /> </div> <!-- 右侧 --> <div class="right-container"> <!-- 设备在线监控 --> <device-online-monitor /> <!-- 设备报警趋势 --> <device-alarm-trend style="margin-top: 20px;" /> <!-- 累计报警统计 --> <alarm-count style="margin-top: 20px;" /> </div> <!-- 设备信息窗体 --> <detail-info ref="detailRef" /> <!-- 地图 --> <a-map ref="mapRef" layer="dark" :zoom="14" :center="[116.397428, 39.90923]" @complete="drawBj" @massMarksClick="massMarksClick" /> <!-- 图例 --> <div v-if="legendData.length" class="amap-legend2"> <div v-for="(item) in legendData" :key="item.name" class="legend-item"> <div class="icon" :class="legend.includes(item.name) ? '' : 'none'"> <img :src="item.img"> </div> <div class="value" @click="clickLegend({ name: item.name, type: item.type })"> {{ item.name }} </div> </div> </div> </div> </template> <styele lang="scss" scoped> .show-count { position: absolute; z-index: 9; left: 400px; top: 100px; width: 240px; } .show-change { position: absolute; top: 100px; right: 400px; z-index: 9; // background-color: #ddd; .change { padding: 10px 20px; text-align: center; background: url("@/assets/fullscren/data-bg.png") no-repeat center center / cover; border: 1px solid #249eff; color: #fff; &:hover { cursor: pointer; } } } .left-container { position: absolute; z-index: 9; top: 100px; left: 15px; background-color: rgba($color: #0B0B0F, $alpha: 0.8); } .right-container { position: absolute; z-index: 9; top: 100px; right: 15px; // background-color: #0b0b0f; background-color: rgba($color: #0B0B0F, $alpha: 0.8); } .amap-legend1 { /* background: url("@/assets/images/dashboard/legend.png") no-repeat center center / cover; */ position: absolute; z-index: 9; bottom: 10px; left: 400px; /* background: rgb(68 66 66 / 80%); */ background-color: rgba($color: #0B0B0F, $alpha: 0.8); border: 2px solid #249eff; color: #fff; padding: 10px; .legend-item { display: flex; margin: 5px; flex-wrap: wrap; color: #a7ceec; img { height: 16px; width: 16px; } .value { margin-left: 5px; height: 16px; line-height: 16px; &:hover { cursor: pointer; } } } } .amap-legend2 { /* background: url("@/assets/images/dashboard/legend.png") no-repeat center center / cover; */ position: absolute; z-index: 9; bottom: 10px; right: 400px; background-color: rgba($color: #0B0B0F, $alpha: 0.8); border: 2px solid #249eff; color: #fff; padding: 10px; .legend-item { display: flex; margin: 5px; flex-wrap: wrap; color: #a7ceec; // .icon { // height: 20px; // width: 20px; // border-radius: 50%; // opacity: 0.8; // } img { height: 16px; width: 16px; } .value { margin-left: 5px; height: 20px; line-height: 20px; &:hover { cursor: pointer; } } } } </styele> <style> .full-container { width: 100%; height: 100vh; } .none { opacity: 0 !important; } .close { width: 150px; height: 70px; position: fixed; top: 0; right: 0; /* background-color: antiquewhite; */ &:hover { .icon { display: block; } } .icon { display: none; width: 50px; height: 50px; background: rgb(145 144 144 / 60%); border-radius: 50%; line-height: 50px; text-align: center; font-size: 18px; font-weight: 700; color: #ccc; margin: 10px auto; &:hover { cursor: pointer; } } } </style>