瀏覽代碼

城市应急

Hwf 2 月之前
父節點
當前提交
3ef9ed9d2a

二進制
src/assets/images/dotIcon/address.png


二進制
src/assets/images/dotIcon/address_hover.png


+ 370 - 0
src/components/Map/index2.vue

@@ -0,0 +1,370 @@
+<template>
+  <div class="map-container">
+    <div id="aMap" class="map-container2"></div>
+  </div>
+</template>
+
+<script setup lang="ts" name="Map">
+import {useAMap} from '@/hooks/AMap/useAMap';
+import {useDrawTool} from '@/hooks/AMap/useDrawTool';
+import {getDictLabel} from '@/utils/dict';
+import {pointDetailTemplate} from './mapData';
+import {getPointInfoList} from "@/api/globalMap";
+import {methodList, titleList} from './data';
+
+interface EventDetails {
+  'event_id': String;
+  'event_title': String;
+  'event_status': String;
+  'keep_time': String;
+  'event_type': String;
+  'event_level': String;
+  'address': String;
+  'event_time': String;
+  'event_source': String;
+  'latitude': String;
+  'longitude': String
+}
+
+interface Props {
+  activeMap: string;
+  pointType: [];
+  eventDetails?: EventDetails;
+  zoom?: number
+  customMarker?: boolean
+}
+
+const props = withDefaults(defineProps<Props>(), {});
+const {proxy} = getCurrentInstance() as ComponentInternalInstance;
+const {point_type} = toRefs<any>(proxy?.useDict('point_type'));
+
+const emits = defineEmits(['onLoadCompleted', 'onMarkerClick', 'selectGraphics', 'unSelectGraphics', 'showTextEditBox', 'onDrawCompleted', 'handleShowVideo', 'handleShowWarehouse']);
+
+const mapState = reactive({
+  center: [110.925175, 21.678955],
+  zoom: 7.9,
+  minZoom: 6,
+  maxZoom: 20,
+  isThreeDimensional: false,
+  // 是否显示比例尺
+  showScale: true
+});
+let AMap, map, scale;
+// 鼠标绘制工具
+const drawTool = useDrawTool();
+// 初始化地图
+const mapUtils = useAMap({
+  key: '9c5041381e5e824f9ee324d8f7a40150', // 申请好的Web端开发者Key,首次调用 load 时必填
+  securityJsCode: '4868bc1b8fac7d9e54e7279ed556879a', // 安全密钥
+  version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
+  pitch: mapState.isThreeDimensional ? 45 : 0,
+  zoom: !!props.zoom ? props.zoom : mapState.zoom,
+  center: !!props.eventDetails && props.eventDetails.longitude && props.eventDetails.latitude ? [props.eventDetails.longitude, props.eventDetails.latitude] : [mapState.center[0], mapState.center[1]],
+  dragEnable: true,
+  scrollWheel: true,
+  enableMouseTool: true,
+  // 加载完成事件
+  onLoadCompleted: () => {
+    AMap = getAMap();
+    map = getMap();
+    scale = getScale();
+    if (!['logical', 'vectorgraph'].includes(props.activeMap)) {
+      switchMap(props.activeMap);
+    } else {
+      map.removeLayer();
+    }
+    drawTool.initMouseTool({container: 'aMap', map, AMap});
+    handleResize();
+    emits('onLoadCompleted')
+  },
+  onMarkerClick: (data) => {
+    // 多点位
+    if (data.type === '1') {
+      let path = [];
+      props.pointType.forEach((item) => {
+        path.push(item.component);
+      });
+      getPointInfoList({
+        option: path.toString(),
+        longitude: data.longitude.toString(),
+        latitude: data.latitude.toString()
+      }).then((res) => {
+        const data2 = res.data.list;
+        let content = document.createElement('div');
+        content.className = 'point-info';
+        let content2 = '';
+        content2 += '<div class="title-box"><div class="gradient-text">多点位信息</div></div>';
+        content2 += '<div class="icon1"></div>';
+        content2 += '<div class="icon2"></div>';
+        content2 += '<div class="icon3"></div>';
+        content2 += '<div class="icon4"></div>';
+        content.innerHTML = content2;
+        let tableBox = document.createElement('div');
+        tableBox.className = 'table-box';
+        let table = document.createElement('div');
+        table.className = 'table';
+        table.innerHTML = '<div class="point-item"><div class="td3">主题</div><div class="td3">名称</div></div>';
+        data2.forEach((item) => {
+          item.longitude = data.longitude;
+          item.latitude = data.latitude;
+          const div = document.createElement('div');
+          div.className = 'point-item point-item-hover';
+          div.innerHTML =
+              '<div class="td4">' + getDictLabel(point_type.value, item.dataType.toString()) + '</div><div class="td4">' + item.name + '</div>';
+          div.addEventListener('click', () => {
+            handlePointDetails(item);
+          });
+          table.appendChild(div);
+        });
+        tableBox.appendChild(table);
+        content.appendChild(tableBox);
+        let closeBtn = document.createElement('div');
+        closeBtn.className = 'close';
+        closeBtn.onclick = hideInfo;
+        content.appendChild(closeBtn);
+        showInfo(content, [data.longitude, data.latitude], true);
+      });
+    } else {
+      if (props.customMarker) {
+        emits('onMarkerClick', data)
+      } else {
+        handlePointDetails(data);
+      }
+    }
+  }
+});
+const {
+  getAMap,
+  getMap,
+  switchMap,
+  addMarker,
+  addSearchMarker,
+  clearMarker,
+  getMarkers,
+  getScale,
+  showInfo,
+  hideInfo,
+  handleHover,
+  creatMask,
+  trackPlayback
+} = {...mapUtils};
+const handlePointDetails = (data) => {
+  const method = methodList[data.dataType];
+  if (!!method) {
+    // 请求接口获取详情
+    method(data.id).then((res) => {
+      if (!!pointDetailTemplate[data.dataType]) {
+        createInfo(data, res);
+      }
+    });
+  } else if (!!pointDetailTemplate[data.detailType]) {
+    // 直接用现有数据展示
+    createInfo(data)
+  }
+};
+const createInfo = (data, res) => {
+  let dataType = '';
+  if (!!titleList[data.dataType]) {
+    dataType = data.dataType;
+  } else if (!!titleList[data.detailType]) {
+    dataType = data.detailType;
+  }
+  let title = titleList[dataType] ? titleList[dataType] :  '信息';
+  let div = document.createElement('div');
+  div.className = 'point-info';
+  let titleDom = document.createElement('div');
+  titleDom.className = 'title-box';
+  titleDom.innerHTML = '<div class="gradient-text">' + title + '</div></div>';
+  div.appendChild(titleDom);
+  if (data.dataType === 2) {
+    let btnBox = document.createElement('div');
+    let btn = document.createElement('div');
+    btnBox.className = 'flex';
+    btn.className = 'btn';
+    btn.innerHTML = '<div class="video-icon"></div><div>物资详情</div>';
+    btn.onclick = () => {
+      emits('handleShowWarehouse', data);
+    };
+    btnBox.appendChild(btn);
+    div.appendChild(btnBox);
+  } else if (data.dataType === 4) {
+    let btnBox = document.createElement('div');
+    let btn = document.createElement('div');
+    btnBox.className = 'flex';
+    btn.className = 'btn';
+    btn.innerHTML = '<div class="video-icon"></div><div>附近视频</div>';
+    btn.onclick = () => {
+      emits('handleShowVideo', data);
+    };
+    btnBox.appendChild(btn);
+    div.appendChild(btnBox);
+  }
+  let icon1 = document.createElement('div');
+  icon1.className = 'icon1';
+  let icon2 = document.createElement('div');
+  icon2.className = 'icon2';
+  let icon3 = document.createElement('div');
+  icon3.className = 'icon3';
+  let icon4 = document.createElement('div');
+  icon4.className = 'icon4';
+  div.appendChild(icon1);
+  div.appendChild(icon2);
+  div.appendChild(icon3);
+  div.appendChild(icon4);
+  let table = document.createElement('div');
+  table.className = 'table-box';
+  let content = '';
+  content += '<div class="table">';
+  let newData = [];
+  if (res) {
+    newData = filterTd(res.rows[0], dataType);
+  } else {
+    newData = filterTd(data, dataType);
+  }
+  newData.forEach((item) => {
+    if (item.type === 'shortText') {
+      content += '<div class="tr">';
+      item.data.forEach((item2) => {
+        content += '<div class="point-item">';
+        content += '<div class="td1">' + item2.label + '</div><div class="td2">' + item2.value + '</div>';
+        content += '</div>';
+      });
+      content += '</div>';
+    } else {
+      content += '<div class="point-item2">';
+      content += '<div class="td1">' + item.data[0].label + '</div><div class="td2">' + item.data[0].value + '</div>';
+      content += '</div>';
+    }
+  });
+  content += '</div>';
+  table.innerHTML = content;
+  div.appendChild(table);
+  let closeBtn = document.createElement('div');
+  closeBtn.className = 'close';
+  closeBtn.onclick = hideInfo;
+  div.appendChild(closeBtn);
+  showInfo(div, [data.longitude, data.latitude], true);
+}
+const filterTd = (obj, dataType) => {
+  let data = [];
+  let tempData = {};
+  let i = 0;
+  const pointDetailTemplateObj = pointDetailTemplate[dataType];
+  Object.keys(pointDetailTemplateObj).forEach((key) => {
+    let keyLabel = pointDetailTemplateObj[key];
+    if (!!keyLabel) {
+      if (i === 2) {
+        i = 0;
+      }
+      const value = !!obj && !!obj[key] ? obj[key] : '';
+      if (value && value.length > 8) {
+        if (i === 0) {
+          data.push({ type: 'longText', data: [{ label: keyLabel, value: value }] });
+          i = 0;
+        } else {
+          tempData = { type: 'longText', data: [{ label: keyLabel, value: value }] };
+        }
+      } else {
+        if (i === 0) {
+          data.push({ type: 'shortText', data: [{ label: keyLabel, value: value }] });
+        } else {
+          data[data.length - 1].data.push({ label: keyLabel, value: value });
+        }
+        i++;
+        if (!!tempData && JSON.stringify(tempData) !== '{}') {
+          data.push(tempData);
+          tempData = {};
+          i = 0;
+        }
+      }
+    }
+  })
+  if (!!tempData && JSON.stringify(tempData) !== '{}') {
+    data.push(tempData);
+  }
+  if (data[data.length - 1].data && data[data.length - 1].data.length === 1 && data[data.length - 1].type === 'shortText') {
+    data[data.length - 1].type = 'longText';
+  }
+  return data;
+};
+// 监听地图类型变化
+watch(
+    () => props.activeMap,
+    () => {
+      switchMap(props.activeMap);
+    }
+);
+
+watch(() => props.eventDetails, () => {
+  if (!!map) {
+    clearMarker('point');
+    map.setCenter(props.eventDetails.longitude && props.eventDetails.latitude ? [props.eventDetails.longitude, props.eventDetails.latitude] : [mapState.center[0], mapState.center[1]]);
+  }
+}, {
+  deep: true
+})
+const getMapUtils = () => {
+  return mapUtils;
+};
+const getDrawTool = () => {
+  return mapUtils.getDrawTool();
+};
+defineExpose({
+  getDrawTool,
+  getMapUtils,
+  addMarker,
+  addSearchMarker,
+  getMarkers,
+  clearMarker,
+  getMap,
+  drawTool,
+  handleHover
+});
+const handleResize = () => {
+  map.resize();
+};
+onMounted(() => {
+  window.addEventListener('resize', handleResize);
+});
+// 卸载事件
+onUnmounted(() => {
+  window.removeEventListener('resize', handleResize);
+});
+</script>
+
+<style lang="scss" scoped>
+@import 'map.scss';
+
+.map-container2 {
+  width: 100%;
+  height: 100%;
+  position: relative;
+  overflow: hidden;
+}
+
+.map-container {
+  width: 100%;
+  height: 100%;
+
+  :deep(.amap-logo),
+  :deep(.amap-copyright) {
+    display: none !important;
+  }
+
+  :deep(.amap-marker-label) {
+    border: 1px solid #474747;
+    background-color: rgba(255, 255, 255, 0.65);
+    padding: 3px 8px;
+    border-radius: 4px;
+  }
+  :deep(.amap-info-content) {
+    padding: 0;
+  }
+  :deep(.amap-info-close) {
+    display: none;
+  }
+  :deep(.amap-info-sharp) {
+    display: none;
+  }
+}
+</style>

+ 1 - 1
src/store/modules/map.ts

@@ -43,7 +43,7 @@ export const useMapStore = defineStore('map', () => {
   // 跳转界面时 初始化所有数据
   const initData = () => {
     mapState.center = [110.925175, 21.978955];
-    activeMap.value = 'satellite2';
+    activeMap.value = 'satellite';
     showMask.value = true;
     pointType.value = [];
   };

+ 1 - 1
src/utils/olMap/olMap.ts

@@ -1509,7 +1509,7 @@ export class olMap {
     return this.drawVector;
   }
   getMap() {
-    return this.map;
+    return this.map;c
   }
   getScale() {
     return this.scale;

+ 1 - 1
src/views/InformationReception/index.vue

@@ -138,7 +138,7 @@
           class="item-content"
         >
           <div class="line-item">
-            <div class="item-label">发布时间:</div>
+            <div class="item-label">发布时间2:</div>
             <div class="item-value">{{ item.recv_time }}</div>
           </div>
           <div class="line-item">

+ 207 - 374
src/views/disasterRiskMonitor/cityEmergencyEvent.vue

@@ -3,317 +3,261 @@
     <div class="event-box">
       <div class="box-header">
         <div class="title-box">
-          <div class="title"><i class="icon-speaker" />重大事件信息</div>
+          <div class="title"><i class="icon-speaker"/>重大事件信息</div>
         </div>
-        <div class="more">查看更多>></div>
       </div>
       <div class="event-content">
-        <div class="text1">{{ noticeBarState.event_title }}</div>
-        <div class="text2">{{ noticeBarState.time }}</div>
+        <div class="text1">{{ noticeBarState[0]?.event_title }}</div>
+        <div class="text2">{{ noticeBarState[0]?.time }}</div>
       </div>
     </div>
     <div ref="searchBoxRef" class="search-box">
       <van-search
-        v-model="queryParams.keywords"
-        placeholder="请输入位置信息"
-        class="common-search"
-        :left-icon="searchImg"
-        show-action
-        @search="onSearchKeyword"
+          v-model="keywords"
+          placeholder="请输入位置信息"
+          class="common-search"
+          :left-icon="searchImg"
+          show-action
+          @search="onSearchKeyword"
       >
         <template #action>
           <div class="search-btn" @click="onSearchKeyword">搜索</div>
         </template>
       </van-search>
       <div v-show="showSearch" class="search-list">
-        <van-list
-          v-model:loading="loading"
-          v-model:error="error"
-          error-text="请求失败,点击重新加载"
-          :finished="finished"
-          finished-text="没有更多了"
-          :immediate-check="false"
-          @load="getSearchList"
-        >
-          <div
+        <div
             v-for="(item, index) in searchList"
             :key="index"
             class="item"
             @click="handleClickItem(item)"
-          >
-            {{ item.name }}
-          </div>
-        </van-list>
+        >
+          {{ item.name }}
+        </div>
       </div>
     </div>
     <div class="content" style="margin-top: 0">
       <Map
-        ref="mapRef"
-        class="map"
-        active-map="satellite"
-        :event-details="eventDetails"
-        @onLoadCompleted="initData"
+          ref="mapRef"
+          class="map"
+          active-map="satellite"
+          customMarker
+          @onLoadCompleted="initData"
+          @onMarkerClick="handleRowClick"
       />
     </div>
     <div class="content">
       <div class="card">
         <div class="card-header">
-          <i class="icon-line" />
+          <i class="icon-line"/>
           <div class="text">趋势统计</div>
         </div>
-        <Chart :option="option1" style="height: 200px" />
+        <Chart :option="option1" style="height: 200px"/>
       </div>
     </div>
     <div class="content">
       <div class="card">
         <div class="card-header">
-          <i class="icon-line" />
+          <i class="icon-line"/>
           <div class="text">事件列表</div>
         </div>
         <div class="select-box" @click="showPicker = true">
           <div class="text1">年度</div>
           <div class="select-item">
             <div class="label">{{ yearLabel ? yearLabel : "请选择" }}</div>
-            <i class="icon-down" />
+            <i class="icon-down"/>
           </div>
         </div>
         <el-table
-          :data="detailsData.dataList"
-          border
-          table-layout="auto"
-          @row-click="handleRowClick"
+            :data="dataList"
+            border
+            table-layout="auto"
+            @row-click="handleRowClick"
         >
           <el-table-column label="类别" prop="event_type" align="center">
             <template #default="scope">
-              <dict-tag :options="mm_event_type" :value="scope.row.event_type" />
+              <dict-tag :options="mm_event_type" :value="scope.row.event_type"/>
             </template>
           </el-table-column>
-          <el-table-column label="位置" prop="address" align="center" />
-          <el-table-column label="发生时间" prop="create_time" align="center" />
-          <el-table-column label="受伤人数" prop="data4" align="center" />
-          <el-table-column label="死亡人数" prop="data5" align="center" />
-          <!--          <el-table-column-->
-          <!--            label="操作"-->
-          <!--            align="center"-->
-          <!--            width="50px"-->
-          <!--            fixed="right"-->
-          <!--          >-->
-          <!--            <template #default="scope">-->
-          <!--              <div-->
-          <!--                class="btn"-->
-          <!--                style="color: #1d92ff"-->
-          <!--                @click="showDetails(scope.row)"-->
-          <!--              >-->
-          <!--                详情-->
-          <!--              </div>-->
-          <!--            </template>-->
-          <!--          </el-table-column>-->
+          <el-table-column label="位置" prop="address" align="center"/>
+          <el-table-column label="发生时间" prop="create_time" align="center"/>
+          <el-table-column label="受伤人数" prop="data4" align="center"/>
+          <el-table-column label="死亡人数" prop="data5" align="center"/>
         </el-table>
       </div>
     </div>
     <van-popup v-model:show="showPicker" round position="bottom">
       <van-picker
-        :columns="columns"
-        @cancel="showPicker = false"
-        @confirm="onPickerConfirm"
+          :columns="columns"
+          @cancel="showPicker = false"
+          @confirm="onPickerConfirm"
       />
     </van-popup>
-  </div>
-  <van-popup v-model:show="showDetailPop" position="bottom">
-    <div class="title">事件详情</div>
-    <div class="unit-box">
-      <div class="text">位置</div>
-      <div class="info-content">{{rowDetail.address}}</div>
-    </div>
-    <div class="unit-box">
-      <div class="text">灾害类型</div>
-      <div class="info-content">
-        <dict-tag :options="mm_event_type" :value="rowDetail.event_type" />
+    <van-popup v-model:show="showDetailPop" position="bottom">
+      <div class="title">事件详情</div>
+      <div class="unit-box">
+        <div class="text">位置</div>
+        <div class="info-content">{{ rowDetail.address }}</div>
       </div>
-    </div>
-    <div class="unit-box">
-      <div class="text">发生时间</div>
-      <div class="info-content">{{rowDetail.create_time}}</div>
-    </div>
-    <div class="unit-box">
-      <div class="text">受伤人数</div>
-      <div class="info-content">{{rowDetail.data4}}</div>
-    </div>
-    <div class="unit-box">
-      <div class="text">死亡人数</div>
-      <div class="info-content">{{rowDetail.data5}}</div>
-    </div>
-  </van-popup>
+      <div class="unit-box">
+        <div class="text">灾害类型</div>
+        <div class="info-content">
+          <dict-tag :options="mm_event_type" :value="rowDetail.event_type"/>
+        </div>
+      </div>
+      <div class="unit-box">
+        <div class="text">发生时间</div>
+        <div class="info-content">{{ rowDetail.create_time }}</div>
+      </div>
+      <div class="unit-box">
+        <div class="text">受伤人数</div>
+        <div class="info-content">{{ rowDetail.data4 }}</div>
+      </div>
+      <div class="unit-box">
+        <div class="text">死亡人数</div>
+        <div class="info-content">{{ rowDetail.data5 }}</div>
+      </div>
+    </van-popup>
+  </div>
 </template>
 
 <script lang="ts" setup name="cityEmergencyEvent">
-import noticeImg from "@/assets/images/notice.png";
-import { onMounted, reactive, ref } from "vue";
-import { useRouter } from "vue-router";
-import { getActiveEventList } from "@/api/event";
+import {ElTable, ElTableColumn} from "element-plus";
+import Map from '@/components/Map/index2.vue';
+import {getEvent} from "@/api/duty/eventing";
+import {chartOption1} from "@/views/disasterRiskMonitor/chartOptions";
 import searchImg from "@/assets/images/search.png";
-import closeImg from "@/assets/images/close.png";
-import { getPointInfoComprehensiveSearch } from "@/api/globalMap";
-import { onClickOutside } from "@vueuse/core";
-import { chartOption1 } from "@/views/disasterRiskMonitor/chartOptions";
-import { ElTable, ElTableColumn } from "element-plus";
-import { getEvent } from "@/api/duty/eventing";
-let mapRef = ref();
-const router = useRouter();
-const noticeBarState = reactive({
-  show: false,
-  event_id: "",
-  time: "2024-03-01 12:12:12",
-  event_title:
-    "茂名市茂南区xxx高速路口发生交通事故,今日凌晨三点在xx高速路口,由于突降暴雨路面湿滑,导致路面积水严重,不少路过车辆都减速慢行…"
-});
-const handleNoticeBar = () => {};
-// 搜索
-const searchBoxRef = ref();
-let showSearch = ref();
-const total = ref(0);
-let loading = ref(false);
-let error = ref(false);
-let finished = ref(false);
-const queryParams = reactive({
-  page: 1,
-  page_size: 10,
-  year: "",
-  keywords: ""
-});
+import { iconList } from '@/components/Map/mapData';
+
 const proxy = getCurrentInstance()?.proxy;
-const { mm_event_type } = toRefs<any>(
+const {mm_event_type} = toRefs<any>(
     proxy?.useDict('mm_event_type')
 );
+let mapRef = ref();
+const noticeBarState = ref([]);
+// 搜索
+const searchBoxRef = ref();
+const keywords = ref('');
+let searchList = ref([]);
+let showSearch = ref(false);
 let yearLabel = ref("");
-const searchList = ref([]);
 onClickOutside(searchBoxRef, event => {
   showSearch.value = false;
 });
-const getSearchList = () => {
-  if (!queryParams.keywords) {
-    return (loading.value = false);
-  }
-  queryParams.page++;
-  getPointInfoComprehensiveSearch(queryParams)
-    .then(res => {
-      const items = res.data.list || [];
-      total.value = res.data.total;
-      if (queryParams.page == 1) {
-        searchList.value = [];
-      }
-      items.forEach(val => {
-        searchList.value.push(val);
-      });
-      if (queryParams.page_size * queryParams.page >= total.value) {
-        finished.value = true;
-      } else {
-        finished.value = false;
-      }
-      showSearch.value = true;
-    })
-    .catch(() => {
-      error.value = true;
-      finished.value = false;
-    })
-    .finally(() => {
-      loading.value = false;
-    });
-};
-const onSearchKeyword = val => {
-  queryParams.keywords = val;
-  queryParams.page = 0;
-  getSearchList();
+const onSearchKeyword = () => {
+  searchList.value = []
+  getSearch();
 };
-const onSearchCancel = () => {
+const handleClickItem = (row) => {
   showSearch.value = false;
-  queryParams.keywords = "";
-  queryParams.page = 0;
-  finished.value = false;
-  searchList.value = [];
-};
-const handleClickItem = item => {
-  showSearch.value = false;
-  queryParams.keywords = "";
-  queryParams.page = 0;
-  finished.value = false;
-  searchList.value = [];
+  const dom = mapRef.value;
+  const map = dom.getMap();
+  const mapUtils = dom.getMapUtils();
+  const center = row.lonlat.split(",").map(Number);
+  const item = iconList['common'];
+  mapUtils.addSearchMarker({
+    icon: item.image,
+    image: item.image,
+    imageHover: item.image,
+    size: item.size,
+    lnglat: center
+  });
+  map.setCenter(center);
+  map.setZoom(16);
 };
-let pointType = ref([]);
-let eventDetails = ref({});
-let detailsData = ref({
-  dataList: []
-});
+const getSearch = async() => {
+  const url = `http://api.tianditu.gov.cn/v2/search?postStr=${encodeURIComponent(JSON.stringify({
+    keyWord: keywords.value,
+    level: '18',
+    mapBound: "73.33,8.33,135.08,53.55",
+    queryType: '1',
+    start: 0,
+    count: 10
+  }))}&tk=a8df87f1695d224d2679aa805c1268d9&type=query`
+  const res = await fetch(url);
+  if (res.status === 200) {
+    const data = await res.json();
+    searchList.value = data.pois
+  }
+  showSearch.value = true;
+}
+let dataList = ref([]);
 const option1 = ref(chartOption1);
+const queryParams = reactive({
+  page: 1,
+  pageSize: 10,
+  year: ''
+});
+let loading = ref(false);
 let showPicker = ref(false);
 const showDetailPop = ref(false);
 let columns = reactive([
-  { text: "2024年", value: "2024" },
-  { text: "2023年", value: "2023" },
-  { text: "2022年", value: "2022" },
-  { text: "2021年", value: "2021" }
+  {text: "2025年", value: "2025"},
+  {text: "2024年", value: "2024"},
+  {text: "2023年", value: "2023"},
+  {text: "2022年", value: "2022"},
+  {text: "2021年", value: "2021"}
 ]);
 const getImageUrl = name => {
   return new URL(
-    `../../assets/images/disasterRiskMonitor/cityEmergencyEvent/${name}`,
-    import.meta.url
+      `../../assets/images/dotIcon/${name}`,
+      import.meta.url
   ).href;
 };
-let iconList = reactive({
-  "1": {
-    image: getImageUrl("icon2.png"),
-    size: [20, 20]
-  },
-  "2": {
-    image: getImageUrl("icon1.png"),
-    size: [20, 20]
-  }
-});
-const onPickerConfirm = ({ selectedOptions }) => {
+const onPickerConfirm = ({selectedOptions}) => {
   showPicker.value = false;
   yearLabel.value = selectedOptions[0].text;
   queryParams.year = selectedOptions[0].value;
-};
-const showDetails = row => {
-  router.push({ name: "CityEmergencyDetails", query: { id: row.id } });
+  getList()
 };
 const getList = () => {
   loading.value = true;
-  getEvent(queryParams)
-    .then(res => {
-      // let data = res.data;
-      // // 确保 data 是数组
-      // if (!Array.isArray(data)) {
-      //   data = [data];
-      // }
-      // // 转换 event_type
-      // data = data.map(item => ({
-      //   ...item,
-      //   event_type: eventType[item.event_type] || item.event_type
-      // }));
-      detailsData.value.dataList = res.data;
-      // total.value = res.total;
-    })
-    .finally(() => {
-      loading.value = false;
+  getEvent(queryParams).then(res => {
+    dataList.value = res.data;
+    dataList.value.forEach(item => {
+      const icon = {
+        image: getImageUrl("address.png"),
+        size: [30, 32]
+      }
+      item.icon = icon.image;
+      item.image = icon.image;
+      item.imageHover = icon.image;
+      item.size = icon.size;
+      item.lnglat = [item.longitude, item.latitude];
     });
+    const dom = mapRef.value;
+    dom.addMarker(dataList.value);
+  }).finally(() => {
+    loading.value = false;
+  });
 };
-getList();
-const rowDetail = ref();
-const handleRowClick = row => {
-  // showDetails(row);
-  showDetailPop.value = true;
-  rowDetail.value = row;
+const rowDetail = ref({
+  address: '',
+  event_type: '',
+  create_time: '',
+  data4: '',
+  data5: ''
+});
+const handleRowClick = (row) => {
+  setTimeout(() => {
+    showDetailPop.value = true;
+    rowDetail.value = row;
+  }, 10)
 };
 const initData = () => {
-  const dom = mapRef.value;
   // getActiveEventList().then(res => {
-  //   if (res.data.event_id != noticeBarState.event_id) {
-  //     noticeBarState.show = true;
-  //     noticeBarState.event_id = res.data.event_id;
-  //     noticeBarState.event_title = res.data.event_title;
+  //   if (res.data.event_id != noticeBarState.value.event_id) {
+  //     noticeBarState.value.show = true;
+  //     noticeBarState.value.event_id = res.data.event_id;
+  //     noticeBarState.value.event_title = res.data.event_title;
   //   }
   // });
+  noticeBarState.value = [
+    {
+      event_id: "",
+      time: "2024-03-01 12:12:12",
+      event_title: "茂名市茂南区xxx高速路口发生交通事故,今日凌晨三点在xx高速路口,由于突降暴雨路面湿滑,导致路面积水严重,不少路过车辆都减速慢行…"
+    }
+  ];
   // 趋势统计
   option1.value.xAxis[0].data = [
     "2024-01",
@@ -330,143 +274,7 @@ const initData = () => {
     281.55, 398.35, 214.02, 179.55, 289.57, 356.14
   ];
   // 事件列表
-  // detailsData.value.dataList = [
-  //   {
-  //     data1: "自然灾害",
-  //     data2: "茂名市电白区黄岭镇石头村",
-  //     data3: "2024-12-14 12:12:13",
-  //     data4: 1,
-  //     data5: 0,
-  //     longitude: "110.719914",
-  //     latitude: "21.609269",
-  //     dataType: "1"
-  //   },
-  //   {
-  //     data1: "自然灾害",
-  //     data2: "茂名市茂南区羊角镇",
-  //     data3: "2024-10-07 08:00:00",
-  //     data4: 2,
-  //     data5: 0,
-  //     longitude: "110.984948",
-  //     latitude: "21.669318",
-  //     dataType: "1"
-  //   },
-  //   {
-  //     data1: "自然灾害",
-  //     data2: "茂名市高州市根子镇",
-  //     data3: "2024-06-15 17:30:00",
-  //     data4: 5,
-  //     data5: 0,
-  //     longitude: "111.049042",
-  //     latitude: "21.798487",
-  //     dataType: "1"
-  //   },
-  //   // 2023年的数据
-  //   {
-  //     data1: "自然灾害",
-  //     data2: "茂名市信宜市池洞镇",
-  //     data3: "2023-11-22 21:45:00",
-  //     data4: 3,
-  //     data5: 0,
-  //     longitude: "110.94942",
-  //     latitude: "22.429006",
-  //     dataType: "1"
-  //   },
-  //   {
-  //     data1: "自然灾害",
-  //     data2: "茂名市化州市同庆镇",
-  //     data3: "2023-08-03 14:20:00",
-  //     data4: 4,
-  //     data5: 0,
-  //     longitude: "110.694616",
-  //     latitude: "21.591756",
-  //     dataType: "1"
-  //   },
-  //   {
-  //     data1: "事故灾害",
-  //     data2: "茂名市电白区观珠镇",
-  //     data3: "2023-05-12 10:10:00",
-  //     data4: 2,
-  //     data5: 0,
-  //     longitude: "111.181376",
-  //     latitude: "21.694578",
-  //     dataType: "2"
-  //   },
-  //   // 新增2021年的数据
-  //   {
-  //     data1: "事故灾害",
-  //     data2: "茂名市茂南区公馆镇",
-  //     data3: "2021-11-05 11:00:00",
-  //     data4: 2,
-  //     data5: 0,
-  //     longitude: "110.841795",
-  //     latitude: "21.679494",
-  //     dataType: "2"
-  //   },
-  //   {
-  //     data1: "自然灾害",
-  //     data2: "茂名市电白区麻岗镇",
-  //     data3: "2021-09-15 15:00:00",
-  //     data4: 1,
-  //     data5: 0,
-  //     longitude: "111.183698",
-  //     latitude: "21.534101",
-  //     dataType: "1"
-  //   },
-  //   {
-  //     data1: "事故灾害",
-  //     data2: "茂名市高州市石鼓镇",
-  //     data3: "2021-07-25 17:00:00",
-  //     data4: 3,
-  //     data5: 0,
-  //     longitude: "110.772332",
-  //     latitude: "21.822757",
-  //     dataType: "2"
-  //   },
-  //   {
-  //     data1: "事故灾害",
-  //     data2: "茂名市化州市林尘镇",
-  //     data3: "2021-05-20 09:00:00",
-  //     data4: 0,
-  //     data5: 0,
-  //     longitude: "110.569997",
-  //     latitude: "21.831692",
-  //     dataType: "2"
-  //   },
-  //   {
-  //     data1: "自然灾害",
-  //     data2: "茂名市电白区树仔镇",
-  //     data3: "2021-03-10 14:00:00",
-  //     data4: 1,
-  //     data5: 0,
-  //     longitude: "111.234894",
-  //     latitude: "21.535935",
-  //     dataType: "1"
-  //   },
-  //   // 原来的2021年数据
-  //   {
-  //     data1: "事故灾害",
-  //     data2: "茂名市茂南区袂花镇",
-  //     data3: "2021-09-28 19:30:00",
-  //     data4: 3,
-  //     data5: 0,
-  //     longitude: "110.937624",
-  //     latitude: "21.58241",
-  //     dataType: "2"
-  //   }
-  // ];
-  detailsData.value.dataList.forEach(item => {
-    const icon =
-      item.dataType && !!iconList[item.dataType].image
-        ? iconList[item.dataType].image
-        : "";
-    item.icon = icon;
-    item.image = icon;
-    item.imageHover = icon;
-    item.size = iconList[item.dataType].size;
-    item.lnglat = [item.longitude, item.latitude];
-  });
-  dom.addMarker(detailsData.value.dataList);
+  getList()
 };
 </script>
 
@@ -476,24 +284,27 @@ const initData = () => {
     width: 100%;
     height: 250px;
   }
+
   .event-box {
     position: relative;
     width: 375px;
     height: 117px;
-    background: url("@/assets/images/disasterRiskMonitor/cityEmergencyEvent/box1.png")
-      no-repeat;
+    background: url("@/assets/images/disasterRiskMonitor/cityEmergencyEvent/box1.png") no-repeat;
     background-size: 100% 100%;
     box-shadow: 0 2px 4px 0 rgba(228, 240, 255, 1);
+
     .box-header {
       display: flex;
       justify-content: space-between;
       align-items: center;
       padding: 0 6px;
+
       .more {
         font-size: 12px;
         color: #2c81ff;
       }
     }
+
     .title-box {
       height: 30px;
       background-color: #ffffff; /* 背景颜色 */
@@ -503,6 +314,7 @@ const initData = () => {
       display: flex;
       align-items: center;
       border-radius: 2px;
+
       &::after {
         content: "";
         position: absolute;
@@ -511,30 +323,32 @@ const initData = () => {
         transform: skewX(20deg);
         width: 11px;
         height: 27px;
-        background: url("@/assets/images/disasterRiskMonitor/riverMonitor/thickness.png")
-          no-repeat;
+        background: url("@/assets/images/disasterRiskMonitor/riverMonitor/thickness.png") no-repeat;
         background-size: 100% 100%;
       }
+
       .title {
         font-size: 14px;
         color: #ffaf00;
         transform: skewX(20deg);
         display: flex;
         align-items: center;
+
         .icon-speaker {
           display: inline-block;
           width: 16px;
           height: 16px;
-          background: url("@/assets/images/disasterRiskMonitor/riverMonitor/speaker.png")
-            no-repeat;
+          background: url("@/assets/images/disasterRiskMonitor/riverMonitor/speaker.png") no-repeat;
           background-size: 100% 100%;
           margin-right: 5px;
         }
       }
     }
+
     .event-content {
       padding: 0 10px;
     }
+
     .text1 {
       display: -webkit-box;
       -webkit-line-clamp: 3;
@@ -544,6 +358,7 @@ const initData = () => {
       font-size: 14px;
       color: #414f64;
     }
+
     .text2 {
       font-size: 12px;
       color: rgba(0, 0, 0, 0.45);
@@ -551,12 +366,14 @@ const initData = () => {
     }
   }
 }
+
 .search-box {
+  position: relative;
   padding: 16px 16px 10px;
 }
 .search-list {
   position: absolute;
-  top: 50px;
+  top: 55px;
   left: 0;
   z-index: 9;
   width: 100%;
@@ -573,44 +390,53 @@ const initData = () => {
   border: 1px solid #dce0ee;
   border-radius: 2px;
   padding: 0;
+
   :deep(.van-field__control) {
     &::placeholder {
       color: #c9cfd9;
     }
   }
+
   :deep(.van-search__content) {
     background-color: #ffffff;
     border: none !important;
   }
+
   :deep(.van-field__left-icon) {
     .van-icon__image {
       width: 12px;
       height: 12px;
     }
   }
+
   :deep(.van-field__right-icon) {
     width: 30px;
     height: 30px;
     padding: 0;
+
     .van-icon__image {
       width: 30px;
       height: 30px;
     }
   }
+
   .search-btn {
     font-size: 14px;
     color: #2c81ff;
   }
 }
+
 .card {
   background-color: #ffffff;
   border: 1px solid #eaedf7;
   border-radius: 4px;
   padding: 2px;
   margin-top: 16px;
+
   &:first-child {
     margin-top: 0;
   }
+
   .card-header {
     font-size: 16px;
     color: #414f64;
@@ -622,6 +448,7 @@ const initData = () => {
     border-top-left-radius: 4px;
     border-top-right-radius: 4px;
     background-image: linear-gradient(180deg, #f3f7fd 0%, #ffffff 100%);
+
     .icon-line {
       display: inline-block;
       width: 6px;
@@ -632,21 +459,25 @@ const initData = () => {
     }
   }
 }
+
 .content {
   padding: 0 16px;
   margin-top: 16px;
 }
+
 .select-box {
   display: flex;
   justify-content: flex-end;
   align-items: center;
   margin-bottom: 10px;
   padding-right: 20px;
+
   .text1 {
     font-size: 14px;
     color: #414f64;
     margin-right: 5px;
   }
+
   .select-item {
     background-color: #f4f7fc;
     padding: 5px;
@@ -657,9 +488,11 @@ const initData = () => {
     color: #414f64;
     display: flex;
     align-items: center;
+
     .label {
       flex: 1;
     }
+
     .icon-down {
       flex-shrink: 0;
       display: inline-block;
@@ -671,6 +504,7 @@ const initData = () => {
     }
   }
 }
+
 /* 移除表单容器背景 */
 :deep(.van-cell-group) {
   background: transparent !important;
@@ -685,10 +519,12 @@ const initData = () => {
 :deep(.van-cell-group--inset) {
   margin: 0;
   box-shadow: none;
+
   &::after {
     border: none !important;
   }
 }
+
 :deep(.van-field--disabled) {
   .van-field__label,
   .van-field__control {
@@ -701,6 +537,7 @@ const initData = () => {
     display: none !important;
   }
 }
+
 .title {
   font-size: 18px;
   font-weight: bold;
@@ -710,28 +547,24 @@ const initData = () => {
   margin-bottom: 8px;
   margin-top: 8px;
 }
+
 .unit-box {
   display: flex;
-  flex-direction: row;
   background-color: #ffffff;
   min-height: 35px;
   width: 100%;
-  margin-top: 5px;
-  align-items: center;
+  border-bottom: 1px solid #f4f5f7;
+  padding: 10px 15px;
 }
 
 .text {
-  flex-shrink: 0;
   color: grey;
-  width: 85px;
-  padding: 5px 10px;
-  text-align-last: justify;
+  width: 64px;
+  flex-shrink: 0;
+  margin-right: 10px;
 }
 
 .info-content {
-  margin: 5px 20px;
-  line-height: 1.5;
   word-break: break-all;
-  white-space: normal;
 }
 </style>

+ 1 - 0
src/views/disasterRiskMonitor/forestFirePrevention.vue

@@ -154,6 +154,7 @@
 </template>
 
 <script lang="ts" setup name="forestFirePrevention">
+import Map from '@/components/Map/index2.vue';
 import { onMounted, reactive, ref } from "vue";
 import searchImg from "@/assets/images/search.png";
 import { chartOption4 } from "@/views/disasterRiskMonitor/chartOptions";

+ 1 - 0
src/views/disasterRiskMonitor/forestFireWarn.vue

@@ -108,6 +108,7 @@
 </template>
 
 <script lang="ts" setup name="forestFireWarn">
+import Map from '@/components/Map/index2.vue';
 let mapRef = ref();
 const queryParams = reactive({
   type: "1",

+ 1 - 0
src/views/disasterRiskMonitor/geologicalDisaster.vue

@@ -179,6 +179,7 @@
 </template>
 
 <script lang="ts" setup name="geologicalDisaster">
+import Map from '@/components/Map/index2.vue';
 import searchImg from "@/assets/images/search.png";
 import { onMounted, reactive, ref } from "vue";
 import { ElTable, ElTableColumn } from "element-plus";

+ 1 - 0
src/views/disasterRiskMonitor/reservoirMonitor.vue

@@ -98,6 +98,7 @@
 </template>
 
 <script lang="ts" setup name="reservoirMonitor">
+import Map from '@/components/Map/index2.vue';
 import searchImg from "@/assets/images/search.png";
 import {reactive, ref } from "vue";
 import { ElTable, ElTableColumn } from "element-plus";

+ 1 - 0
src/views/disasterRiskMonitor/riverMonitor.vue

@@ -68,6 +68,7 @@
 </template>
 
 <script lang="ts" setup name="riverMonitor">
+import Map from '@/components/Map/index2.vue';
 import searchImg from "@/assets/images/search.png";
 import { onMounted, reactive, ref } from "vue";
 import { ElTable, ElTableColumn } from "element-plus";

+ 1 - 1
src/views/mobileControl/index.vue

@@ -414,7 +414,7 @@ watch(
               latitude: lnglat[1],
               image: getImageUrl('address.png'),
               imageHover: getImageUrl('address_hover.png'),
-              size: [45, 48],
+              size: [30, 32],
               name: '灾害地点'
             });
           });