|
|
|
|
<template>
|
|
|
|
|
<OpenLayerMap
|
|
|
|
|
class="w-full map-container"
|
|
|
|
|
v-if="inited"
|
|
|
|
|
:showDrawFences="false"
|
|
|
|
|
:showTrajectories="false"
|
|
|
|
|
:markers="markers"
|
|
|
|
|
:fences="fences"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<div class="top-panel" v-show="!appStore.mobile">
|
|
|
|
|
<div class="top-panel__left">
|
|
|
|
|
<div class="search-group">
|
|
|
|
|
<el-input v-model="search" class="search-input" placeholder="请输入关键词" />
|
|
|
|
|
</div>
|
|
|
|
|
<!-- <div>
|
|
|
|
|
<el-checkbox-group v-model="openFences">
|
|
|
|
|
<el-checkbox label="显示电子围栏" value="1" />
|
|
|
|
|
</el-checkbox-group>
|
|
|
|
|
</div> -->
|
|
|
|
|
</div>
|
|
|
|
|
<div class="top-panel__center">
|
|
|
|
|
<div class="data_item">
|
|
|
|
|
<span class="data_item__title">手持设备</span>
|
|
|
|
|
<span class="data_item__value">{{ handDetectorCount }}</span>
|
|
|
|
|
<span class="data_item__unit">台</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="data_item">
|
|
|
|
|
<span class="data_item__title">在线数量</span>
|
|
|
|
|
<span class="data_item__value">{{ onlineCount }}</span>
|
|
|
|
|
<span class="data_item__unit">台</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="top-panel__right">
|
|
|
|
|
<span class="legend-title">报警图例:</span>
|
|
|
|
|
<div class="normal-legend">正常状态</div>
|
|
|
|
|
<div class="alarm1-legend">围栏报警</div>
|
|
|
|
|
<div class="alarm2-legend">气体报警</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
|
import OpenLayerMap from './components/OpenLayerMap.vue'
|
|
|
|
|
import { getLastestDetectorData } from '@/api/gas'
|
|
|
|
|
import { HandDetectorData } from '@/api/gas/handdetector'
|
|
|
|
|
import { MarkerData, FenceData } from './components/types/map.types'
|
|
|
|
|
import { useAppStore } from '@/store/modules/app'
|
|
|
|
|
import { useHandDetectorStore } from '@/store/modules/handDetector'
|
|
|
|
|
|
|
|
|
|
import dayjs from 'dayjs'
|
|
|
|
|
|
|
|
|
|
const appStore = useAppStore()
|
|
|
|
|
|
|
|
|
|
const handDetectorStore = useHandDetectorStore() // 手持探测器 store
|
|
|
|
|
|
|
|
|
|
const getDataTimer = ref<NodeJS.Timeout | null>(null)
|
|
|
|
|
const markers = ref<MarkerData[]>([])
|
|
|
|
|
const fences = ref<FenceData[]>([])
|
|
|
|
|
const inited = ref(false)
|
|
|
|
|
|
|
|
|
|
const search = ref('')
|
|
|
|
|
// 手持设备数量
|
|
|
|
|
const handDetectorCount = computed(() => markers.value.length)
|
|
|
|
|
const onlineCount = computed(() => markers.value.filter((item) => item.onlineStatus === 1).length)
|
|
|
|
|
|
|
|
|
|
const getMarkers = async () => {
|
|
|
|
|
console.log('getMarkers')
|
|
|
|
|
return await getLastestDetectorData().then((res: HandDetectorData[]) => {
|
|
|
|
|
res = res.filter((i) => i.enableStatus === 1)
|
|
|
|
|
var res2 = res.map((i) => {
|
|
|
|
|
return {
|
|
|
|
|
...i,
|
|
|
|
|
coordinates: [i.longitude, i.latitude],
|
|
|
|
|
data: [],
|
|
|
|
|
time: i.time ? dayjs(i.time).format('YYYY-MM-DD HH:mm:ss') : '',
|
|
|
|
|
value: i.value,
|
|
|
|
|
unit: i.unit,
|
|
|
|
|
gasStatus: i.gasStatus, //气体报警状态
|
|
|
|
|
batteryStatus: i.batteryStatus, //电池报警状态
|
|
|
|
|
fenceStatus: i.fenceStatus, //电子围栏报警状态
|
|
|
|
|
onlineStatus: i.onlineStatus, //在线状态
|
|
|
|
|
enableStatus: i.enableStatus //启用状态
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
markers.value = res2 as unknown as any[]
|
|
|
|
|
inited.value = true
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
const getFences = async () => {
|
|
|
|
|
return await handDetectorStore.getAllFences().then((res) => {
|
|
|
|
|
console.log('getFences', res)
|
|
|
|
|
let fencesData = res.map((i) => {
|
|
|
|
|
return {
|
|
|
|
|
...i,
|
|
|
|
|
fenceRange: JSON.parse(i.fenceRange)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
fences.value = fencesData as unknown as FenceData[]
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
getMarkers()
|
|
|
|
|
getFences()
|
|
|
|
|
console.log('定时器,暂时关掉,太烦了')
|
|
|
|
|
|
|
|
|
|
// getDataTimer.value = setInterval(() => {
|
|
|
|
|
// getMarkers()
|
|
|
|
|
// getFences()
|
|
|
|
|
// }, 5000)
|
|
|
|
|
})
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
clearInterval(getDataTimer.value as NodeJS.Timeout)
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
.map-container {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: calc(100vh - 140px);
|
|
|
|
|
}
|
|
|
|
|
/* 顶部面板样式 */
|
|
|
|
|
.top-panel {
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 12px;
|
|
|
|
|
left: 50px;
|
|
|
|
|
right: 10px;
|
|
|
|
|
z-index: 1000;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
gap: 12px;
|
|
|
|
|
padding: 10px 12px;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
|
|
.top-panel__left {
|
|
|
|
|
// flex: 0 0 260px;
|
|
|
|
|
background: rgba(255, 255, 255, 0.7);
|
|
|
|
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
|
|
|
|
|
height: 100%;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
.search-group {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
|
|
|
|
// .search-type {
|
|
|
|
|
// flex: 0 0 120px;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
.search-input {
|
|
|
|
|
width: 220px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.top-panel__center {
|
|
|
|
|
flex: 1 1 auto;
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
|
|
|
gap: 12px;
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
|
|
.data_item {
|
|
|
|
|
background: rgba(255, 255, 255, 0.9);
|
|
|
|
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
padding: 12px 12px;
|
|
|
|
|
// min-height: 56px;
|
|
|
|
|
// display: flex;
|
|
|
|
|
// flex-direction: column;
|
|
|
|
|
// justify-content: center;
|
|
|
|
|
|
|
|
|
|
.data_item__title {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #909399;
|
|
|
|
|
vertical-align: middle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.data_item__value {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
padding: 0 10px;
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: #3399ff;
|
|
|
|
|
vertical-align: middle;
|
|
|
|
|
}
|
|
|
|
|
.data_item__unit {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #909399;
|
|
|
|
|
vertical-align: middle;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.top-panel__right {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
flex: 0 0 auto;
|
|
|
|
|
background: rgba(255, 255, 255, 0.85);
|
|
|
|
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
|
|
|
|
padding: 12px 12px;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
|
|
.legend-title {
|
|
|
|
|
color: #606266;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.normal-legend {
|
|
|
|
|
padding: 4px 8px;
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
color: #fff;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
line-height: 1;
|
|
|
|
|
background: #67c23a;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.alarm1-legend {
|
|
|
|
|
padding: 4px 8px;
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
color: #fff;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
line-height: 1;
|
|
|
|
|
background: #e6a23c;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.alarm2-legend {
|
|
|
|
|
padding: 4px 8px;
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
color: #fff;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
line-height: 1;
|
|
|
|
|
background: #f56c6c;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (max-width: 992px) {
|
|
|
|
|
.top-panel {
|
|
|
|
|
.top-panel__left {
|
|
|
|
|
flex: 1 1 100%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.top-panel__center {
|
|
|
|
|
flex: 1 1 100%;
|
|
|
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.top-panel__right {
|
|
|
|
|
flex: 1 1 100%;
|
|
|
|
|
justify-content: flex-start;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (max-width: 600px) {
|
|
|
|
|
.top-panel {
|
|
|
|
|
.top-panel__center {
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|