Hwf 8 mesiacov pred
rodič
commit
c80d3be14f

+ 253 - 0
src/utils/convergedCommunication.ts

@@ -0,0 +1,253 @@
+const socketUrl = import.meta.env.VITE_COMMUNICATION_WEBSOCKET;
+const base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+const base64DecodeChars = new Array(
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
+  -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
+
+export class ConvergedCommunication {
+  private retryCount;
+  public socket;
+  public svr;
+  public port;
+  public userid;
+  public openchannelid;
+  // tmtype设置模板样式。
+  public tmtype;
+  // wndid设置在几号窗口接收openchannelid的图像
+  public wndid;
+  // top置顶窗口是否置顶:top="1":窗口置顶,top="0":窗口不置顶。
+  public top;
+  //  x指定窗口的左边的位置。
+  public x;
+  // y指定窗口的顶部的位置。
+  public y;
+  // width指定窗口的宽度。
+  public width;
+  // height指定窗口的高度。
+  public height;
+  // visible窗口是否显示 1显示
+  public visible;
+  // showcaption设置是否显示标题栏 1显示
+  public showcaption;
+
+  // 初始化
+  constructor() {
+    this.svr = '19.152.196.106';
+    this.port = '4222';
+    this.userid = 'Of18NRTvjjpugOx37pezInXhuL0OEksX';
+    this.openchannelid = 'cs0001@xf_00';
+    this.tmtype = '4';
+    this.wndid = '0';
+    this.top = '1';
+    this.x = '20';
+    this.y = '20';
+    this.width = '960';
+    this.height = '540';
+    this.visible = '1';
+    this.showcaption = '1';
+    this.openSocket();
+  }
+
+  openSocket() {
+    if (this.socket != null) {
+      this.socket.close();
+      this.socket = null;
+    }
+
+    this.socket = new WebSocket(socketUrl);
+
+    this.socket.onopen = () => {
+      console.log('onopen');
+    };
+
+    this.socket.onclose = () => {
+      console.log('onclose');
+    };
+
+    this.socket.onmessage = (message) => {
+      console.log('onmessage: ', message);
+    };
+
+    this.socket.onerror = () => {
+      console.log('onerror');
+      this.restartSocket();
+    };
+  }
+  startSocket() {
+    this.openSocket();
+  }
+
+  restartSocket() {
+    this.retryCount++;
+    console.log('第' + this.retryCount + '次重连.');
+    setTimeout(() => {
+      this.openSocket();
+    }, 1000);
+  }
+
+  stopSocket() {
+    if (this.socket != null) {
+      this.socket.close();
+      this.socket = null;
+    }
+  }
+
+  base64encode(str) {
+    let out, i, len;
+    let c1, c2, c3;
+    len = str.length;
+    i = 0;
+    out = '';
+    while (i < len) {
+      c1 = str.charCodeAt(i++) & 0xff;
+      if (i == len) {
+        out += base64EncodeChars.charAt(c1 >> 2);
+        out += base64EncodeChars.charAt((c1 & 0x3) << 4);
+        out += '==';
+        break;
+      }
+      c2 = str.charCodeAt(i++);
+      if (i == len) {
+        out += base64EncodeChars.charAt(c1 >> 2);
+        out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
+        out += base64EncodeChars.charAt((c2 & 0xF) << 2);
+        out += '=';
+        break;
+      }
+      c3 = str.charCodeAt(i++);
+      out += base64EncodeChars.charAt(c1 >> 2);
+      out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
+      out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
+      out += base64EncodeChars.charAt(c3 & 0x3F);
+    }
+    return out;
+  }
+
+  base64decode(str) {
+    let c1, c2, c3, c4;
+    let i, len, out;
+    len = str.length;
+    i = 0;
+    out = '';
+    while (i < len) {
+      /* c1 */
+      do {
+        c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
+      } while (i < len && c1 == -1);
+      if (c1 == -1)
+        break;
+      /* c2 */
+      do {
+        c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
+      } while (i < len && c2 == -1);
+      if (c2 == -1)
+        break;
+      out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
+      /* c3 */
+      do {
+        c3 = str.charCodeAt(i++) & 0xff;
+        if (c3 == 61)
+          return out;
+        c3 = base64DecodeChars[c3];
+      } while (i < len && c3 == -1);
+      if (c3 == -1)
+        break;
+      out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
+      /* c4 */
+      do {
+        c4 = str.charCodeAt(i++) & 0xff;
+        if (c4 == 61)
+          return out;
+        c4 = base64DecodeChars[c4];
+      } while (i < len && c4 == -1);
+      if (c4 == -1)
+        break;
+      out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
+    }
+    return out;
+  }
+
+  utf16to8(str) {
+    let out, i, len, c;
+    out = '';
+    len = str.length;
+    for (i = 0; i < len; i++) {
+      c = str.charCodeAt(i);
+      if ((c >= 0x0001) && (c <= 0x007F)) {
+        out += str.charAt(i);
+      } else if (c > 0x07FF) {
+        out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
+        out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
+        out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
+      } else {
+        out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
+        out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
+      }
+    }
+    return out;
+  }
+
+  utf8to16(str) {
+    const len = str.length;
+    let out, i, c;
+    let char2, char3;
+    out = '';
+    i = 0;
+    while (i < len) {
+      c = str.charCodeAt(i++);
+      switch (c >> 4) {
+        case 0:
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
+          // 0xxxxxxx
+          out += str.charAt(i - 1);
+          break;
+        case 12:
+        case 13:
+          // 110x xxxx   10xx xxxx
+          char2 = str.charCodeAt(i++);
+          out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
+          break;
+        case 14:
+          // 1110 xxxx  10xx xxxx  10xx xxxx
+          char2 = str.charCodeAt(i++);
+          char3 = str.charCodeAt(i++);
+          out += String.fromCharCode(((c & 0x0F) << 12) |
+            ((char2 & 0x3F) << 6) |
+            ((char3 & 0x3F) << 0));
+          break;
+      }
+    }
+    return out;
+  }
+
+  start() {
+    const str =
+      `-r svr="${this.svr}" port="${this.port}" userid="${this.port}" openchannelid="${this.openchannelid}"` +
+      `tmtype="${this.tmtype}" wndid="${this.wndid}" top="${this.top}" x="${this.x}" y="${this.y}"` +
+      `w="${this.width}" h="${this.height}" visible="${this.visible}" showcaption="${this.showcaption}"`;
+    const val = 'AVCON-OCX://' + this.base64encode(this.utf16to8(str));
+    if (str.match('-r') && str.match('startws="1"')) {
+      setTimeout(() => {
+        this.startSocket();
+      }, 5000);
+    }
+    // 创建一个a标签元素
+    const a = document.createElement('a');
+    // 设置a标签的href属性
+    a.href = val;
+    // 触发点击事件
+    a.click();
+  }
+}

+ 24 - 16
src/views/emergencyCommandMap/LeftSection/VideoMonitor.vue

@@ -15,19 +15,19 @@
     <div class="search-box">
       <div class="box-left">
         <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="200px" label-position="left">
-          <el-form-item label="实景视频" prop="eventType">
-            <el-select
-              v-model="queryParams.realisticVideoType"
-              size="large"
-              class="custom-select"
-              popper-class="custom-select-popper"
-              :teleported="false"
-              placeholder="全部"
-            >
-              <el-option label="全部" value=""></el-option>
-              <el-option v-for="item in realistic_video" key="item.value" :label="item.label" :value="item.value" />
-            </el-select>
-          </el-form-item>
+<!--          <el-form-item label="实景视频" prop="eventType">-->
+<!--            <el-select-->
+<!--              v-model="queryParams.realisticVideoType"-->
+<!--              size="large"-->
+<!--              class="custom-select"-->
+<!--              popper-class="custom-select-popper"-->
+<!--              :teleported="false"-->
+<!--              placeholder="全部"-->
+<!--            >-->
+<!--              <el-option label="全部" value=""></el-option>-->
+<!--              <el-option v-for="item in realistic_video" key="item.value" :label="item.label" :value="item.value" />-->
+<!--            </el-select>-->
+<!--          </el-form-item>-->
           <el-form-item prop="name">
             <el-input
               v-model="queryParams.name"
@@ -35,7 +35,6 @@
               placeholder="请输入摄像头名称"
               size="large"
               style="width: 500px"
-              @input="getList"
             />
           </el-form-item>
           <el-form-item>
@@ -94,7 +93,6 @@
 <script lang="ts" setup name="VideoMonitor">
 import { getEmergencyVideoCata, getUserVideoPoints, getVideoListByUser, updateUserVideoPoints } from '@/api/videoMonitor';
 import { deepClone } from '@/utils';
-import AMapLoader from '@amap/amap-jsapi-loader';
 
 const props = defineProps({
   longitude: String,
@@ -147,7 +145,17 @@ const getList = async () => {
   await getUserVideoPoints().then((res) => {
     selectData.value = res.data.videoInfos;
   });
-  getEmergencyVideoCata(queryParams).then((res) => {
+  let newParams = {
+    latitude: queryParams.latitude,
+    longitude: queryParams.longitude,
+    current: queryParams.current,
+    size: queryParams.size,
+    query: {
+      name: queryParams.name,
+      realisticVideoType: queryParams.realisticVideoType
+    }
+  };
+  getEmergencyVideoCata(newParams).then((res) => {
     selectData.value.forEach((item) => {
       for (let i = 0; i < res.rows.length; i++) {
         if (item.video_code_int === res.rows[i].video_code) {

+ 453 - 0
src/views/emergencyCommandMap/RightSection/InitConsultation.vue

@@ -0,0 +1,453 @@
+<template>
+  <Dialog custom-show type="lg" title="发起会商" hide-footer @close="handleClose">
+    <div class="content">
+      <div class="left-content">
+        <el-input v-model="queryParams.keyword" class="custom-input" placeholder="组织架构搜索">
+          <template #prefix>
+            <el-icon class="el-input__icon"><search /></el-icon>
+          </template>
+        </el-input>
+        <div class="tree-container">
+          <div class="tree-box">
+            <el-tree :data="treeData" accordion @node-click="handleNodeClick" />
+          </div>
+        </div>
+      </div>
+      <div class="middle-content">
+        <div class="search-box">
+          <el-select
+            v-model="queryParams.value1"
+            class="custom-select select-box"
+            placeholder="全部"
+            popper-class="custom-select-popper"
+            :teleported="false"
+          >
+            <el-option v-for="level in options" :key="level.value" :label="level.name" :value="level.value"></el-option>
+          </el-select>
+          <el-input v-model="queryParams.keyword" class="custom-input" placeholder="组织架构搜索">
+            <template #prefix>
+              <el-icon class="el-input__icon"><search /></el-icon>
+            </template>
+          </el-input>
+        </div>
+        <div class="user-box">
+          <div class="user-table">
+            <div class="tr">
+              <div class="td2">
+                <div :class="getCheckedClass()" @click="handleChecked"></div>
+              </div>
+              <div class="td">姓名</div>
+              <div class="td3">职务</div>
+            </div>
+            <div class="table-content">
+              <div v-for="(item, index) in userList" :key="index" class="tr2">
+                <div class="td2">
+                  <div :class="item.checked ? 'common-checked-active' : 'common-checked'" @click="handleChecked2(item)"></div>
+                </div>
+                <div class="td">{{ item.name }}</div>
+                <div class="td3">
+                  {{ item.duty }}
+                  <div class="phone-icon"></div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="select-box2">
+        <div class="select-header">
+          <div class="left-item">
+            <div>已选择:</div>
+            <div class="text">{{ selectList.length }}</div>
+            <div>人</div>
+          </div>
+          <div class="clear-btn" @click="clearSelect">清空</div>
+        </div>
+        <div class="select-content">
+          <div v-for="(item, index) in selectList" :key="index" class="box-item">
+            <div class="line">
+              <div class="text1">{{ item.name }}</div>
+              <div class="text2">{{ item.duty }}</div>
+            </div>
+            <div class="line" style="margin-top: 20px">
+              <div class="text2">{{ item.dept }}</div>
+            </div>
+            <div class="close-btn" @click="deleteItem(item)"></div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="footer">
+      <div></div>
+      <div class="btn-box">
+        <div class="common-btn-primary2" style="margin-right: 20px">电话呼叫</div>
+        <div class="common-btn-primary2" @click="handleStartMeeting">发起会议</div>
+      </div>
+    </div>
+  </Dialog>
+</template>
+
+<script lang="ts" setup>
+import { Search } from '@element-plus/icons-vue';
+import { ConvergedCommunication } from '@/utils/convergedCommunication';
+
+const emits = defineEmits(['close']);
+let activeIndex = ref(0);
+const options = ref([{ name: '全部', value: '全部' }]);
+const queryParams = ref({
+  value1: '',
+  keyword: ''
+});
+const menu = ref([{ name: '视频会商' }, { name: '无人机' }, { name: '单兵设备' }]);
+const treeData = ref([
+  {
+    label: '茂名市',
+    children: [
+      {
+        label: '茂名市委',
+        children: [
+          {
+            label: '茂名市纪委监委',
+            isLeaf: true
+          },
+          {
+            label: '茂名市委办公室',
+            isLeaf: true
+          },
+          {
+            label: '茂名市委组织部',
+            isLeaf: true
+          }
+        ]
+      },
+      {
+        label: '茂名市人大',
+        children: [
+          {
+            label: '茂名市人大常委会秘书长、副秘书长',
+            isLeaf: true
+          },
+          {
+            label: '茂名市人大常委会办公室',
+            isLeaf: true
+          },
+          {
+            label: '茂名市人大常委会研究室',
+            isLeaf: true
+          }
+        ]
+      }
+    ]
+  }
+]);
+const userList = ref([]);
+const selectList = computed(() => {
+  const data = [];
+  userList.value.forEach((item) => {
+    if (item.checked) {
+      data.push(item);
+    }
+  });
+  return data;
+});
+const getCheckedClass = () => {
+  let res = 'common-checked';
+  const len = userList.value.length;
+  const len2 = selectList.value.length;
+  if (len2 > 0 && len2 === len) {
+    res = 'common-checked-active';
+  } else if (len2 > 0) {
+    res = 'common-checked-half';
+  }
+  return res;
+};
+const handleNodeClick = (item) => {
+  if (item.isLeaf) {
+    const data = [
+      {
+        id: 1,
+        name: '李莉莉',
+        duty: '副主任',
+        dept: '茂名市/茂名市政府/茂名应急管理局'
+      },
+      {
+        id: 2,
+        name: '何里',
+        duty: '副主任',
+        dept: '茂名市/茂名市政府/茂名应急管理局'
+      },
+      {
+        id: 3,
+        name: '张三',
+        duty: '副主任',
+        dept: '茂名市/茂名市政府/茂名应急管理局'
+      },
+      {
+        id: 4,
+        name: '张三',
+        duty: '副主任',
+        dept: '茂名市/茂名市政府/茂名应急管理局'
+      },
+      {
+        id: 5,
+        name: '张三',
+        duty: '副主任',
+        dept: '茂名市/茂名市政府/茂名应急管理局'
+      },
+      {
+        id: 6,
+        name: '张三',
+        duty: '副主任',
+        dept: '茂名市/茂名市政府/茂名应急管理局'
+      }
+    ];
+    data.forEach((item) => {
+      item.checked = false;
+    });
+    userList.value = data;
+  }
+};
+// 全选、全取消
+const handleChecked = () => {
+  const checkedClass = getCheckedClass();
+  let flag = true;
+  if (checkedClass === 'common-checked-active') {
+    flag = false;
+  }
+  userList.value.forEach((item) => {
+    item.checked = flag;
+  });
+};
+// 单个选中、取消选中
+const handleChecked2 = (item) => {
+  item.checked = !item.checked;
+};
+// 清空
+const clearSelect = () => {
+  userList.value.forEach((item) => {
+    if (item.checked) {
+      item.checked = false;
+    }
+  });
+};
+// 清空指定项
+const deleteItem = (item) => {
+  for (let i = 0; i < userList.value.length; i++) {
+    if (item.id === userList.value[i].id) {
+      userList.value[i].checked = false;
+      break;
+    }
+  }
+};
+
+// 弹窗关闭后
+const handleClose = () => {
+  emits('close');
+};
+
+// 融合通信参数
+// 发起会议
+const handleStartMeeting = () => {
+  const convergedCommunication = new ConvergedCommunication();
+  convergedCommunication.start();
+};
+</script>
+
+<style lang="scss" scoped>
+.content {
+  height: calc(100% - 136px);
+  display: flex;
+  margin-top: 12px;
+  .left-content {
+    width: 910px;
+    padding-right: 30px;
+    border-right: 1px solid #2187ff;
+  }
+  .middle-content {
+    width: 910px;
+    padding: 0 30px;
+    border-right: 1px solid #2187ff;
+    .search-box {
+      display: flex;
+      .select-box {
+        flex-shrink: 0;
+        width: 176px !important;
+        height: 56px;
+        line-height: 56px;
+        margin: 0 10px;
+        color: #83a3be;
+        font-size: 32px;
+      }
+    }
+    .user-box {
+      margin-left: 10px;
+      width: 100%;
+      height: 100%;
+      .user-table {
+        padding: 15px 0;
+        display: flex;
+        flex-direction: column;
+        font-size: 38px;
+        color: #fbffff;
+        .tr {
+          background-color: #102e76;
+        }
+        .tr,
+        .tr2 {
+          display: flex;
+          padding: 6px 0;
+          .td {
+            flex: 1;
+            display: flex;
+            align-items: center;
+          }
+          .td2 {
+            width: 65px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+          }
+          .td3 {
+            flex: 2;
+            display: flex;
+            align-items: center;
+          }
+        }
+        .table-content {
+          height: 858px;
+          overflow-y: auto;
+        }
+        .tr2 {
+          margin-top: 10px;
+          background-color: #122868;
+        }
+        .phone-icon {
+          width: 62px;
+          height: 63px;
+          background: url('@/assets/images/emergencyCommandMap/communication/phone.png');
+          cursor: pointer;
+        }
+      }
+    }
+  }
+
+  .custom-select-popper {
+    .el-scrollbar {
+      .el-select-dropdown__item {
+        color: #b1cae0;
+        font-size: 32px;
+        height: 56px;
+        line-height: 56px;
+      }
+    }
+  }
+  .input {
+    background: transparent;
+    color: #83a3be;
+    font-size: 32px;
+    outline: none;
+    appearance: none;
+    height: 100%;
+    border: none;
+    &::placeholder {
+      color: #83a3be;
+    }
+  }
+  .tree-container {
+    margin-top: 15px;
+    display: flex;
+    .tree-box {
+      width: 100%;
+      height: 920px;
+      overflow-y: auto;
+      padding: 15px 8px;
+      :deep(.el-tree) {
+        height: 100%;
+        background-color: transparent;
+        color: #fbffff;
+        font-size: 38px;
+        .el-tree-node__content {
+          height: auto;
+          padding-top: 10px;
+          padding-bottom: 10px;
+          white-space: normal;
+          word-break: break-all;
+        }
+        .el-tree-node__expand-icon {
+          color: #297cfc;
+          font-size: 23px;
+        }
+        .el-tree-node:focus > .el-tree-node__content,
+        .el-tree-node__content:hover {
+          background-color: transparent !important;
+        }
+      }
+    }
+  }
+  .select-box2 {
+    margin-left: 30px;
+    width: 910px;
+    height: 100%;
+    .select-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      color: #fbffff;
+      font-size: 32px;
+      border-bottom: 1px solid #247dff;
+      padding: 20px;
+      .left-item {
+        display: flex;
+        align-items: center;
+        .text {
+          margin: 0 10px;
+          color: #00e8ff;
+          font-family: 'BEBAS-1';
+        }
+      }
+      .clear-btn {
+        color: #00e8ff;
+        cursor: pointer;
+      }
+    }
+    .select-content {
+      height: 858px;
+      overflow-y: auto;
+      .box-item {
+        border-bottom: 1px solid #247dff;
+        padding: 20px;
+        position: relative;
+        .line {
+          color: #fff;
+          font-size: 38px;
+          display: flex;
+          .text1 {
+            margin-right: 35px;
+          }
+          .text2 {
+            color: #a7ccdf;
+          }
+        }
+        .close-btn {
+          position: absolute;
+          right: 10px;
+          top: 50px;
+          cursor: pointer;
+          width: 29px;
+          height: 29px;
+          background: url('@/assets/images/emergencyCommandMap/communication/close.png') no-repeat;
+        }
+      }
+    }
+  }
+}
+.footer {
+  height: 136px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  .btn-box {
+    display: flex;
+  }
+}
+</style>

+ 8 - 3
src/views/emergencyCommandMap/RightSection/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="right-section">
     <div class="task-header">
-      <div class="task-item">
+      <div class="task-item" @click="handleShowInitConsultation">
         <div class="icon">
           <div class="icon1"></div>
         </div>
@@ -35,13 +35,14 @@
     <RightTop :event-id="eventId" />
     <PublicOpinionSupervision />
     <JointDuty />
+    <InitConsultation v-if="showInitConsultation" />
     <StartPlan v-if="startPlanState.show" v-model:show="startPlanState.show" :title="startPlanState.title" :event-id="startPlanState.eventId" />
     <SelectPlan v-model="selectPlanState.show" :title="selectPlanState.title" :temp-event-id="eventId" @update-plan="updatePlan" />
     <RenWuDengJi v-if="renWuDengJiState.show" v-model:show="renWuDengJiState.show" :event-id="eventId" />
   </div>
 </template>
 
-<script lang="ts" setup>
+<script lang="ts" setup name="RightSection">
 import { onMounted, ref, reactive, nextTick } from 'vue';
 import { useRoute } from 'vue-router';
 import { getEventDetail } from '@/api/duty/eventing';
@@ -49,6 +50,7 @@ import JointDuty from '@/views/emergencyCommandMap/RightSection/JointDuty.vue';
 import RightTop from '@/views/emergencyCommandMap/RightSection/RightTop.vue';
 import StartPlan from './StartPlan.vue';
 import SelectPlan from './SelectPlan.vue';
+import InitConsultation from './InitConsultation.vue';
 import PublicOpinionSupervision from '@/views/emergencyCommandMap/RightSection/PublicOpinionSupervision.vue';
 import RenWuDengJi from '@/views/emergencyCommandMap/RightSection/RenWuDengJi.vue';
 
@@ -124,7 +126,10 @@ const loadPlans = () => {
     { id: 3, name: '应急预案C' }
   ];
 };
-
+let showInitConsultation = ref(false);
+const handleShowInitConsultation = () => {
+  showInitConsultation.value = true;
+};
 // 初始化数据
 const initData = () => {
   eventId.value = route.query.event_id as string || '';

+ 3 - 0
src/views/globalMap/RightMenu/DrawTools.vue

@@ -340,6 +340,9 @@ const analysisSpatial = (data) => {
   }
   emits('handleAnalysisData', location);
 };
+onBeforeUnmount(() => {
+  //
+});
 </script>
 
 <style lang="scss" scoped>

+ 4 - 1
src/views/globalMap/RightMenu/SpatialAnalysis.vue

@@ -159,9 +159,12 @@ watch(
   }
 }
 .item2 {
-  background-color: #fff;
+  background-color: #0b184b;
   font-size: 36px;
   padding: 10px 20px;
   margin-right: 20px;
+  color: #ffffff;
+  border: 2px solid #247dff;
+  border-radius: 4px;
 }
 </style>