Przeglądaj źródła

1. 对接神东历史数据接口

hongrunxia 6 miesięcy temu
rodzic
commit
3a475b87f3

+ 50 - 1
src/hooks/system/useListPage.ts

@@ -8,7 +8,7 @@ import { useMessage } from '/@/hooks/web/useMessage';
 import { useMethods } from '/@/hooks/system/useMethods';
 import { useDesign } from '/@/hooks/web/useDesign';
 import { filterObj } from '/@/utils/common/compUtils';
-const { handleExportXls, handleImportXls } = useMethods();
+const { handleExportXls, handleImportXls, handleExportXlsPost } = useMethods();
 
 // 定义 useListPage 方法所需参数
 interface ListPageOptions {
@@ -110,6 +110,54 @@ export function useListPage(options: ListPageOptions) {
     }
   }
 
+  async function onExportXlsPost(selectForm?) {
+    //update-begin---author:wangshuai ---date:20220411  for:导出新增自定义参数------------
+    const { url, name, params } = options?.exportConfig ?? {};
+    const realUrl = typeof url === 'function' ? url() : url;
+    if (realUrl) {
+      const title = typeof name === 'function' ? name() : name;
+      //update-begin-author:taoyan date:20220507 for: erp代码生成 子表 导出报错,原因未知-
+      let paramsForm: any = {};
+      try {
+        if (selectForm) {
+          paramsForm = selectForm;
+        } else {
+          paramsForm = await getForm().validate();
+        }
+      } catch (e) {
+        console.error(e);
+      }
+      //update-end-author:taoyan date:20220507 for: erp代码生成 子表 导出报错,原因未知-
+
+      //update-begin-author:liusq date:20230410 for:[/issues/409]导出功能没有按排序结果导出,设置导出默认排序,创建时间倒序
+      if (!paramsForm?.column) {
+        Object.assign(paramsForm, { column: 'createTime', order: 'desc' });
+      }
+      //update-begin-author:liusq date:20230410 for: [/issues/409]导出功能没有按排序结果导出,设置导出默认排序,创建时间倒序
+
+      //如果参数不为空,则整合到一起
+      //update-begin-author:taoyan date:20220507 for: erp代码生成 子表 导出动态设置mainId
+      if (params) {
+        Object.keys(params).map((k) => {
+          const temp = (params as object)[k];
+          if (temp) {
+            paramsForm[k] = unref(temp);
+          }
+        });
+      }
+      //update-end-author:taoyan date:20220507 for: erp代码生成 子表 导出动态设置mainId
+      if (selectedRowKeys.value && selectedRowKeys.value.length > 0) {
+        paramsForm['selections'] = selectedRowKeys.value.join(',');
+      }
+      console.log();
+      return handleExportXlsPost(title as string, realUrl, filterObj(paramsForm));
+      //update-end---author:wangshuai ---date:20220411  for:导出新增自定义参数--------------
+    } else {
+      $message.createMessage.warn('没有传递 exportConfig.url 参数');
+      return Promise.reject();
+    }
+  }
+
   // 导入 excel
   function onImportXls(file) {
     const { url, success } = options?.importConfig ?? {};
@@ -171,6 +219,7 @@ export function useListPage(options: ListPageOptions) {
     ...$design,
     ...$message,
     onExportXls,
+    onExportXlsPost,
     onImportXls,
     doRequest,
     doDeleteRecord,

+ 36 - 0
src/hooks/system/useMethods.ts

@@ -51,6 +51,41 @@ export function useMethods() {
   }
 
   /**
+   * 导出xls post
+   * @param name
+   * @param url
+   */
+  async function exportXlsPost(name, url, params, isXlsx = false) {
+    const data = await defHttp.post({ url: url, params: params, responseType: 'blob' }, { isTransformResponse: false });
+    if (!data) {
+      createMessage.warning('文件下载失败');
+      return;
+    }
+    if (!name || typeof name != 'string') {
+      name = '导出文件';
+    }
+    const blobOptions = { type: 'application/vnd.ms-excel' };
+    let fileSuffix = '.xls';
+    if (isXlsx === true) {
+      blobOptions['type'] = XLSX_MIME_TYPE;
+      fileSuffix = XLSX_FILE_SUFFIX;
+    }
+    if (typeof window.navigator.msSaveBlob !== 'undefined') {
+      window.navigator.msSaveBlob(new Blob([data], blobOptions), name + fileSuffix);
+    } else {
+      const url = window.URL.createObjectURL(new Blob([data], blobOptions));
+      const link = document.createElement('a');
+      link.style.display = 'none';
+      link.href = url;
+      link.setAttribute('download', name + fileSuffix);
+      document.body.appendChild(link);
+      link.click();
+      document.body.removeChild(link); //下载完成移除元素
+      window.URL.revokeObjectURL(url); //释放掉blob对象
+    }
+  }
+
+  /**
    * 导入xls
    * @param data 导入的数据
    * @param url
@@ -91,6 +126,7 @@ export function useMethods() {
 
   return {
     handleExportXls: (name: string, url: string, params?: object) => exportXls(name, url, params),
+    handleExportXlsPost: (name: string, url: string, params?: object) => exportXlsPost(name, url, params),
     handleImportXls: (data, url, success) => importXls(data, url, success),
     handleExportXlsx: (name: string, url: string, params?: object) => exportXls(name, url, params, true),
   };

+ 194 - 191
src/layouts/default/header/components/MessageBroadcast.vue

@@ -7,263 +7,266 @@
     </div>
     <div v-if="isShowWarningBroad" class="broadcast">
       <div class="title">
-        <div class="message-title">预警通知</div>
+        <div class="message-title">消息通知</div>
         <div class="badge-box">
           <SoundOutlined :class="{ 'no-play': !isBroad }" style="font-size: 16px; color: #fff" @click="handleBroad" />
-         
         </div>
       </div>
       <div class="broadcast-context">
         <div class="context-tab">
-          <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 0 }" @click="toSelectList(0)">
-            全部</div>
-          <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 1 }" @click="toSelectList(1)">
-            未读</div>
-          <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 2 }" @click="toSelectList(2)">
-            已读</div>
+          <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 0 }" @click="toSelectList(0)"> 全部</div>
+          <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 1 }" @click="toSelectList(1)"> 未读</div>
+          <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 2 }" @click="toSelectList(2)"> 已读</div>
         </div>
         <div class="context-box">
           <div v-if="broadcastList.length == 0" class="no-context">暂无内容</div>
-          <div class="context-detail" v-else v-for="(item, index) in broadcastList" :key="index"
-            :style="{ color: item['isok'] == 0 ? 'red' : '#eee' }">
+          <div
+            class="context-detail"
+            v-else
+            v-for="(item, index) in broadcastList"
+            :key="index"
+            :style="{ color: item['isok'] == 0 ? 'red' : '#eee' }"
+          >
             <div>{{ item['createTime'] }}</div>
             <div>{{ item['devicekind_dictText'] }}</div>
             <div>{{ item['wardescrip'] || item['nwartype_dictText'] }}</div>
             <div>{{ item['isok'] ? '已解决' : '未解决' }}</div>
           </div>
-          <div v-if="broadcastList.length > 0" class="more" @click="toMore">更多>></div>
+          <!-- <div v-if="broadcastList.length > 0" class="more" @click="toMore">更多>></div> -->
         </div>
       </div>
     </div>
   </div>
 </template>
 <script lang="ts">
-import { Tooltip, Badge } from 'ant-design-vue';
-import { SoundOutlined, BellOutlined, WarningOutlined } from '@ant-design/icons-vue';
-import Icon from '/@/components/Icon';
-import { defineComponent, ref, unref, onMounted } from 'vue';
-import { defHttp } from '/@/utils/http/axios';
-import { useRouter } from 'vue-router';
-import { connectWebSocket, onWebSocket } from '/@/hooks/web/useWebSocket';
-import { getToken } from '/@/utils/auth';
-import { useUserStore } from '/@/store/modules/user';
-import { useGlobSetting } from '/@/hooks/setting';
-import SpeakVoice from './notify/speakVoice';
+  import { Tooltip, Badge } from 'ant-design-vue';
+  import { SoundOutlined, BellOutlined, WarningOutlined } from '@ant-design/icons-vue';
+  import Icon from '/@/components/Icon';
+  import { defineComponent, ref, unref, onMounted } from 'vue';
+  import { defHttp } from '/@/utils/http/axios';
+  import { useRouter } from 'vue-router';
+  import { connectWebSocket, onWebSocket } from '/@/hooks/web/useWebSocket';
+  import { getToken } from '/@/utils/auth';
+  import { useUserStore } from '/@/store/modules/user';
+  import { useGlobSetting } from '/@/hooks/setting';
+  import SpeakVoice from './notify/speakVoice';
 
-export default defineComponent({
-  name: 'VoiceBroadcast',
-  components: { Icon, Tooltip, Badge, SoundOutlined, BellOutlined, WarningOutlined },
+  export default defineComponent({
+    name: 'VoiceBroadcast',
+    components: { Icon, Tooltip, Badge, SoundOutlined, BellOutlined, WarningOutlined },
 
-  setup() {
-    const speakVoice = new SpeakVoice();
-    const userStore = useUserStore();
-    const glob = useGlobSetting();
-    const router = useRouter();
-    const list = (params) => defHttp.get({ url: '/safety/ventanalyAlarmLog/list', params });
-    const activeKey = ref(0);
-    const isShowWarningBroad = ref(false);
-    const isBroad = ref(true);
-    const isWarningDot = ref(false);
-    const broadcastList = ref([]);
-    function showWarningBroad() {
-      isShowWarningBroad.value = !isShowWarningBroad.value;
-      if (isShowWarningBroad.value) {
-        toSelectList(0);
+    setup() {
+      const speakVoice = new SpeakVoice();
+      const userStore = useUserStore();
+      const glob = useGlobSetting();
+      const router = useRouter();
+      const list = (params) => defHttp.get({ url: '/safety/ventanalyAlarmLog/list', params });
+      const activeKey = ref(0);
+      const isShowWarningBroad = ref(false);
+      const isBroad = ref(true);
+      const isWarningDot = ref(false);
+      const broadcastList = ref([]);
+      function showWarningBroad() {
+        isShowWarningBroad.value = !isShowWarningBroad.value;
+        if (isShowWarningBroad.value) {
+          toSelectList(0);
+        }
       }
-    }
 
-    function handleBroad() {
-      isBroad.value = !isBroad.value;
-    }
+      function handleBroad() {
+        isBroad.value = !isBroad.value;
+      }
 
-    async function toSelectList(key) {
-      activeKey.value = key;
-      const res = await list({ pageSize: 20, devicetype: '', isok: key == 1 ? 0 : key == 2 ? 1 : null });
-      broadcastList.value = res['records'];
-      // const isHasWarning = broadcastList.value.findIndex((item) => !item['isok']);
-      // isWarningDot.value = isHasWarning > -1 ? true : false;
-    }
+      async function toSelectList(key) {
+        activeKey.value = key;
+        const res = await list({ pageSize: 20, devicetype: '', isok: key == 1 ? 0 : key == 2 ? 1 : null });
+        broadcastList.value = res['records'];
+        // const isHasWarning = broadcastList.value.findIndex((item) => !item['isok']);
+        // isWarningDot.value = isHasWarning > -1 ? true : false;
+      }
 
-    async function toMore() {
-      await router.push({ path: '/monitorChannel/device-monitor/warningHistory' });
-      showWarningBroad();
-    }
+      async function toMore() {
+        await router.push({ path: '/monitorChannel/device-monitor/warningHistory' });
+        showWarningBroad();
+      }
 
-    // 初始化 WebSocket
-    function initWebSocket() {
-      let token = getToken();
-      //将登录token生成一个短的标识
-      // let wsClientId = md5(token);
-      // let userId = unref(userStore.getUserInfo).id + '_' + wsClientId;
-      let userId = unref(userStore.getUserInfo).id + '?token=' + token;
-      // WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
-      let url = glob.wsUrl?.replace('https://', 'wss://').replace('http://', 'ws://') + '/websocket/' + userId;
-      connectWebSocket(url);
-      onWebSocket(onWebSocketMessage);
-    }
+      // 初始化 WebSocket
+      function initWebSocket() {
+        let token = getToken();
+        //将登录token生成一个短的标识
+        // let wsClientId = md5(token);
+        // let userId = unref(userStore.getUserInfo).id + '_' + wsClientId;
+        let userId = unref(userStore.getUserInfo).id + '?token=' + token;
+        // WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
+        let url = glob.wsUrl?.replace('https://', 'wss://').replace('http://', 'ws://') + '/websocket/' + userId;
+        connectWebSocket(url);
+        onWebSocket(onWebSocketMessage);
+      }
 
-    function onWebSocketMessage(data) {
-      // console.log('WebSocket 监测消息--------------》', data);
-      if (data.topic === 'warn' || data.cmd === 'user') {
-        if (isBroad.value) {
-          const messageText = data['warndata'];
-          // const messageText = '这是一个测试';
-          speakVoice.handleReply(messageText);
-        }
-        if (!isShowWarningBroad.value) {
-          isWarningDot.value = true;
-        } else {
-          isWarningDot.value = false;
-        }
-        setTimeout(() => {
-          if (isShowWarningBroad.value) {
-            toSelectList(0);
+      function onWebSocketMessage(data) {
+        // console.log('WebSocket 监测消息--------------》', data);
+        if (data.topic === 'warn' || data.cmd === 'user') {
+          if (isBroad.value) {
+            const messageText = data['warndata'];
+            // const messageText = '这是一个测试';
+            speakVoice.handleReply(messageText);
+          }
+          if (!isShowWarningBroad.value) {
+            isWarningDot.value = true;
+          } else {
+            isWarningDot.value = false;
           }
-        }, 0);
+          setTimeout(() => {
+            if (isShowWarningBroad.value) {
+              toSelectList(0);
+            }
+          }, 0);
+        }
       }
-    }
-    onMounted(() => {
-      initWebSocket();
-    });
+      onMounted(() => {
+        initWebSocket();
+      });
 
-    return { showWarningBroad, isShowWarningBroad, activeKey, toSelectList, broadcastList, toMore, isBroad, handleBroad, isWarningDot };
-  },
-});
+      return { showWarningBroad, isShowWarningBroad, activeKey, toSelectList, broadcastList, toMore, isBroad, handleBroad, isWarningDot };
+    },
+  });
 </script>
 <style lang="less" scoped>
-.btn {
-  line-height: 30px;
-  margin-right: 20px;
-  cursor: pointer;
-  display: flex;
-}
+  .btn {
+    line-height: 30px;
+    margin-right: 20px;
+    cursor: pointer;
+    display: flex;
+  }
 
-.no-play {
-  background: linear-gradient(to bottom left,
+  .no-play {
+    background: linear-gradient(
+      to bottom left,
       transparent 0%,
       transparent calc(50% - 1px),
       #000000 50%,
       transparent calc(50% + 1px),
-      transparent 100%);
-}
-
-.broadcast {
-  width: 400px;
-  height: 250px;
-  border-radius: 4px;
-  position: fixed;
-  top: 50px;
-  right: 20px;
-  background-color: rgb(255, 255, 255);
-  background: url('../../../../assets/images/warn-dialog-bg.png') no-repeat center;
-  background-size: 100% 100%;
-  z-index: 9999999;
-  color: #FFF;
-
-  .title {
-    height: 32px;
-    padding: 0 20px;
+      transparent 100%
+    );
+  }
 
-    :deep(.ant-badge:not(.ant-badge-status)) {
-      margin-right: 40px !important;
-    }
+  .broadcast {
+    width: 400px;
+    height: 250px;
+    border-radius: 4px;
+    position: fixed;
+    top: 50px;
+    right: 20px;
+    background-color: rgb(255, 255, 255);
+    background: url('../../../../assets/images/warn-dialog-bg.png') no-repeat center;
+    background-size: 100% 100%;
+    z-index: 9999999;
+    color: #fff;
 
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    margin-bottom: 5px;
+    .title {
+      height: 32px;
+      padding: 0 20px;
 
-    .message-title {
-      font-size: 16px;
-    }
+      :deep(.ant-badge:not(.ant-badge-status)) {
+        margin-right: 40px !important;
+      }
 
-    .badge-box {
       display: flex;
       align-items: center;
+      justify-content: space-between;
+      margin-bottom: 5px;
 
-      .badge-title {
-        display: inline-block;
-        width: 62px;
-        line-height: 32px;
-        background-color: #2174f0;
-        border-radius: 26px;
-        text-align: center;
-        color: #fff;
-        padding-bottom: 2px;
+      .message-title {
+        font-size: 16px;
       }
-    }
-  }
-
-  .broadcast-context {
-    .context-tab {
-      display: flex;
 
-      .context-tab-item {
-        line-height: 24px;
-        background-color: #6b6b6b;
-        border-radius: 24px;
-        text-align: center;
-        padding: 0 10px;
-        color: #fff;
-        margin: 5px;
-        cursor: pointer;
-        font-size: 14px;
-      }
+      .badge-box {
+        display: flex;
+        align-items: center;
 
-      .context-tab-item-active {
-        background-color: #2174f0;
+        .badge-title {
+          display: inline-block;
+          width: 62px;
+          line-height: 32px;
+          background-color: #2174f0;
+          border-radius: 26px;
+          text-align: center;
+          color: #fff;
+          padding-bottom: 2px;
+        }
       }
     }
 
-    .context-box {
-      flex: 1;
-      padding: 0 10px;
-      height: 178px;
-      overflow-y: auto;
-
-      .no-context {
+    .broadcast-context {
+      .context-tab {
         display: flex;
-        justify-content: center;
-        padding-top: 30px;
-        font-size: 16px;
+
+        .context-tab-item {
+          line-height: 24px;
+          background-color: #6b6b6b;
+          border-radius: 24px;
+          text-align: center;
+          padding: 0 10px;
+          color: #fff;
+          margin: 5px;
+          cursor: pointer;
+          font-size: 14px;
+        }
+
+        .context-tab-item-active {
+          background-color: #2174f0;
+        }
       }
 
-      .context-detail {
-        display: flex;
-        justify-content: space-between;
-        line-height: 24px;
-        padding: 0px 3px;
+      .context-box {
+        flex: 1;
+        padding: 0 10px;
+        height: 178px;
+        overflow-y: auto;
 
-        div {
+        .no-context {
           display: flex;
-          justify-content: flex-start;
+          justify-content: center;
+          padding-top: 30px;
+          font-size: 16px;
+        }
 
-          &:nth-child(1) {
-            width: 40%;
-          }
+        .context-detail {
+          display: flex;
+          justify-content: space-between;
+          line-height: 24px;
+          padding: 0px 3px;
 
-          &:nth-child(2) {
-            width: 20%;
-          }
+          div {
+            display: flex;
+            justify-content: flex-start;
 
-          &:nth-child(3) {
-            width: 25%;
-          }
+            &:nth-child(1) {
+              width: 40%;
+            }
+
+            &:nth-child(2) {
+              width: 20%;
+            }
 
-          &:nth-child(4) {
-            width: 15%;
+            &:nth-child(3) {
+              width: 25%;
+            }
+
+            &:nth-child(4) {
+              width: 15%;
+            }
           }
         }
-      }
 
-      .more {
-        cursor: pointer;
+        .more {
+          cursor: pointer;
 
-        &:hover {
-          color: #2174f0;
+          &:hover {
+            color: #2174f0;
+          }
         }
       }
     }
   }
-}
 </style>

+ 1 - 1
src/layouts/default/header/components/VoiceBroadcast.vue

@@ -38,7 +38,7 @@
             <div>{{ item['isok'] ? '已解决' : '未解决' }}</div>
           </div>
         </div>
-        <div v-if="broadcastList.length > 0" class="more" @click="toMore">更多>></div>
+        <!-- <div v-if="broadcastList.length > 0" class="more" @click="toMore">更多>></div> -->
       </div>
     </div>
   </div>

+ 0 - 655
src/views/vent/home/clique/components/mine-wind1.vue

@@ -1,655 +0,0 @@
-<template>
-    <div class="mineWind">
-        <div class="mine-title">{{ mineTitle }}</div>
-        <div class="mine-content">
-            <div class="content-tabs">
-                <div :class="activeIndex == '1' ? 'tabs-item1' : 'tabs-item'" @click="getChange('1')">信息列表</div>
-                <div :class="activeIndex == '2' ? 'tabs-item1' : 'tabs-item'" @click="getChange('2')">信息统计</div>
-            </div>
-            <!-- 信息列表 -->
-            <div class="content-search" v-if="activeIndex == '1'">
-                <div class="risk-select">
-                    <a-select style="width: 120px" v-model:value="selectVal" allowClear class="code-mode-select"
-                        @change="changeSelect">
-                        <a-select-option v-for="item in selectList" :key="item.orgname" :value="item.orgcode">{{
-                            item.orgname }} </a-select-option>
-                    </a-select>
-                    <a-select style="width: 120px" v-model:value="selectVal" allowClear class="code-mode-select"
-                        @change="changeSelect">
-                        <a-select-option v-for="item in selectList" :key="item.orgname" :value="item.orgcode">{{
-                            item.orgname }} </a-select-option>
-                    </a-select>
-                    <a-select style="width: 120px" v-model:value="selectVal" allowClear class="code-mode-select"
-                        @change="changeSelect">
-                        <a-select-option v-for="item in selectList" :key="item.orgname" :value="item.orgcode">{{
-                            item.orgname }} </a-select-option>
-                    </a-select>
-                </div>
-            </div>
-            <div class="content-table" v-if="activeIndex == '1'">
-                <div class="table-head">
-                    <div class="head-item" v-for="(ite, ind) in headList" :key="ind">{{ ite.label }}</div>
-                </div>
-                <div class="table-cont">
-                    <div class="cont-item" v-for="(item, index) in contList" :key="index">
-                        <div class="item-val">{{ item.id }}</div>
-                        <div class="item-val">{{ item.name }}</div>
-                        <div class="item-val">{{ item.address }}</div>
-                        <div class="item-val">{{ item.smoke }}</div>
-                        <div class="item-val">{{ item.person }}</div>
-                        <div class="item-val">{{ item.br }}</div>
-                        <div class="item-val">{{ item.brz }}</div>
-                    </div>
-                </div>
-            </div>
-            <!-- 统计信息 -->
-            <div class="echart-box" v-if="activeIndex == '2'">
-                <div class="piebox" ref="piebox"></div>
-            </div>
-            <div class="echart-all-box" v-if="activeIndex == '2'">
-                <div class="pieboxall" ref="pieboxall"></div>
-            </div>
-        </div>
-    </div>
-</template>
-<script lang="ts" setup>
-import { ref, reactive, watch, defineProps, nextTick, } from 'vue';
-import * as echarts from 'echarts';
-
-let props = defineProps({
-    airKjStatus: {
-        type: Array,
-        default: () => {
-            return [];
-        },
-    },
-});
-
-let activeIndex = ref('1')
-//获取dom元素节点
-let piebox = ref<any>();
-let pieboxall = ref<any>();
-let mineTitle = ref('矿井通风状态监测');
-let selectVal = ref('');
-let selectList = ref<any>([]);
-let contList = reactive<any[]>([
-    { id: '1', name: 'xx煤矿', address: '陕西省榆林市', smoke: 800, person: 1435, br: 1, brz: 1 },
-    { id: '2', name: 'xx煤矿', address: '陕西省榆林市', smoke: 800, person: 1435, br: 1, brz: 1 },
-    { id: '3', name: 'xx煤矿', address: '陕西省榆林市', smoke: 800, person: 1435, br: 1, brz: 1 },
-    { id: '4', name: 'xx煤矿', address: '陕西省榆林市', smoke: 800, person: 1435, br: 1, brz: 1 },
-    { id: '5', name: 'xx煤矿', address: '陕西省榆林市', smoke: 800, person: 1435, br: 1, brz: 1 },
-    { id: '6', name: 'xx煤矿', address: '陕西省榆林市', smoke: 800, person: 1435, br: 1, brz: 1 },
-    { id: '7', name: 'xx煤矿', address: '陕西省榆林市', smoke: 800, person: 1435, br: 1, brz: 1 },
-    { id: '8', name: 'xx煤矿', address: '陕西省榆林市', smoke: 800, person: 1435, br: 1, brz: 1 },
-    { id: '9', name: 'xx煤矿', address: '陕西省榆林市', smoke: 800, person: 1435, br: 1, brz: 1 },
-])
-let headList = reactive<any>([
-    { label: '序号' },
-    { label: '矿井名称' },
-    { label: '所属地区市/县' },
-    { label: '原煤产量/百万吨' },
-    { label: '从业人数/人' },
-    { label: '尘肺病累计病例/人' },
-    { label: '本年度尘肺病病例/人' },
-])
-
-//tabs选项切换
-function getChange(active) {
-    activeIndex.value = active
-    switch (activeIndex.value) {
-        case '1':
-
-            break;
-        case '2':
-            getOption()
-            getOptionAll()
-            break;
-    }
-}
-//下拉框选项切换
-function changeSelect(val) { }
-function getOption() {
-    nextTick(() => {
-        let myChart = echarts.init(piebox.value);
-        let option = {
-            tooltip: {
-                trigger: 'item',
-                formatter: "{a} <br/>{b} : {c} ({d}%)"
-            },
-            color: ['#faa526', '#d5eb0f', '#afec07', '#f3f720', '#0ee93d', '#17d1b2', '#2ae271', '#11bce7', '#c127f0', '#ee125b',],
-            title: {
-                "text": "陕西省尘肺病地区比例分析",
-                "left": "center",
-                "top": 5,
-                "textStyle": {
-                    "color": "#00d8ff",
-                    fontSize: 14
-                }
-            },
-            legend: {
-                orient: 'vertical',
-                right: 10,
-                align: 'auto',
-                top: 'middle',
-                itemGap: 0.5,
-                textStyle: {
-                    color: '#fff',
-                    fontSize: 10,
-                },
-                icon: 'circle',
-                data: ['西安市', '宝鸡市', '咸阳市', '铜川市', '渭南市', '延安市', '榆林市', '汉中市', '安康市', '商洛市'],
-                // formatter: function (name) {
-                //     var oa = option.series[0].data;
-                //     var num = oa[0].value + oa[1].value + oa[2].value + oa[3].value;
-                //     for (var i = 0; i < option.series[0].data.length; i++) {
-                //         if (name == oa[i].name) {
-                //             return name + '     ' + oa[i].value + '     ' + (oa[i].value / num * 100).toFixed(2) + '%';
-                //         }
-                //     }
-                // }
-            },
-            series: [
-                {
-                    name: '比例分析',
-                    type: 'pie',
-                    radius: '55%',
-                    center: ['48%', '50%'],
-                    data: [
-                        { value: 335, name: '西安市' },
-                        { value: 310, name: '宝鸡市' },
-                        { value: 234, name: '咸阳市' },
-                        { value: 135, name: '铜川市' },
-                        { value: 335, name: '渭南市' },
-                        { value: 310, name: '延安市' },
-                        { value: 234, name: '榆林市' },
-                        { value: 135, name: '汉中市' },
-                        { value: 335, name: '安康市' },
-                        { value: 310, name: '商洛市' },
-
-                    ],
-
-                    itemStyle: {
-                        normal: {
-                            label: {
-                                show: true,
-                                fontSize: 10,
-                                color: '#fff',
-                                formatter: '{b} : {d}%'
-                            }
-                        },
-                        labelLine: {
-                            normal: {
-                                show: true,
-                                length: 50,
-                                length2: 50,
-                                lineStyle: {
-                                    color: '#fff',
-                                    width: 2
-                                }
-                            }
-                        },
-                    }
-                }
-            ]
-        };
-        myChart.setOption(option);
-        window.onresize = function () {
-            myChart.resize();
-        };
-    })
-}
-function getOptionAll() {
-    nextTick(() => {
-        let scaleData = [{
-            'name': '横山区',
-            'value': 10
-        },
-        {
-            'name': '神木市',
-            'value': 10
-        },
-        {
-            'name': '府谷县',
-            'value': 10
-        },
-        {
-            'name': '靖边县',
-            'value': 10
-        },
-        {
-            'name': '定边县',
-            'value': 10
-        },
-        {
-            'name': '绥德县',
-            'value': 10
-        },
-        {
-            'name': '米脂县',
-            'value': 10
-        },
-        {
-            'name': '佳县',
-            'value': 10
-        },
-        {
-            'name': '吴堡县',
-            'value': 10
-        },
-        {
-            'name': '清涧县',
-            'value': 10
-        },
-
-        ];
-        let rich = {
-            white: {
-                color: '#fff',
-                align: 'center',
-                fontSize: 12,
-                padding: [3, 0]
-            }
-        };
-        let placeHolderStyle = {
-            normal: {
-                label: {
-                    show: false
-                },
-                labelLine: {
-                    show: false
-                },
-                color: 'rgba(0, 0, 0, 0)',
-                borderColor: 'rgba(0, 0, 0, 0)',
-                borderWidth: 0
-            }
-        };
-        let data: any[] = [];
-        let color1 = ['rgb(255, 153, 153)', 'rgb(255, 176, 63)', 'rgb(61, 186, 45)', 'rgb(43, 166, 254)', 'rgb(255,222,0)', 'rgb(255,0,0)', '#faa526', '#d5eb0f', '#afec07', '#f3f720', '#0ee93d', '#17d1b2', '#2ae271', '#11bce7', '#c127f0', '#ee125b',];
-
-        for (let i = 0; i < scaleData.length; i++) {
-            data.push({
-                value: scaleData[i].value,
-                name: scaleData[i].name,
-                itemStyle: {
-                    normal: {
-                        borderWidth: 2,
-                        shadowBlur: 0,
-                        borderColor: color1[i],
-                        shadowColor: color1[i],
-                        color: color1[i],
-                        opacity: 1,
-                    }
-                }
-            }, {
-                value: 2,
-                name: '',
-                itemStyle: placeHolderStyle
-            });
-        }
-        let seriesObj = [{
-            name: '',
-            type: 'pie',
-            clockWise: false,
-            radius: [40, 75],
-            center: ['48%', '56%'],
-            hoverAnimation: false,
-            itemStyle: {
-                normal: {
-                    label: {
-                        show: true,
-                        position: 'inner',
-                        fontSize: 10,
-                        color: '#fff',
-                        formatter: function (params) {
-                            let percent: any = 0;
-                            let total = 0;
-                            for (var i = 0; i < scaleData.length; i++) {
-                                total += scaleData[i].value;
-                            }
-                            percent = ((params.value / total) * 100).toFixed(0);
-                            if (params.name !== '') {
-                                return params.name;
-                            } else {
-                                return '';
-                            }
-                        },
-                        rich: rich
-                    },
-                    labelLine: {
-                        show: false,
-                    }
-                }
-            },
-            data: data
-        }];
-        let myChart = echarts.init(pieboxall.value);
-        let option = {
-            tooltip: {
-                trigger: 'item',
-                formatter: "{b} : {c} ({d}%)"
-            },
-            "title": {
-                "text": "榆林市尘肺病比例分析",
-                "left": "center",
-                "top": 0,
-                "textStyle": {
-                    "color": "#00d8ff",
-                    fontSize: 14
-                }
-            },
-            legend: {
-                orient: 'vertical',
-                right: 10,
-                align: 'auto',
-                top: 'middle',
-                itemGap: 0.5,
-                textStyle: {
-                    color: '#fff',
-                    fontSize: 10,
-                },
-                icon: 'circle',
-                data: ['横山区', '神木市', '府谷县', '靖边县', '定边县', '绥德县', '米脂县', '佳县', '吴堡县', '清涧县'],
-
-            },
-            toolbox: {
-                show: false
-            },
-            series: seriesObj
-        }
-        myChart.setOption(option);
-        window.onresize = function () {
-            myChart.resize();
-        };
-    })
-}
-
-watch(
-    () => props.airKjStatus,
-    (newA, oldA) => {
-        console.log(newA, 'airKjStatus-----------');
-    },
-    {
-        immediate: true,
-        deep: true,
-    }
-);
-
-</script>
-<style lang="less" scoped>
-@font-face {
-    font-family: 'douyuFont';
-    src: url('../../../../assets/font/douyuFont.otf');
-}
-
-.mineWind {
-    position: relative;
-    width: 100%;
-    height: 100%;
-
-    .mine-title {
-        position: absolute;
-        left: 50px;
-        top: 12px;
-        color: #fff;
-        font-family: 'douyuFont';
-        font-size: 14px;
-    }
-
-    .mine-content {
-        height: 100%;
-        padding: 40px 0px 28px 0px;
-        box-sizing: border-box;
-        display: flex;
-        flex-direction: column;
-        align-items: center;
-
-        .content-tabs {
-            width: 100%;
-            height: 45px;
-            padding: 0px 30px;
-            display: flex;
-            align-items: center;
-
-            .tabs-item {
-                color: #fff;
-                cursor: pointer;
-
-                &:nth-child(1) {
-                    margin-right: 10px;
-                }
-            }
-
-            .tabs-item1 {
-                color: rgba(0, 216, 255, );
-                cursor: pointer;
-                border-bottom: 2px solid;
-                border-image: linear-gradient(to right, transparent, rgba(49, 184, 255, 1), transparent) 1 1 1;
-                margin-right: 10px;
-            }
-
-        }
-
-        .content-search {
-            position: relative;
-            width: 100%;
-            height: 35px;
-            margin-bottom: 10px;
-            // padding: 0px 30px;
-            display: flex;
-            align-items: center;
-
-            .risk-select {
-                position: absolute;
-                width: 90%;
-                height: 30px;
-                left: 50%;
-                transform: translate(-50%, 0);
-                top: 0px;
-                background: url('../../../../../assets/images/company/content-label.png') no-repeat center;
-                background-size: 100% 100%;
-                z-index: 9999;
-
-                .zxm-select {
-                    position: absolute;
-                    top: 50%;
-                    transform: translate(0, -50%);
-
-                    &:nth-child(1) {
-                        left: 10px;
-                    }
-
-                    &:nth-child(2) {
-                        left: 135px;
-                    }
-
-                    &:nth-child(3) {
-                        left: 260px;
-                    }
-                }
-
-
-            }
-        }
-
-        .content-table {
-
-            position: relative;
-            width: 90%;
-            height: calc(100% - 90px);
-            margin: 0px 30px;
-            border: 1px solid rgba(0, 216, 255, .3);
-
-            .table-head {
-                display: flex;
-                justify-content: space-between;
-                height: 50px;
-                border-bottom: 1px solid rgba(0, 216, 255, .3);
-
-                .head-item {
-                    display: flex;
-                    align-items: center;
-                    justify-content: center;
-                    height: 100%;
-                    color: rgba(0, 216, 255, );
-                    font-size: 12px;
-                    border-right: 1px solid rgba(0, 216, 255, .1);
-
-                    &:nth-child(1) {
-                        width: 5%;
-                        text-align: center;
-                    }
-
-                    &:nth-child(2) {
-                        width: 10%;
-                        text-align: center;
-                    }
-
-                    &:nth-child(3) {
-                        width: 15%;
-                        text-align: center;
-                    }
-
-                    &:nth-child(4) {
-                        width: 15%;
-                        text-align: center;
-                    }
-
-                    &:nth-child(5) {
-                        width: 15%;
-                        text-align: center;
-                    }
-
-                    &:nth-child(6) {
-                        width: 20%;
-                        text-align: center;
-                    }
-
-                    &:nth-child(7) {
-                        width: 20%;
-                        text-align: center;
-                    }
-
-                }
-            }
-
-            .table-cont {
-                height: calc(100% - 51px);
-
-                .cont-item {
-                    display: flex;
-                    justify-content: space-between;
-                    height: 32.5px;
-                    border-bottom: 1px solid rgba(0, 216, 255, .1);
-
-                    .item-val {
-                        display: flex;
-                        align-items: center;
-                        justify-content: center;
-                        height: 100%;
-                        font-size: 12px;
-                        border-right: 1px solid rgba(0, 216, 255, .1);
-                        font-size: 12px;
-                        border-right: 1px solid rgba(0, 216, 255, .1);
-                        color: #fff;
-
-                        &:nth-child(1) {
-                            width: 5%;
-                            text-align: center;
-                        }
-
-                        &:nth-child(2) {
-                            width: 10%;
-                            text-align: center;
-                        }
-
-                        &:nth-child(3) {
-                            width: 15%;
-                            text-align: center;
-                        }
-
-                        &:nth-child(4) {
-                            width: 15%;
-                            text-align: center;
-                        }
-
-                        &:nth-child(5) {
-                            width: 15%;
-                            text-align: center;
-                        }
-
-                        &:nth-child(6) {
-                            width: 20%;
-                            text-align: center;
-                        }
-
-                        &:nth-child(7) {
-                            width: 20%;
-                            text-align: center;
-                        }
-                    }
-
-                }
-            }
-
-        }
-
-        .echart-box {
-            width: 100%;
-            height: 205px;
-
-            .piebox {
-                width: 100%;
-                height: 100%;
-            }
-        }
-
-        .echart-all-box {
-            width: 100%;
-            height: calc(100% - 250px);
-
-            .pieboxall {
-                width: 100%;
-                height: 100%;
-            }
-        }
-    }
-}
-
-::v-deep .zxm-select-single:not(.zxm-select-customize-input) .zxm-select-selector {
-    height: 24px;
-}
-
-::v-deep .zxm-select-single:not(.zxm-select-customize-input) .zxm-select-selector .zxm-select-selection-search-input {
-    height: 24px;
-}
-
-::v-deep .zxm-select-selection-placeholder {
-    color: #fff !important;
-    line-height: 22px !important;
-}
-
-::v-deep .zxm-select-single:not(.zxm-select-customize-input) .zxm-select-selector::after {
-    line-height: 24px;
-}
-
-::v-deep .zxm-select:not(.zxm-select-customize-input) .zxm-select-selector {
-    background-color: transparent;
-    border-top: 0px;
-    border-bottom: 0px;
-    border-left: 2px solid;
-    border-right: 2px solid;
-    border-image: linear-gradient(to bottom, transparent, rgba(49, 184, 255, 1), transparent) 1 1 1;
-}
-
-::v-deep .zxm-select-arrow {
-    color: #fff !important;
-}
-
-::v-deep .zxm-select-selection-item {
-    color: #fff !important;
-}
-
-::v-deep .zxm-select-single .zxm-select-selector .zxm-select-selection-item {
-    line-height: 24px !important;
-}
-</style>

+ 3 - 3
src/views/vent/home/clique/dust-index.vue

@@ -9,7 +9,7 @@
           <!-- 矿井通风状态监测 -->
           <div class="area-card">
             <!-- <mineWind :airKjStatus="airKjStatus" /> -->
-             <mineWind1 :airKjStatus="airKjStatus"></mineWind1>
+            <mineWind1 :airKjStatus="airKjStatus" />
           </div>
           <!-- 一通三防风险分析与预警 -->
           <div class="area-card1">
@@ -47,8 +47,8 @@
 </template>
 <script lang="ts" setup>
   import { ref, reactive, nextTick, onMounted, onUnmounted } from 'vue';
-  import mineWind from './dustComponents/mine-wind.vue';
-  import mineWind1 from './components/mine-wind1.vue';
+  // import mineWind from './dustComponents/mine-wind.vue';
+  import mineWind1 from './dustComponents/mine-wind1.vue';
   import riskWarn from './dustComponents/risk-warn.vue';
   // import fileShare from './components/file-share.vue';
   import Billboard from './dustComponents/billboard.vue';

+ 7 - 3
src/views/vent/monitorManager/comment/HistoryTable.vue

@@ -91,7 +91,7 @@
     if (stationType.value !== 'redis') {
       return '/safety/ventanalyMonitorData/export/historydata';
     } else {
-      return '/monitor/history/getHistoryData/exportXls';
+      return '/monitor/history/exportHistoryData';
     }
   };
   const emit = defineEmits(['change']);
@@ -284,7 +284,7 @@
   }
 
   // 列表页面公共参数、方法
-  const { tableContext, onExportXls } = useListPage({
+  const { tableContext, onExportXls, onExportXlsPost } = useListPage({
     tableProps: {
       // api: list,
       columns: props.columnsType ? columns : (props.columns as any[]),
@@ -458,7 +458,11 @@
 
   function onExportXlsFn() {
     // 判断时间间隔和查询时间区间,数据量下载大时进行提示
-    onExportXls();
+    if (stationType.value !== 'redis') {
+      return onExportXls();
+    } else {
+      return onExportXlsPost();
+    }
   }
 
   watchEffect(() => {

+ 292 - 272
src/views/vent/performance/fileDetail/commen/treeList.vue

@@ -1,7 +1,17 @@
 <template>
   <div class="vtl-node" :id="model.id" :class="{ 'vtl-leaf-node': !isFolder, 'vtl-tree-node': isFolder }">
-    <div :class="treeNodeClass" :draggable="draggable" @dragover="dragOver" @drop="drop" @dragstart="dragStart"
-      @mouseover="mouseOver" @dragenter="dragEnter" @dragleave="dragLeave" @mouseout="mouseOut" @click.stop="toggle">
+    <div
+      :class="treeNodeClass"
+      :draggable="draggable"
+      @dragover="dragOver"
+      @drop="drop"
+      @dragstart="dragStart"
+      @mouseover="mouseOver"
+      @dragenter="dragEnter"
+      @dragleave="dragLeave"
+      @mouseout="mouseOut"
+      @click.stop="toggle"
+    >
       <div class="vtl-border-text">
         <template v-if="isFolder">
           <slot v-if="expanded" :item="{ title: model.title, isFolder: true, expanded: true }" name="icon"> </slot>
@@ -11,8 +21,7 @@
         <span class="vtl-node-content ellipsis" v-if="!editable && !model.isAdd">
           {{ model.title }}
         </span>
-        <input v-else class="vtl-input" type="text" ref="nodeInput" v-model="model.title"
-          @keyup.enter.native="setUnEditable" @blur="setUnEditable" />
+        <input v-else class="vtl-input" type="text" ref="nodeInput" v-model="model.title" @keyup.enter.native="setUnEditable" @blur="setUnEditable" />
       </div>
       <div class="vtl-operation" v-show="isHover && !editable && !model.isAdd">
         <!-- <span @click.stop.prevent="addChildFolder" v-if="isFolder">
@@ -35,12 +44,23 @@
   </div>
   <div class="vtl-tree-margin" v-show="expanded" v-if="isFolder">
     <!-- 这里无法使用$attr来透传属性官方还未解决此bug -->
-    <treeList @on-click="(depth) => $emit('onClick', depth)" @change-name="(depth) => $emit('changeName', depth)"
-      @delete-node="(depth) => $emit('deleteNode', depth)" @download-node="(depth) => $emit('downloadNode', depth)"
-      @add-node="(depth) => $emit('addNode', depth)" @on-drop="(depth) => $emit('onDrop', depth)"
-      @add-folder="(depth) => $emit('addFolder', depth)" @dragStart="(depth) => $emit('dragStart', depth)"
-      @setDragEnterNode="setDragEnterNode" @setDragFile="setDragFile" @setDragFolder="setDragFolder"
-      v-for="newmodel in model.children" :selected="selected" :model="newmodel" :key="newmodel.id">
+    <treeList
+      @on-click="(depth) => $emit('onClick', depth)"
+      @change-name="(depth) => $emit('changeName', depth)"
+      @delete-node="(depth) => $emit('deleteNode', depth)"
+      @download-node="(depth) => $emit('downloadNode', depth)"
+      @add-node="(depth) => $emit('addNode', depth)"
+      @on-drop="(depth) => $emit('onDrop', depth)"
+      @add-folder="(depth) => $emit('addFolder', depth)"
+      @dragStart="(depth) => $emit('dragStart', depth)"
+      @setDragEnterNode="setDragEnterNode"
+      @setDragFile="setDragFile"
+      @setDragFolder="setDragFolder"
+      v-for="newmodel in model.children"
+      :selected="selected"
+      :model="newmodel"
+      :key="newmodel.id"
+    >
       <template #icon="slotProps">
         <slot name="icon" v-bind="slotProps"></slot>
       </template>
@@ -51,302 +71,302 @@
   </div>
 </template>
 <script setup lang="ts">
-import { computed, ref, watchEffect } from 'vue';
-interface IFileSystem {
-  id: string;
-  title: string;
-  pid: string;
-  isFolder: boolean;
-  isAdd: boolean;
-  children?: IFileSystem[];
-}
-// 吐出去的事件
-const emit = defineEmits([
-  'onClick',
-  'changeName',
-  'deleteNode',
-  'downloadNode',
-  'addNode',
-  'addFolder',
-  'onDrop',
-  'setDragEnterNode',
-  'setDragFile',
-  'setDragFolder',
-  'dragStart',
-]);
-// 拿到传入的值
-const props = withDefaults(
-  defineProps<{
-    model: IFileSystem;
-    draggable?: boolean;
-    selected?: IFileSystem;
-  }>(),
-  {
-    draggable: true,
+  import { computed, ref, watchEffect } from 'vue';
+  interface IFileSystem {
+    id: string;
+    title: string;
+    pid: string;
+    isFolder: boolean;
+    isAdd: boolean;
+    children?: IFileSystem[];
   }
-);
-//是否移入
-const isHover = ref(false);
-// 修改目录名字
-const editable = ref(false);
-// 拖拽移入
-const isDragEnterNode = ref(false);
-// 是否拖拽文件
-const isDragFile = ref(false);
-// 是否展开
-const expanded = ref(true);
-// inputRef
-const nodeInput = ref(null);
-// 是否是文件夹
-const isFolder = computed(() => {
-  return props.model.isFolder;
-});
-const isSelected = computed(() => props.selected.id === props.model.id);
-// 拖拽样式
-const treeNodeClass = computed(() => {
-  return {
-    'vtl-node-main': true,
-    'vtl-active': isDragEnterNode.value,
-    'vtl-active-file': isDragFile.value,
-    selected: isSelected.value,
-  };
-});
-// 最后一个移入的内容保存为了防止重复移入
-let lastenter = null;
-// 删除目录
-const delNode = () => {
-  emit('deleteNode', {
-    ...props.model,
-    eventType: 'delete',
+  // 吐出去的事件
+  const emit = defineEmits([
+    'onClick',
+    'changeName',
+    'deleteNode',
+    'downloadNode',
+    'addNode',
+    'addFolder',
+    'onDrop',
+    'setDragEnterNode',
+    'setDragFile',
+    'setDragFolder',
+    'dragStart',
+  ]);
+  // 拿到传入的值
+  const props = withDefaults(
+    defineProps<{
+      model: IFileSystem;
+      draggable?: boolean;
+      selected?: IFileSystem;
+    }>(),
+    {
+      draggable: true,
+    }
+  );
+  //是否移入
+  const isHover = ref(false);
+  // 修改目录名字
+  const editable = ref(false);
+  // 拖拽移入
+  const isDragEnterNode = ref(false);
+  // 是否拖拽文件
+  const isDragFile = ref(false);
+  // 是否展开
+  const expanded = ref(true);
+  // inputRef
+  const nodeInput = ref(null);
+  // 是否是文件夹
+  const isFolder = computed(() => {
+    return props.model.isFolder;
   });
-};
-//下载目录
-const downNode = () => {
-  emit('downloadNode', {
-    ...props.model,
-    eventType: 'download',
+  const isSelected = computed(() => props.selected.id === props.model.id);
+  // 拖拽样式
+  const treeNodeClass = computed(() => {
+    return {
+      'vtl-node-main': true,
+      'vtl-active': isDragEnterNode.value,
+      'vtl-active-file': isDragFile.value,
+      selected: isSelected.value,
+    };
   });
-};
-// 选中effect
-watchEffect(() => {
-  const $input = nodeInput.value;
-  if ($input) {
-    // 获取焦点
-    $input.focus();
-    // 设置光标位置
-    $input.setSelectionRange(0, $input.value.length);
-  }
-});
-// 编辑目录名字
-const setEditable = () => {
-  editable.value = true;
-  props.model.isAdd = false; //lxh
-};
-// 修改目录名字
-const setUnEditable = (e) => {
-  if (props.model.isAdd) {
-    console.log('新增文档失去焦点');
-    props.model.isAdd = false;
-    emit('addNode', {
-      id: props.model.id,
-      isFolder: false,
-      newName: props.model.title,
-    });
-  } else if (editable.value) {
-    console.log('编辑文档失去焦点');
-    editable.value = false;
-    props.model.title = e.target.value;
-    emit('changeName', {
-      id: props.model.id,
-      pid: props.model.pid,
-      isAdd: props.model.isAdd,
-      newName: e.target.value,
-      eventType: 'blur',
-      isFolder: isFolder.value,
-    });
-  }
-};
-// 展开收起
-const toggle = () => {
-  if (isFolder.value) {
-    expanded.value = !expanded.value;
-    emit('onClick', {
+  // 最后一个移入的内容保存为了防止重复移入
+  let lastenter = null;
+  // 删除目录
+  const delNode = () => {
+    emit('deleteNode', {
       ...props.model,
-    }); //lxh
-  } else {
-    emit('onClick', {
+      eventType: 'delete',
+    });
+  };
+  //下载目录
+  const downNode = () => {
+    emit('downloadNode', {
       ...props.model,
+      eventType: 'download',
     });
-  }
-};
-// 拖拽结束
-const mouseOver = () => {
-  isHover.value = true;
-};
-// 移出
-const mouseOut = () => {
-  isHover.value = false;
-};
-// // 添加目录
-// const addChildFolder = () => {
-//   props.model.isAdd = true; //lxh
-//   props.model.title = '';//lxh
-//   emit('addFolder', {
-//     id: props.model.id,
-//     isFolder: true,
-//   });
-// };
-// 添加文件
-const addChildDocument = (node) => {
-  props.model.title = ''; //lxh
-  props.model.isAdd = true; //lxh
-  editable.value = false; //
-};
-// 拖拽开始
-const dragStart = () => {
-  console.log(0);
-  emit('dragStart', {
-    ...props.model,
-  });
-};
-const dragOver = (e) => {
-  e.preventDefault();
-  return true;
-};
-
-const dragEnter = (e) => {
-  lastenter = e.target;
-  console.log('进入', props.model.id);
-  // 由于 dragEnter 发生在 dragLeave 之前,导致必须要使用定时器做一个延时
-  setTimeout(() => {
-    if (isFolder.value) {
-      expanded.value = true;
-      isDragFile.value = true;
-    } else {
-      emit('setDragFile', true);
+  };
+  // 选中effect
+  watchEffect(() => {
+    const $input = nodeInput.value;
+    if ($input) {
+      // 获取焦点
+      $input.focus();
+      // 设置光标位置
+      $input.setSelectionRange(0, $input.value.length);
     }
-    isDragEnterNode.value = true;
-    emit('setDragEnterNode', true);
   });
-};
-const dragLeave = (e) => {
-  // 为了防止多次选中问题
-  if (lastenter == e.target) {
-    console.log('离开', props.model.id);
+  // 编辑目录名字
+  const setEditable = () => {
+    editable.value = true;
+    props.model.isAdd = false; //lxh
+  };
+  // 修改目录名字
+  const setUnEditable = (e) => {
+    if (props.model.isAdd) {
+      console.log('新增文档失去焦点');
+      props.model.isAdd = false;
+      emit('addNode', {
+        id: props.model.id,
+        isFolder: false,
+        newName: props.model.title,
+      });
+    } else if (editable.value) {
+      console.log('编辑文档失去焦点');
+      editable.value = false;
+      props.model.title = e.target.value;
+      emit('changeName', {
+        id: props.model.id,
+        pid: props.model.pid,
+        isAdd: props.model.isAdd,
+        newName: e.target.value,
+        eventType: 'blur',
+        isFolder: isFolder.value,
+      });
+    }
+  };
+  // 展开收起
+  const toggle = () => {
     if (isFolder.value) {
-      isDragFile.value = false;
+      expanded.value = !expanded.value;
+      emit('onClick', {
+        ...props.model,
+      }); //lxh
     } else {
-      emit('setDragFile', false);
+      emit('onClick', {
+        ...props.model,
+      });
     }
-    emit('setDragEnterNode', false);
+  };
+  // 拖拽结束
+  const mouseOver = () => {
+    isHover.value = true;
+  };
+  // 移出
+  const mouseOut = () => {
+    isHover.value = false;
+  };
+  // // 添加目录
+  // const addChildFolder = () => {
+  //   props.model.isAdd = true; //lxh
+  //   props.model.title = '';//lxh
+  //   emit('addFolder', {
+  //     id: props.model.id,
+  //     isFolder: true,
+  //   });
+  // };
+  // 添加文件
+  const addChildDocument = (node) => {
+    props.model.title = ''; //lxh
+    props.model.isAdd = true; //lxh
+    editable.value = false; //
+  };
+  // 拖拽开始
+  const dragStart = () => {
+    console.log(0);
+    emit('dragStart', {
+      ...props.model,
+    });
+  };
+  const dragOver = (e) => {
+    e.preventDefault();
+    return true;
+  };
+
+  const dragEnter = (e) => {
+    lastenter = e.target;
+    console.log('进入', props.model.id);
+    // 由于 dragEnter 发生在 dragLeave 之前,导致必须要使用定时器做一个延时
+    setTimeout(() => {
+      if (isFolder.value) {
+        expanded.value = true;
+        isDragFile.value = true;
+      } else {
+        emit('setDragFile', true);
+      }
+      isDragEnterNode.value = true;
+      emit('setDragEnterNode', true);
+    });
+  };
+  const dragLeave = (e) => {
+    // 为了防止多次选中问题
+    if (lastenter == e.target) {
+      console.log('离开', props.model.id);
+      if (isFolder.value) {
+        isDragFile.value = false;
+      } else {
+        emit('setDragFile', false);
+      }
+      emit('setDragEnterNode', false);
+      isDragEnterNode.value = false;
+    }
+  };
+  const drop = (e) => {
+    isDragFile.value = false;
     isDragEnterNode.value = false;
-  }
-};
-const drop = (e) => {
-  isDragFile.value = false;
-  isDragEnterNode.value = false;
-  emit('setDragEnterNode', false);
-  emit('setDragFile', false);
-  // 为了获取路径需要判断是不是文件夹,如果不是文件夹向上找
-  if (isFolder.value) {
-    emit('onDrop', props.model);
-  } else {
-    if (props.model.pid) {
-      emit('setDragFolder');
-    } else {
+    emit('setDragEnterNode', false);
+    emit('setDragFile', false);
+    // 为了获取路径需要判断是不是文件夹,如果不是文件夹向上找
+    if (isFolder.value) {
       emit('onDrop', props.model);
+    } else {
+      if (props.model.pid) {
+        emit('setDragFolder');
+      } else {
+        emit('onDrop', props.model);
+      }
     }
-  }
-};
-const setDragEnterNode = (bol) => {
-  isDragEnterNode.value = bol;
-};
-const setDragFile = (bol) => {
-  isDragFile.value = bol;
-};
-// 找到文件夹
-const setDragFolder = () => {
-  emit('onDrop', props.model);
-};
+  };
+  const setDragEnterNode = (bol) => {
+    isDragEnterNode.value = bol;
+  };
+  const setDragFile = (bol) => {
+    isDragFile.value = bol;
+  };
+  // 找到文件夹
+  const setDragFolder = () => {
+    emit('onDrop', props.model);
+  };
 </script>
 <style lang="less">
-.vtl-node {
-  .vtl-node-main {
-    display: flex;
-    align-items: center;
-    padding: 2px 0 2px 2px;
-    cursor: pointer;
+  .vtl-node {
+    .vtl-node-main {
+      display: flex;
+      align-items: center;
+      padding: 2px 0 2px 2px;
+      cursor: pointer;
 
-    &:hover {
-      .vtl-border-text {
-        width: 80%;
+      &:hover {
+        .vtl-border-text {
+          width: 80%;
+        }
       }
-    }
 
-    .vtl-border-text {
-      display: flex; //lxh
-      flex: 1;
-      align-items: center; //lxh
-      width: 100%;
-      padding-left: 5px;
+      .vtl-border-text {
+        display: flex; //lxh
+        flex: 1;
+        align-items: center; //lxh
+        width: 100%;
+        padding-left: 5px;
 
-      .iconfont {
-        width: 16px;
-        height: 16px;
-        vertical-align: text-bottom;
+        .iconfont {
+          width: 16px;
+          height: 16px;
+          vertical-align: text-bottom;
+        }
       }
-    }
 
-    &.selected {
-      // background-color: rgba(45, 113, 134, 0.2);
-      background-color: #1c4869;
-    }
+      &.selected {
+        // background-color: rgba(45, 113, 134, 0.2);
+        background-color: #1c4869;
+      }
 
-    .vtl-input {
-      border: none;
-      max-width: 150px;
-      padding: 5px 0;
-      padding-left: 5px;
-      margin-left: 5px;
+      .vtl-input {
+        border: none;
+        max-width: 150px;
+        padding: 5px 0;
+        padding-left: 5px;
+        margin-left: 5px;
 
-      &:focus {
-        outline: none;
+        &:focus {
+          outline: none;
+        }
       }
-    }
-
-    .vtl-node-content {
-      color: #fff;
-      padding-left: 5px;
-      font-size: 14px;
-      width: 80%;
-      display: inline-block;
-      vertical-align: bottom;
-    }
 
-    &:hover {
       .vtl-node-content {
         color: #fff;
-        overflow: hidden;
+        padding-left: 5px;
+        font-size: 14px;
+        width: 80%;
+        display: inline-block;
+        vertical-align: bottom;
       }
-    }
 
-    &.vtl-active {
-      * {
-        pointer-events: none;
+      &:hover {
+        .vtl-node-content {
+          color: #fff;
+          overflow: hidden;
+        }
       }
-    }
 
-    &.vtl-active-file {
-      outline: 2px dashed #353f51;
-    }
+      &.vtl-active {
+        * {
+          pointer-events: none;
+        }
+      }
 
-    .vtl-operation {
-      padding-right: 10px;
+      &.vtl-active-file {
+        outline: 2px dashed #353f51;
+      }
+
+      .vtl-operation {
+        padding-right: 10px;
+      }
     }
   }
-}
 
-.vtl-tree-margin {
-  padding-left: 1em;
-}
+  .vtl-tree-margin {
+    padding-left: 1em;
+  }
 </style>