Hwf před 6 měsíci
rodič
revize
b9ca05de76

+ 2 - 0
package.json

@@ -27,7 +27,9 @@
     "axios": "^1.6.8",
     "crypto-js": "^4.2.0",
     "dayjs": "^1.11.13",
+    "echarts": "^5.5.1",
     "element-plus": "^2.8.5",
+    "element-resize-detector": "^1.2.4",
     "file-saver": "^2.0.5",
     "jsencrypt": "^3.3.2",
     "nanoid": "^5.0.7",

+ 38 - 0
pnpm-lock.yaml

@@ -35,9 +35,15 @@ importers:
       dayjs:
         specifier: ^1.11.13
         version: 1.11.13
+      echarts:
+        specifier: ^5.5.1
+        version: 5.5.1
       element-plus:
         specifier: ^2.8.5
         version: 2.8.5(vue@3.5.11(typescript@5.4.5))
+      element-resize-detector:
+        specifier: ^1.2.4
+        version: 1.2.4
       file-saver:
         specifier: ^2.0.5
         version: 2.0.5
@@ -1225,6 +1231,9 @@ packages:
     resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==}
     engines: {node: '>=0.10.0'}
 
+  batch-processor@1.0.0:
+    resolution: {integrity: sha512-xoLQD8gmmR32MeuBHgH0Tzd5PuSZx71ZsbhVxOCRbgktZEPe4SQy7s9Z50uPp0F/f7iw2XmkHN2xkgbMfckMDA==}
+
   big.js@5.2.2:
     resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==}
 
@@ -1748,6 +1757,9 @@ packages:
   eastasianwidth@0.2.0:
     resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
 
+  echarts@5.5.1:
+    resolution: {integrity: sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==}
+
   ejs@3.1.10:
     resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==}
     engines: {node: '>=0.10.0'}
@@ -1761,6 +1773,9 @@ packages:
     peerDependencies:
       vue: ^3.2.0
 
+  element-resize-detector@1.2.4:
+    resolution: {integrity: sha512-Fl5Ftk6WwXE0wqCgNoseKWndjzZlDCwuPTcoVZfCP9R3EHQF8qUtr3YUPNETegRBOKqQKPW3n4kiIWngGi8tKg==}
+
   emoji-regex@8.0.0:
     resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
 
@@ -3693,6 +3708,9 @@ packages:
   ts-interface-checker@0.1.13:
     resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
 
+  tslib@2.3.0:
+    resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==}
+
   tslib@2.7.0:
     resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
 
@@ -4062,6 +4080,9 @@ packages:
     resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==}
     engines: {node: '>=12.20'}
 
+  zrender@5.6.0:
+    resolution: {integrity: sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==}
+
   zstddec@0.1.0:
     resolution: {integrity: sha512-w2NTI8+3l3eeltKAdK8QpiLo/flRAr2p8AGeakfMZOXBxOg9HIu4LVDxBi81sYgVhFhdJjv1OrB5ssI8uFPoLg==}
 
@@ -5108,6 +5129,8 @@ snapshots:
       mixin-deep: 1.3.2
       pascalcase: 0.1.1
 
+  batch-processor@1.0.0: {}
+
   big.js@5.2.2: {}
 
   binary-extensions@2.3.0: {}
@@ -5698,6 +5721,11 @@ snapshots:
 
   eastasianwidth@0.2.0: {}
 
+  echarts@5.5.1:
+    dependencies:
+      tslib: 2.3.0
+      zrender: 5.6.0
+
   ejs@3.1.10:
     dependencies:
       jake: 10.9.2
@@ -5725,6 +5753,10 @@ snapshots:
     transitivePeerDependencies:
       - '@vue/composition-api'
 
+  element-resize-detector@1.2.4:
+    dependencies:
+      batch-processor: 1.0.0
+
   emoji-regex@8.0.0: {}
 
   emoji-regex@9.2.2: {}
@@ -7813,6 +7845,8 @@ snapshots:
 
   ts-interface-checker@0.1.13: {}
 
+  tslib@2.3.0: {}
+
   tslib@2.7.0: {}
 
   tsscmp@1.0.6: {}
@@ -8208,4 +8242,8 @@ snapshots:
 
   yocto-queue@1.1.1: {}
 
+  zrender@5.6.0:
+    dependencies:
+      tslib: 2.3.0
+
   zstddec@0.1.0: {}

+ 172 - 0
src/components/Chart/echarts_auto_tooltip.js

@@ -0,0 +1,172 @@
+/**
+ *  echarts tooltip 自动轮播
+ *  @param chart
+ *  @param chartOption
+ *  @param options
+ *  {
+ *  interval    轮播时间间隔,单位毫秒,默认为2000
+ *  loopSeries  boolean类型,默认为false。
+ *              true表示循环所有series的tooltip,false则显示指定seriesIndex的tooltip
+ * 	seriesIndex 默认为0,指定某个系列(option中的series索引)循环显示tooltip,
+ * 	            当loopSeries为true时,从seriesIndex系列开始执行.
+ *  }
+ * @returns {{clearLoop: clearLoop}}
+ */
+
+export const autoToolTip = (chart, chartOption, options) => {
+  let defaultOptions = {
+    interval: 2000,
+    loopSeries: false,
+    seriesIndex: 0,
+    updateData: null
+  }
+
+  if (!chart || !chartOption) {
+    return {}
+  }
+
+  let dataIndex = 0; // 数据索引,初始化为-1,是为了判断是否是第一次执行
+  let seriesIndex = 0; // 系列索引
+  let timeTicket = 0;
+  let seriesLen = chartOption.series.length; // 系列个数
+  let dataLen = 0; // 某个系列数据个数
+  let chartType; // 系列类型
+  let first = true;
+  // 不循环series时seriesIndex指定显示tooltip的系列,不指定默认为0,指定多个则默认为第一个
+  // 循环series时seriesIndex指定循环的series,不指定则从0开始循环所有series,指定单个则相当于不循环,指定多个
+  // 要不要添加开始series索引和开始的data索引?
+
+  if (options) {
+    options.interval = options.interval || defaultOptions.interval;
+    options.loopSeries = options.loopSeries || defaultOptions.loopSeries;
+    options.seriesIndex = options.seriesIndex || defaultOptions.seriesIndex;
+    options.updateData = options.updateData || defaultOptions.updateData;
+  } else {
+    options = defaultOptions;
+  }
+
+  // 如果设置的seriesIndex无效,则默认为0
+  if (options.seriesIndex < 0 || options.seriesIndex >= seriesLen) {
+    seriesIndex = 0;
+  } else {
+    seriesIndex = options.seriesIndex;
+  }
+
+  function autoShowTip() {
+    function showTip() {
+      // 判断是否更新数据
+      if (dataIndex === 0 && !first && typeof options.updateData === 'function') {
+        options.updateData();
+        chart.setOption(chartOption);
+      }
+      let series = chartOption.series;
+      chartType = series[seriesIndex].type; // 系列类型
+      dataLen = series[seriesIndex].data.length; // 某个系列的数据个数
+      let tipParams = { seriesIndex: seriesIndex };
+      // 数据长度为0或1不循环
+      if (dataLen <= 1) {
+        return false;
+      }
+      switch (chartType) {
+        case 'map':
+        case 'pie':
+        case 'chord':
+          tipParams.name = series[seriesIndex].data[dataIndex].name;
+          break;
+        case 'radar': // 雷达图
+          tipParams.seriesIndex = seriesIndex;
+          tipParams.dataIndex = dataIndex;
+          break;
+        default:
+          tipParams.dataIndex = dataIndex;
+          break;
+      }
+
+      if (chartType === 'pie' || chartType === 'radar') {
+        // 取消之前高亮的图形
+        chart.dispatchAction({
+          type: 'downplay',
+          seriesIndex: options.loopSeries ? (seriesIndex === 0 ? seriesLen - 1 : seriesIndex - 1) : seriesIndex,
+          dataIndex: dataIndex === 0 ? dataLen - 1 : dataIndex - 1
+        });
+
+        // 高亮当前图形
+        chart.dispatchAction({
+          type: 'highlight',
+          seriesIndex: seriesIndex,
+          dataIndex: dataIndex
+        });
+      }
+
+      // 显示 tooltip
+      tipParams.type = 'showTip';
+      chart.dispatchAction(tipParams);
+
+      dataIndex = dataLen === 0 ? 0 : (dataIndex + 1) % dataLen;
+      if (options.loopSeries && dataIndex === 0 && !first) {
+        // 数据索引归0表示当前系列数据已经循环完
+        seriesIndex = (seriesIndex + 1) % seriesLen;
+      }
+
+      first = false;
+    }
+
+    showTip();
+    timeTicket = setInterval(showTip, options.interval);
+  }
+
+  // 关闭轮播
+  function stopAutoShow() {
+    if (timeTicket) {
+      clearInterval(timeTicket);
+      timeTicket = 0;
+
+      if (chartType === 'pie' || chartType === 'radar') {
+        // 取消高亮的图形
+        chart.dispatchAction({
+          type: 'downplay',
+          seriesIndex: options.loopSeries ? (seriesIndex === 0 ? seriesLen - 1 : seriesIndex - 1) : seriesIndex,
+          dataIndex: dataIndex === 0 ? dataLen - 1 : dataIndex - 1
+        });
+      }
+    }
+  }
+
+  let zRender = chart.getZr();
+
+  function zRenderMouseMove(param) {
+    if (param.event) {
+      // 阻止canvas上的鼠标移动事件冒泡
+      param.event.cancelBubble = true;
+    }
+
+    stopAutoShow();
+  }
+
+  // 离开echarts图时恢复自动轮播
+  function zRenderGlobalOut() {
+    if (!timeTicket) {
+      autoShowTip();
+    }
+  }
+
+  // 鼠标在echarts图上时停止轮播
+  chart.on('mousemove', stopAutoShow);
+  zRender.on('mousemove', zRenderMouseMove);
+  zRender.on('globalout', zRenderGlobalOut);
+
+  autoShowTip();
+
+  return {
+    clearLoop: function(){
+      if (timeTicket) {
+        clearInterval(timeTicket);
+        timeTicket = 0;
+      }
+
+      chart.off('mousemove', stopAutoShow);
+      zRender.off('mousemove', zRenderMouseMove);
+      zRender.off('globalout', zRenderGlobalOut);
+    }
+  };
+};

+ 106 - 0
src/components/Chart/index.vue

@@ -0,0 +1,106 @@
+<template>
+  <div ref="canvas" class="canvas" />
+</template>
+
+<script setup lang="ts" name="Chart">
+import ElementResizeDetectorMaker from 'element-resize-detector';
+import { autoToolTip } from './echarts_auto_tooltip';
+import * as echarts from 'echarts';
+import {nextTick, onMounted, onUnmounted, ref, shallowRef, watch} from 'vue';
+
+interface Props {
+  option: object;
+  rotation?: boolean;
+  chartClick?: Function;
+  legendChange?: Function;
+}
+const props = withDefaults(defineProps<Props>(), {
+  rotation: false,
+  legendChange: () => {}
+});
+const emits = defineEmits(['ready', 'click']);
+
+// 渲染容器
+const canvas = ref<HTMLElement>();
+// echarts
+const myChart = shallowRef(null);
+// 加载状态
+let loaded = ref(false);
+
+watch(
+  props.option,
+  () => {
+    if (Object.keys(props.option).length !== 0) {
+      if (loaded.value && !!myChart.value) {
+        myChart.value.setOption(props.option, true);
+      } else {
+        load();
+      }
+    } else if (!!myChart.value) {
+      myChart.value.clear();
+    }
+  },
+  {
+    deep: true
+  }
+);
+
+// 加载事件
+const load = () => {
+  const that = this;
+  if (!myChart.value || Object.keys(myChart.value).length === 0) {
+    myChart.value = echarts.init(canvas.value);
+  }
+  // 基于准备好的dom,初始化echarts实例
+  myChart.value.clear();
+  myChart.value.setOption(props.option);
+  // 监听元素变化
+  const erd = ElementResizeDetectorMaker();
+
+  erd.listenTo(canvas.value, function () {
+    nextTick(function () {
+      // 使echarts尺寸重置
+      setTimeout(function () {
+        myChart.value.resize();
+      }, 500);
+    });
+  });
+  if (props.rotation) {
+    autoToolTip(myChart.value, props.option, { loopSeries: true });
+  }
+  emits('ready', myChart.value);
+  // 监听点击事件
+  if (props.chartClick) {
+    myChart.value.off('click', handleClick);
+    myChart.value.on('click', handleClick);
+  }
+  if (props.legendChange) {
+    myChart.value.on('legendselectchanged', function (params) {
+      props.legendChange(params, myChart.value);
+    });
+  }
+  loaded.value = true;
+};
+
+const handleClick = (params: any) => {
+  props.chartClick(params);
+};
+
+onMounted(() => {
+  if (!(JSON.stringify(props.option) === '{}')) {
+    load();
+  }
+});
+
+onUnmounted(() => {
+  myChart.value = null;
+});
+</script>
+
+<style lang="scss" scoped>
+.canvas {
+  width: 100%;
+  height: 100%;
+  // flex: 1;
+}
+</style>

+ 9 - 0
src/router/routes.ts

@@ -78,6 +78,15 @@ export const constantRoutes: Array<RouteRecordRaw> = [
       noCache: true
     }
   },
+  {
+    path: "/cityEmergencyEvent",
+    name: "CityEmergencyEvent",
+    component: () => import("@/views/disasterRiskMonitor/cityEmergencyEvent.vue"),
+    meta: {
+      title: "城市应急事件专题",
+      noCache: true
+    }
+  },
   {
     path: "/infoReception",
     name: "InfoReception",

+ 193 - 0
src/views/disasterRiskMonitor/chartOptions.ts

@@ -0,0 +1,193 @@
+import {graphic} from "echarts";
+
+export const chartOption1 = {
+    tooltip: {
+        trigger: 'axis',
+        axisPointer: {
+            lineStyle: {
+                color: {
+                    type: 'linear',
+                    x: 0,
+                    y: 0,
+                    x2: 0,
+                    y2: 1,
+                    colorStops: [{
+                        offset: 0,
+                        color: 'rgba(0, 255, 233,0)'
+                    }, {
+                        offset: 0.5,
+                        color: 'rgba(255, 255, 255,1)',
+                    }, {
+                        offset: 1,
+                        color: 'rgba(0, 255, 233,0)'
+                    }],
+                    global: false
+                }
+            },
+        },
+    },
+    grid: {
+        top: '15%',
+        left: '5%',
+        right: '5%',
+        bottom: '15%',
+        // containLabel: true
+    },
+    xAxis: [{
+        type: 'category',
+        axisLine: {
+            show: true
+        },
+        splitArea: {
+            // show: true,
+            color: '#f00',
+            lineStyle: {
+                color: '#f00'
+            },
+        },
+        axisLabel: {
+            color: '#fff'
+        },
+        splitLine: {
+            show: false
+        },
+        boundaryGap: false,
+        data: ['A', 'B', 'C', 'D', 'E', 'F'],
+
+    }],
+
+    yAxis: [{
+        type: 'value',
+        min: 0,
+        // max: 140,
+        splitNumber: 4,
+        splitLine: {
+            show: true,
+            lineStyle: {
+                color: 'rgba(255,255,255,0.1)'
+            }
+        },
+        axisLine: {
+            show: false,
+        },
+        axisLabel: {
+            show: false,
+            margin: 20,
+            textStyle: {
+                color: '#d1e6eb',
+
+            },
+        },
+        axisTick: {
+            show: false,
+        },
+    }],
+    series: [{
+        name: '注册总量',
+        type: 'line',
+        smooth: true, //是否平滑
+        showAllSymbol: true,
+        // symbol: 'image://./static/images/guang-circle.png',
+        symbol: 'circle',
+        symbolSize: 15,
+        lineStyle: {
+            normal: {
+                color: "#00b3f4",
+                shadowColor: 'rgba(0, 0, 0, .3)',
+                shadowBlur: 0,
+                shadowOffsetY: 5,
+                shadowOffsetX: 5,
+            },
+        },
+        label: {
+            show: true,
+            position: 'top',
+            textStyle: {
+                color: '#00b3f4',
+            }
+        },
+        itemStyle: {
+            color: "#00b3f4",
+            borderColor: "#fff",
+            borderWidth: 3,
+            shadowColor: 'rgba(0, 0, 0, .3)',
+            shadowBlur: 0,
+            shadowOffsetY: 2,
+            shadowOffsetX: 2,
+        },
+        tooltip: {
+            show: false
+        },
+        areaStyle: {
+            normal: {
+                color: new graphic.LinearGradient(0, 0, 0, 1, [{
+                    offset: 0,
+                    color: 'rgba(0,179,244,0.3)'
+                },
+                    {
+                        offset: 1,
+                        color: 'rgba(0,179,244,0)'
+                    }
+                ], false),
+                shadowColor: 'rgba(0,179,244, 0.9)',
+                shadowBlur: 20
+            }
+        },
+        data: [502.84, 205.97, 332.79, 281.55, 398.35, 214.02, ]
+    },
+        {
+            name: '注册总量',
+            type: 'line',
+            smooth: true, //是否平滑
+            showAllSymbol: true,
+            // symbol: 'image://./static/images/guang-circle.png',
+            symbol: 'circle',
+            symbolSize: 15,
+            lineStyle: {
+                normal: {
+                    color: "#00ca95",
+                    shadowColor: 'rgba(0, 0, 0, .3)',
+                    shadowBlur: 0,
+                    shadowOffsetY: 5,
+                    shadowOffsetX: 5,
+                },
+            },
+            label: {
+                show: true,
+                position: 'top',
+                textStyle: {
+                    color: '#00ca95',
+                }
+            },
+
+            itemStyle: {
+                color: "#00ca95",
+                borderColor: "#fff",
+                borderWidth: 3,
+                shadowColor: 'rgba(0, 0, 0, .3)',
+                shadowBlur: 0,
+                shadowOffsetY: 2,
+                shadowOffsetX: 2,
+            },
+            tooltip: {
+                show: false
+            },
+            areaStyle: {
+                normal: {
+                    color: new graphic.LinearGradient(0, 0, 0, 1, [{
+                        offset: 0,
+                        color: 'rgba(0,202,149,0.3)'
+                    },
+                        {
+                            offset: 1,
+                            color: 'rgba(0,202,149,0)'
+                        }
+                    ], false),
+                    shadowColor: 'rgba(0,202,149, 0.9)',
+                    shadowBlur: 20
+                }
+            },
+            data: [281.55, 398.35, 214.02, 179.55, 289.57, 356.14, ],
+        },
+    ]
+}

+ 199 - 0
src/views/disasterRiskMonitor/cityEmergencyEvent.vue

@@ -0,0 +1,199 @@
+<template>
+  <div class="container">
+    <van-notice-bar
+        v-show="noticeBarState.show"
+        :left-icon="noticeImg"
+        scrollable
+        background="linear-gradient(180deg, #F3F7FF 0%, #FDFEFF 100%)"
+        mode="closeable"
+        :text="noticeBarState.event_title"
+        class="notice"
+        @click="handleNoticeBar"
+    />
+    <div ref="searchBoxRef" class="search-box">
+      <van-search
+          v-model="queryParams.keywords"
+          class="common-search"
+          :left-icon="searchImg"
+          :right-icon="closeImg"
+          :clearable="false"
+          placeholder="请输入位置信息"
+          @search="onSearchKeyword"
+          @click-right-icon.stop="onSearchCancel"
+      />
+      <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
+              v-for="(item, index) in searchList"
+              :key="index"
+              class="item"
+              @click="handleClickItem(item)"
+          >
+            {{ item.name }}
+          </div>
+        </van-list>
+      </div>
+    </div>
+    <Map ref="mapRef" class="map" active-map="vectorgraph" :point-type="pointType" :event-details="eventDetails" />
+    <Chart :option="option1" style="height: 200px" />
+  </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 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";
+
+const router = useRouter();
+const noticeBarState = reactive({
+  show: false,
+  event_id: "",
+  event_title: ""
+});
+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: 0,
+  page_size: 10,
+  keywords: ''
+});
+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 onSearchCancel = () => {
+  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 = [];
+};
+let pointType = ref([]);
+let eventDetails = ref({});
+const initData = () => {
+  // 通知栏数据
+  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;
+    }
+  });
+  // 菜单数据
+};
+
+const option1 = ref(chartOption1);
+
+onMounted(() => {
+  initData();
+});
+</script>
+
+<style lang="scss" scoped>
+.container {
+  .map {
+    width: 100%;
+    height: 250px;
+  }
+}
+.search-box {
+  margin-bottom: 10px;
+}
+.search-list {
+  position: absolute;
+  top: 50px;
+  left: 0;
+  z-index: 9;
+  width: 100%;
+  height: calc(100vh - 400px);
+  overflow-y: auto;
+  background-color: #ffffff;
+  border-top: 1px solid #eeeeee;
+  .item {
+    padding: 8px 15px;
+    border-bottom: 1px solid #eeeeee;
+  }
+}
+.common-search {
+  border: 1px solid #ededed;
+  :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;
+    }
+  }
+}
+</style>

+ 3 - 3
src/views/leader/index.vue

@@ -157,7 +157,7 @@ const menu2 = ref([
     children: [
       { name: "自然灾害", icon: "nature", url: "" },
       { name: "事故灾害", icon: "accident", url: "" },
-      { name: "城市事件", icon: "city", url: "" }
+      { name: "城市应急事件专题", icon: "city", url: "CityEmergencyEvent" }
     ]
   }
 ]);
@@ -226,7 +226,7 @@ const getSearchList = () => {
       loading.value = false;
     });
 };
-const on_search_keyword = val => {
+const on_search_keyword = (val) => {
   queryParams.keywords = val;
   queryParams.page = 0;
   getSearchList();
@@ -464,7 +464,7 @@ onUnmounted(() => {
         flex-direction: column;
         justify-content: center;
         align-items: center;
-        width: 20%;
+        min-width: 20%;
         font-size: 12px;
         .icon {
           width: 32px;