Browse Source

master: Fixed 弹窗逻辑增加

gitboyzcf 4 months ago
parent
commit
44b812d483

+ 2 - 2
index.html

@@ -1,5 +1,5 @@
 <!doctype html>
-<html lang="en">
+<html lang="zn">
 
 <head>
   <meta charset="UTF-8" />
@@ -79,4 +79,4 @@
   <script type="module" src="/src/main.js"></script>
 </body>
 
-</html>
+</html>

+ 1 - 0
package.json

@@ -15,6 +15,7 @@
     "@ffmpeg/ffmpeg": "^0.12.10",
     "@ffmpeg/util": "^0.12.1",
     "@primevue/themes": "^4.2.1",
+    "@turf/turf": "^7.2.0",
     "@tweenjs/tween.js": "^25.0.0",
     "@vueuse/core": "^11.2.0",
     "animate.css": "^4.1.1",

File diff suppressed because it is too large
+ 1343 - 0
pnpm-lock.yaml


BIN
src/assets/images/box.png


BIN
src/assets/images/e2.png


BIN
src/assets/images/e3.png


BIN
src/assets/images/e4.png


+ 18 - 241
src/assets/scss/reset.scss

@@ -1,243 +1,20 @@
-.n-config-provider {
-  height: 100%;
+:root {
+  --p-content-background: transparent !important;
+  --p-datatable-header-cell-background: rgba(34, 98, 172) !important;
+  --p-datatable-row-color: #fff !important;
+  --p-datatable-header-cell-color: #fff !important;
+  --p-paginator-nav-button-selected-background: var(--p-blue-500) !important;
 }
-// .n-modal-mask {
-//   background-color: transparent;
-// }
 
-// .n-input,
-// .n-input n-input--textarea,
-// .n-base-selection {
-//   background-color: transparent;
-//   border-radius: 0;
-//   --n-border: 1px solid #007bff !important;
-//   --n-border-hover: 1px solid #007bff !important;
-//   --n-border-focus: 1px solid #007bff !important;
-
-//   .n-input__input-el,
-//   .n-input__textarea-el {
-//     color: #fff;
-//   }
-
-//   &:not(.n-input--disabled).n-input--focus,
-//   &.n-input--error-status:not(.n-input--disabled).n-input--focus {
-//     background-color: transparent;
-//   }
-// }
-// .n-input-group-label .n-input-group-label__border {
-//   border-color: #007bff;
-// }
-// .n-base-select-menu {
-//   background-color: rgba(0, 123, 255, 0.6);
-//   .n-base-select-option {
-//     color: #fff;
-//   }
-//   .n-base-select-option.n-base-select-option--pending::before {
-//     background-color: rgba(0, 123, 255, 1);
-//   }
-// }
-// .n-base-select-menu .n-base-select-option:active,
-// .n-base-select-menu .n-base-select-option.n-base-select-option--selected,
-// .n-base-select-menu .n-base-select-option .n-base-select-option__check {
-//   color: #007bff;
-// }
-// .n-base-selection.n-base-selection--error-status:not(
-//     .n-base-selection--disabled
-//   ).n-base-selection--active
-//   .n-base-selection-label {
-//   background-color: transparent;
-// }
-
-// .n-button {
-//   border-radius: 0;
-//   background-color: rgba(0, 123, 255, 0.4);
-//   color: #fff;
-//   // --n-border-hover: #007bff!important;
-//   // .n-button__border {
-//   //   border: 1px solid #007bff;
-//   // }
-// }
-// .n-button--default-type:not(.n-button--disabled):hover {
-//   color: #fff;
-//   background-color: #007bff;
-// }
-// .n-button--default-type:not(.n-button--disabled):hover .n-button__state-border,
-// .n-button--default-type .n-button__state-border {
-//   border-color: #007bff !important;
-// }
-
-// .n-dropdown-menu {
-//   background-color: rgba(0, 123, 255, 0.4);
-//   border-radius: 0;
-//   color: #fff;
-//   .n-dropdown-option-body__label {
-//     color: #fff;
-//   }
-// }
-
-// .n-dropdown-menu
-//   .n-dropdown-option
-//   .n-dropdown-option-body:not(
-//     .n-dropdown-option-body--disabled
-//   ).n-dropdown-option-body--pending::before {
-//   background-color: rgba(0, 123, 255);
-// }
-
-// .n-message {
-//   border-radius: 0;
-//   padding: 5px 20px;
-//   // background-color: rgba(0, 123, 255, 0.6);
-//   color: #fff;
-// }
-// .n-message-container.n-message-container--top {
-//   top: 80px;
-// }
-// .n-message--warning-type,
-// .n-button--warning-type {
-//   background-color: rgb(240, 160, 32, 0.4);
-// }
-// .n-message--success-type,
-// .n-button--success-type {
-//   background-color: rgb(24, 160, 88, 0.4);
-// }
-// .n-message--error-type,
-// .n-button--error-type {
-//   background-color: rgb(208, 48, 80, 0.4);
-// }
-// .n-color-picker-trigger {
-//   border-radius: 0;
-// }
-// .n-color-picker-panel {
-//   background-color: rgba(0, 123, 255, 1);
-//   color: #fff;
-// }
-// .n-popover:not(.n-popover--raw),
-// .n-dialog {
-//   background-color: rgba(0, 123, 255, 0.4);
-//   border-radius: 0;
-//   backdrop-filter: blur(10px);
-//   color: #fff;
-// }
-// .n-popover-shared .n-popover-arrow-wrapper .n-popover-arrow {
-//   background-color: rgba(0, 123, 255, 0.4);
-// }
-// .n-dialog .n-dialog__title {
-//   color: #fff;
-// }
-
-// .n-tree {
-//   &.n-tree--block-line
-//     .n-tree-node:not(.n-tree-node--disabled).n-tree-node--selectable:not(
-//       .n-tree-node--selected
-//     ):active {
-//     background-color: #007bff !important;
-//   }
-//   &.n-tree--block-line .n-tree-node:not(.n-tree-node--disabled):hover {
-//     background-color: rgba(0, 128, 255, 0.4);
-//     .n-tree-node-content {
-//       color: #fff;
-//     }
-//   }
-//   .n-tree-node.n-tree-node--highlight .n-tree-node-content .n-tree-node-content__text {
-//     border: 0;
-//   }
-//   &.n-tree--block-line .n-tree-node:not(.n-tree-node--disabled).n-tree-node--selected,
-//   &.n-tree--block-line .n-tree-node:not(.n-tree-node--disabled).n-tree-node--pending {
-//     background-color: rgba(0, 128, 255, 0.2);
-//   }
-
-//   .n-tree-node {
-//     border-radius: 0;
-//   }
-
-//   .n-tree-node-wrapper {
-//     .n-tree-node-content {
-//       color: #ccc;
-//     }
-//   }
-// }
-// .n-radio {
-//   color: #fff;
-//   --n-box-shadow: inset 0 0 0 1px #0080ff;
-//   --n-box-shadow-active: inset 0 0 0 1px #0080ff;
-//   --n-box-shadow-disabled: inset 0 0 0 1px #0080ff;
-//   --n-box-shadow-focus: inset 0 0 0 1px #0080ff, 0 0 0 2px rgba(24, 160, 88, 0.2) !important;
-//   --n-box-shadow-hover: inset 0 0 0 1px #0080ff;
-//   .n-radio__label {
-//     color: #8ac5ff;
-//   }
-//   .n-radio__dot {
-//     background-color: transparent;
-//   }
-//   &:not(.n-radio--disabled):hover .n-radio__dot,
-//   .n-radio__dot.n-radio__dot--checked {
-//     box-shadow: inset 0 0 0 1px #0080ff;
-//   }
-//   .n-radio__dot::before {
-//     background-color: #0080ff;
-//   }
-// }
-
-// .n-checkbox.n-checkbox--checked .n-checkbox-box .n-checkbox-box__border,
-// .n-checkbox.n-checkbox--indeterminate .n-checkbox-box .n-checkbox-box__border,
-// .n-checkbox:hover .n-checkbox-box .n-checkbox-box__border {
-//   border-color: #007bff;
-// }
-// .n-checkbox .n-checkbox-box .n-checkbox-box__border {
-//   border-radius: 0;
-// }
-// .n-checkbox.n-checkbox--checked .n-checkbox-box,
-// .n-checkbox.n-checkbox--indeterminate .n-checkbox-box {
-//   background-color: #0080ff;
-// }
-// .n-checkbox .n-checkbox-box {
-//   background-color: transparent;
-// }
-// .n-checkbox.n-checkbox--checked:focus:not(:active) .n-checkbox-box .n-checkbox-box__border,
-// .n-checkbox.n-checkbox--indeterminate:focus:not(:active) .n-checkbox-box .n-checkbox-box__border,
-// .n-checkbox:focus:not(:active) .n-checkbox-box .n-checkbox-box__border {
-//   box-shadow:
-//     inset 0 0 0 1px #0080ff,
-//     0 0 0 2px rgba(0, 128, 255, 0.2) !important;
-//   border-color: #007bff !important;
-// }
-
-// .n-empty {
-//   .n-empty__description,
-//   .n-empty__icon {
-//     color: #8ac5ff;
-//   }
-// }
-
-// /* 禁止选中文字 */
-// .select-font {
-//   -moz-user-select: none; /*火狐*/
-//   -webkit-user-select: none; /*webkit浏览器*/
-//   -ms-user-select: none; /*IE10*/
-//   -khtml-user-select: none; /*早期浏览器*/
-//   user-select: none;
-// }
-
-// svg {
-//   outline: none;
-// }
-
-// .n-data-table {
-//   --n-th-color-modal: #007bff !important;
-//   --n-border-color-modal: #007bff !important;
-//   --n-merged-td-color-striped: rgba(0, 123, 255, 0.2) !important;
-//   --n-td-color-hover-modal: rgba(0, 123, 255, 0.4) !important;
-//   --n-th-text-color: #fff !important;
-//   --n-td-text-color: #fff !important;
-//   --n-td-color-modal: transparent !important;
-// }
-// .n-pagination {
-//   --n-item-color-disabled: rgba(0, 123, 255, 0.4) !important;
-//   --n-button-icon-color: #fff !important;
-//   --n-item-color-hover: rgba(0, 123, 255, 0.2) !important;
-//   --n-item-text-color-hover: rgb(0, 123, 255) !important;
-//   --n-item-text-color: #fff !important;
-//   --n-button-color: #007bff !important;
-//   --n-button-border: 1px solid #007bff !important;
-//   --n-item-border-disabled: 1px solid rgba(0, 123, 255, 0.6) !important;
-// }
+.p-dialog {
+  background: url(../../assets/images/box.png) no-repeat !important;
+  background-size: 100% 100% !important;
+  color: #fff !important;
+  .p-dialog-header {
+    padding: 50px 26px 20px 26px !important;
+  }
+  .p-dialog-content {
+    padding: 30px !important;
+    padding-top: 0 !important;
+  }
+}

+ 2 - 3
src/components/ECharts/ECharts.vue

@@ -67,9 +67,8 @@
       text: '',
       color: '#409eff',
       textColor: '#000',
-      maskColor: 'rgba(56, 155, 255, .45)',
-      zlevel: 0,
-      lineWidth: 2
+      maskColor: '#041027',
+      zlevel: 0
     })
 
     //自适应不同屏幕时改变图表尺寸

File diff suppressed because it is too large
+ 13 - 9
src/components/ECharts/optionsConfig.js


+ 17 - 0
src/components/PubDialog.vue

@@ -0,0 +1,17 @@
+<template>
+  <Dialog :draggable="false" :style="style" v-model:visible="visible" modal v-bind="$attrs">
+    <slot>内容</slot>
+  </Dialog>
+</template>
+
+<script setup>
+  const visible = defineModel('visible', { type: Boolean, default: false })
+  defineProps({
+    style: {
+      type: Object,
+      default: () => ({ width: '900px', height: '736px' })
+    }
+  })
+
+  defineEmits(['update:visible'])
+</script>

+ 0 - 191
src/layout/HomeMap.vue

@@ -1,191 +0,0 @@
-<template>
-  <div class="home-map w-full h-full">
-    <div
-      class="linebox absolute w-full h-full transform-scale-y-80 transform-scale-x-120 opacity-50 flex justify-center items-center"
-    >
-      <img
-        class="line1 w-1000px ml--3px mt--7px animate-[scales2_60s_linear_infinite]"
-        src="@/assets/images/lines1.png"
-      />
-      <img class="line2 animate-[scales1_15s_linear_infinite]" src="@/assets/images/lines2.png" />
-      <img
-        class="line3 animate-[scales2_20s_linear_infinite] opacity-100"
-        src="@/assets/images/lines3.png"
-      />
-    </div>
-    <ECharts
-      id="home-map-echarts"
-      width="100%"
-      height="100%"
-      ref="echartsRef"
-      :loading="loading"
-      :fullOptions="fullOptions"
-    />
-    <Dialog v-model:visible="visible" modal header="Edit Profile" :style="{ width: '25rem' }">
-      <span class="text-surface-500 dark:text-surface-400 block mb-8"
-        >Update your information.</span
-      >
-      <div class="flex items-center gap-4 mb-4">
-        <label for="username" class="font-semibold w-24">Username</label>
-        <InputText id="username" class="flex-auto" autocomplete="off" />
-      </div>
-      <div class="flex items-center gap-4 mb-8">
-        <label for="email" class="font-semibold w-24">Email</label>
-        <InputText id="email" class="flex-auto" autocomplete="off" />
-      </div>
-      <div class="flex justify-end gap-2">
-        <Button type="button" label="Cancel" severity="secondary" @click="visible = false"></Button>
-        <Button type="button" label="Save" @click="visible = false"></Button>
-      </div>
-    </Dialog>
-  </div>
-</template>
-
-<script setup>
-  import { chartOptions } from '@/components/ECharts/optionsConfig'
-  import { useOutsideHomeStore } from '@/stores/modules/home'
-  import { $mitt } from '@/utils'
-
-  const { API_GET_GEO_JSON_GET } = useRequest()
-  const useHomeStore = useOutsideHomeStore()
-  const loading = ref(true)
-  const echartsRef = ref()
-  const visible = ref(false)
-
-  var toolTipData = [
-    {
-      name: '湖南省',
-      value: 5
-    },
-    {
-      name: '安徽省',
-      value: 5
-    },
-    {
-      name: '山东省',
-      value: 5
-    },
-    {
-      name: '四川省',
-      value: 5
-    },
-    {
-      name: '云南省',
-      value: 27
-    },
-    {
-      name: '黑龙江省',
-      value: 13
-    },
-    {
-      name: '甘肃省',
-      value: 42
-    },
-    {
-      name: '西藏自治区',
-      value: 74
-    }
-  ]
-  var geoCoordMap = {}
-
-  const fullOptions = ref({ options: {} })
-
-  // 南沙诸岛以缩略图展示
-  const formatJson = (chinaGeoJson) => {
-    chinaGeoJson.features.forEach((v) => {
-      if (v.properties && v.properties.name == '海南省') {
-        v.geometry.coordinates = v.geometry.coordinates.slice(0, 1)
-      }
-    })
-    // 过滤掉海南诸岛边界线
-    chinaGeoJson.features = chinaGeoJson.features.filter(
-      (item) => item.properties.adcode !== '100000_JD'
-    )
-    return chinaGeoJson
-  }
-  const setData = async (code = 100000, name = 'china') => {
-    const geoJSON = await API_GET_GEO_JSON_GET({ code })
-    loading.value = false
-    const data = []
-    formatJson(geoJSON).features.forEach((item) => {
-      data.push({
-        name: item.properties.name,
-        adcode: item.properties.adcode,
-        level: item.properties.level,
-        lonlat: item.properties.center
-      })
-      geoCoordMap[item.properties.name] = item.properties.center
-    })
-    echartsRef.value.myChart?.clear()
-    const options = chartOptions.setMapOption(data, geoJSON, toolTipData, geoCoordMap, name)
-    options.geo.forEach((v) => {
-      v.layoutSize = name == 'china' ? '130%' : '100%'
-    })
-    fullOptions.value.options = options
-    // echartsRef.value.myChart.on('georoam', function (params) {
-    //   var option = echartsRef.value.myChart.getOption() //获得option对象
-    //   if (params.zoom != null && params.zoom != undefined) {
-    //     //捕捉到缩放时
-    //     option.geo[1].zoom = option.geo[0].zoom //下层geo的缩放等级跟着上层的geo一起改变
-    //     option.geo[1].center = option.geo[0].center //下层的geo的中心位置随着上层geo一起改变
-    //   } else {
-    //     //捕捉到拖曳时
-    //     option.geo[1].center = option.geo[0].center //下层的geo的中心位置随着上层geo一起改变
-    //   }
-    //   echartsRef.value.myChart.dispatchAction({
-    //     type: 'restore'
-    //   })
-    //   echartsRef.value.myChart.setOption(option) //设置option
-    // })
-  }
-  const init = async () => {
-    setData()
-    echartsRef.value.myChart.on('dblclick', async function (params) {
-      if (params.data) {
-        const { adcode, name, level } = params.data
-        if (level === 'district' || params.componentSubType != 'map') {
-          return
-        }
-        console.log(level)
-
-        useHomeStore.setCode({ code: adcode, name })
-        setData(adcode, name)
-      }
-    })
-
-    $mitt.on('onPreLevel', (item) => {
-      if (useHomeStore.codes[useHomeStore.codes.length - 1].code === item.code) return
-      useHomeStore.codes = useHomeStore.codes.slice(
-        0,
-        useHomeStore.codes.findIndex((v) => v.name === item.name) + 1
-      )
-      setData(item.code, item.name === '中国' ? 'china' : item.name)
-    })
-  }
-  onMounted(() => {
-    init()
-  })
-</script>
-
-<style lang="scss">
-  .linebox > img {
-    position: absolute;
-    max-width: unset;
-  }
-  @keyframes scales1 {
-    0% {
-      transform: rotate(0);
-    }
-    100% {
-      transform: rotate(360deg);
-    }
-  }
-  @keyframes scales2 {
-    0% {
-      transform: rotate(0);
-    }
-    100% {
-      transform: rotate(-360deg);
-    }
-  }
-</style>

+ 305 - 0
src/layout/HomeMap/HomeMap.vue

@@ -0,0 +1,305 @@
+<template>
+  <div class="home-map w-full h-full">
+    <div
+      class="linebox absolute w-full h-full transform-scale-y-80 transform-scale-x-120 opacity-50 flex justify-center items-center"
+    >
+      <img
+        class="line1 w-1000px ml--3px mt--7px animate-[scales2_60s_linear_infinite]"
+        src="@/assets/images/lines1.png"
+      />
+      <img class="line2 animate-[scales1_15s_linear_infinite]" src="@/assets/images/lines2.png" />
+      <img
+        class="line3 animate-[scales2_20s_linear_infinite] opacity-100"
+        src="@/assets/images/lines3.png"
+      />
+    </div>
+    <ECharts
+      id="home-map-echarts"
+      width="100%"
+      height="100%"
+      ref="echartsRef"
+      class="flex justify-center items-center animate__animated animate__zoomIn"
+      :loading="loading"
+      :fullOptions="fullOptions"
+    />
+    <PubDialog
+      v-model:visible="visible"
+      :header="mapType == 1 ? '监控列表' : '报警列表'"
+      maximizable
+    >
+      <DataList :flag="mapType" />
+    </PubDialog>
+  </div>
+</template>
+
+<script setup>
+  import { chartOptions } from '@/components/ECharts/optionsConfig'
+  import { useOutsideHomeStore } from '@/stores/modules/home'
+  import { $mitt, getStaticResource } from '@/utils'
+  import DataList from './components/dataList.vue'
+
+  const { API_GET_GEO_JSON_GET } = useRequest()
+  const useHomeStore = useOutsideHomeStore()
+  const loading = ref(true)
+  const echartsRef = ref()
+  const visible = ref(false)
+
+  var toolTipData = [
+    {
+      name: '湖南省',
+      value: 5,
+      lonlat: [112.982279, 28.19409]
+    },
+    {
+      name: '安徽省',
+      value: 5,
+      lonlat: [117.283042, 31.86119]
+    },
+    {
+      name: '山东省',
+      value: 5,
+      lonlat: [117.000923, 36.675807]
+    },
+    {
+      name: '四川省',
+      value: 5,
+      lonlat: [104.065735, 30.659462]
+    },
+    {
+      name: '云南省',
+      value: 27,
+      lonlat: [102.712251, 25.040609]
+    },
+    {
+      name: '黑龙江省',
+      value: 13,
+      lonlat: [126.642464, 45.756967]
+    },
+    {
+      name: '甘肃省',
+      value: 42,
+      lonlat: [103.823557, 36.058039]
+    },
+    {
+      name: '西藏自治区',
+      value: 74,
+      lonlat: [91.132212, 29.660361]
+    }
+  ]
+  const fullOptions = ref({ options: {} })
+  // 判断当前经纬度是否在规定区域内
+  function isPointInMultiPolygon(point, multiPolygons) {
+    for (let polygon of multiPolygons) {
+      let coordinates = polygon.geometry.coordinates
+      if (isPointInAnyPolygon(point, coordinates)) {
+        return true
+      }
+    }
+    return false
+  }
+  function isPointInAnyPolygon(point, polygons) {
+    for (let polygon of polygons) {
+      if (isPointInPolygon(point, polygon[0])) {
+        return true
+      }
+    }
+    return false
+  }
+  function isPointInPolygon(point, polygon) {
+    // 射线法判断点是否在多边形内部
+    let x = point[0],
+      y = point[1]
+    let inside = false
+    for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
+      let xi = polygon[i][0],
+        yi = polygon[i][1]
+      let xj = polygon[j][0],
+        yj = polygon[j][1]
+      let intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi
+      if (intersect) {
+        inside = !inside
+      }
+    }
+    return inside
+  }
+
+  // 南沙诸岛以缩略图展示
+  const formatJson = (chinaGeoJson) => {
+    chinaGeoJson.features.forEach((v) => {
+      if (v.properties && v.properties.name == '海南省') {
+        v.geometry.coordinates = v.geometry.coordinates.slice(0, 1)
+      }
+    })
+    // 过滤掉海南诸岛边界线
+    chinaGeoJson.features = chinaGeoJson.features.filter(
+      (item) => item.properties.adcode !== '100000_JD'
+    )
+    return chinaGeoJson
+  }
+
+  let mapType = 0
+  let currentMap = { name: 'china', code: 100000 }
+  let optionConfig = null
+  const setData = async (code = 100000, name = 'china') => {
+    const geoJSON = await API_GET_GEO_JSON_GET({ code })
+    const data = []
+    loading.value = false
+    const newGeojson = formatJson(geoJSON)
+    newGeojson.features.forEach((item) => {
+      data.push({
+        name: item.properties.name,
+        adcode: item.properties.adcode,
+        level: item.properties.level,
+        lonlat: item.properties.center
+      })
+    })
+
+    // 过滤出当前地图的点位,过滤掉不属于改地图区域的点位
+    // let currentData = toolTipData.filter((v) => {
+    //   return isPointInMultiPolygon([v.lonlat[0], v.lonlat[1]], newGeojson.features)
+    // })
+
+    echartsRef.value.myChart?.clear()
+    optionConfig = chartOptions.setMapOption(
+      data,
+      geoJSON,
+      code === 100000 ? toolTipData : [],
+      name
+    )
+    optionConfig.option.geo.forEach((v) => {
+      v.layoutSize = name == 'china' ? '140%' : '100%'
+    })
+    currentMap = { name, code }
+    optionConfig.option.series.splice(
+      1,
+      0,
+      ...(mapType === 0
+        ? optionConfig.getSeries1()
+        : mapType === 1
+          ? optionConfig.getSeries2()
+          : optionConfig.getSeries1())
+    )
+    fullOptions.value.options = optionConfig.option
+    // echartsRef.value.myChart.on('georoam', function (params) {
+    //   var option = echartsRef.value.myChart.getOption() //获得option对象
+    //   if (params.zoom != null && params.zoom != undefined) {
+    //     //捕捉到缩放时
+    //     option.geo[1].zoom = option.geo[0].zoom //下层geo的缩放等级跟着上层的geo一起改变
+    //     option.geo[1].center = option.geo[0].center //下层的geo的中心位置随着上层geo一起改变
+    //   } else {
+    //     //捕捉到拖曳时
+    //     option.geo[1].center = option.geo[0].center //下层的geo的中心位置随着上层geo一起改变
+    //   }
+    //   echartsRef.value.myChart.dispatchAction({
+    //     type: 'restore'
+    //   })
+    //   echartsRef.value.myChart.setOption(option) //设置option
+    // })
+  }
+  const init = async () => {
+    setData()
+    echartsRef.value.myChart.on('dblclick', async function (params) {
+      if (params.data) {
+        const { adcode, name, level } = params.data
+        if (level === 'district' || params.componentSubType != 'map') {
+          return
+        }
+        useHomeStore.setCode({ code: adcode, name })
+        setData(adcode, name)
+      }
+    })
+    echartsRef.value.myChart.on('click', async function (params) {
+      console.log(params)
+      if (params.seriesType === 'scatter') {
+        visible.value = true
+      }
+    })
+
+    $mitt.on('onPreLevel', (item) => {
+      if (useHomeStore.codes[useHomeStore.codes.length - 1].code === item.code) return
+      useHomeStore.codes = useHomeStore.codes.slice(
+        0,
+        useHomeStore.codes.findIndex((v) => v.name === item.name) + 1
+      )
+      setData(item.code, item.name === '中国' ? 'china' : item.name)
+    })
+    const toolsIndex = (i) => {
+      const series = fullOptions.value.options.series
+      let newSeries = [series[0]]
+      const index = series.findIndex((v) => v.name === '热力图')
+      if (typeof i === 'number') {
+        mapType = i
+        if (i === 0) {
+          if (index != -1) {
+            newSeries = [...newSeries, series[index], ...optionConfig.getSeries1()]
+          } else {
+            newSeries = [...newSeries, ...optionConfig.getSeries1()]
+          }
+        } else if (i === 1) {
+          if (index != -1) {
+            newSeries = [...newSeries, series[index], ...optionConfig.getSeries2()]
+          } else {
+            newSeries = [...newSeries, ...optionConfig.getSeries2()]
+          }
+        }
+        fullOptions.value.options.series = newSeries
+      } else {
+        if (i.type === 'rlt') {
+          if (i.selected) {
+            series.push(...optionConfig.getSeries3())
+          } else {
+            if (index == -1) return
+            delete fullOptions.value.options.visualMap
+            series.splice(
+              series.findIndex((v) => v.name === '热力图'),
+              1
+            )
+          }
+        } else if (i.type === 'xs') {
+          if (i.selected) {
+            toolsIndex(mapType)
+            toolsIndex({ type: 'rlt' })
+          } else {
+            fullOptions.value.options.series = [series[0]]
+          }
+        }
+      }
+    }
+    $mitt.on('onToolsIndex', toolsIndex)
+  }
+
+  watch(
+    () => useHomeStore.temp,
+    (val) => {
+      if (val === 'video') {
+        visible.value = false
+      }
+    }
+  )
+  onMounted(() => {
+    init()
+  })
+</script>
+
+<style lang="scss">
+  .linebox > img {
+    position: absolute;
+    max-width: unset;
+  }
+  @keyframes scales1 {
+    0% {
+      transform: rotate(0);
+    }
+    100% {
+      transform: rotate(360deg);
+    }
+  }
+  @keyframes scales2 {
+    0% {
+      transform: rotate(0);
+    }
+    100% {
+      transform: rotate(-360deg);
+    }
+  }
+</style>

+ 82 - 0
src/layout/HomeMap/components/dataList.vue

@@ -0,0 +1,82 @@
+<template>
+  <div class="data-list w-full h-full">
+    <template v-if="flagCom">
+      <DataTable :value="tableData" scrollable scrollHeight="flex" paginator :rows="10">
+        <Column field="bj" header="报警"></Column>
+        <Column field="type" header="报警类型"></Column>
+        <Column field="time" header="报警时间"></Column>
+        <Column field="level" header="报警级别">
+          <template #body="slotProps">
+            {{ slotProps.data.level ? '故障' : '告警' }}
+          </template>
+        </Column>
+        <Column field="handle" header="处理">
+          <template #body="slotProps">
+            {{ slotProps.data.handle ? '已处理' : '未处理' }}
+          </template>
+        </Column>
+        <Column header="操作">
+          <template #body="{ data }">
+            <Button size="small" label="查看" severity="info" />
+          </template>
+        </Column>
+      </DataTable>
+    </template>
+    <template v-else>
+      <DataTable :value="tableData" scrollable scrollHeight="flex" paginator :rows="10">
+        <Column field="name" header="设备"></Column>
+        <Column field="status" header="状态"></Column>
+        <Column header="操作" class="w-24">
+          <template #body="{ data }">
+            <Button size="small" label="查看" severity="info"  @click="useHomeStore.temp = 'video'"/>
+          </template>
+        </Column>
+      </DataTable>
+    </template>
+  </div>
+</template>
+
+<script setup>
+  import { useOutsideHomeStore } from '@/stores/modules/home'
+
+  const useHomeStore = useOutsideHomeStore()
+  const props = defineProps({ flag: { type: Number, default: 0 } })
+  const tableData = ref([])
+  const flagCom = computed(() => props.flag === 0)
+
+  onMounted(() => {
+    if (flagCom.value) {
+      tableData.value = [
+        {
+          id: 1000,
+          bj: 'XY7080',
+          type: '工服',
+          time: '2022-01-01',
+          level: 1,
+          handle: 0
+        },
+        {
+          id: 1001,
+          bj: 'XY7080',
+          type: '工服',
+          time: '2022-01-01',
+          level: 0,
+          handle: 1
+        }
+      ]
+    } else {
+      tableData.value = [
+        {
+          id: 1000,
+          name: 'XY7080',
+          status: '在线'
+        },
+        {
+          id: 1001,
+          name: 'XY7080',
+          status: '离线'
+        }
+      ]
+    }
+  })
+</script>

+ 1 - 1
src/views/home/home.vue

@@ -47,7 +47,7 @@
   import MiddleTopBox from './middleTopBox/index.vue'
   import VideoBox from '../VideoBox/index.vue'
   // import Map from '@/layout/Map.vue'
-  import HomeMap from '@/layout/HomeMap.vue'
+  import HomeMap from '@/layout/HomeMap/HomeMap.vue'
   import { $mitt } from '@/utils'
   import { useOutsideHomeStore } from '@/stores/modules/home'
 

+ 15 - 3
src/views/home/middleTopBox/components/tool.vue

@@ -58,19 +58,22 @@
       icon: getStaticResource('assets/images/gn1-icon.png'),
       yes: getStaticResource('assets/images/gn-yes-bg.png'),
       no: getStaticResource('assets/images/gn-no-bg.png'),
-      selected: true
+      selected: true,
+      type: 'mr'
     },
     {
       icon: getStaticResource('assets/images/gn2-icon.png'),
       yes: getStaticResource('assets/images/gn-yes-bg.png'),
       no: getStaticResource('assets/images/gn-no-bg.png'),
-      selected: false
+      selected: false,
+      type: 'rlt'
     },
     {
       icon: getStaticResource('assets/images/gn3-icon.png'),
       yes: getStaticResource('assets/images/gn-yes-bg.png'),
       no: getStaticResource('assets/images/gn-no-bg.png'),
-      selected: false
+      selected: true,
+      type: 'xs'
     },
     {
       icon: getStaticResource('assets/images/gn3-icon.png'),
@@ -82,6 +85,9 @@
 
   const toolClick = (item) => {
     item.selected = !item.selected
+    if (item?.type === 'rlt' || item?.type === 'xs') {
+      $mitt.emit('onToolsIndex', item)
+    }
   }
 
   const oneActive = ref(0)
@@ -91,6 +97,11 @@
       yes: getStaticResource('assets/images/yes-icon.png'),
       no: getStaticResource('assets/images/no-icon.png')
     },
+    {
+      name: '监控分布',
+      yes: getStaticResource('assets/images/yes-icon.png'),
+      no: getStaticResource('assets/images/no-icon.png')
+    },
     {
       name: '国界入侵报警',
       yes: getStaticResource('assets/images/yes-icon.png'),
@@ -104,6 +115,7 @@
   ])
   const oneClick = (i) => {
     oneActive.value = i
+    $mitt.emit('onToolsIndex', i)
   }
   const twoActive = ref(0)
   const twoList = ref([

Some files were not shown because too many files changed in this diff