Newer
Older
SpaceIntegration_front / src / views / home / index.vue
<!-- 首页 -->
<script name="Home" setup lang="ts">
import { ref } from 'vue'
import dayjs from 'dayjs'
import { ElMessage } from 'element-plus'
import statisticsData from './components/statistics.vue'
import dateSelect from './components/date.vue'
import useMapStore from '@/store/modules/map'
import MapComponent from '@/components/map/Map.vue'
import homeIcon from '@/assets/images/点位图标/地图菜单/首页未选中.png'
import gasIcon from '@/assets/images/点位图标/地图菜单/甲烷未选中.png'
import identifyIcon from '@/assets/images/点位图标/地图菜单/识别未选中.png'
import occupyIcon from '@/assets/images/点位图标/地图菜单/占压未选中.png'
import couplingIcon from '@/assets/images/点位图标/地图菜单/耦合未选中.png'
import dateIcon from '@/assets/images/点位图标/地图菜单/日期未选中.png'
import homeCheck from '@/assets/images/点位图标/地图菜单/首页选中.png'
import gasCheck from '@/assets/images/点位图标/地图菜单/甲烷选中.png'
import identifyCheck from '@/assets/images/点位图标/地图菜单/识别选中.png'
import occupyCheck from '@/assets/images/点位图标/地图菜单/占压选中.png'
import couplingCheck from '@/assets/images/点位图标/地图菜单/耦合选中.png'
import dateCheck from '@/assets/images/点位图标/地图菜单/日期选中.png'
import gas1 from '@/assets/images/点位图标/点位图标/甲烷/甲烷已处置.png'
import gas2 from '@/assets/images/点位图标/点位图标/甲烷/甲烷未处置.png'
import car1 from '@/assets/images/点位图标/点位图标/首页/巡检车在线.png'
import car2 from '@/assets/images/点位图标/点位图标/首页/巡检车离线.png'
import task from '@/assets/images/点位图标/点位图标/首页/巡检任务.png'
import analyse1 from '@/assets/images/点位图标/点位图标/耦合/正常.png'
import analyse2 from '@/assets/images/点位图标/点位图标/耦合/低风险.png'
import analyse3 from '@/assets/images/点位图标/点位图标/耦合/一般风险.png'
import analyse4 from '@/assets/images/点位图标/点位图标/耦合/较高风险.png'
import analyse5 from '@/assets/images/点位图标/点位图标/耦合/严重风险.png'
import recognition1 from '@/assets/images/点位图标/点位图标/识别/正常.png'
import recognition2 from '@/assets/images/点位图标/点位图标/识别/低风险.png'
import recognition3 from '@/assets/images/点位图标/点位图标/识别/一般风险.png'
import recognition4 from '@/assets/images/点位图标/点位图标/识别/较高风险.png'
import recognition5 from '@/assets/images/点位图标/点位图标/识别/严重风险.png'
import { getAnalyse, getCarList, getGasList, getRecognition, getTaskList } from '@/api/page/page'
const mapRef = ref() // 地图实例
const mapStore = useMapStore() // 地图仓库
watch(() => mapStore.detailList, (newVal) => {
  if (newVal) {
    // 清空原来轨迹
    mapRef.value.clearLine()
    // 绘制轨迹
    mapRef.value.drawLine(newVal)
  }
}, {
  deep: true,
})
const center = ref([116.26759100, 39.91563500]) // 地图中心
const zoom = ref(17) // 地图显示的缩放级别
const pegeLoading = ref(false)
// 日期选择组件实例
const dateRef = ref()
// 日期选择top距离
const dateTop = ref(0)
// 菜单选中
const select = ref(0)
const preSelect = ref(0)
// 条件菜单选中
const cselect = ref<string[]>(['0', '1'])
// 菜单列表
const menu = ref([
  {
    name: '首页',
    icon: homeIcon,
    check: homeCheck,
    menu: [
      {
        name: '巡检车辆',
        value: '0',
        color: '#2DBF00',
      },
      {
        name: '巡检任务',
        value: '1',
        color: '#2763BC',
      },
    ],
  },
  {
    name: '甲烷',
    icon: gasIcon,
    check: gasCheck,
    menu: [
      {
        name: '已处置',
        value: '1',
        color: '#2DBF00',
      },
      {
        name: '未处置',
        value: '0',
        color: '#9F1919',
      },
    ],
  },
  {
    name: '识别',
    icon: identifyIcon,
    check: identifyCheck,
    menu: [
      {
        name: '正常',
        value: '正常',
        color: '#2DBF00',
      },
      {
        name: '低风险',
        value: '低风险',
        color: '#2763BC',
      },
      {
        name: '一般风险',
        value: '一般风险',
        color: '#FFD800',
      },
      {
        name: '较高风险',
        value: '较高风险',
        color: '#D98200',
      },
      {
        name: '严重风险',
        value: '严重风险',
        color: '#9F1919',
      },
    ],
  },
  {
    name: '占压',
    icon: occupyIcon,
    check: occupyCheck,
    menu: [
      // {
      //   name: '正常',
      //   value: '0',
      //   color: '#2DBF00',
      // },
      // {
      //   name: '低风险',
      //   value: '1',
      //   color: '#2763BC',
      // },
      {
        name: '较小隐患',
        value: '2',
        color: '#FFD800',
      },
      {
        name: '一般隐患',
        value: '3',
        color: '#D98200',
      },
      {
        name: '重大隐患',
        value: '4',
        color: '#9F1919',
      },
    ],
  },
  {
    name: '耦合',
    icon: couplingIcon,
    check: couplingCheck,
    menu: [
      // {
      //   name: '正常',
      //   value: '0',
      //   color: '#2DBF00',
      // },
      {
        name: '低风险',
        value: '低风险',
        color: '#2763BC',
      },
      {
        name: '中风险',
        value: '中风险',
        color: '#FFD800',
      },
      {
        name: '较高风险',
        value: '较高风险',
        color: '#D98200',
      },
      {
        name: '严重风险',
        value: '严重风险',
        color: '#9F1919',
      },
    ],
  },
  {
    name: '日期',
    icon: dateIcon,
    check: dateCheck,
  },
])

// 切换菜单
const change = (index: number) => {
  if (pegeLoading.value) {
    return
  }
  if (index === 5) {
    preSelect.value = select.value
    const ele = document.getElementById('menu-item5')
    dateTop.value = ele?.getBoundingClientRect().top as number
    select.value = index
    return
  }// 清空地图绘制
  mapRef.value?.clearDraw()
  if (select.value !== index) {
    cselect.value = menu.value[index].menu.map((item: any) => item.value)
  }
  select.value = index
}
// 日期选择top距离
window.addEventListener('resize', () => {
  const ele = document.getElementById('menu-item5')
  dateTop.value = ele?.getBoundingClientRect().top as number
})
// 改变条件菜单
const cchange = (value: string) => {
  if (pegeLoading.value) {
    return
  }
  if (cselect.value.includes(value)) {
    cselect.value = cselect.value.filter((item: string) => item !== value)
  }
  else {
    cselect.value.push(value)
  }
  change(select.value)
}
// 确认日期
const confirmData = () => {
  change(preSelect.value)
}
// 获取首页数据
const fetchHome = async () => {
  // 获取车辆列表
  const fetchCar = async () => {
    pegeLoading.value = true
    const res1 = await getCarList({})
    console.log(res1, '车')
    const data1 = res1.data.map((item: any) => {
      return {
        ...item,
        lat: item.latitude,
        lng: item.longitude,
        // lng: '116.265872',
        // lat: '39.914083',
        dialog: 'car',
        // 0 离线  1 在线
        icon: item.status === '离线' ? car2 : car1,
      }
    }).filter((item: any) => item.lat && item.lng)
    // 绘制标记点
    // mapRef.value.drawPonit(data1)
    pegeLoading.value = false
    return data1
  }
  // 获取任务列表
  const fetchTask = async () => {
    pegeLoading.value = true
    const res2 = await getTaskList({
      beginDate: dateRef.value?.dateActive,
      endDate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
    })
    console.log(res2, '任务')
    const data2 = res2.data.rows.map((item: any) => {
      return {
        ...item,
        dialog: 'task',
        lat: item.latitude,
        lng: item.longitude,
        icon: task,
      }
    }).filter((item: any) => item.lat && item.lng)
    // 绘制标记点
    // mapRef.value.drawPonit(data2)
    pegeLoading.value = false
    return data2
  }
  // 车0 任务1
  if (cselect.value.length === 2) {
    const res1 = await fetchCar()
    const res2 = await fetchTask()
    // 绘制标记点
    if (!res1.length) {
      ElMessage.warning('暂无巡检车数据')
    }
    if (!res2.length) {
      ElMessage.warning('暂无巡检任务数据')
    }
    mapRef.value.drawPonit([...res1, ...res2])
  }
  else if (cselect.value.length === 1) {
    if (cselect.value.includes('0')) {
      const res = await fetchCar()
      if (!res.length) {
        ElMessage.warning('暂无巡检车数据')
      }
      mapRef.value.drawPonit(res)
    }
    else if (cselect.value.includes('1')) {
      const res = await fetchTask()
      if (!res.length) {
        ElMessage.warning('暂无巡检任务数据')
      }
      mapRef.value.drawPonit(res)
    }
  }
}
// 清空折线轨迹
const clearTrack = () => {
  mapRef.value.clearLine()
  mapStore.setDetailList([])
}
// 获取甲烷数据
const fetchGas = () => {
  pegeLoading.value = true
  getGasList({
    alarmType: '1',
    alarmStatus: cselect.value.length === 2 ? '' : cselect.value[0], // 报警状态
    beginDate: dateRef.value?.dateActive, // 报警开始时间
    endDate: dayjs().format('YYYY-MM-DD HH:mm:ss'), // 报警结束时间
  }).then((res) => {
    console.log(res.data, '甲烷数据')
    // 整理数据
    const data = res.data.rows.map((item: any) => {
      return {
        ...item,
        lat: item.alarmLatitude,
        lng: item.alarmLongitude,
        icon: item.alarmStatus === '已处置' ? gas1 : gas2,
        dialog: 'gas',
      }
    }).filter((item: any) => item.lat && item.lng)
    if (!data.length) {
      ElMessage.warning('暂无甲烷数据')
    }
    // 绘制标记点
    mapRef.value.drawPonit(data)
    pegeLoading.value = false
  }).catch(() => {
    pegeLoading.value = false
  })
}
// 获取第三方智能识别
const fetchRecognition = () => {
  pegeLoading.value = true
  getRecognition({
    beginDate: dateRef.value?.dateActive, // 报警开始时间
    endDate: dayjs().format('YYYY-MM-DD HH:mm:ss'), // 报警结束时间
  }).then((res) => {
    console.log(res.data, '第三方智能识别')
    // recognitionLevel
    const data = res.data.rows.map((item: any) => {
      let icon = ''
      switch (item.recognitionLevel) {
        case '正常':
          icon = recognition1
          break
        case '低风险':
          icon = recognition2
          break
        case '一般风险':
          icon = recognition3
          break
        case '较高风险':
          icon = recognition4
          break
        case '严重风险':
          icon = recognition5
          break
      }
      return {
        ...item,
        // lat: item.latitude,
        // lng: item.longitude,
        // lat: '39.914193',
        // lng: '116.265982',
        icon,
        dialog: 'recognition',
        // alarmPicture: '2023-11\\e9109d1dc73c453b9f4cf47c6e0c90da.png',
      }
    }).filter((item: any) => item.lat && item.lng)
    let Filter = []
    if (cselect.value.length === 5) {
      Filter = data
    }
    else {
      Filter = data.filter(item => cselect.value.includes(item.recognitionLevel))
    }
    if (!Filter.length) {
      ElMessage.warning('暂无识别数据')
    }
    // 绘制标记点
    mapRef.value.drawPonit(Filter)
    pegeLoading.value = false
  }).catch(() => {
    pegeLoading.value = false
  })
}
// 获取耦合数据
const fetchAnalyse = () => {
  pegeLoading.value = true
  getAnalyse({
    beginDate: dateRef.value?.dateActive, // 开始时间
    endDate: dayjs().format('YYYY-MM-DD HH:mm:ss'), // 结束时间
  }).then((res) => {
    console.log(res.data, '风险耦合分析')
    const data = res.data.rows.map((item: any) => {
      let icon = ''
      switch (item.couplingResult) {
        case '低风险':
          icon = analyse2
          break
        case '中风险':
          icon = analyse3
          break
        case '较高风险':
          icon = analyse4
          break
        case '严重风险':
          icon = analyse5
          break
      }
      return {
        ...item,
        lat: item.latitude,
        lng: item.longitude,
        icon,
        dialog: 'analyse',
      }
    }).filter((item: any) => item.lat && item.lng)
    let Filter = []
    if (cselect.value.length === 4) {
      Filter = data
    }
    else {
      Filter = data.filter(item => cselect.value.includes(item.couplingResult))
    }
    if (!Filter.length) {
      ElMessage.warning('暂无耦合数据')
    }
    // 绘制标记点
    mapRef.value.drawPonit(Filter)
    pegeLoading.value = false
  }).catch(() => {
    pegeLoading.value = false
  })
}
// 获取点位数据
watch(() => [select.value, cselect.value], (newVal: any[], oldVal) => {
  if (!mapRef.value?.isMap) {
    console.log('初始化未完成')
    return
  }
  if (!newVal[1].length) {
    // 清空地图绘制
    mapRef.value?.clearDraw()
    return
  }
  // 清空地图绘制
  mapRef.value?.clearDraw()
  switch (newVal[0]) {
    case 0:
      fetchHome()
      console.log('首页')
      break
    case 1:
      fetchGas()
      console.log('甲烷')
      break
    case 2:
      fetchRecognition()
      console.log('识别')
      break
    case 3:
      console.log('占压')
      break
    case 4:
      fetchAnalyse()
      console.log('耦合')
      break
  }
}, {
  deep: true,
  immediate: true,
})
// 监听地图是否初始化完成
watch(() => mapRef.value?.isMap, (newVal) => {
  if (newVal) {
  // 初始化完成
    fetchHome()
  }
}, {
  deep: true,
  immediate: true,
})
</script>

<template>
  <div class="home">
    <div id="container" style="height: calc(100vh - 50px); width: 100%; padding: 0;margin: 0;">
      <div class="title">
        地上地下一体化管线风险识别与预警地图看板
      </div>
      <map-component ref="mapRef" :center="center" :zoom="zoom" />
      <!-- 主菜单 -->
      <div class="menu">
        <div v-for="(item, index) in menu" :id="`menu-item${index}`" :key="index" :class="`${pegeLoading ? 'ban-select' : 'select-menu'}`" class="menu-item" @click="change(index)">
          <el-tooltip
            class="box-item"
            effect="dark"
            :content="item.name"
            placement="right"
          >
            <img :src="select === index ? item.check : item.icon" width="70" height="70">
          </el-tooltip>
        </div>
      </div>
      <!-- 时间查询 -->
      <date-select v-show="select === 5" ref="dateRef" class="date-select" :style="`top:${dateTop - 60}px`" @confirm="confirmData" />
      <!-- 条件菜单 -->
      <div class="cmenu">
        <div v-if="select === 0 && mapStore.detailList.length" class="menu-child" style="background-color: #666;" @click="clearTrack">
          清空轨迹
        </div>
        <div v-for="(child, cindex) in menu[select].menu" :key="cindex" :class="`${pegeLoading ? 'ban-select' : 'select-menu'}`" class="menu-child" :style="`background:${cselect.includes(child.value) ? child.color : '#666'};`" @click="cchange(child.value)">
          {{ child.name }}
        </div>
      </div>
    </div>
    <!-- 统计数据 -->
    <statistics-data />
  </div>
</template>

<style lang="scss" scoped>
.ban-select {
  &:hover {
    cursor: not-allowed;
  }
}

.select-menu {
  &:hover {
    cursor: pointer;
  }
}

.title {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  z-index: 999;
  color: #fff;
  background-color: rgba($color: #2f4261, $alpha: 70%);
  font-size: 20px;
  padding: 20px;
  font-weight: 700;
  border-radius: 20px;
}

.menu {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  left: 10px;
  z-index: 999;

  .menu-item {
    margin-top: 10px;
    position: relative;
  }
}

.cmenu {
  position: absolute;
  right: 28%;
  top: 80px;
  z-index: 999;
  display: flex;

  .menu-child {
    margin: 10px;
    padding: 10px;
    color: #fff;
    font-size: 18px;
    font-weight: 700;
    border-radius: 8px;

  }
}

.home {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  overflow: hidden;

  .container {
    overflow: hidden;
  }
}
</style>

<style>
/* 隐藏高德logo  */
.amap-logo {
  display: none !important;
}

/* 隐藏高德版权  */
.amap-copyright {
  display: none !important;
}

.img-map-marker {
  width: 20px;
  height: 20px;
}
</style>