|
|
|
|
<template>
|
|
|
|
|
<div class="flex flex-row overflow-auto" style="height: calc(100vh - 160px)">
|
|
|
|
|
<div class="flex-1 h-full position-relative">
|
|
|
|
|
<OpenLayerMap
|
|
|
|
|
ref="mapRef"
|
|
|
|
|
class="map-container"
|
|
|
|
|
:showDrawFences="true"
|
|
|
|
|
:showTrajectories="true"
|
|
|
|
|
:markers="filterMarkers"
|
|
|
|
|
:fences="fences"
|
|
|
|
|
/>
|
|
|
|
|
<TopPanel
|
|
|
|
|
v-model="search"
|
|
|
|
|
:handDetectorCount="handDetectorCount"
|
|
|
|
|
:onlineCount="onlineCount"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="markerList">
|
|
|
|
|
<el-scrollbar height="100%">
|
|
|
|
|
<!--marker列表 -->
|
|
|
|
|
<el-collapse accordion>
|
|
|
|
|
<el-collapse-item :name="item.name" v-for="item in filterMarkers" :key="item.id">
|
|
|
|
|
<template #title>
|
|
|
|
|
<div class="flex flex-row w-100%">
|
|
|
|
|
<div class="flex-1 text-left font-500">
|
|
|
|
|
{{ item.name }}
|
|
|
|
|
</div>
|
|
|
|
|
<div class="text-gray-500 font-400 text-12px">
|
|
|
|
|
{{ item.onlineStatus === 1 ? '在线' : '离线' }}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<div class="markerList-content">
|
|
|
|
|
<div> <span>SN:</span>{{ item.sn }}</div>
|
|
|
|
|
<div> <span>类型:</span>{{ item.gasChemical }}</div>
|
|
|
|
|
<div> <span>气体状态:</span>{{ item.gasStatus }}</div>
|
|
|
|
|
<div> <span>电池告警状态:</span>{{ item.batteryStatus }}</div>
|
|
|
|
|
<div> <span>电池:</span>{{ item.battery }}</div>
|
|
|
|
|
<div> <span>围栏状态:</span>{{ item.fenceStatus }}</div>
|
|
|
|
|
<!-- <div> <span>在线状态:</span>{{ item.onlineStatus }}</div> -->
|
|
|
|
|
<div> <span>数值:</span>{{ item.value }} {{ item.unit }}</div>
|
|
|
|
|
<div> <span>时间:</span>{{ dayjs(item.time).format('YYYY-MM-DD HH:mm:ss') }}</div>
|
|
|
|
|
|
|
|
|
|
<!-- {{ item }} -->
|
|
|
|
|
</div>
|
|
|
|
|
</el-collapse-item>
|
|
|
|
|
</el-collapse>
|
|
|
|
|
</el-scrollbar>
|
|
|
|
|
<!-- <div v-for="item in filterMarkers" :key="item.id" class="marker-item">
|
|
|
|
|
<div>{{ item.name }}:{{ item.onlineStatus === 1 ? '在线' : '离线' }}</div>
|
|
|
|
|
</div> -->
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
|
import OpenLayerMap from './components/OpenLayerMap.vue'
|
|
|
|
|
import TopPanel from './components/TopPanel.vue'
|
|
|
|
|
|
|
|
|
|
import { getLastDetectorData } from '@/api/gas'
|
|
|
|
|
import { HandDetectorData } from '@/api/gas/handdetector'
|
|
|
|
|
import { tdengineApi, tdStruct, tdQuery } from '@/api/gas/tdengine/index'
|
|
|
|
|
|
|
|
|
|
import { MarkerData, FenceData } from './components/types/map.types'
|
|
|
|
|
|
|
|
|
|
import { useHandDetectorStore } from '@/store/modules/handDetector'
|
|
|
|
|
|
|
|
|
|
import dayjs from 'dayjs'
|
|
|
|
|
|
|
|
|
|
const handDetectorStore = useHandDetectorStore() // 手持探测器 store
|
|
|
|
|
|
|
|
|
|
const getDataTimer = ref<NodeJS.Timeout | null>(null)
|
|
|
|
|
const markers = ref<MarkerData[]>([])
|
|
|
|
|
const fences = ref<FenceData[]>([])
|
|
|
|
|
|
|
|
|
|
const mapRef = ref<typeof OpenLayerMap>()
|
|
|
|
|
const search = ref('')
|
|
|
|
|
watch(
|
|
|
|
|
() => search.value,
|
|
|
|
|
(newSearch, oldSearch) => {
|
|
|
|
|
if (newSearch !== oldSearch) {
|
|
|
|
|
mapRef.value?.fitToMarkers()
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{ immediate: false }
|
|
|
|
|
)
|
|
|
|
|
// 手持设备数量
|
|
|
|
|
const handDetectorCount = computed(() => markers.value.length)
|
|
|
|
|
const onlineCount = computed(() => markers.value.filter((item) => item.onlineStatus === 1).length)
|
|
|
|
|
const filterMarkers = computed(() => {
|
|
|
|
|
if (search.value) {
|
|
|
|
|
return markers.value.filter((item) => {
|
|
|
|
|
var isName = item.name.includes(search.value)
|
|
|
|
|
var isSn = item.sn?.includes(search.value)
|
|
|
|
|
var isGasChemical = item.gasChemical?.includes(search.value)
|
|
|
|
|
|
|
|
|
|
return isName || isSn || isGasChemical
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
return markers.value
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const getMarkers = async () => {
|
|
|
|
|
console.log('getMarkers')
|
|
|
|
|
return await getLastDetectorData().then((res: HandDetectorData[]) => {
|
|
|
|
|
res = res.filter((i) => i.enableStatus === 1)
|
|
|
|
|
var res2 = res.map((i) => {
|
|
|
|
|
// console.log([i.longitude, i.latitude])
|
|
|
|
|
|
|
|
|
|
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[]
|
|
|
|
|
getMarkersHistory()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.filter((i) => i.status === 1)
|
|
|
|
|
fences.value = fencesData as unknown as FenceData[]
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
// const markersHistory = ref<tdStruct[]>([])
|
|
|
|
|
const getMarkersHistory = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const data = await tdengineApi.getPage({
|
|
|
|
|
pageNo: 1,
|
|
|
|
|
pageSize: 100,
|
|
|
|
|
sn: '867989072729904'
|
|
|
|
|
})
|
|
|
|
|
// markersHistory.value = data.list
|
|
|
|
|
markers.value.map((item) => {
|
|
|
|
|
if (item.sn === '867989072729904') {
|
|
|
|
|
item.data = data.list.map((j) => {
|
|
|
|
|
return {
|
|
|
|
|
...j,
|
|
|
|
|
lng: j.longitude,
|
|
|
|
|
lat: j.latitude,
|
|
|
|
|
time:dayjs(j.ts).format('YYYY-MM-DD HH:mm:ss'),
|
|
|
|
|
timeStr: dayjs(j.ts).format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
} finally {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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: 100%;
|
|
|
|
|
}
|
|
|
|
|
.markerList {
|
|
|
|
|
width: 240px;
|
|
|
|
|
height: 100%;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
background-color: white;
|
|
|
|
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
|
|
|
|
padding: 0 10px;
|
|
|
|
|
margin-left: 10px;
|
|
|
|
|
|
|
|
|
|
.markerList-content {
|
|
|
|
|
padding: 10px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
min-width: 70px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|