Newer
Older
laserPTZFrontV2.0 / src / views / map / mapAMap.vue
wangxitong on 26 Sep 8 KB 流媒体
<script lang="ts" setup name="Map">
import type { Ref } from 'vue'
import { getCurrentInstance, ref } from 'vue'
import dayjs from 'dayjs'
import type { PointListInfo } from '../device/dev-interface'
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 type { DateReturn, TypeReturn } from '@/views/statistics/statistics-interface'
import HKVideo from '@/components/HKVideo/index.vue'
const { proxy } = getCurrentInstance()
const websocket = useWebsocketStore()

const toParentsMap = ref({
  lat: '',
  lng: '',
})

const keyword = ref('')
const refreshMarker = ref(false)
const isRightShow = ref(false)
const pointList: Ref<PointListInfo[]> = 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
  getDevMap(keyword.value).then((res) => {
    pointList.value = res.data.map((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
        case '2':
          icon = './marker/red.png'
          color = 'red'
          break
      }
      return {
        ...item,
        icon,
        label: {
          content: item.monitorName, // 标签文本
          offset: new AMap.Pixel(35, 5),
          style: {
            color: 'red',
            fontSize: '12px',
          },
        },
        message:
          `<div style="padding: 10px;width: 230px">
            <div style="font-size: 16px;font-weight: bold;margin-bottom: 10px">${item.monitorName || ''}</div>
            <div><span>所在场站:</span>${item.stationName || ''}</div>
            <div style="color: ` + `${color}` + `">
            <span style="color: black">设备状态:</span>${item.deviceStatusName || ''}</div>
            <div style="margin-bottom: 10px; word-break: break-all; "><span>详细位置:</span>${item.location || ''}</div>
            <div class="btnDetail" style="color: #3776ff;margin-left: 170px;cursor: pointer;font-size: 15px" id="btnDetail_${item.monitorId || ''}">详情</div>
         </div>`,
      }
    })
    refreshMarker.value = true
    // 定位
    if (pointList.value.length > 0) {
      console.log(pointList.value[0].latitude, pointList.value[0].longitude)
      toParentsMap.value = {
        lat: pointList.value[0].latitude,
        lng: pointList.value[0].longitude,
      }
    }
  })
}
search()

onMounted(() => {
  toParentsMap.value.lat = proxy.$position.lat
  toParentsMap.value.lng = proxy.$position.lng
})
function clickRecall(item: any) {
  webRtcServer.value = null
  const pressTimer = setTimeout(() => {
    document.getElementsByClassName('btnDetail')[0].onclick = function () {
      isRightShow.value = true
      currentName.value = item.monitorName
      monitorId.value = item.monitorId
      deviceIp.value = item.deviceIp
      monitorId.value && getDevInfo(monitorId.value).then((res) => {
        device.value = {}
        device.value = res.data
        // const devInfo = res.data;
        // webRtcServer.value = new WebRtcStreamer("video", proxy.rtspServer);
        // webRtcServer.value.connect(`rtsp://${devInfo.deviceUser}:${devInfo.devicePassword}@${devInfo.deviceIp}`);
        // console.log(`rtsp://${devInfo.deviceUser}:${devInfo.devicePassword}@${devInfo.deviceIp}`)
      })
      nextTick(() => {
        devCH4Loading.value = true
        const param = {
          monitorId: item.monitorId,
          startTime: dayjs(Date.now() - 1 * 60 * 1000).format('YYYY-MM-DD HH:mm:ss'),
          endTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
        }
        getDataHisList(param).then((res) => {
          const yValue = res.data.reverse().map((item: DateReturn) => {
            if (Object.keys(item).toString().includes('num')) {
              Number(item.num)
            }
            else {
              Number(item.concentration)
            }
          })
          devCH4YDataMax.value = Math.max(yValue) > 10 ? Math.max(yValue) : 10
          devCH4XData.value = res.data.map((item: TypeReturn) => item.logTime ? item.logTime.split(' ')[1] : '')
          devCH4Data.value = [{ name: 'CH4', data: yValue }]
          devCH4Loading.value = false
        })
      })
    }
  }, 500)
}
// watch监听websocket变化
const unwatch = watch(websocket, (newVal) => {
  if (newVal.refreshMap) {
    search()
  }
  if (newVal.lineData && Object.keys(newVal.lineData).length >= 1 && isRightShow.value) {
    // console.log('监测到新的数据,并且右侧面板开启!')
    // 匹配id
    if (newVal.lineData.deviceIp === deviceIp.value) {
      devCH4Loading.value = true
      // 判断数据长度
      if (devCH4XData.value.length > 300) {
        devCH4XData.value.splice(0, 100)
        devCH4Data.value[0].data.splice(0, 100)
      }
      devCH4XData.value = [...devCH4XData.value, dayjs(newVal.lineData.time).format('HH:mm:ss')]
      devCH4Data.value = [{ name: 'CH4', data: devCH4Data.value[0].data.concat(newVal.lineData.gasData) }]
      devCH4Loading.value = false
    }
  }
})

onBeforeUnmount(() => {
  if (webRtcServer.value && typeof webRtcServer.value.disconnect === 'function') {
    webRtcServer.value.disconnect()
    webRtcServer.value = null
  }
  unwatch()
})
</script>

<template>
  <a-map
    ref="amap"
    :to-parents-map="toParentsMap"
    :zoom="proxy.$zoom.zoom"
    :points="pointList"
    :refresh-marker="refreshMarker"
    class="map"
    @clickRecall="clickRecall"
  />
  <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="red" />
    <div class="item">
      正常
    </div>
    <div class="item">
      离线
    </div>
    <div class="item">
      报警
    </div>
  </div>
  <div v-if="isRightShow" class="right">
    <svg-icon name="icon-close" class="close" @click="isRightShow = false" />
    <div class="devName">
      {{ currentName }}
    </div>
    <bench-col id="home" icon="icon-video" title="视频监控" height="250px" style="background: #faefe0;padding: 0;">
      <h-k-video id="map" style="width: 100%;height: 100%;background: currentcolor;" :device="device" />
      <!--      <video id="video" autoPlay style="width: 100%;height: 100%;background:currentColor;"></video> -->
    </bench-col>
    <bench-col
      v-loading="devCH4Loading" icon="icon-line" title="浓度监控(ppm·m)" height="250px"
      style="background: #faefe0;padding: 0;"
    >
      <line-chart
        :x-axis-data="devCH4XData" width="340px" :data="devCH4Data" unit="" :grid="{
          top: 10,
          left: 10,
          right: 30,
          bottom: 20,
          containLabel: true, // 是否包含坐标轴的刻度标签
        }
        "
      />
    </bench-col>
  </div>
</template>

<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 {
    cursor: pointer;
    width: 20px;
    height: 20px;
    position: absolute;
    right: 10px;
    top: 20px;
  }
}

.input {
  position: absolute;
  top: 20px;
  left: 20px;
  width: 280px;
  height: 34px;
  display: flex;
}

.cover {
  position: absolute;
  bottom: 25px;
  left: 5px;
  width: 120px;
  height: 170px;
  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>