ソースを参照

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	src/views/disasterRiskMonitor/geologicalDisaster.vue
Hwf 7 ヶ月 前
コミット
52ab84a0a2

BIN
src/assets/images/disasterRiskMonitor/galeDisaster/icon1.png


BIN
src/assets/images/disasterRiskMonitor/warningSituation/icon1.png


BIN
src/assets/images/disasterRiskMonitor/warningSituation/icon2.png


BIN
src/assets/images/disasterRiskMonitor/warningSituation/icon3.png


BIN
src/assets/images/disasterRiskMonitor/warningSituation/icon4.png


BIN
src/assets/images/disasterRiskMonitor/warningSituation/icon5.png


+ 3 - 1
src/components/Tabbar/index.vue

@@ -83,7 +83,7 @@ watch(
           iconActive: "commandActive",
           title: "事件管理",
           to: {
-            name: "Event2"
+            name: "workerEvent"
           }
         },
         {
@@ -116,6 +116,7 @@ const getImageUrl = name => {
     .href;
 };
 onMounted(() => {
+  /*
   const mobile_control_status =
     localStorage.getItem("mobile_control_status") || "0";
   // 动态切换平时态或者应急态
@@ -129,6 +130,7 @@ onMounted(() => {
       }
     };
   }
+  */
 });
 </script>
 <style lang="scss" scoped>

+ 26 - 15
src/router/routes.ts

@@ -7,7 +7,7 @@ export const constantRoutes: Array<RouteRecordRaw> = [
     name: "RoleSelect",
     component: () => import("@/views/index.vue"),
     meta: {
-      title: '角色选择'
+      title: "角色选择"
     }
   },
   {
@@ -54,7 +54,8 @@ export const constantRoutes: Array<RouteRecordRaw> = [
   {
     path: "/hydrologicalMonitor",
     name: "HydrologicalMonitor",
-    component: () => import("@/views/disasterRiskMonitor/hydrologicalMonitor/index.vue"),
+    component: () =>
+      import("@/views/disasterRiskMonitor/hydrologicalMonitor/index.vue"),
     meta: {
       title: "水文监测",
       noCache: true
@@ -63,7 +64,10 @@ export const constantRoutes: Array<RouteRecordRaw> = [
   {
     path: "/reservoirMonitor",
     name: "ReservoirMonitor",
-    component: () => import("@/views/disasterRiskMonitor/hydrologicalMonitor/reservoirMonitor.vue"),
+    component: () =>
+      import(
+        "@/views/disasterRiskMonitor/hydrologicalMonitor/reservoirMonitor.vue"
+      ),
     meta: {
       title: "水库监测",
       noCache: true
@@ -72,7 +76,10 @@ export const constantRoutes: Array<RouteRecordRaw> = [
   {
     path: "/riverMonitor",
     name: "RiverMonitor",
-    component: () => import("@/views/disasterRiskMonitor/hydrologicalMonitor/riverMonitor.vue"),
+    component: () =>
+      import(
+        "@/views/disasterRiskMonitor/hydrologicalMonitor/riverMonitor.vue"
+      ),
     meta: {
       title: "河道监测",
       noCache: true
@@ -90,7 +97,8 @@ export const constantRoutes: Array<RouteRecordRaw> = [
   {
     path: "/cityEmergencyEvent",
     name: "CityEmergencyEvent",
-    component: () => import("@/views/disasterRiskMonitor/cityEmergencyEvent.vue"),
+    component: () =>
+      import("@/views/disasterRiskMonitor/cityEmergencyEvent.vue"),
     meta: {
       title: "城市应急事件专题",
       noCache: true
@@ -99,7 +107,8 @@ export const constantRoutes: Array<RouteRecordRaw> = [
   {
     path: "/forestFirePrevention",
     name: "ForestFirePrevention",
-    component: () => import("@/views/disasterRiskMonitor/forestFirePrevention.vue"),
+    component: () =>
+      import("@/views/disasterRiskMonitor/forestFirePrevention.vue"),
     meta: {
       title: "森林防火应急专题",
       noCache: true
@@ -108,7 +117,8 @@ export const constantRoutes: Array<RouteRecordRaw> = [
   {
     path: "/windAndFloodPrevention",
     name: "WindAndFloodPrevention",
-    component: () => import("@/views/disasterRiskMonitor/windAndFloodPrevention.vue"),
+    component: () =>
+      import("@/views/disasterRiskMonitor/windAndFloodPrevention.vue"),
     meta: {
       title: "防风防汛应急专题"
     }
@@ -218,16 +228,17 @@ export const constantRoutes: Array<RouteRecordRaw> = [
   {
     path: "/patorlTaskResultAdd",
     name: "patorlTaskResultAdd",
-    component: () => import("@/views/worker/inspectionWork/patorlTaskResultAdd.vue"),
+    component: () =>
+      import("@/views/worker/inspectionWork/patorlTaskResultAdd.vue"),
     meta: {
       title: "巡查上报"
     }
-  }
-  ,
+  },
   {
     path: "/patorlTaskResultList",
     name: "patorlTaskResultList",
-    component: () => import("@/views/worker/inspectionWork/patorlTaskResultList.vue"),
+    component: () =>
+      import("@/views/worker/inspectionWork/patorlTaskResultList.vue"),
     meta: {
       title: "巡查结果"
     }
@@ -302,9 +313,9 @@ export const leaderRoute: Array<RouteRecordRaw> = [
 export const workerRoute = [
   {
     path: "/worker",
-    name: 'Worker',
+    name: "Worker",
     component: Layout,
-    redirect: 'Index',
+    redirect: "Index",
     children: [
       {
         path: "index",
@@ -326,8 +337,8 @@ export const workerRoute = [
       },
       {
         path: "event",
-        name: "Event2",
-        component: () => import("@/views/event/detail.vue"),
+        name: "workerEvent",
+        component: () => import("@/views/worker/eventManagement/index.vue"),
         meta: {
           title: "事件管理",
           noCache: true

+ 189 - 88
src/views/disasterRiskMonitor/cityEmergencyEvent.vue

@@ -1,63 +1,69 @@
 <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"
+      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"
+        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"
+          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)"
+            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="satellite" :point-type="pointType" :event-details="eventDetails" />
+    <Map
+      ref="mapRef"
+      class="map"
+      active-map="satellite"
+      :point-type="pointType"
+      :event-details="eventDetails"
+    />
     <div class="box">
       <div class="box-title">趋势统计</div>
-      <Chart :option="option1" style="height: 200px;" />
+      <Chart :option="option1" style="height: 200px" />
     </div>
     <div class="box">
       <div class="box-title">事件列表</div>
       <van-field
-          v-model="yearLabel"
-          is-link
-          readonly
-          label="年度"
-          placeholder="请选择"
-          @click="showPicker = true"
+        v-model="yearLabel"
+        is-link
+        readonly
+        label="年度"
+        placeholder="请选择"
+        @click="showPicker = true"
       />
-      <el-table :data="detailsData.dataList" border table-layout='auto'>
+      <el-table :data="detailsData.dataList" border table-layout="auto">
         <el-table-column label="类别" prop="data1" align="center" />
         <el-table-column label="位置" prop="data2" align="center" />
         <el-table-column label="发生时间" prop="data3" align="center" />
@@ -67,9 +73,9 @@
     </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>
@@ -77,15 +83,15 @@
 
 <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 { 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";
-import {ElTable, ElTableColumn} from "element-plus";
+import { getPointInfoComprehensiveSearch } from "@/api/globalMap";
+import { onClickOutside } from "@vueuse/core";
+import { chartOption1 } from "@/views/disasterRiskMonitor/chartOptions";
+import { ElTable, ElTableColumn } from "element-plus";
 
 const router = useRouter();
 const noticeBarState = reactive({
@@ -93,9 +99,7 @@ const noticeBarState = reactive({
   event_id: "",
   event_title: ""
 });
-const handleNoticeBar = () => {
-
-};
+const handleNoticeBar = () => {};
 // 搜索
 const searchBoxRef = ref();
 let showSearch = ref();
@@ -106,10 +110,10 @@ let finished = ref(false);
 const queryParams = reactive({
   page: 0,
   page_size: 10,
-  year: '',
-  keywords: ''
+  year: "",
+  keywords: ""
 });
-let yearLabel = ref('');
+let yearLabel = ref("");
 const searchList = ref([]);
 onClickOutside(searchBoxRef, event => {
   showSearch.value = false;
@@ -120,31 +124,31 @@ const getSearchList = () => {
   }
   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;
+    .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) => {
+const onSearchKeyword = val => {
   queryParams.keywords = val;
   queryParams.page = 0;
   getSearchList();
@@ -167,21 +171,21 @@ let pointType = ref([]);
 let eventDetails = ref({});
 let detailsData = ref({
   dataList: []
-})
+});
 const option1 = ref(chartOption1);
 let showPicker = ref(false);
 let columns = reactive([
-  { text: '2024年', value: '2024' },
-  { text: '2023年', value: '2023' },
-  { text: '2022年', value: '2022' },
-  { text: '2021年', value: '2021' }
-])
+  { text: "2024年", value: "2024" },
+  { text: "2023年", value: "2023" },
+  { text: "2022年", value: "2022" },
+  { text: "2021年", value: "2021" }
+]);
 
-const onPickerConfirm = ({selectedOptions}) => {
+const onPickerConfirm = ({ selectedOptions }) => {
   showPicker.value = false;
   yearLabel.value = selectedOptions[0].text;
   queryParams.year = selectedOptions[0].value;
-}
+};
 const initData = () => {
   // 通知栏数据
   getActiveEventList().then(res => {
@@ -192,13 +196,110 @@ const initData = () => {
     }
   });
   // 趋势统计
-  option1.value.xAxis[0].data = ['2019-01', '2019-02', '2019-03', '2019-04', '2019-05', '2019-06'];
-  option1.value.series[0].data = [502.84, 205.97, 332.79, 281.55, 398.35, 214.02];
-  option1.value.series[1].data = [281.55, 398.35, 214.02, 179.55, 289.57, 356.14];
+  option1.value.xAxis[0].data = [
+    "2024-01",
+    "2024-02",
+    "2024-03",
+    "2024-04",
+    "2024-05",
+    "2024-06"
+  ];
+  option1.value.series[0].data = [
+    502.84, 205.97, 332.79, 281.55, 398.35, 214.02
+  ];
+  option1.value.series[1].data = [
+    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 }
-  ]
+    {
+      data1: "暴雨引发山体滑坡",
+      data2: "茂名市电白区黄岭镇石头村",
+      data3: "2024-12-14 12:12:13",
+      data4: 1,
+      data5: 0
+    },
+    {
+      data1: "台风",
+      data2: "茂名市茂南区羊角镇",
+      data3: "2024-10-07 08:00:00",
+      data4: 2,
+      data5: 0
+    },
+    {
+      data1: "洪水",
+      data2: "茂名市高州市根子镇",
+      data3: "2024-06-15 17:30:00",
+      data4: 5,
+      data5: 0
+    },
+    // 2023年的数据
+    {
+      data1: "地震",
+      data2: "茂名市信宜市池洞镇",
+      data3: "2023-11-22 21:45:00",
+      data4: 3,
+      data5: 0
+    },
+    {
+      data1: "暴雨",
+      data2: "茂名市化州市同庆镇",
+      data3: "2023-08-03 14:20:00",
+      data4: 4,
+      data5: 0
+    },
+    {
+      data1: "台风",
+      data2: "茂名市电白区观珠镇",
+      data3: "2023-05-12 10:10:00",
+      data4: 2,
+      data5: 0
+    },
+    // 新增2021年的数据
+    {
+      data1: "暴雨",
+      data2: "茂名市茂南区公馆镇",
+      data3: "2021-11-05 11:00:00",
+      data4: 2,
+      data5: 0
+    },
+    {
+      data1: "台风",
+      data2: "茂名市电白区麻岗镇",
+      data3: "2021-09-15 15:00:00",
+      data4: 1,
+      data5: 0
+    },
+    {
+      data1: "洪水",
+      data2: "茂名市高州市石鼓镇",
+      data3: "2021-07-25 17:00:00",
+      data4: 3,
+      data5: 0
+    },
+    {
+      data1: "山体滑坡",
+      data2: "茂名市化州市林尘镇",
+      data3: "2021-05-20 09:00:00",
+      data4: 0,
+      data5: 0
+    },
+    {
+      data1: "暴雨",
+      data2: "茂名市电白区树仔镇",
+      data3: "2021-03-10 14:00:00",
+      data4: 1,
+      data5: 0
+    },
+    // 原来的2021年数据
+    {
+      data1: "暴雨",
+      data2: "茂名市茂南区袂花镇",
+      data3: "2021-09-28 19:30:00",
+      data4: 3,
+      data5: 0
+    }
+  ];
 };
 
 onMounted(() => {

+ 148 - 29
src/views/disasterRiskMonitor/forestFireWarn.vue

@@ -1,13 +1,26 @@
 <template>
   <div class="container">
-    <Map ref="mapRef" class="map" active-map="satellite" :point-type="pointType" :event-details="eventDetails" />
+    <Map
+      ref="mapRef"
+      class="map"
+      active-map="satellite"
+      :point-type="pointType"
+      :event-details="eventDetails"
+    />
     <div class="info-box">
       <div class="select-box">
-        <van-radio-group v-model="queryParams.type" direction="horizontal" @change="handleChange">
+        <van-radio-group
+          v-model="queryParams.type"
+          direction="horizontal"
+          @change="handleChange"
+        >
           <van-radio name="1">当日热点</van-radio>
           <van-radio name="2">
             <div class="picker-container">
-              <DateRangePicker v-model="dateState.selectDate" @change="handleChange" />
+              <DateRangePicker
+                v-model="dateState.selectDate"
+                @change="handleChange"
+              />
             </div>
           </van-radio>
         </van-radio-group>
@@ -17,16 +30,22 @@
       <div class="content-header">
         <div class="text-box">
           <div class="text1">经统计:</div>
-          <div class="text1">{{queryParams.date[0]}}</div>
+          <div class="text1">{{ queryParams.date[0] }}</div>
           <div class="text1">至</div>
-          <div class="text1">{{queryParams.date[1]}}</div>
+          <div class="text1">{{ queryParams.date[1] }}</div>
           <div class="text1">共</div>
           <div class="text2">{{ forestFireData.total }}</div>
           <div class="text1">条数据</div>
         </div>
       </div>
-      <van-swipe v-if="forestFireData.dataList && forestFireData.dataList.length > 0">
-        <van-swipe-item v-for="(item, index) in forestFireData.dataList" :key="index" class="swipe-card">
+      <van-swipe
+        v-if="forestFireData.dataList && forestFireData.dataList.length > 0"
+      >
+        <van-swipe-item
+          v-for="(item, index) in forestFireData.dataList"
+          :key="index"
+          class="swipe-card"
+        >
           <div class="card-cell">
             <div class="text1">{{ item.name }}</div>
           </div>
@@ -46,12 +65,16 @@
           <div class="card-cell">
             <div class="card-item">
               <div class="item-label">亮温强度</div>
-              <div class="item-value2">{{ !!item.data1 ? item.data1 : '--' }}K</div>
+              <div class="item-value2">
+                {{ !!item.data1 ? item.data1 : "--" }}K
+              </div>
             </div>
           </div>
           <div class="card-cell">
             <div class="card-item">
-              <div class="item-label">热点定位({{ item.lng + ',' + item.lat }})</div>
+              <div class="item-label">
+                热点定位({{ item.lng + "," + item.lat }})
+              </div>
               <div class="item-value">{{ item.address }}</div>
             </div>
           </div>
@@ -66,16 +89,16 @@
 </template>
 
 <script lang="ts" setup name="forestFireWarn">
-import {onMounted, reactive, ref} from "vue";
+import { onMounted, reactive, ref } from "vue";
 
 const queryParams = reactive({
-  type: '1',
+  type: "1",
   date: []
 });
 let dateState = reactive({
   nowDate: [],
   selectDate: []
-})
+});
 let pointType = ref([]);
 let eventDetails = ref({});
 let forestFireData = reactive({
@@ -84,24 +107,120 @@ let forestFireData = reactive({
 });
 
 const initData = () => {
-  console.log('初始化数据', queryParams);
+  console.log("初始化数据", queryParams);
   forestFireData = {
-    total: 4,
+    total: 10,
     dataList: [
-      { name: '茂名市-高州市1', time1: '2024-07-25 10:30:01', time2: '2024-07-26 12:30:01', data1: '11', lng: '115.03', lat: '24.99', address: '立刻电视机风口浪尖分厘卡撒酒疯', data2: '林火' },
-      { name: '茂名市-高州市2', time1: '2024-07-25 10:30:01', time2: '2024-07-26 12:30:01', data1: '11', lng: '115.03', lat: '24.99', address: '立刻电视机风口浪尖分厘卡撒酒疯立刻电视机风口浪尖分厘卡撒酒疯立刻电视机风口浪尖分厘卡撒酒疯', data2: '林火' },
-      { name: '茂名市-高州市3', time1: '2024-07-25 10:30:01', time2: '2024-07-26 12:30:01', data1: '11', lng: '115.03', lat: '24.99', address: '立刻电视机风口浪尖分厘卡撒酒疯', data2: '林火' },
-      { name: '茂名市-高州市4', time1: '2024-07-25 10:30:01', time2: '2024-07-26 12:30:01', data1: '11', lng: '115.03', lat: '24.99', address: '立刻电视机风口浪尖分厘卡撒酒疯', data2: '林火' }
+      {
+        name: "茂名市-电白区-观珠镇",
+        time1: "2024-07-25 10:30:01",
+        time2: "2024-07-26 12:30:01",
+        data1: 350, // 亮温强度
+        lng: "111.18", // 观珠镇经度
+        lat: "21.69", // 观珠镇纬度
+        address: "281省道附近",
+        data2: "初期火灾" // 类型
+      },
+      {
+        name: "茂名市-高州市-石鼓镇",
+        time1: "2024-08-05 08:45:00",
+        time2: "2024-08-06 10:00:00",
+        data1: 420, // 亮温强度
+        lng: "110.77", // 石鼓镇经度
+        lat: "21.82", // 石鼓镇纬度
+        address: "高州市石鼓镇石鼓公园",
+        data2: "草地火灾" // 类型
+      },
+      {
+        name: "茂名市-信宜市-池洞镇",
+        time1: "2024-07-30 14:00:00",
+        time2: "2024-07-31 16:00:00",
+        data1: 380, // 亮温强度
+        lng: "110.95", // 池洞镇经度
+        lat: "22.43", // 池洞镇纬度
+        address: "广海路37号附近",
+        data2: "初期火灾" // 类型
+      },
+      {
+        name: "茂名市-茂南区-袂花镇",
+        time1: "2024-08-01 11:00:00",
+        time2: "2024-08-02 13:00:00",
+        data1: 450, // 亮温强度
+        lng: "110.94", // 袂花镇经度
+        lat: "21.58", // 袂花镇纬度
+        address: "袂花镇茂名市第六中学",
+        data2: "中期火灾" // 类型
+      },
+      {
+        name: "茂名市-电白区-麻岗镇",
+        time1: "2024-08-03 16:00:00",
+        time2: "2024-08-04 18:00:00",
+        data1: 370, // 亮温强度
+        lng: "111.18", // 麻岗镇经度
+        lat: "21.53", // 麻岗镇纬度
+        address: "麻岗镇温泉中路",
+        data2: "草地火灾" // 类型
+      },
+      {
+        name: "茂名市-高州市-谢鸡镇",
+        time1: "2024-08-07 09:00:00",
+        time2: "2024-08-08 11:00:00",
+        data1: 400, // 亮温强度
+        lng: "110.99", // 谢鸡镇经度
+        lat: "21.92", // 谢鸡镇纬度
+        address: "谢鸡镇府前路1号",
+        data2: "初期火灾" // 类型
+      },
+      {
+        name: "茂名市-信宜市-丁堡镇",
+        time1: "2024-08-09 15:00:00",
+        time2: "2024-08-10 17:00:00",
+        data1: 390, // 亮温强度
+        lng: "110.99", // 丁堡镇经度
+        lat: "22.30", // 丁堡镇纬度
+        address: "丁堡旧街1号",
+        data2: "草地火灾" // 类型
+      },
+      {
+        name: "茂名市-茂南区-金塘镇",
+        time1: "2024-08-11 10:00:00",
+        time2: "2024-08-12 12:00:00",
+        data1: 430, // 亮温强度
+        lng: "110.84", // 金塘镇经度
+        lat: "21.75", // 金塘镇纬度
+        address: "人民二路2号",
+        data2: "中期火灾" // 类型
+      },
+      {
+        name: "茂名市-电白区-林头镇",
+        time1: "2024-08-13 08:00:00",
+        time2: "2024-08-14 10:00:00",
+        data1: 360, // 亮温强度
+        lng: "111.06", // 林头镇经度
+        lat: "21.66", // 林头镇纬度
+        address: "林头镇s281西街和北街交叉口",
+        data2: "草地火灾" // 类型
+      },
+      {
+        name: "茂名市-茂南区-羊角镇",
+        time1: "2024-08-15 17:00:00",
+        time2: "2024-08-16 19:00:00",
+        data1: 410, // 亮温强度
+        lng: "110.98", // 羊角镇经度
+        lat: "21.67", // 羊角镇纬度
+        address: "羊正街12号附近",
+        data2: "中期火灾" // 类型
+      }
     ]
-  }
-}
+  };
+};
 
 // 选项变化
 const handleChange = () => {
-  if (queryParams.type === '1') {
+  if (queryParams.type === "1") {
     createNowDate();
     initData();
-  } else if (dateState.selectDate[0] || dateState.selectDate[1]){
+  } else if (dateState.selectDate[0] || dateState.selectDate[1]) {
     queryParams.date = dateState.selectDate;
     initData();
   }
@@ -110,16 +229,16 @@ const handleChange = () => {
 const createNowDate = () => {
   const now = new Date();
   const year = now.getFullYear();
-  const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始,所以要加1,并且使用padStart来确保是两位数
-  const day = String(now.getDate()).padStart(2, '0'); // 使用padStart来确保是两位数
-  const date = `${year}-${month}-${day}`
+  const month = String(now.getMonth() + 1).padStart(2, "0"); // 月份从0开始,所以要加1,并且使用padStart来确保是两位数
+  const day = String(now.getDate()).padStart(2, "0"); // 使用padStart来确保是两位数
+  const date = `${year}-${month}-${day}`;
   dateState.nowDate = [date, date];
   queryParams.date = [date, date];
-}
+};
 onMounted(() => {
   createNowDate();
   initData();
-})
+});
 </script>
 
 <style lang="scss" scoped>
@@ -176,7 +295,7 @@ onMounted(() => {
       font-size: 16px;
       font-weight: bold;
     }
-    .card-item  {
+    .card-item {
       .item-label {
         color: #969799;
         display: flex;
@@ -200,7 +319,7 @@ onMounted(() => {
     }
   }
 }
-.van-swipe{
+.van-swipe {
   position: relative;
   margin: 0 10px 10px;
   background-color: #ffffff;

+ 99 - 50
src/views/disasterRiskMonitor/galeDisaster.vue

@@ -4,10 +4,14 @@
       <div class="box-item">
         <div class="box-label">实况:</div>
         <div
-            v-for="(item, index) in option1"
-            :key="index"
-            :class="(queryParams.value1 === '1' && queryParams.value2 === item.value) ? 'box-tag tag-active' : 'box-tag'"
-            @click="handleClickMenu('1', item.value)"
+          v-for="(item, index) in option1"
+          :key="index"
+          :class="
+            queryParams.value1 === '1' && queryParams.value2 === item.value
+              ? 'box-tag tag-active'
+              : 'box-tag'
+          "
+          @click="handleClickMenu('1', item.value)"
         >
           {{ item.text }}
         </div>
@@ -15,89 +19,134 @@
       <div class="box-item">
         <div class="box-label">预警:</div>
         <div
-            v-for="(item, index) in option1"
-            :key="index"
-            :class="(queryParams.value1 === '2' && queryParams.value2 === item.value) ? 'box-tag tag-active' : 'box-tag'"
-            @click="handleClickMenu('2', item.value)"
+          v-for="(item, index) in option1"
+          :key="index"
+          :class="
+            queryParams.value1 === '2' && queryParams.value2 === item.value
+              ? 'box-tag tag-active'
+              : 'box-tag'
+          "
+          @click="handleClickMenu('2', item.value)"
         >
           {{ item.text }}
         </div>
       </div>
     </div>
-    <van-image :src="detailsData.img" style="display: block;" />
-    <van-text-ellipsis class="text-box" :content="detailsData.text" rows="3" expand-text="展开" collapse-text="收起" />
-    <el-table :data="detailsData.dataList" border table-layout='auto'>
+    <van-image :src="detailsData.img" style="display: block" />
+    <van-text-ellipsis
+      class="text-box"
+      :content="detailsData.text"
+      rows="3"
+      expand-text="展开"
+      collapse-text="收起"
+    />
+    <el-table :data="detailsData.dataList" border table-layout="auto">
       <el-table-column label="地区" prop="area" align="center" />
       <el-table-column prop="level" align="center">
         <template #header>
           <div class="table-line" @click="showLevelPicker = true">
-            <div>{{ labelData.level ? labelData.level : '县区' }}</div>
+            <div>{{ labelData.level ? labelData.level : "县区" }}</div>
             <i class="icon-down" />
           </div>
         </template>
       </el-table-column>
-      <el-table-column label="站址" prop="address" align="center" width="160px" />
+      <el-table-column
+        label="站址"
+        prop="address"
+        align="center"
+        width="160px"
+      />
       <el-table-column label="风速(m/s)" prop="speed" align="center" sortable />
     </el-table>
     <van-popup v-model:show="showLevelPicker" round position="bottom">
       <van-picker
-          :columns="levelColumns"
-          @cancel="showLevelPicker = false"
-          @confirm="onSelectLevelConfirm"
+        :columns="levelColumns"
+        @cancel="showLevelPicker = false"
+        @confirm="onSelectLevelConfirm"
       />
     </van-popup>
   </div>
 </template>
 
 <script lang="ts" setup>
-import {onMounted, reactive, ref} from "vue";
-import {ElTable, ElTableColumn} from "element-plus";
+import { onMounted, reactive, ref } from "vue";
+import { ElTable, ElTableColumn } from "element-plus";
 
 const option1 = reactive([
-  { text: '1h', value: '1' },
-  { text: '3h', value: '3' },
-  { text: '6h', value: '6' },
-  { text: '12h', value: '12' },
-  { text: '24h', value: '24' }
+  { text: "1h", value: "1" },
+  { text: "3h", value: "3" },
+  { text: "6h", value: "6" },
+  { text: "12h", value: "12" },
+  { text: "24h", value: "24" }
 ]);
 const labelData = reactive({
-  type: '',
-  level: '',
-  area: ''
-})
+  type: "",
+  level: "",
+  area: ""
+});
 const queryParams = reactive({
-  value1: '1',
-  value2: '24',
-  type: '',
-  level: '',
-  area: ''
+  value1: "1",
+  value2: "24",
+  type: "",
+  level: "",
+  area: ""
 });
 const detailsData = ref({
-  img: '',
-  text: '',
+  img: "",
+  text: "",
   dataList: []
 });
 const initData = () => {
   detailsData.value = {
-    img: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg',
-    text: '就诞生了附件两款发动机了解案件来看世界分手机否结束骄傲就开了房间离开家可怜见立刻就杀了对方吉林省大家逻辑了及时了解多方了解逻辑范德萨发给收到发给对方独放个',
+    img: "src/assets/images/disasterRiskMonitor/galeDisaster/icon1.png",
+    text: "截至2024年10月29日17时,茂名地区遭受大风影响,平均风速达到20米/秒以上,部分地区阵风超过25米/秒。目前,电白区、茂南区等地已启动应急预案,提醒市民减少外出,确保人身安全。各监测站点正持续监控风速变化,并将实时更新信息。",
     dataList: [
-      { area: '电白', type: '滨海新区', address: '但是看了放进塑料袋发艰苦拉萨的飞机快乐设计逻辑地', speed: '12.1' },
+      {
+        area: "茂名",
+        level: "电白区",
+        address: "电白区黄岭镇石头村气象站",
+        speed: "25.3 m/s" // 风速合理范围:强风级别
+      },
+      {
+        area: "茂名",
+        level: "茂南区",
+        address: "茂南区袂花镇气象观测点",
+        speed: "22.5 m/s"
+      },
+      {
+        area: "茂名",
+        level: "高州市",
+        address: "高州市石鼓镇风速监测站",
+        speed: "20.7 m/s"
+      },
+      {
+        area: "茂名",
+        level: "化州市",
+        address: "化州市同庆镇风力监测点",
+        speed: "18.9 m/s"
+      },
+      {
+        area: "茂名",
+        level: "信宜市",
+        address: "信宜市池洞镇气象站点",
+        speed: "21.2 m/s"
+      }
     ]
-  }
-}
+  };
+};
 
 const levelColumns = ref([
-  { text: '全部', value: '' },
-  { text: '滨海新区', value: '0' },
-  { text: '信宜', value: '1' },
-  { text: '电白', value: '2' },
-  { text: '高州', value: '3' }
-])
+  { text: "全部", value: "" },
+  { text: "滨海新区", value: "0" },
+  { text: "信宜", value: "1" },
+  { text: "电白", value: "2" },
+  { text: "高州", value: "3" }
+]);
 let showLevelPicker = ref(false);
-const onSelectLevelConfirm  = ({selectedOptions}) => {
+const onSelectLevelConfirm = ({ selectedOptions }) => {
   showLevelPicker.value = false;
-  labelData.level = selectedOptions[0].text === '全部' ? '县区' :selectedOptions[0].text;
+  labelData.level =
+    selectedOptions[0].text === "全部" ? "县区" : selectedOptions[0].text;
   queryParams.level = selectedOptions[0].value;
   initData();
 };
@@ -105,10 +154,10 @@ const handleClickMenu = (value1, value2) => {
   queryParams.value1 = value1;
   queryParams.value2 = value2;
   initData();
-}
+};
 
 onMounted(() => {
-  initData()
+  initData();
 });
 </script>
 
@@ -152,7 +201,7 @@ onMounted(() => {
       flex-shrink: 0;
       width: 14px;
       height: 14px;
-      background: url('@/assets/images/down.png') no-repeat;
+      background: url("@/assets/images/down.png") no-repeat;
       background-size: 100% 100%;
     }
   }

+ 132 - 65
src/views/disasterRiskMonitor/warningSituation.vue

@@ -1,24 +1,53 @@
 <template>
   <div class="container">
     <van-image :src="detailsData.img" />
-    <el-table :data="detailsData.dataList" border table-layout='auto'>
+    <el-table :data="detailsData.dataList" border table-layout="auto">
       <el-table-column prop="type" align="center">
         <template #header>
           <div class="table-line" @click="showTypePicker = true">
-            <div>{{ labelData.type ? labelData.type : '类型' }}</div>
+            <div>{{ labelData.type ? labelData.type : "类型" }}</div>
             <i class="icon-down" />
           </div>
         </template>
+        <template #default="scope">
+          <img
+            v-if="scope.row.level === '1'"
+            :src="'src/assets/images/disasterRiskMonitor/warningSituation/icon5.png'"
+            alt="blue alert"
+            class="alert-icon"
+          />
+          <img
+            v-else-if="scope.row.level === '2'"
+            :src="'src/assets/images/disasterRiskMonitor/warningSituation/icon2.png'"
+            alt="yellow alert"
+            class="alert-icon"
+          />
+          <img
+            v-else-if="scope.row.level === '3'"
+            :src="'src/assets/images/disasterRiskMonitor/warningSituation/icon3.png'"
+            alt="orange alert"
+            class="alert-icon"
+          />
+          <img
+            v-else-if="scope.row.level === '4'"
+            :src="'src/assets/images/disasterRiskMonitor/warningSituation/icon4.png'"
+            alt="red alert"
+            class="alert-icon"
+          />
+          <span v-else>无预警</span>
+        </template>
       </el-table-column>
       <el-table-column prop="level" align="center">
         <template #header>
           <div class="table-line" @click="showLevelPicker = true">
-            <div>{{ labelData.level ? labelData.level : '等级' }}</div>
+            <div>{{ labelData.level ? labelData.level : "等级" }}</div>
             <i class="icon-down" />
           </div>
         </template>
         <template #default="scope">
-          <div :class="getClass(scope.row.level)">{{ getLabel(scope.row.level) }}</div>
+          <div :class="getClass(scope.row.level)">
+            {{ getLabel(scope.row.level) }}
+          </div>
         </template>
       </el-table-column>
       <el-table-column label="地区" prop="area" align="center" />
@@ -26,86 +55,120 @@
     </el-table>
     <van-popup v-model:show="showTypePicker" round position="bottom">
       <van-picker
-          :columns="typeColumns"
-          @cancel="showTypePicker = false"
-          @confirm="onSelectTypeConfirm"
+        :columns="typeColumns"
+        @cancel="showTypePicker = false"
+        @confirm="onSelectTypeConfirm"
       />
     </van-popup>
     <van-popup v-model:show="showLevelPicker" round position="bottom">
       <van-picker
-          :columns="levelColumns"
-          @cancel="showLevelPicker = false"
-          @confirm="onSelectLevelConfirm"
+        :columns="levelColumns"
+        @cancel="showLevelPicker = false"
+        @confirm="onSelectLevelConfirm"
       />
     </van-popup>
   </div>
 </template>
 
 <script lang="ts" setup name="warningSituation">
-import {onMounted, reactive, ref} from "vue";
+import { onMounted, reactive, ref } from "vue";
 import { ElTable, ElTableColumn } from "element-plus";
 
 const labelData = reactive({
-  type: '',
-  level: '',
-  area: ''
-})
+  type: "",
+  level: "",
+  area: ""
+});
 const queryParams = reactive({
-  type: '',
-  level: '',
-  area: ''
+  type: "",
+  level: "",
+  area: ""
 });
 const detailsData = ref({
-  img: '',
+  img: "",
   dataList: []
 });
 const getClass = (data: string) => {
-  let res = 'text';
-  if (data === '1') {
-    res = 'text text-blue'
-  } else if (data === '2') {
-    res = 'text text-yellow'
-  } else if (data === '3') {
-    res = 'text text-orange'
-  } else if (data === '4') {
-    res = 'text text-red'
+  let res = "text";
+  if (data === "1") {
+    res = "text text-blue";
+  } else if (data === "2") {
+    res = "text text-yellow";
+  } else if (data === "3") {
+    res = "text text-orange";
+  } else if (data === "4") {
+    res = "text text-red";
   }
   return res;
 };
 const getLabel = (data: string) => {
-  let res = '无预警';
-  if (data === '1') {
-    res = '蓝色'
-  } else if (data === '2') {
-    res = '黄色'
-  } else if (data === '3') {
-    res = '橙色'
-  } else if (data === '4') {
-    res = '红色'
+  let res = "无预警";
+  if (data === "1") {
+    res = "蓝色";
+  } else if (data === "2") {
+    res = "黄色";
+  } else if (data === "3") {
+    res = "橙色";
+  } else if (data === "4") {
+    res = "红色";
   }
   return res;
 };
 const initData = () => {
   detailsData.value = {
-    img: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg',
+    img: "src/assets/images/disasterRiskMonitor/warningSituation/icon1.png",
     dataList: [
-      { area: '电白', type: '1', level: '1', publicTime: '2024-10-03 15:42:01' },
-      { area: '高新', type: '1', level: '2', publicTime: '2024-10-03 15:42:01' },
-      { area: '茂南', type: '1', level: '3', publicTime: '2024-10-03 15:42:01' },
-      { area: '滨海', type: '1', level: '4', publicTime: '2024-10-03 15:42:01' },
-      { area: '化州', type: '1', level: '0', publicTime: '2024-10-03 15:42:01' },
-      { area: '高州', type: '1', level: '1', publicTime: '2024-10-03 15:42:01' },
-      { area: '信宜', type: '1', level: '1', publicTime: '2024-10-03 15:42:01' }
+      {
+        area: "电白",
+        type: "1",
+        level: "2",
+        publicTime: "2024-10-28 13:32:01"
+      },
+      {
+        area: "高新",
+        type: "1",
+        level: "2",
+        publicTime: "2024-10-28 14:42:21"
+      },
+      {
+        area: "茂南",
+        type: "1",
+        level: "0",
+        publicTime: "2024-10-28 15:13:13"
+      },
+      {
+        area: "滨海",
+        type: "1",
+        level: "2",
+        publicTime: "2024-10-28 16:27:21"
+      },
+      {
+        area: "化州",
+        type: "1",
+        level: "1",
+        publicTime: "2024-10-28 17:31:55"
+      },
+      {
+        area: "高州",
+        type: "1",
+        level: "3",
+        publicTime: "2024-10-28 17:49:01"
+      },
+      { area: "信宜", type: "1", level: "3", publicTime: "2024-10-28 18:09:11" }
     ]
-  }
-}
-
+  };
+};
+// 获取类型标签
+const getTypeLabel = (typeCode: string) => {
+  const typeItem = typeColumns.value.find(item => item.value === typeCode);
+  return typeItem ? typeItem.text : "未知类型";
+};
 const typeColumns = ref([
-  { text: '全部', value: '' },
-  { text: '森林火险', value: '1' }
-])
+  { text: "全部", value: "" },
+  { text: "森林火险", value: "1" }
+]);
 let showTypePicker = ref(false);
-const onSelectTypeConfirm  = ({selectedOptions}) => {
+const onSelectTypeConfirm = ({ selectedOptions }) => {
   showTypePicker.value = false;
   labelData.type = selectedOptions[0].text;
   queryParams.type = selectedOptions[0].value;
@@ -113,15 +176,15 @@ const onSelectTypeConfirm  = ({selectedOptions}) => {
 };
 
 const levelColumns = ref([
-  { text: '全部', value: '' },
-  { text: '无预警', value: '0' },
-  { text: '蓝色', value: '1' },
-  { text: '黄色', value: '2' },
-  { text: '橘色', value: '3' },
-  { text: '红色', value: '4' }
-])
+  { text: "全部", value: "" },
+  { text: "无预警", value: "0" },
+  { text: "蓝色", value: "1" },
+  { text: "黄色", value: "2" },
+  { text: "橘色", value: "3" },
+  { text: "红色", value: "4" }
+]);
 let showLevelPicker = ref(false);
-const onSelectLevelConfirm  = ({selectedOptions}) => {
+const onSelectLevelConfirm = ({ selectedOptions }) => {
   showLevelPicker.value = false;
   labelData.level = selectedOptions[0].text;
   queryParams.level = selectedOptions[0].value;
@@ -130,7 +193,7 @@ const onSelectLevelConfirm  = ({selectedOptions}) => {
 
 onMounted(() => {
   initData();
-})
+});
 </script>
 
 <style lang="scss" scoped>
@@ -147,25 +210,29 @@ onMounted(() => {
       flex-shrink: 0;
       width: 14px;
       height: 14px;
-      background: url('@/assets/images/down.png') no-repeat;
+      background: url("@/assets/images/down.png") no-repeat;
       background-size: 100% 100%;
     }
   }
   .text {
     font-size: 14px;
-    color: #A3A7AD;
+    color: #a3a7ad;
   }
   .text-blue {
-    color: #2C81FF;
+    color: #2c81ff;
   }
   .text-yellow {
     color: #ffd700;
   }
   .text-orange {
-    color: #FFAF00;
+    color: #ffaf00;
   }
   .text-red {
     color: #ec2734;
   }
 }
+.alert-icon {
+  width: 36px;
+  height: 24px;
+}
 </style>

+ 462 - 0
src/views/worker/eventManagement/eventList.vue

@@ -0,0 +1,462 @@
+<template>
+  <div class="container">
+<!--搜索框-->
+    <van-search
+      v-model="queryParams.search_keyword"
+      class="common-search"
+      :left-icon="searchImg"
+      :right-icon="closeImg"
+      :clearable="false"
+      @search="on_search_keyword"
+      @click-right-icon.stop="on_search_cancel"
+    />
+<!--三个类型选择-->
+    <van-dropdown-menu>
+      <van-dropdown-item
+        v-model="queryParams.event_type"
+        :title="!!queryParams.event_type ? '' : '类型'"
+        :options="opt_event_type"
+        @change="change_event_type"
+      />
+      <van-dropdown-item
+        v-model="queryParams.event_level"
+        :title="!!queryParams.event_level ? '' : '等级'"
+        :options="opt_event_level"
+        @change="change_event_level"
+      />
+      <van-dropdown-item
+        v-model="queryParams.event_status"
+        :title="!!queryParams.event_status ? '' : '状态'"
+        :options="opt_event_status"
+        @change="change_event_status"
+      />
+    </van-dropdown-menu>
+
+    <van-list
+      v-model:loading="loading"
+      v-model:error="error"
+      error-text="请求失败,点击重新加载"
+      :finished="finished"
+      finished-text="没有更多事件了"
+      class="list"
+      @load="getList"
+    >
+      <div
+        v-for="(item, index) in event_list"
+        :key="item.id"
+        class="event-list-item"
+      >
+        <div class="item-title">
+          <div class="item-title-text">
+            {{ item.event_title }}
+          </div>
+          <div class="item-title-control">
+            <van-button
+              v-if="item.event_status == '0'"
+              type="primary"
+              @click="handleStartEvent(index)"
+            >
+              开始指挥
+            </van-button>
+            <van-button
+              v-if="item.event_status == '1'"
+              type="danger"
+              size="small"
+              @click="handleCloseEvent(item)"
+            >
+              结束指挥
+            </van-button>
+          </div>
+        </div>
+        <div class="item-content" @click="handleEventDetail(index)">
+          <div class="item-data">
+            <div class="item-left">
+              <i class="icon1" />
+              <div class="item-data-label">事件类型:</div>
+            </div>
+            <div class="item-data-value">
+              <dict-tag :options="mm_event_type" :value="item.event_type" />
+            </div>
+          </div>
+          <div class="item-data">
+            <div class="item-left">
+              <i class="icon2" />
+              <div class="item-data-label">事件等级:</div>
+            </div>
+            <div class="item-data-value">
+              <dict-tag :options="mm_event_level" :value="item.event_level" />
+            </div>
+          </div>
+          <div class="item-data">
+            <div class="item-left">
+              <i class="icon3" />
+              <div class="item-data-label">事件状态:</div>
+            </div>
+            <div class="item-data-value">
+              <dict-tag :options="mm_event_state" :value="item.event_status" />
+            </div>
+          </div>
+          <div class="item-data">
+            <div class="item-left">
+              <i class="icon4" />
+              <div class="item-data-label">事发时间:</div>
+            </div>
+            <div class="item-data-value">{{ item.event_time }}</div>
+          </div>
+          <div class="item-data">
+            <div class="item-left">
+              <i class="icon5" />
+              <div class="item-data-label">事发地点:</div>
+            </div>
+            <div class="item-data-value">{{ item.address }}</div>
+          </div>
+        </div>
+      </div>
+    </van-list>
+    <!--
+    <StartEventDialog
+      v-model="startEventState.show"
+      :data="startEventState.form"
+      @update:model-value="onStartEventDialogClose"
+    />
+    <CloseEventDialog
+      v-model="closeEventState.show"
+      :data="closeEventState.form"
+      @update:model-value="onCloseEventDialogClose"
+    />
+    -->
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { getCurrentInstance, reactive, ref, toRefs, onMounted } from "vue";
+import { useRouter } from "vue-router";
+import { showConfirmDialog, showSuccessToast } from "vant";
+// import StartEventDialog from "./StartEventDialog.vue";
+// import CloseEventDialog from "./CloseEventDialog.vue";
+
+import { closeEvent, getEventList } from "@/api/event";
+import searchImg from "@/assets/images/search.png";
+import closeImg from "@/assets/images/close.png";
+
+const proxy = getCurrentInstance()?.proxy;
+const { mm_event_type, mm_event_level, mm_event_state } = toRefs<any>(
+  proxy?.useDict("mm_event_type", "mm_event_level", "mm_event_state")
+);
+
+const router = useRouter();
+
+const opt_event_type = [
+  { text: "全部", value: "" },
+  { text: "自然灾害", value: "0" },
+  { text: "事故灾害", value: "1" },
+  { text: "公共卫生事件", value: "2" },
+  { text: "社会安全事件", value: "3" }
+];
+
+const opt_event_level = [
+  { text: "全部", value: "" },
+  { text: "一般", value: "1" },
+  { text: "较大", value: "2" },
+  { text: "重大", value: "3" },
+  { text: "特别重大", value: "4" },
+  { text: "其他", value: "0" }
+];
+
+const opt_event_status = [
+  { text: "全部", value: "" },
+  { text: "已登记", value: "0" },
+  { text: "指挥中", value: "1" },
+  { text: "指挥结束", value: "2" },
+  { text: "已关闭", value: "2" }
+];
+
+const current_item = ref(null);
+const event_list = ref([]);
+const total = ref(0);
+const loading = ref(false);
+const error = ref(false);
+const finished = ref(false);
+const queryParams = ref({
+  page: 0,
+  page_size: 10,
+  event_type: "",
+  event_level: "",
+  event_status: "",
+  search_keyword: ""
+});
+
+const on_search_keyword = val => {
+  queryParams.value.search_keyword = val;
+  queryParams.value.page = 0;
+  getList();
+};
+
+const on_search_cancel = () => {
+  queryParams.value.search_keyword = "";
+  queryParams.value.page = 0;
+  getList();
+};
+
+const change_event_type = () => {
+  queryParams.value.page = 0;
+  getList();
+};
+
+const change_event_level = () => {
+  queryParams.value.page = 0;
+  getList();
+};
+
+const change_event_status = () => {
+  queryParams.value.page = 0;
+  getList();
+};
+
+const getList = () => {
+  queryParams.value.page++;
+  getEventList(queryParams.value)
+    .then(res => {
+      var items = res.data || [];
+      total.value = res.total;
+      if (queryParams.value.page == 1) {
+        event_list.value = [];
+      }
+      items.forEach(val => {
+        event_list.value.push(val);
+      });
+      if (queryParams.value.page_size * queryParams.value.page >= total.value) {
+        finished.value = true;
+      } else {
+        finished.value = false;
+      }
+    })
+    .catch(() => {
+      error.value = true;
+      finished.value = false;
+    })
+    .finally(() => {
+      loading.value = false;
+    });
+};
+
+const startEventState = reactive({
+  show: false,
+  form: {
+    event_id: "",
+    event_title: "",
+    event_level: "",
+    event_level_text: ""
+  }
+});
+
+const closeEventState = reactive({
+  show: false,
+  form: {
+    event_id: "",
+    event_title: "",
+    event_level: "",
+    event_level_text: "",
+    deaths: "",
+    injuries: "",
+    missing: ""
+  }
+});
+
+const onStartEventDialogClose = t => {
+  startEventState.show = false;
+  console.log(startEventState.form);
+  if (t) {
+    queryParams.value.page = 0;
+    getList();
+  }
+};
+
+const onCloseEventDialogClose = t => {
+  closeEventState.show = false;
+  console.log(closeEventState.form);
+  if (t) {
+    queryParams.value.page = 0;
+    getList();
+  }
+};
+
+const onConfirm = () => {
+  showConfirmDialog({
+    title: "提示",
+    message: "确认进入移动指挥(应急态)"
+  })
+    .then(() => {
+      localStorage.setItem("mobile_control_status", "1");
+      router.push("/leader/mobile_control");
+    })
+    .catch(() => {});
+};
+
+const handleEventDetail = index => {
+  current_item.value = event_list.value[index];
+  router.push("/event/detail?event_id=" + current_item.value.event_id);
+};
+
+const handleStartEvent = index => {
+  current_item.value = event_list.value[index];
+  console.log("handleStartEvent", current_item.value.event_id);
+  startEventState.form.event_id = current_item.value.event_id;
+  startEventState.form.event_title = current_item.value.event_title;
+  startEventState.form.event_level = current_item.value.event_level;
+  startEventState.show = true;
+  return false;
+};
+
+const handleCloseEvent = item => {
+  showConfirmDialog({
+    title: "结束指挥",
+    message: "是否确定结束指挥?"
+  }).then(() => {
+    const params = {
+      eventId: item.value.event_id,
+      address: item.value.address,
+      latitude: item.value.latitude,
+      longitude: item.value.longitude
+    };
+    // 如果 flag 为 true,则直接调用 closeEvent 接口关闭事件
+    closeEvent(params).then(() => {
+      showSuccessToast("结束指挥成功");
+      router.push("/leader/index");
+    });
+  });
+};
+</script>
+
+<style lang="scss" scoped>
+.list {
+  height: calc(100vh - 102px);
+  overflow-y: auto;
+}
+.van-doc-block__title {
+  color: var(--van-doc-text-color-4);
+  margin: 0;
+  padding: 32px 16px 16px;
+  font-size: 14px;
+  font-weight: 400;
+  line-height: 16px;
+}
+
+.event-list-item {
+  position: relative;
+  margin: 16px 16px 0;
+  background: #ffffff;
+  border-radius: 4px;
+  border: 0.5px solid #eaedf7;
+  box-shadow: 0 0 4px 0 #4554661a;
+  &:first-child {
+    margin-top: 0;
+  }
+  .item-title {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    min-height: 46px;
+    background-image: linear-gradient(180deg, #f3f7fd 0%, #ffffff 100%);
+    padding: 0 12px;
+    .item-title-text {
+      font-size: 16px;
+      color: #414f64;
+      font-weight: 600;
+    }
+
+    .item-title-control {
+      display: inline-flex;
+      justify-content: center;
+      align-items: center;
+    }
+    .van-button {
+      width: 73px;
+      height: 24px;
+      padding: 0;
+    }
+  }
+  .item-content {
+    padding: 0 12px 12px;
+  }
+  .item-data {
+    font-size: 14px;
+    display: flex;
+    flex-direction: row;
+    align-items: flex-start;
+    justify-content: start;
+    line-height: 26px;
+    .item-left {
+      display: flex;
+      align-items: center;
+      flex-shrink: 0;
+    }
+    .item-data-label {
+      flex-shrink: 0;
+      color: #414f64;
+    }
+
+    .item-data-value {
+      color: #414f64;
+    }
+  }
+}
+.van-dropdown-menu {
+  :deep(.van-dropdown-menu__bar) {
+    background: transparent;
+    box-shadow: none;
+  }
+}
+.common-search {
+  :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;
+    }
+  }
+}
+.icon1 {
+  width: 17px;
+  height: 16px;
+  background: url("@/assets/images/event/icon1.png") no-repeat;
+  background-size: 100% 100%;
+  margin-right: 7px;
+}
+.icon2 {
+  width: 17px;
+  height: 16px;
+  background: url("@/assets/images/event/icon2.png") no-repeat;
+  background-size: 100% 100%;
+  margin-right: 7px;
+}
+.icon3 {
+  width: 17px;
+  height: 16px;
+  background: url("@/assets/images/event/icon3.png") no-repeat;
+  background-size: 100% 100%;
+  margin-right: 7px;
+}
+.icon4 {
+  width: 17px;
+  height: 16px;
+  background: url("@/assets/images/event/icon4.png") no-repeat;
+  background-size: 100% 100%;
+  margin-right: 7px;
+}
+.icon5 {
+  width: 16px;
+  height: 16px;
+  background: url("@/assets/images/event/icon5.png") no-repeat;
+  background-size: 100% 100%;
+  margin-right: 7px;
+}
+</style>

+ 81 - 0
src/views/worker/eventManagement/index.vue

@@ -0,0 +1,81 @@
+<template>
+    <div class="container">
+      <div class="tabs">
+        <div v-for="item in tabs" :key="item.id" class="tab" @click="handleClickTab(item.id)">
+          <i :class="item.icon" />
+          <div :class="activeIndex === item.id ? 'tab-text text-active' : 'tab-text'">{{ item.name }}</div>
+        </div>
+      </div>
+      <div class="content">
+        <eventList v-if="activeIndex === 'event'" @changIndex="handleClickTab" />
+        <!--
+        <HiddenSource v-else-if="activeIndex === 'task'" />
+        <investigationRecords v-else-if="activeIndex === 'job'" />
+      -->
+      </div>
+    </div>
+  </template>
+  <script setup lang="ts">
+  import { ref } from "vue";
+  import eventList from "./eventList.vue";
+  //import HiddenSource from "./HiddenSource.vue";
+  //import dangerousSource from "./dangerousSource.vue";
+  
+  let activeIndex = ref('event');
+  let tabs = ref([
+    { id: 'event', name: '事件管理', icon: 'icon1' },
+    { id: 'task', name: '任务管理', icon: 'icon2' },
+    { id: 'job', name: '工作请示', icon: 'icon3' },
+  ]);
+  
+  // 点击tab
+  const handleClickTab = (id) => {
+    activeIndex.value = id;
+  };
+  
+  </script>
+  
+  
+  <style lang="scss" scoped>
+  .container {
+    height: calc(100vh - 55px);
+    padding-top: 12px;
+    position: relative;
+    display: flex;
+    flex-direction: column;
+    .tabs {
+      height: 90px;
+      flex-shrink: 0;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      padding: 0 16px;
+      .tab {
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        .icon1, .icon2, .icon3, .icon4 {
+          display: inline-block;
+          width: 48px;
+          height: 48px;
+          background-color: #9d9d9d;
+        }
+        .tab-text {
+          color: #414F64;
+          font-size: 14px;
+          margin-top: 8px;
+        }
+        .text-active {
+          color: #2C81FF;
+        }
+      }
+    }
+    .content {
+      margin-top: 10px;
+      height: calc(100vh - 180px);
+      overflow-y: auto;
+    }
+  }
+  </style>
+