Bladeren bron

On master: 1

hongrunxia 1 jaar geleden
bovenliggende
commit
bbf3f38831
51 gewijzigde bestanden met toevoegingen van 1201 en 630 verwijderingen
  1. 1 1
      .env.development
  2. 7 4
      .env.production
  3. BIN
      public/model/glft/cf/dscf.glb
  4. BIN
      public/model/glft/fire/chamber.glb
  5. BIN
      public/model/glft/yafeng/nitrogen.glb
  6. 1 1
      src/App.vue
  7. 1 1
      src/assets/icons/aveg-temperature.svg
  8. 0 6
      src/assets/icons/max-temperature.svg.svg
  9. 1 1
      src/assets/icons/min-temperature.svg
  10. 1 0
      src/components/Table/src/BasicTable.vue
  11. 1 1
      src/components/vent/fourBorderBg.vue
  12. 7 0
      src/design/vent/comment.less
  13. 4 2
      src/design/vent/index.less
  14. 2 2
      src/enums/pageEnum.ts
  15. 1 1
      src/layouts/default/content/index.vue
  16. 8 7
      src/layouts/default/sider/bottomSideder.vue
  17. 2 1
      src/qiankun/state.ts
  18. 6 2
      src/utils/threejs/main.worker.ts
  19. 20 21
      src/views/dashboard/Analysis/homePage/network.vue
  20. 25 23
      src/views/dashboard/Analysis/homePage/workerFace.vue
  21. 6 61
      src/views/dashboard/Analysis/index.vue
  22. 1 1
      src/views/vent/monitorManager/chamberMonitor/chamber.api.ts
  23. 62 0
      src/views/vent/monitorManager/chamberMonitor/chamber.data.ts
  24. 1 1
      src/views/vent/monitorManager/chamberMonitor/chamber.threejs.base.ts
  25. 3 2
      src/views/vent/monitorManager/chamberMonitor/chamber.threejs.ts
  26. 154 124
      src/views/vent/monitorManager/chamberMonitor/index.vue
  27. 39 3
      src/views/vent/monitorManager/comment/AlarmHistoryTable.vue
  28. 40 5
      src/views/vent/monitorManager/comment/HandlerHistoryTable.vue
  29. 36 3
      src/views/vent/monitorManager/comment/HistoryTable.vue
  30. 24 6
      src/views/vent/monitorManager/comment/MonitorTable.vue
  31. 1 1
      src/views/vent/monitorManager/deviceMonitor/device.api.ts
  32. 454 71
      src/views/vent/monitorManager/deviceMonitor/index.vue
  33. 126 52
      src/views/vent/monitorManager/deviceMonitor/modal/dust.modal.vue
  34. 5 3
      src/views/vent/monitorManager/deviceMonitor/modal/fiber.modal.vue
  35. 2 2
      src/views/vent/monitorManager/fanLocalMonitor/index.vue
  36. 3 3
      src/views/vent/monitorManager/fiberMonitor/fiber.ds.threejs.ts
  37. 2 2
      src/views/vent/monitorManager/fiberMonitor/index.vue
  38. 2 2
      src/views/vent/monitorManager/gateMonitor/index.vue
  39. 2 2
      src/views/vent/monitorManager/mainFanMonitor/index.vue
  40. 0 87
      src/views/vent/monitorManager/nitrogen/components/bottomMenu.vue
  41. 1 1
      src/views/vent/monitorManager/nitrogen/components/nitrogenAlarmHistory.vue
  42. 1 1
      src/views/vent/monitorManager/nitrogen/components/nitrogenHistory.vue
  43. 0 5
      src/views/vent/monitorManager/nitrogen/components/nitrogenHome.vue
  44. 12 34
      src/views/vent/monitorManager/nitrogen/index.vue
  45. 28 25
      src/views/vent/monitorManager/nitrogen/nitrogen.dishang.threejs.ts
  46. 1 1
      src/views/vent/monitorManager/nitrogen/nitrogen.threejs.ts
  47. 3 3
      src/views/vent/monitorManager/sensorMonitor/index.vue
  48. 2 2
      src/views/vent/monitorManager/windowMonitor/index.vue
  49. 67 41
      src/views/vent/monitorManager/windrectMonitor/duishe.threejs.ts
  50. 22 4
      src/views/vent/monitorManager/windrectMonitor/index.vue
  51. 13 8
      src/views/vent/monitorManager/windrectMonitor/windrect.threejs.ts

+ 1 - 1
.env.development

@@ -26,5 +26,5 @@ VITE_GLOB_API_URL_PREFIX=
 
 #微前端qiankun应用,命名必须以VITE_APP_SUB_开头,jeecg-app-1为子应用的项目名称,也是子应用的路由父路径
 #VITE_APP_SUB_APP = [["micro-need-air", "//182.92.126.35:8099/"], ["micro-vent-3dModal", "//localhost:8091/"], ["micro-fire-front", "//localhost:8090/"]]
-VITE_APP_SUB_APP = [["micro-vent-3dModal", "//localhost:8091/"], ["micro-need-air", "//localhost:8099/"], ["micro-fire-front", "//localhost:8090/"]]
+VITE_APP_SUB_APP = [["micro-vent-3dModal", "//localhost:7121/"], ["micro-need-air", "//localhost:8099/"], ["micro-fire-front", "//localhost:8090/"]]
 

+ 7 - 4
.env.production

@@ -15,10 +15,11 @@ VITE_BUILD_COMPRESS = 'gzip'
 # 使用压缩时是否删除原始文件,默认为false
 VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
 #VITE_PROXY = [["/jeecgsystem","http://47.94.222.6:9999"],["/upload","http://localhost:3300/upload"]]
-#VITE_PROXY = [["/jeecgsystem","http://192.168.0.79:9999"],["/upload","http://localhost:3300/upload"]]
+#VITE_PROXY = [["/jeecgsystem","http://192.168.1.4:9999"],["/upload","http://localhost:3300/upload"]]
+VITE_PROXY = [["/jeecgsystem","http://192.168.0.79:9999"],["/upload","http://localhost:3300/upload"]]
 #VITE_PROXY = [["/jeecgsystem","http://42.194.132.36:8099"],["/upload","http://localhost:3300/upload"]]
 #VITE_PROXY = [["/jeecgsystem","http://192.168.0.30:8086"],["/upload","http://localhost:3300/upload"]]
-VITE_PROXY = [["/jeecgsystem","http://127.0.0.1:9999"],["/upload","http://localhost:3300/upload"]]
+#VITE_PROXY = [["/jeecgsystem","http://127.0.0.1:9999"],["/upload","http://localhost:3300/upload"]]
 
 #后台接口父地址(必填)
 VITE_GLOB_API_URL=/jeecgsystem
@@ -26,7 +27,9 @@ VITE_GLOB_API_URL=/jeecgsystem
 #后台接口全路径地址(必填)
 #VITE_GLOB_DOMAIN_URL=http://jeecg-boot-system:8080/jeecg-boot
 #VITE_GLOB_DOMAIN_URL=http://47.94.222.6:9999
-VITE_GLOB_DOMAIN_URL=http://127.0.0.1:9999
+#VITE_GLOB_DOMAIN_URL=http://192.168.1.4:9999
+VITE_GLOB_DOMAIN_URL=http://192.168.0.79:9999
+#VITE_GLOB_DOMAIN_URL=http://127.0.0.1:9999
 #VITE_GLOB_DOMAIN_URL=http://42.194.132.36:8099
 #采育服务器
 #VITE_GLOB_DOMAIN_URL=http://192.168.0.79:9999
@@ -46,6 +49,6 @@ VITE_LEGACY = false
 
 #微前端qiankun应用,命名必须以VITE_APP_SUB_开头,jeecg-app-1为子应用的项目名称,也是子应用的路由父路径
 #VITE_APP_SUB_APP = [["micro-need-air", "//47.94.222.6:7123/"], ["micro-vent-3dModal", "//47.94.222.6:7121/"],["micro-fire-front", "//47.94.222.6:7124/"]]
-#VITE_APP_SUB_APP = []
+#VITE_APP_SUB_APP = [["micro-vent-3dModal", "//192.168.0.79:7121/"]]
 #VITE_APP_SUB_APP = [["micro-need-air", "//127.0.0.1:20000/"], ["micro-vent-3dModal", "//127.0.0.1:30000/"], ["micro-fire-front", "//127.0.0.1:40000/"]]
 VITE_APP_SUB_APP = [["micro-need-air", "//127.0.0.1:7123/"], ["micro-vent-3dModal", "//127.0.0.1:7121/"]]

BIN
public/model/glft/cf/dscf.glb


BIN
public/model/glft/fire/chamber.glb


BIN
public/model/glft/yafeng/nitrogen.glb


+ 1 - 1
src/App.vue

@@ -23,7 +23,7 @@
   // support Multi-language
   const { getAntdLocale } = useLocale();
   const width = ref(1920);
-  const height = ref(929);
+  const height = ref(928);
 
   const body = document.body.getBoundingClientRect();
   if (screen.height === body.height && screen.width === body.width) {

+ 1 - 1
src/assets/icons/aveg-temperature.svg

@@ -1,6 +1,6 @@
 <svg xmlns="http://www.w3.org/2000/svg" width="50.313" height="73.149" viewBox="0 0 50.313 73.149">
   <g id="组_13141" data-name="组 13141" transform="translate(-506.549 -355.112)">
     <path id="路径_55369" data-name="路径 55369" d="M234.565,40.948V23.1a1.971,1.971,0,0,0-1.968-1.968h-.156a1.909,1.909,0,0,0-1.91,1.91v17.9a6.93,6.93,0,0,0-5.086,6.606,7.106,7.106,0,1,0,9.12-6.606Zm10.451-7.905a1.8,1.8,0,0,1-.7-1.364V11.5a11.773,11.773,0,0,0-23.54,0v19.6a2.8,2.8,0,0,1-.955,2.15,18.709,18.709,0,0,0-6.69,14.3,19.427,19.427,0,0,0,38.844,0A18.71,18.71,0,0,0,245.016,33.043ZM232.545,60.5a13.14,13.14,0,0,1-13.3-12.946,12.824,12.824,0,0,1,6.216-10.939l.942-.578a1.044,1.044,0,0,0,.494-.883V11.5a5.66,5.66,0,0,1,11.315,0v23.65a1.044,1.044,0,0,0,.494.883l.942.578a12.81,12.81,0,0,1,6.21,10.939A13.154,13.154,0,0,1,232.545,60.5Z" transform="translate(293.42 361.739)" fill="#fff"/>
-    <path id="路径_55371" data-name="路径 55371" d="M64,120.4v3.586H81.725V120.4Zm0,21.934H81.725v-3.586H64Zm0-9.172H81.725v-3.586H64Z" transform="translate(475.138 234.712)" fill="#fff"/>
+    <path id="路径_55371" data-name="路径 55371" d="M64,120.4v3.586H81.725V120.4Zm0,21.934H81.725v-3.586H64Zm0-9.172H81.725v-3.586H64Z" transform="translate(475.138 234.712)" fill="#3df6ff"/>
   </g>
 </svg>

+ 0 - 6
src/assets/icons/max-temperature.svg.svg

@@ -1,6 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="50.313" height="73.149" viewBox="0 0 50.313 73.149">
-  <g id="组_13139" data-name="组 13139" transform="translate(-506.549 -355.112)">
-    <path id="路径_55369" data-name="路径 55369" d="M234.565,40.948V23.1a1.971,1.971,0,0,0-1.968-1.968h-.156a1.909,1.909,0,0,0-1.91,1.91v17.9a6.93,6.93,0,0,0-5.086,6.606,7.106,7.106,0,1,0,9.12-6.606Zm10.451-7.905a1.8,1.8,0,0,1-.7-1.364V11.5a11.773,11.773,0,0,0-23.54,0v19.6a2.8,2.8,0,0,1-.955,2.15,18.709,18.709,0,0,0-6.69,14.3,19.427,19.427,0,0,0,38.844,0A18.71,18.71,0,0,0,245.016,33.043ZM232.545,60.5a13.14,13.14,0,0,1-13.3-12.946,12.824,12.824,0,0,1,6.216-10.939l.942-.578a1.044,1.044,0,0,0,.494-.883V11.5a5.66,5.66,0,0,1,11.315,0v23.65a1.044,1.044,0,0,0,.494.883l.942.578a12.81,12.81,0,0,1,6.21,10.939A13.154,13.154,0,0,1,232.545,60.5Z" transform="translate(293.42 361.739)" fill="#fff"/>
-    <path id="路径_55370" data-name="路径 55370" d="M284.718,159.821v14.623h2.954V159.821l3.1,3.1,2.068-2.216L286.2,154.06l-6.647,6.647,2.068,2.068Zm-7.385-7.533h17.725v-2.954H277.333Z" transform="translate(261.805 205.778)" fill="#fff"/>
-  </g>
-</svg>

+ 1 - 1
src/assets/icons/min-temperature.svg

@@ -1,6 +1,6 @@
 <svg xmlns="http://www.w3.org/2000/svg" width="50.313" height="73.149" viewBox="0 0 50.313 73.149">
   <g id="组_13140" data-name="组 13140" transform="translate(-506.549 -355.112)">
     <path id="路径_55369" data-name="路径 55369" d="M234.565,40.948V23.1a1.971,1.971,0,0,0-1.968-1.968h-.156a1.909,1.909,0,0,0-1.91,1.91v17.9a6.93,6.93,0,0,0-5.086,6.606,7.106,7.106,0,1,0,9.12-6.606Zm10.451-7.905a1.8,1.8,0,0,1-.7-1.364V11.5a11.773,11.773,0,0,0-23.54,0v19.6a2.8,2.8,0,0,1-.955,2.15,18.709,18.709,0,0,0-6.69,14.3,19.427,19.427,0,0,0,38.844,0A18.71,18.71,0,0,0,245.016,33.043ZM232.545,60.5a13.14,13.14,0,0,1-13.3-12.946,12.824,12.824,0,0,1,6.216-10.939l.942-.578a1.044,1.044,0,0,0,.494-.883V11.5a5.66,5.66,0,0,1,11.315,0v23.65a1.044,1.044,0,0,0,.494.883l.942.578a12.81,12.81,0,0,1,6.21,10.939A13.154,13.154,0,0,1,232.545,60.5Z" transform="translate(293.42 361.739)" fill="#fff"/>
-    <path id="路径_55370" data-name="路径 55370" d="M284.718,163.956V149.334h2.954v14.623l3.1-3.1,2.068,2.216-6.647,6.647-6.647-6.647L281.616,161Zm-7.385,7.533h17.725v2.954H277.333Z" transform="translate(261.805 205.778)" fill="#fff"/>
+    <path id="路径_55370" data-name="路径 55370" d="M284.718,163.956V149.334h2.954v14.623l3.1-3.1,2.068,2.216-6.647,6.647-6.647-6.647L281.616,161Zm-7.385,7.533h17.725v2.954H277.333Z" transform="translate(261.805 205.778)" fill="#3df6ff"/>
   </g>
 </svg>

+ 1 - 0
src/components/Table/src/BasicTable.vue

@@ -434,6 +434,7 @@
 <style lang="less" scoped>
   @ventSpace: zxm;
   :deep(.@{ventSpace}-select-dropdown) {
+    left: 0px !important;
     top: 36px !important;
   }
 </style>

+ 1 - 1
src/components/vent/fourBorderBg.vue

@@ -29,7 +29,7 @@ export default defineComponent ({
     border: 1px solid #4D7AD855;
     border-radius: 2px;
     background-color: #001d3055;
-    backdrop-filter: blur(8px);
+    backdrop-filter: blur(2px);
     box-shadow: 0 0 10px #5984E055 inset;
     padding: 5px 8px;
     color: #ffffffee;

+ 7 - 0
src/design/vent/comment.less

@@ -22,4 +22,11 @@
   flex-direction: column;
   justify-content: center;
   align-items: center;
+}
+
+.vent-margin-b-20{
+  margin-bottom: 20px;
+}
+.vent-margin-t-20 {
+  margin-top: 20px;
 }

+ 4 - 2
src/design/vent/index.less

@@ -442,6 +442,8 @@
   }
 }
 
-
-
+/** 摄像头 */
+.video-wrapper{
+  height: 100%;
+}
 

+ 2 - 2
src/enums/pageEnum.ts

@@ -5,9 +5,9 @@ export enum PageEnum {
   // 暂时修改
   // BASE_LOGIN = '/monitor/monitor-fan-main',
   // basic home path
-  // BASE_HOME = '/micro-vent-3dModal/dashboard/analysis',
+  BASE_HOME = '/micro-vent-3dModal/dashboard/analysis',
   // BASE_HOME = '/micro-need-air',
-  BASE_HOME = '/monitorChannel/monitor-windrect',
+  // BASE_HOME = '/monitorChannel/monitor-windrect',
   // error page path
   ERROR_PAGE = '/exception',
   // error log page path

+ 1 - 1
src/layouts/default/content/index.vue

@@ -40,7 +40,7 @@
       const { currentRoute } = router;
       const globSetting = useGlobSetting();
       const openQianKun = globSetting.openQianKun;
-      const loading = ref(true);
+      const loading = ref(false);
       let actions;
       if (openQianKun == 'true') {
         actions = getActions();

+ 8 - 7
src/layouts/default/sider/bottomSideder.vue

@@ -17,7 +17,7 @@
         <div class="vent-flex-row program-group">
           <template v-for="(programMenu, key) in menuModules" :key="key">
             <div
-              v-if="programMenu.title !== '首页'"
+              v-if="!programMenu.title.startsWith('首页')"
               class="program-menu"
               :class="{ 'program-menu-active': currentParentRoute == programMenu }"
               @mouseenter="selectMenu(programMenu)"
@@ -26,9 +26,9 @@
           </template>
         </div>
         <div class="setting-group">
-          <Icon class="icon-style" size="18" name="home" @click="go('/micro-vent-3dModal/dashboard/analysis')" />
-          <Icon class="icon-style" size="18" name="fixed" />
-          <Icon class="icon-style" size="18" name="enter" />
+          <SvgIcon class="icon-style" size="18" name="home" @click="go('/micro-vent-3dModal/dashboard/analysis')" />
+          <SvgIcon class="icon-style" size="18" name="fixed" />
+          <SvgIcon class="icon-style" size="18" name="enter" />
           <!-- <SvgIcon class="icon-style" size="18" name="setting" />  
           <SvgIcon class="icon-style" size="18" name="hidden" /> -->
         </div>
@@ -45,14 +45,14 @@
   import { defineComponent, onMounted, ref, unref } from 'vue';
   import type { Menu } from '/@/router/types';
   import FourBorderBg from '/@/components/vent/fourBorderBg.vue';
-  import { Icon } from '/@/components/Icon';
+  import { SvgIcon } from '/@/components/Icon';
   import { getMenus } from '/@/router/menus';
   import { useGo } from '/@/hooks/web/usePage';
   import { useRouter } from 'vue-router';
 
   export default defineComponent({
     name: 'BottomSider',
-    components: { FourBorderBg, Icon },
+    components: { FourBorderBg, SvgIcon },
     setup() {
       const isShowMenu = ref(0);
       let menuModules = ref<Menu[]>([]);
@@ -124,7 +124,7 @@
     position: fixed;
     bottom: 2px;
     left: 0px;
-    z-index: 9999;
+    z-index: 999990;
     color: #fff;
     .menu-container {
       width: 480px;
@@ -134,6 +134,7 @@
       // background-color: #06115a;
       border: 1px solid #0099e6;
       background-color: #0c1e2b;
+      z-index: 999;
       // backdrop-filter: blur(8px);
       .four-border-bg {
         margin: 5px;

+ 2 - 1
src/qiankun/state.ts

@@ -24,7 +24,7 @@ export function getProps() {
  * 定义全局状态,并返回通信方法,在主应用使用,微应用通过 props 获取通信方法。
  * @param state 主应用穿的公共数据
  */
-export function initGlState(info: any = { token: '', userInfo: {}, isMounted: false , widthScale: 1, heightScale: 1}) {
+export function initGlState(info: any = { token: '', userInfo: {}, isMounted: false,locationObj: null, locationId: '', pageObj: null,  widthScale: 1, heightScale: 1}) {
   if (actions) return;
   // 初始化state
   actions = initGlobalState(info);
@@ -32,6 +32,7 @@ export function initGlState(info: any = { token: '', userInfo: {}, isMounted: fa
   actions.setGlobalState({
     token: getToken(),
     isMounted: false,
+    pageObj: {},
     widthScale: 1,
     heightScale: 1
   });

+ 6 - 2
src/utils/threejs/main.worker.ts

@@ -18,6 +18,8 @@ export function initModalWorker() {
     'cf/lmcfSide.glb',
     'cf/zdcf.glb',
     'cf/dscf.glb',
+    'cf/dsgd.glb',
+    'cf/dsmove.glb',
     'jbfj/jbfj_hd.glb',
     'jbfj/jbfj_fm.glb',
     'jbfj/jbfj_fc.glb',
@@ -27,8 +29,10 @@ export function initModalWorker() {
     'ztfj/bg.glb',
     'fire/laneway.glb',
     'fire/chamber.glb',
-    'yafeng/nitrogen.glb',
-    // 'ceshi/glass.glb',
+    'fire/workFace.glb',
+    'yafeng/compressor.glb',
+    'fire/nitrogen.glb',
+    'fire/grout.glb',
   ];
 
   const db: any = new Dexie('DB');

+ 20 - 21
src/views/dashboard/Analysis/homePage/network.vue

@@ -1,10 +1,9 @@
 <template>
   <div class="zl-box">
     <div class="zl-container-box">
-      
       <div class="top-box">
         <div class="left-box lr-box">
-          <div class = "container-title">
+          <!-- <div class = "container-title">
             <a-select
               class="title-select"
               ref="select"
@@ -15,7 +14,7 @@
               <a-select-option value="1598491318007898113">采煤工作面</a-select-option>
               <a-select-option value="3">掘进工作面</a-select-option>
             </a-select>
-          </div>
+          </div> -->
           <div class="analysis-box">
             <div class="pie-group">
               <div class="item-pie">
@@ -312,24 +311,24 @@ onUnmounted(() => {
     }
 
     .left-box {
-      .container-title {
-        width: 398px;
-        height: 34px;
-        top: -30px;
-        background: url('/@/assets/images/vent/new-home/container-title-bg.png') no-repeat;
-        background-size: contain;
-        padding: 0 0 0 180px;
-        font-size: 20px;
-        pointer-events: auto;
-        position: relative;
-
-        .title-select {
-          width: 198px;
-          position: absolute;
-          top: 0;
-          left: 180px;
-        }
-      }
+      // .container-title {
+      //   width: 398px;
+      //   height: 34px;
+      //   top: -30px;
+      //   background: url('/@/assets/images/vent/new-home/container-title-bg.png') no-repeat;
+      //   background-size: contain;
+      //   padding: 0 0 0 180px;
+      //   font-size: 20px;
+      //   pointer-events: auto;
+      //   position: relative;
+
+      //   .title-select {
+      //     width: 198px;
+      //     position: absolute;
+      //     top: 0;
+      //     left: 180px;
+      //   }
+      // }
 
       .analysis-box {
         position: relative;

+ 25 - 23
src/views/dashboard/Analysis/homePage/workerFace.vue

@@ -1,13 +1,13 @@
 <template>
   <div class="center-container">
     <div class="lr-box left-box">
-      <div class="container-title">
+      <!-- <div class="container-title">
         <a-select class="title-select" ref="select" v-model:value="currentTitleValue" @change="handleTitleChange">
           <a-select-option value="2">15212工作面</a-select-option>
           <a-select-option value="1598491318007898113">采煤工作面</a-select-option>
           <a-select-option value="3">掘进工作面</a-select-option>
         </a-select>
-      </div>
+      </div> -->
 
       <div class="item">
         <dv-decoration7 style="height: 30px">
@@ -28,7 +28,7 @@
           </div>
         </div>
         <div class="item-container">
-          <!-- <BarAndLineCustom xAxisPropType="time" :chartData="monitorData" height="240px" :propTypeArr="['jin', 'hui']" :option="echartsOption" /> -->
+          <BarAndLineCustom xAxisPropType="time" :chartData="monitorData" height="240px" :propTypeArr="['jin', 'hui']" :option="echartsOption" />
         </div>
       </div>
       <div class="item">
@@ -181,7 +181,7 @@
   import { onMounted, onUnmounted, ref, reactive } from 'vue';
   import { Decoration7 as DvDecoration7, ScrollBoard as DvScrollBoard, BorderBox7 as DvBorderBox7 } from '@kjgl77/datav-vue3';
   import { workerFaceDeviceList } from '../home.data';
-  // import BarAndLineCustom from '/@/components/chart/BarAndLineCustom.vue';
+  import BarAndLineCustom from '/@/components/chart/BarAndLineCustom.vue';
   import { list, deviceMonitor } from '../home.api';
   import echarts from '/@/utils/lib/echarts';
   import MonitorTable from '/@/views/vent/monitorManager/comment/MonitorTable.vue';
@@ -400,32 +400,31 @@
       flex-direction: column;
       pointer-events: auto;
 
-      .container-title {
-        width: 398px;
-        height: 34px;
-        position: relative;
-        top: -30px;
-        background: url('/@/assets/images/vent/new-home/container-title-bg.png') no-repeat;
-        background-size: contain;
-        padding: 0 0 0 180px;
-        font-size: 20px;
-        pointer-events: auto;
-        position: relative;
+      // .container-title {
+      //   width: 398px;
+      //   height: 34px;
+      //   position: relative;
+      //   top: -30px;
+      //   background: url('/@/assets/images/vent/new-home/container-title-bg.png') no-repeat;
+      //   background-size: contain;
+      //   padding: 0 0 0 180px;
+      //   font-size: 20px;
+      //   pointer-events: auto;
+      //   position: relative;
 
-        .title-select {
-          width: 198px;
-          position: absolute;
-          top: 0;
-          left: 180px;
-        }
-      }
+      //   .title-select {
+      //     width: 198px;
+      //     position: absolute;
+      //     top: 0;
+      //     left: 180px;
+      //   }
+      // }
       .item {
         // flex: 1;
         width: 100%;
         display: flex;
         justify-content: center;
         flex-direction: column;
-        min-height: 200px;
         margin-bottom: 20px;
         align-items: center;
         .item-container {
@@ -652,6 +651,9 @@
 
       }
     }
+    .left-box{
+      margin-top: 30px;
+    }
   }
 
   :deep(.@{ventSpace}-table-thead){

+ 6 - 61
src/views/dashboard/Analysis/index.vue

@@ -1,9 +1,6 @@
 <template>
   <div class="vent-home">
-    <div class="vent-home-header">
-      <Decoration5 class="header-icon" :dur="2" :color="['#21437F', '#2CF7FE']" style="width:500px;height:40px;" />
-      <div class="header-text">智能管控系统</div>
-    </div>
+    <customHeader>智能管控系统</customHeader>
     <div class="home-container">
       <workerFace v-if="isBtnActive == 'workFace'"/>
       <netWork v-if="isBtnActive == 'netWork'"/>
@@ -19,10 +16,11 @@
 </template>
 <script lang="ts" setup>
   import {onMounted, onUnmounted, ref } from 'vue'
-  import { Decoration5,  Decoration11 } from '@kjgl77/datav-vue3'
+  import { Decoration11 } from '@kjgl77/datav-vue3'
   import { bottomBtnList } from "./home.data";
   import workerFace from './homePage/workerFace.vue'
   import netWork from './homePage/network.vue'
+  import customHeader from '/@/views/vent/comment/components/customHeader.vue';
 
   const activeColors = []
   const noActiveColors = ['#aaa', '#aaa']
@@ -48,32 +46,12 @@
   })
 
 </script>
-<style lang="less">
-   @import '/@/design/vent/modal.less';
-   .@{ventSpace}-select-dropdown {
-    border-bottom: 1px solid #ececec66;
-    background: transparent !important;
-    backdrop-filter: blur(50px);
-
-    .@{ventSpace}-select-item {
-      color: #fff !important;
-    }
 
-    .@{ventSpace}-select-item-option-selected,
-    .@{ventSpace}-select-item-option-active {
-      background-color: #00678b66 !important;
-    }
-    .@{ventSpace}-select-item:hover {
-      background-color: #008fc366 !important;
-    }
-  }
-   
-</style>
 <style lang="less" scoped>
   @ventSpace: zxm;
   .vent-home {
     width: 100%;
-    height: calc(100%);
+    // height: calc(100%);
     position: fixed;
     z-index: 99;
     display: flex;
@@ -81,25 +59,7 @@
     justify-content: center;
     align-items: center;
     pointer-events: none;
-    .vent-home-header {
-      width: 100%;
-      height: 100px;
-      position: fixed;
-      top: 0;
-      background: url('/@/assets/images/vent/new-home/header-bg.png') no-repeat;
-      background-size: contain;
-      display: flex;
-      justify-content: center;
-      .header-icon{
-        margin-top: 45px;
-      }
-      .header-text{
-        position: fixed;
-        top: 18px;
-        color: #fff;
-        font-size: 26px;
-      }
-    }
+    top: 0;
     .home-container {
       width: 100%;
       height: calc(100% - 200px);
@@ -127,22 +87,7 @@
     }
     
   }
-  :deep(.zxm-select){
-    width: 300px;
-  
-    .@{ventSpace}-select-selector{
-      background: transparent !important;
-      border: none !important;
-      box-shadow: none !important;
-      .zxm-select-selection-item{
-        color: #fff !important;
-        font-size: 20px;
-      }
-    }
-    .@{ventSpace}-select-arrow{
-      color: #fff !important;
-    }
-  }
+
 
   
 </style>

+ 1 - 1
src/views/vent/monitorManager/chamberMonitor/chamber.api.ts

@@ -3,7 +3,7 @@ import { Modal } from 'ant-design-vue';
 
 enum Api {
   list = '/monitor/device',
-  baseList = '/safety/ventanalyWindow/list',
+  baseList = '/safety/ventanalyDeviceInfo/list',
 }
 /**
  * 列表接口

+ 62 - 0
src/views/vent/monitorManager/chamberMonitor/chamber.data.ts

@@ -0,0 +1,62 @@
+import { reactive } from 'vue';
+import { BasicColumn } from '/@/components/Table';
+
+export const warningConfig = reactive({
+  data: [
+    ['火焰6', '318℃', '严重报警', '03-05'],
+    ['测点43', '142℃', '一般预警', '03-05'],
+    ['CO23', '167℃', '一版预警', '03-05'],
+    ['测点6', '198℃', '超高预警', '03-05'],
+    ['测点65', '197℃', '超高预警', '03-05'],
+    ['温度4', '154℃', '一般预警', '03-05'],
+    ['测点61', '104℃', '一般预警', '03-05'],
+    ['测点87', '150℃', '一般信息', '03-05'],
+  ],
+  index: false,
+  // columnWidth: [150, 80, 150, 150],
+  headerBGC: '#3d9dd45d',
+  oddRowBGC: '#009acd10',
+  evenRowBGC: '#009acd05',
+  align: ['center', 'center', 'center'],
+});
+
+export const sensorColumns: BasicColumn[] = [
+  {
+    title: '名称',
+    dataIndex: 'strname',
+    width: 100,
+    align: 'center',
+  },
+  {
+    title: '实时值',
+    dataIndex: 'smokeval',
+    width: 80,
+    align: 'center',
+  },
+  {
+    title: '报警',
+    dataIndex: 'warnFlag',
+    width: 100,
+    align: 'center',
+  },
+];
+export const dustColumns: BasicColumn[] = [
+  {
+    title: '名称',
+    dataIndex: 'strname',
+    width: 100,
+    align: 'center',
+  },
+  {
+    title: '链接状态',
+    dataIndex: 'netStatus',
+    width: 80,
+    align: 'center',
+  },
+  {
+    title: '操作',
+    dataIndex: 'action',
+    width: 100,
+    align: 'center',
+  },
+];

+ 1 - 1
src/views/vent/monitorManager/chamberMonitor/chamber.threejs.base.ts

@@ -90,7 +90,7 @@ class ChamberBase {
         this.group = gltf[0];
         if (this.group) {
           this.group?.scale.set(0.1, 0.1, 0.1);
-          this.group.position.y += 60;
+          this.group.position.y += 40;
           resolve(null);
           this.addLight();
         }

+ 3 - 2
src/views/vent/monitorManager/chamberMonitor/chamber.threejs.ts

@@ -14,6 +14,7 @@ const appStore = useAppStore();
 // 鼠标点击事件
 const mouseEvent = (event) => {
   event.stopPropagation();
+  if (!model) return;
   const widthScale = appStore.getWidthScale;
   const heightScale = appStore.getHeightScale;
   // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
@@ -73,8 +74,8 @@ export const setModelType = (type) => {
         await animateCamera(
           oldCameraPosition,
           oldCameraPosition,
-          { x: 1.6659700995438462, y: 315.8350412885176, z: 568.1266662409791 },
-          { x: 1.6659700995440048, y: -32.575630674334704, z: 22.306948260174813 },
+          { x: 0.519594036828229, y: 411.8877286329627, z: 330.7728952161751 },
+          { x: 3.534969685817257, y: 14.506061950306899, z: -16.565361577001262 },
           model,
           0.8
         );

+ 154 - 124
src/views/vent/monitorManager/chamberMonitor/index.vue

@@ -17,177 +17,207 @@
     </div> -->
   </div>
   <div class="scene-box">
-    <div class="title-text">
-      {{ selectData.strname }}
-    </div>
+    <customHeader :fieldNames="{ label: 'strinstallpos', value: 'deviceID', options: 'children' }" :options = 'options' @change="getSelectRow" :optionValue="optionValue">硐室监测管控</customHeader>
     <div class="center-container">
-      <div class="lr left-box"></div>
-      <div class="lr right-box">
-        <div class="">
-
-        </div>
-        <div class="">
-
+      <chamberHome v-if="activeKey == 'monitor'" :deviceId = 'optionValue' />
+      <div v-else class="history-group">
+        <div class="device-button-group" v-if="deviceList.length > 0">
+          <div class="device-button" :class="{ 'device-active': deviceActive == device.deviceType }" v-for="(device, index) in deviceList" :key="index" @click="deviceChange(index)">{{ device.deviceName }}</div>
         </div>
-      </div>
-    </div>
-    <div class="bottom-tabs-box">
-      <MonitorTable columnsType="fiber_monitor" :dataSource="fiberDataSource" @selectRow="getSelectRow"
-        design-scope="fiber-monitor" title="风窗监测" :scroll="{y: 240}" :isShowPagination="false">
-        <template #filterCell="{ column, record }">
-          <a-tag v-if="column.dataIndex === 'warnFlag'" :color="record.warnFlag == 0 ? 'green' : 'red'">{{
-            record.warnFlag == 0 ? '正常' : '报警'
-          }}</a-tag>
-          <a-tag v-if="column.dataIndex === 'netStatus'" :color="record.netStatus == 0 ? 'default' : 'green'">{{
-            record.netStatus == 0 ? '断开' : '连接'
-          }}</a-tag>
-          <div v-if="record.nwindownum == 1 && column.dataIndex === 'rearArea'">/</div>
-        </template>
-      </MonitorTable>
+        <div class="history-container">
+          <chamberHistory v-if="activeKey == 'monitor_history'" ref="historyTable" class="vent-margin-t-20" :deviceId = 'optionValue' :device-type="deviceType"/>
+          <chamberHandleHistoryVue v-if="activeKey == 'handler_history'" ref="alarmHistoryTable" class="vent-margin-t-20" :deviceId = 'optionValue' :device-type="deviceType" />
+          <chamberAlarmHistory v-if="activeKey == 'faultRecord'" ref="handlerHistoryTable" class="vent-margin-t-20" :deviceId = 'optionValue' :device-type="deviceType"/>
+        </div> 
+      </div>      
     </div>
+    <BottomMenu @change="changeActive"/>
   </div>
+  
 </template>
 
 <script setup lang="ts">
-// import { message } from 'ant-design-vue';
+import customHeader from '/@/views/vent/comment/components/customHeader.vue';
 import { onBeforeMount, ref, onMounted, onUnmounted, reactive, toRaw } from 'vue';
-import MonitorTable from '../comment/MonitorTable.vue';
-import { mountedThree, destroy, addChamberText, setModelType } from './chamber.threejs';
 import { list } from './chamber.api';
-import lodash from 'lodash';
+import BottomMenu from '/@/views/vent/comment/components/bottomMenu.vue';
+import chamberHome from './components/chamberHome.vue';
+import chamberHistory from './components/chamberHistory.vue';
+import chamberHandleHistoryVue from './components/chamberHandleHistory.vue';
+import chamberAlarmHistory from './components/chamberAlarmHistory.vue';
+import { useRouter } from 'vue-router';
+
+type DeviceType = { deviceType: string, deviceName: string, datalist: any[] };
 
-const activeKey = ref('1');
+const { currentRoute } = useRouter();
+const activeKey = ref('monitor');
 const loading = ref(false);
 
+const historyTable = ref()
+const alarmHistoryTable = ref()
+const handlerHistoryTable = ref()
+
+
+//关联设备
+const deviceList = ref<DeviceType[]>([])
+const deviceActive = ref('')
+const deviceType = ref('')
+
+const options = ref()
 // 默认初始是第一行
 const selectRowIndex = ref(0);
 const dataSource = ref([])
-const fiberDataSource = ref([]); //dusting
-const dustDataSource = ref([]); 
 
-const tabChange = (activeKeyVal) => {
-  activeKey.value = activeKeyVal;
-};
-
-const initData = {
-  deviceID: '',
-  deviceType: '',
-  strname: '',
-};
+const optionValue = ref('')
 
 // 监测数据
-const selectData = reactive(lodash.cloneDeep(initData));
-
-// https获取监测数据
-let timer: null | NodeJS.Timeout = null;
-const getMonitor = () => {
-  if (Object.prototype.toString.call(timer) === '[object Null]') {
-    timer = setTimeout(async () => {
-      const data = await getSysDataSource();
-      Object.assign(selectData, data);
-
-      if (timer) {
-        timer = null;
-      }
-      getMonitor();
-    }, 1000);
-  }
+const selectData = reactive({});
+
+function changeActive(activeValue) {
+  activeKey.value = activeValue
+}
+
+function deviceChange(index) {
+  deviceActive.value = deviceType.value = deviceList.value[index].deviceType
+}
+
+// 查询关联设备列表
+async function getDeviceList() {
+  const res = await list({ devicetype: 'sys', systemID: optionValue.value });
+  const result = res.msgTxt;
+  const deviceArr = <DeviceType[]>[]
+  result.forEach(item => {
+    const data = item['datalist'].filter((data: any) => {
+      const readData = data.readData;
+      return Object.assign(data, readData);
+    })
+    if (item.type != 'sys') {
+      deviceArr.unshift({ deviceType: item.type, deviceName: item['typeName'] ? item['typeName'] : item['datalist'][0]['typeName'], datalist: data })
+    }
+  })
+  deviceList.value = deviceArr
+  deviceActive.value = deviceArr[0].deviceType
+  deviceChange(0)
 };
 
-const getSysDataSource = async () => {
+async function getSysDataSource () {
   const res = await list({ devicetype: 'sys_dongshi', pagetype: 'normal' });
   dataSource.value = res.msgTxt[0].datalist || [];
   dataSource.value.forEach((data: any) => {
     const readData = data.readData;
     data = Object.assign(data, readData);
   });
+  
+  if(!options.value) {
+    // 初始时选择第一条数据
+    options.value = dataSource.value
+    if(!optionValue.value){
+      optionValue.value = dataSource.value[0]['deviceID']
+      Object.assign(selectData, dataSource.value[0])
+    }else{
+      const currentData = dataSource.value.find(item => item['deviceID'] === optionValue.value) || {}
+      Object.assign(selectData, currentData)
+    }
+  }
   const data: any = toRaw(dataSource.value[selectRowIndex.value]); //maxarea
   return data;
 };
 
-const getDataSource = async (systemID) => {
-  const res = await list({ devicetype: 'sys', systemID });
-  const result = res.msgTxt[0];
-  result.forEach(item => {
-    if (item.type === 'dusting_auto') {
-      // 喷粉
-      dustDataSource.value = item.filter((data: any) => {
-        const readData = data.readData;
-        return Object.assign(data, readData);
-      })
-    }
-    if (item.type === 'fiber_normal') {
-      // 光纤
-      fiberDataSource.value = item.filter((data: any) => {
-        const readData = data.readData;
-        return Object.assign(data, readData);
-      })
-    }
-    if (item.type === 'sys') {
-      // 硐室基本
-      // fiberDataSource.value = item.filter((data: any) => {
-      //   const readData = data.readData;
-      //   return Object.assign(data, readData);
-      // })
-    }
-  })
-}
-
-
 // 切换检测数据
-const getSelectRow = (selectRow, index) => {
-  if (!selectRow) return;
-  selectRowIndex.value = index;
-
-  Object.assign(selectData, initData, selectRow);
-  getDataSource(selectData.deviceID)
-  // setModelType(type).then(() => {
-   
-  // });
+function getSelectRow(deviceID){
+  const currentData = dataSource.value.find((item: any) => {
+    return item.deviceID == deviceID
+  })
+  if(currentData){
+    optionValue.value = currentData['deviceID']
+    Object.assign(selectData, currentData)
+  }
 }
 
 onBeforeMount(() => {
 
 });
 
-onMounted(() => {
-  loading.value = true;
-  mountedThree().then(async () => {
-    await setModelType('chamberBase');
-    loading.value = false;
-    getMonitor();
-  });
+onMounted(async() => {
+  if (currentRoute.value['query'] && currentRoute.value['query']['id']) optionValue.value = currentRoute.value['query']['id']
+  await getSysDataSource()
+  await getDeviceList()
 });
+
 onUnmounted(() => {
-  destroy();
-  if (timer) {
-    clearTimeout(timer);
-    timer = undefined;
-  }
+ 
 });
 </script>
 <style lang="less" scoped>
 @import '/@/design/vent/modal.less';
 @ventSpace: zxm;
-
-.center-container{
-  width: 100%;
-  height: 550px;
-  border: 1px solid #fff;
-  margin-top: 30px;
-  display: flex;
-  justify-content: space-between;
-  .lr{
-    width: 250px;
-    height: 100%;
-    border: 1px solid #73e8fe;
-    display: flex;
-    flex-direction: column;
+.scene-box{
+  pointer-events: none;
+  .history-group{
+    padding: 0 20px;
+    .history-container{
+      position: relative;
+      background: #6176AF11;
+      width: calc(100% + 10px);
+      top: 0px;
+      left: -10px;
+      border: 1px solid #ffffff22;
+      padding: 10px 0;
+    }
   }
-  .right-box{
-    width: 280px;
+  .device-button-group{
+    // margin: 0 20px;
+    display: flex;
+    pointer-events: auto;
+    position: relative;
+    margin-top: 90px;
+    &::after{
+      position:absolute;
+      content: '';
+      width: calc(100% + 10px);
+      height: 2px;
+      top: 30px;
+      left: -10px;
+      border-bottom: 1px solid #0efcff;
+    }
+    .device-button{
+      padding: 4px 15px;
+      position: relative;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      font-size: 14px;
+      
+      color: #fff;
+      cursor: pointer;
+      margin: 0 3px;
+
+      &::before{
+        content: '';
+        position: absolute;
+        top: 0;
+        right: 0;
+        bottom: 0;
+        left: 0;
+        border: 1px solid #6176AF;
+        transform: skewX(-38deg);
+        background-color: rgba(0, 77, 103,85%);
+        z-index: -1;
+      }
+    }
+    .device-active{
+      // color: #0efcff;
+      &::before{
+        border-color: #0efcff;
+        box-shadow: 1px 1px 3px 1px #0efcff inset;
+      }
+    }
   }
 }
+.center-container{
+  width: 100%;
+  height: calc(100% - 200px);
+}
 
 :deep(.@{ventSpace}-tabs-tabpane-active) {
   overflow: auto;

+ 39 - 3
src/views/vent/monitorManager/comment/AlarmHistoryTable.vue

@@ -1,15 +1,17 @@
 <template>
   <div class="alarm-history-table">
-    <BasicTable @register="registerTable" />
+    <BasicTable ref="alarmHistory" @register="registerTable" />
   </div>
 </template>
 
 <script lang="ts" name="system-user" setup>
   //ts语法
+  import { watch, ref, defineExpose } from 'vue'
   import { BasicTable } from '/@/components/Table';
   import { useListPage } from '/@/hooks/system/useListPage';
   import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
   import { defHttp } from '/@/utils/http/axios';
+import { prefetchApps } from 'qiankun';
 
   const list = (params) => defHttp.get({ url: '/safety/ventanalyAlarmLog/list', params });
 
@@ -29,13 +31,43 @@
     designScope: {
       type: String,
     },
+    sysId: {
+      type: String,
+    },
     scroll: {
       type: Object,
       default: () => { }
     }
   });
+  const alarmHistory = ref()
+  const columns = ref([])
+
+  watch(
+    () => {
+      return props.columnsType;
+    },
+    (newVal) => {
+      const column = getTableHeaderColumns(newVal + '_history')
+      if (column && column.length < 1) {
+        const arr = newVal.split('_')
+        const columnKey = arr.reduce((prev, cur, index) => {
+          if (index !== arr.length - 2) {
+            return prev + '_' + cur
+          } else {
+            return prev
+          }
+        })
+        columns.value = getTableHeaderColumns(arr[0] + '_history');
+      } else {
+        columns.value = column
+      }
+      if (alarmHistory.value) reload()
+    },
+    {
+      immediate: true
+    }
+  );
 
-  const columns = getTableHeaderColumns(props.columnsType);
   // 列表页面公共参数、方法
   const { tableContext } = useListPage({
     tableProps: {
@@ -84,11 +116,15 @@
       },
       beforeFetch(params) {
         params.gdevicetype = props.deviceType + '*';
+        if (props.sysId) {
+          params.sysId = props.sysId;
+        }
       },
     },
   });
   //注册table数据
-  const [registerTable] = tableContext;
+  const [registerTable, { reload, setLoading }] = tableContext;
+  defineExpose({ setLoading })
 </script>
 
 <style scoped lang="less">

+ 40 - 5
src/views/vent/monitorManager/comment/HandlerHistoryTable.vue

@@ -1,12 +1,12 @@
 <template>
   <div class="handler-history-table">
-    <BasicTable @register="registerTable" />
+    <BasicTable ref="handlerHistory" @register="registerTable" />
   </div>
 </template>
 
 <script lang="ts" name="system-user" setup>
   //ts语法
-  import { watch } from 'vue';
+  import { watch, ref, defineExpose } from 'vue';
   import { BasicTable } from '/@/components/Table';
   import { useListPage } from '/@/hooks/system/useListPage';
   import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
@@ -31,13 +31,45 @@
     designScope: {
       type: String,
     },
+    sysId: {
+      type: String,
+    },
     scroll: {
       type: Object,
       default: () => {}
     }
   });
   
-  const columns = getTableHeaderColumns(props.columnsType);
+  const handlerHistory = ref()
+  const columns = ref([])
+
+  watch(
+    () => {
+      return props.columnsType;
+    },
+    (newVal) => {
+      const column = getTableHeaderColumns(newVal)
+      debugger
+      if (column && column.length < 1) {
+        const arr = newVal.split('_')
+        const columnKey = arr.reduce((prev, cur, index) => {
+          if (index !== arr.length - 2) {
+            return prev + '_' + cur
+          } else {
+            return prev
+          }
+        })
+        columns.value = getTableHeaderColumns(arr[0] + '_history');
+      } else {
+        columns.value = column
+      }
+      if (handlerHistory.value) reload()
+    },
+    {
+      immediate: true
+    }
+  );
+
   // 列表页面公共参数、方法
   const { tableContext } = useListPage({
     tableProps: {
@@ -85,12 +117,15 @@
       },
       beforeFetch(params) {
         params.gdevicetype = props.deviceType + '*';
+        if (props.sysId) {
+          params.sysId = props.sysId;
+        }
       },
     },
   });
   //注册table数据
-  const [registerTable, { reload }] = tableContext;
-  
+  const [registerTable, { reload, setLoading }] = tableContext;
+  defineExpose({ setLoading })
 </script>
 
 <style scoped lang="less">

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

@@ -10,7 +10,7 @@
 
 <script lang="ts" name="system-user" setup>
   //ts语法
-  import { watchEffect, ref } from 'vue';
+  import { watchEffect, ref, watch, defineExpose } from 'vue';
   import { BasicTable } from '/@/components/Table';
   import { useListPage } from '/@/hooks/system/useListPage';
   import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
@@ -35,13 +35,41 @@
     designScope: {
       type: String,
     },
+    sysId: {
+      type: String,
+    },
     scroll: {
       type: Object,
       default: () => { }
     }
   });
+  const columns = ref([])
 
-  const columns = getTableHeaderColumns(props.columnsType);
+  watch(
+  () => {
+    return props.columnsType;
+  },
+  (newVal) => {
+    const column = getTableHeaderColumns(newVal + '_history')
+    if (column && column.length < 1) {
+      const arr = newVal.split('_')
+      const columnKey = arr.reduce((prev, cur, index) => {
+        if (index !== arr.length - 2) {
+          return prev + '_' + cur
+        } else {
+          return prev
+        }
+      })
+      columns.value = getTableHeaderColumns(arr[0] + '_history');
+    } else {
+      columns.value = column
+    }
+    if(historyTable.value) reload()
+  },
+  {
+    immediate: true
+  }
+);
 
   // 列表页面公共参数、方法
   const { tableContext } = useListPage({
@@ -140,6 +168,9 @@
       },
       beforeFetch(params) {
         params.strtype = props.deviceType + '*';
+        if(props.sysId){
+          params.sysId = props.sysId;
+        }
       },
       afterFetch(resultItems) {
         resultItems.map((item) => {
@@ -150,7 +181,7 @@
     },
   });
   //注册table数据
-  const [registerTable, { getDataSource }] = tableContext;
+  const [registerTable, { getDataSource, reload, setLoading }] = tableContext;
 
   watchEffect(() => {
     if (historyTable.value && getDataSource) {
@@ -159,6 +190,8 @@
       console.log('[ data ] >', data);
     }
   });
+
+  defineExpose({ setLoading })
 </script>
 
 <style scoped lang="less">

+ 24 - 6
src/views/vent/monitorManager/comment/MonitorTable.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="vent-table">
-    <BasicTable ref="ventTableRef" @register="registerTable" :rowSelection="props.isShowSelect ? rowSelection: undefined" :loading="loading">
+    <BasicTable ref="ventTableRef" @register="registerTable" :rowSelection="props.isShowSelect ? rowSelection: undefined">
       <template #tableTitle>
         <div></div>
       </template>
@@ -65,7 +65,7 @@
   });
   const emits = defineEmits(['selectRow']);
   const dataTableSource = ref<any[]>([]);
-  const loading = ref(true);
+  // const loading = ref(true);
 
   const ventTableRef = ref();
 
@@ -77,7 +77,7 @@
       return props.dataSource;
     },
     (newVal, oldVal) => {
-      if (oldVal.length < 1 && newVal.length > 0) {
+      if (oldVal && newVal && oldVal.length < 1 && newVal.length > 0) {
         // 第一次
         setSelectedRowKeys([newVal[0].deviceID]);
       }
@@ -86,7 +86,10 @@
         list.push(toRaw(item));
       });
       dataTableSource.value = list;
-      loading.value = false;
+      if(ventTableRef.value) setLoading(false)
+    },
+    {
+      immediate: true
     }
   );
    watch(
@@ -94,7 +97,20 @@
       return props.columnsType;
     },
     (newVal) => {
-      columns.value = getTableHeaderColumns(newVal);
+      const column =  getTableHeaderColumns(newVal)
+      if(column && column.length < 1){
+        const arr = newVal.split('_')
+        const columnKey =  arr.reduce((prev, cur, index) => {
+          if(index !== arr.length - 2){
+            return prev + '_' + cur
+          }else {
+            return prev
+          }
+        })
+        columns.value = getTableHeaderColumns(arr[0]+'_monitor');
+      }else{
+        columns.value = column
+      }
     },
     {
       immediate: true
@@ -118,6 +134,7 @@
       scroll: props.scroll,
       rowKey: 'deviceID',
       // striped: true,
+      loading: true,
       actionColumn: {
         width: 180,
       },
@@ -133,7 +150,7 @@
   });
 
   //注册table数据
-  const [registerTable, { reload, setLoading, setSelectedRowKeys }, { rowSelection, selectedRowKeys }] = tableContext;
+  const [registerTable, { reload, setLoading, setSelectedRowKeys }, { rowSelection, selectedRowKeys,  }] = tableContext;
   watch(
     selectedRowKeys,
     (oldKeys, newKeys) => {
@@ -148,6 +165,7 @@
   defineExpose({
     doRequest,
     setSelectedRowKeys,
+    setLoading
   });
 
   onMounted(() => {

+ 1 - 1
src/views/vent/monitorManager/deviceMonitor/device.api.ts

@@ -3,7 +3,7 @@ import { defHttp } from '/@/utils/http/axios';
 enum Api {
   list = '/monitor/device',
   baseList = '/safety/ventanalyDeviceInfo/list',
-  deviceTypeList = '/sys/dict/DeviceKind/query',
+  deviceTypeList = '/safety/ventanalyDeviceInfo/DeviceKind/query',
 }
 /**
  * 列表接口

+ 454 - 71
src/views/vent/monitorManager/deviceMonitor/index.vue

@@ -1,22 +1,41 @@
 <template>
-  <div class="scene-box">
+  <div class="scene-box" v-if="routerParam !== 'home'">
+  <!-- <div class="scene-box"> -->
     <div class="device-header">智能通风管控系统</div>
-    <div class="device-select-box">
-      <a-tree
-        :show-line="true"
-        :tree-data="treeData"
-        @select="onSelect"
-      >
-      </a-tree>
+    <div class="select-node" :class="{ 'node-select-show': !treeShow, 'node-select-hide': treeShow, }">
+      <SvgIcon class="is-expansion-icon put-away-icon" size="38" name="expansion" @click="showTree(true)" />
+      <span class="title">{{ treeNodeTitle }}</span>
+    </div>
+    <div class="device-select" :class="{ 'device-select-show': treeShow, 'device-select-hide': !treeShow, }">
+      <SvgIcon class="is-expansion-icon expansion-icon" size="28" name="put-away" @click="showTree(false)" />
+      <div class="device-select-box">
+        <a-tree
+          :show-line="true"
+          :tree-data="treeData"
+          v-model:selectedKeys="selectedKeys"
+          v-model:expandedKeys="expandedKeys"
+          @select="onSelect"
+        >
+        </a-tree>
+      </div>  
     </div>
     <div class="bottom-tabs-box" @mousedown="setDivHeight" id="monitorBox">
+      <div class="to-small" @click="toHome"></div>
+      <div class="device-button-group" v-if="deviceList.length > 0">
+        <div class="device-button" :class="{ 'device-active': deviceActive == device.deviceType }" v-for="(device, index) in deviceList" :key="index" @click="monitorChange(index)">{{ device.deviceName }}</div>
+        <div class="enter-detail" @click="goDetail()">
+          <send-outlined />
+          {{ treeNodeTitle }}详情
+        </div>
+      </div>
       <a-tabs class="tabs-box" v-model:activeKey="activeKey" @change="tabChange" >
         <a-tab-pane key="1" tab="实时监测">
-          <template v-if="deviceType == 'fan'">
+          <template v-if="deviceType == 'fan' && activeKey == '1'">
             <GroupMonitorTable :dataSource="dataSource" :columnsType="`${deviceType}_monitor`" />
           </template>
-          <template v-else>
+          <template v-else-if = "activeKey == '1'">
             <MonitorTable
+              ref="monitorTable"
               :columnsType="`${deviceType}_monitor`"
               :dataSource="dataSource"
               design-scope="device_monitor"
@@ -43,113 +62,180 @@
         </a-tab-pane>
         <a-tab-pane key="2" tab="历史数据">
           <div class="tab-item">
-            <HistoryTable :columns-type="`${deviceType}_history`" :device-type="deviceType" :device-list-api="getDeviceList.bind(null, { devicekind : deviceType})" designScope="device-history" />
+            <HistoryTable ref="historyTable" v-if="activeKey == '2'" :sysId="systemID" :columns-type="`${deviceType}`" :device-type="deviceType" :device-list-api="getDeviceList.bind(null, { strtype : deviceType, sysId: systemID })" designScope="device-history" />
           </div>
         </a-tab-pane>
         <a-tab-pane key="3" tab="报警历史">
           <div class="tab-item">
-            <AlarmHistoryTable columns-type="alarm_history" :device-type="deviceType" :device-list-api="getDeviceList.bind(null, { devicekind: deviceType })" designScope="alarm-history" />
+            <AlarmHistoryTable ref="alarmHistoryTable" v-if="activeKey == '3'" :sysId="systemID" columns-type="alarm" :device-type="deviceType" :device-list-api="getDeviceList.bind(null, { strtype: deviceType, sysId: systemID })" designScope="alarm-history" />
           </div>
         </a-tab-pane>
         <a-tab-pane key="4" tab="操作历史">
           <div class="tab-item">
-            <HandlerHistoryTable columns-type="operatorhistory" :device-type="deviceType"  :device-list-api="getDeviceList.bind(null, { devicekind: deviceType })" designScope="operator-history" />
-          </div>
+            <HandlerHistoryTable ref="handlerHistoryTable" v-if="activeKey == '4'" :sysId="systemID" columns-type="operatorhistory" :device-type="deviceType"  :device-list-api="getDeviceList.bind(null, { strtype: deviceType, sysId: systemID  })" designScope="operator-history" />
+          </div> 
         </a-tab-pane>
       </a-tabs>
     </div>
-    <component :is="currentModal" v-model:visible="modalVisible" :dataSource="dataSource" :activeID="activeID" />
+    <component v-if="modalVisible" :is="currentModal" v-model:visible="modalVisible" :dataSource="dataSource" :activeID="activeID" />
   </div>
 </template>
 <script setup lang="ts">
   import {ref, onMounted, onUnmounted, ComponentOptions, shallowRef } from 'vue'
+  import { SendOutlined } from '@ant-design/icons-vue';
   import { list, getDeviceList, getDeviceTypeList } from './device.api'
   import AlarmHistoryTable from '../comment/AlarmHistoryTable.vue';
   import HistoryTable from '../comment/HistoryTable.vue';
   import HandlerHistoryTable from '../comment/HandlerHistoryTable.vue';
   import MonitorTable from '../comment/MonitorTable.vue';
   import GroupMonitorTable from '../comment/GroupMonitorTable.vue';
-  import type { TreeProps } from 'ant-design-vue';
+  import { TreeProps, message } from 'ant-design-vue';
   import { TableAction } from '/@/components/Table';
   import FiberModal from './modal/fiber.modal.vue';
   import DustModal from './modal/dust.modal.vue'
+  import { SvgIcon } from '/@/components/Icon';
+  import { getActions } from '/@/qiankun/state';
+  import { useRouter } from 'vue-router';
+  
+
+  type DeviceType = { deviceType: string, deviceName: string, datalist: any[] };
+
+  const router = useRouter()
+
+  const actions = getActions();
+  actions.setGlobalState({ pageObj: { pageType: 'home' } });
 
+  const monitorTable = ref()
+  const historyTable = ref()
+  const alarmHistoryTable = ref()
+  const handlerHistoryTable = ref()
+
+  const routerParam = ref('home') // 默认进来时首页
   // 模态框
-  const currentModal = shallowRef<Nullable<ComponentOptions>>(null);
-  const modalVisible = ref<Boolean>(false);
+  const currentModal = shallowRef<Nullable<ComponentOptions>>(null); //模态框
+  const modalVisible = ref<Boolean>(false); // 模态框是否可见
 
   //
-  const drawerHeight = ref(700) 
-  
-  const activeKey = ref('1');
-  const dataSource = shallowRef([])
-  const activeID = ref('')
-  const deviceType = ref('window')
+  const drawerHeight = ref(240) // 监测框最小高度
+  const treeShow = ref(true) //是否显示树形菜单
+  const treeNodeTitle = ref('') // 选中的树形标题
+
+  const deviceList = ref<DeviceType[]>([])
+  const deviceActive = ref('')
+  const activeKey = ref('1'); // tab key
+  const dataSource = shallowRef([]) // 实时监测数据
+  const activeID = ref('') // 打开详情modal时监测的设备id
+  const deviceType = ref('') // 监测设备类型
+  const systemType = ref('')
+  const systemID = ref('') // 系统监测时,系统id
+  const selectedKeys = ref<string[]>([]);
+  const expandedKeys = ref<string[]>([]);
   const scroll = ref({
     y: drawerHeight.value - 100
   })
-
   const treeData = ref<TreeProps['treeData']>([]);
-  const onSelect: TreeProps['onSelect'] = (selectedKeys) => {
-    // console.log('selected', selectedKeys, info);
-    // info.node.title
-    deviceType.value = selectedKeys[0]
 
+  //树形菜单选择事件
+  const onSelect: TreeProps['onSelect'] = async(keys, e) => {
+    deviceType.value = ''
+    systemID.value = ''
+    deviceList.value = []
+    if(e.node.parent && (e.node.parent.node.type.toString()).startsWith('sys')){
+      systemType.value = e.node.parent.node.type
+      deviceType.value = e.node.parent.node.type
+      systemID.value = e.node.type
+      // 传递工作面id信息,用于定位
+      actions.setGlobalState({ locationObj: { pageType: deviceType.value ,deviceid: systemID.value }, pageObj: null });
+    }else{
+      systemType.value = e.node.type
+      deviceType.value = e.node.type
+    }
+    selectedKeys.values = keys
+    treeNodeTitle.value = e.node.title
+
+    if (timer) clearInterval(timer);
+    await getDataSource()
+    getMonitor() 
   };
   
   function tabChange(activeKeyVal) {
     activeKey.value = activeKeyVal;
   };
+
+  function showTree(flag) {
+    treeShow.value = flag
+  }
   
   async function getDeviceType () {
     const result = await getDeviceTypeList({})
     if (result.length > 0) {
       const dataSource = <TreeProps['treeData']>[]
-      const getData = (resultList, dataSourceList) => {
-        resultList.forEach((item) => {
-
+      let key = '0'
+      const getData = (resultList, dataSourceList, keyVal) => {
+        resultList.forEach((item, index) => {
           if (item.children && item.children.length > 0) {
-            const children = getData(item.children, [])
+            const children = getData(item.children, [], `${keyVal}-${index}`)
             dataSourceList.push({
               children: children,
               title: item.itemText,
-              key: item.itemValue,
+              key: `${keyVal}-${index}`,
+              type: item.itemValue,
             });
             
           } else {
             dataSourceList.push({
+              children: [],
               title: item.itemText,
-              key: item.itemValue,
-              children: []
+              key: `${keyVal}-${index}`,
+              type: item.itemValue,
             });
           }
         });
         return dataSourceList
       }
-      treeData.value = getData(result, dataSource)
+      console.log('树形菜单-------------->', treeData.value)
+      treeData.value = getData(result, dataSource, key)
+      
     }
   }
 
   // https获取监测数据
   let timer: null | NodeJS.Timeout = null;
   function getMonitor() {
-    if (Object.prototype.toString.call(timer) === '[object Null]') {
-      timer = setTimeout(async () => {
-        const res = await list({ devicetype: deviceType.value, pagetype: 'normal' });
-        debugger
+    timer = setInterval(async () => {
+      await getDataSource()
+    }, 1000);
+  };
+
+  async function getDataSource() {
+    if (deviceType.value.startsWith('sys') && systemID.value) {
+      const res = await list({ devicetype: 'sys', systemID: systemID.value });
+      const result = res.msgTxt;
+      const deviceArr = <DeviceType[]>[]
+      result.forEach(item => {
+        const data = item['datalist'].filter((data: any) => {
+          const readData = data.readData;
+          return Object.assign(data, readData);
+        })
+        if (item.type != 'sys') {
+          deviceArr.unshift({ deviceType: item.type, deviceName: item['typeName'] ? item['typeName'] : item['datalist'][0]['typeName'], datalist: data })
+        }
+      })
+      console.log('关联设备列表', deviceArr)
+      deviceList.value = deviceArr
+      deviceActive.value = deviceArr[1].deviceType
+      monitorChange(1)
+    } else {
+      const res = await list({ devicetype: deviceType.value, pagetype: 'normal' })
+      if (res.msgTxt[0]) {
         dataSource.value = res.msgTxt[0].datalist || [];
         dataSource.value.filter((data: any) => {
           const readData = data.readData;
           return Object.assign(data, readData);
         });
-
-        if (timer) {
-          timer = null;
-        }
-        getMonitor();
-      }, 1000);
+      }
     }
-  };
+  }
 
   function setDivHeight(e: MouseEvent) {
     const divObject = document.getElementById('monitorBox') as HTMLElement
@@ -160,10 +246,10 @@
       res.preventDefault()
       const distY = Math.abs(res.clientY - startY)
       if(res.clientY > startY){
-        if(divHeight - distY >= 300){
+        if(divHeight - distY >= 240){
           drawerHeight.value = divHeight - distY
         }else{
-          drawerHeight.value = 300
+          drawerHeight.value = 240
         }
       }
       if(res.clientY < startY){
@@ -182,31 +268,126 @@
       }
     }
   }
-
-  function goLocation() {
-
+  // 定位
+  function goLocation(record) {
+    actions.setGlobalState({ locationId: record.deviceID, locationObj: null, pageObj: null });
   }
-  function goDetail(record){
-    if(deviceType.value.startsWith('fiber')){
-      activeID.value = record.deviceID
-      currentModal.value = FiberModal
-      modalVisible.value = true;
+  // 详情
+  function goDetail(record?){
+
+    if(record){
+      if (deviceType.value.startsWith('fiber')) {
+        activeID.value = record.deviceID
+        currentModal.value = FiberModal
+        modalVisible.value = true;
+      } else if (deviceType.value.startsWith('dusting')) {
+        activeID.value = record.deviceID
+        currentModal.value = DustModal
+        modalVisible.value = true;
+      } else if (deviceType.value.indexOf("gate") != -1) {
+        const newPage = router.resolve({path: '/monitorChannel/monitor-gate'})
+        window.open(newPage.href, '_blank')
+      } else if (deviceType.value.indexOf("window") != -1) {
+        const newPage = router.resolve({ path: '/monitorChannel/monitor-window' })
+        window.open(newPage.href, '_blank')
+      } else if (deviceType.value.indexOf("windrect") != -1) {
+        const newPage = router.resolve({ path: '/monitorChannel/monitor-windrect' })
+        window.open(newPage.href, '_blank')
+      } else if (deviceType.value.indexOf("fanmain") != -1) {
+        const newPage = router.resolve({ path: '/monitorChannel/monitor-fan-main' })
+        window.open(newPage.href, '_blank')
+      } else if (deviceType.value.indexOf("fanlocal") != -1) {
+        const newPage = router.resolve({ path: '/monitorChannel/monitor-fan-local' })
+        window.open(newPage.href, '_blank')
+      } else {
+        message.info('待开发。。。')
+      }
+    }else{
+      if (systemType.value.indexOf("sys_dongshi") != -1) {
+        const newPage = router.resolve({ path: '/chamber-home', query: {id: systemID.value }})
+        window.open(newPage.href, '_blank')
+      }else{
+        message.info('待开发。。。')
+      }
     }
-    if (deviceType.value.startsWith('dusting')) {
-      activeID.value = record.deviceID
-      currentModal.value = DustModal
-      modalVisible.value = true;
+    
+  }
+  
+  function toHome() {
+    deviceList.value = []
+    actions.setGlobalState({ pageObj: { pageType: 'home'} });
+  }
+  // 遍历树形菜单
+  async function findTreeDataValue(data:[], obj) {
+    const findDeviceType = (data: [], obj) => {
+      let type = ''
+      if (obj.deviceid) {
+        type = obj.deviceid
+      } else {
+        type = obj.deviceType
+      }
+      data.find((item: any) => {
+        if (item.children.length > 0) {
+          findDeviceType(item.children, obj)
+        }
+        if (item.type == type) {
+          deviceType.value = obj.deviceid ? 'sys' : item.type
+          if (obj.deviceid) systemID.value = obj.deviceid
+          selectedKeys.value = [item.key]
+          expandedKeys.value = [item.key]
+          treeNodeTitle.value = item.title
+        }
+      })
     }
+    findDeviceType(data, obj)
+    if (timer) clearInterval(timer);
+    await getDataSource()
+    getMonitor()
   }
 
+  function monitorChange(index) {
+    dataSource.value = []
+    deviceActive.value = deviceType.value = deviceList.value[index].deviceType
+
+    if (activeKey.value == '1' && monitorTable.value) {
+      monitorTable.value.setLoading(true)
+      dataSource.value = deviceList.value[index].datalist
+    }
+    if(activeKey.value == '2' && historyTable.value){
+      historyTable.value.setLoading(true)
+    }
+    if (activeKey.value == '3' && alarmHistoryTable.value) {
+      alarmHistoryTable.value.setLoading(true)
+    }
+    if (activeKey.value == '4' && handlerHistoryTable.value) {
+      handlerHistoryTable.value.setLoading(true)
+    }
+  }
+  
   onMounted(async() => {
+    actions.onGlobalStateChange(async(newState, prev) => {
+      for (const key in newState) {
+        if (key === 'pageObj') {
+          const pageObj = newState[key]
+          if (pageObj) {
+            routerParam.value = pageObj.pageType
+            if (pageObj.deviceid) {
+              await findTreeDataValue(treeData.value, { deviceid: pageObj.deviceid })
+            } else {
+              await findTreeDataValue(treeData.value, { deviceType: pageObj.pageType })
+            }
+          }
+        }
+      }
+    })
     await getDeviceType()
-    getMonitor()
+    // await getDataSource()
+    // getMonitor()
   })
+  
   onUnmounted(() => {
     if (timer) {
-      clearTimeout(timer);
-      timer = undefined;
+      clearInterval(timer);
     }
   })
 
@@ -226,15 +407,81 @@
     font-weight: 600;
     z-index: -1;
   }
-  .device-select-box{
+  .select-node{
+    position: fixed;
+    top: 60px;
+    left: 10px;
+    color: #fff;
+    display: flex;
+    justify-content: center;
+    font-size: 24px;
+    .title{
+      margin-left: 10px;
+    }
+  }
+  .device-select{
     width: 250px;
     height: 500px;
+    background: url('/@/assets/images/vent/home/tree-bg.png') no-repeat;
     position: fixed;
-    top: 55px;
-    left: 0;
-    color: #fff;
+    top: 60px;
+    left: 10px;
+    background-size: contain;
     pointer-events: auto;
-    overflow-y: auto;
+    padding: 20px 10px 30px 10px;
+    .expansion-icon{
+      position: absolute;
+      left: 190px;
+      top: 25px;
+    }
+  }
+  .is-expansion-icon{
+    background: url('/@/assets/images/vent/home/tree-icon-bg.png') no-repeat;
+    background-size: contain;
+    padding: 5px;
+    pointer-events: auto;
+    z-index: 999;
+    &:hover{
+      background: url('/@/assets/images/vent/home/tree-icon-hover-bg.png') no-repeat;
+      background-size: contain;
+    }
+  }
+  .put-away-icon{
+    display: inline-block;
+  }
+  .device-select-show{
+    left: 10px;
+    animation-name: treeShow;
+    /* 持续时间 */
+    animation-duration: 1s;
+    transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) .5s;
+  }
+  .device-select-hide{
+    left: -250px;
+    animation-name: treeHide;
+    /* 持续时间 */
+    animation-duration: 1s;
+    transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) .5s;
+  }
+  .node-select-show{
+    left: 10px;
+    animation-name: treeShow;
+    /* 持续时间 */
+    animation-duration: 1s;
+    transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) .5s;
+  }
+  .node-select-hide{
+    left: -400px;
+    animation-name: treeHide;
+    /* 持续时间 */
+    animation-duration: 1s;
+    transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) .5s;
+  }
+  .device-select-box{
+    width: 208px;
+    height: 450px;
+    overflow-y: auto;    
+    color: #fff;    
     :deep(.zxm-tree){
       background: transparent !important;
       color: #fff !important;
@@ -245,7 +492,7 @@
         background-color: #00b1c8;
       }
       .zxm-tree-node-content-wrapper:hover{
-        background-color: #00b1c8;
+        background-color: #00b1c855;
       }
       input{
         height: 0px !important;
@@ -255,12 +502,148 @@
       -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
       border-radius: 10px;
       background: #ededed22;
+      height: 100px;
     }
     &::-webkit-scrollbar-thumb {
       -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
       background: #4288A444;
     }
   }
+  .bottom-tabs-box{
+    
+    position: relative;
+    .to-small{
+      width: 60px;
+      height: 60px;
+      background: url('/@/assets/images/vent/home/tosmall.png') no-repeat center;
+      background-size: auto;
+      position: absolute;
+      top: -65px;
+      right: 30px;
+      border-radius: 10px;
+      padding: 8px;
+      backdrop-filter: blur(10px);
+      background-color: rgba(0, 58, 128, 0.418);
+      &:hover{
+        background-color: rgba(42, 85, 138, 0.418);
+      }
+    }
+    .device-button-group{
+      position: absolute;
+      top: -30px;
+      left: 30px;
+      display: flex;
+      width: 100%;
+      
+      .device-button{
+        padding: 4px 15px;
+        position: relative;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        font-size: 14px;
+        
+        color: #fff;
+        cursor: pointer;
+        margin: 0 3px;
+
+        &::before{
+          content: '';
+          position: absolute;
+          top: 0;
+          right: 0;
+          bottom: 0;
+          left: 0;
+          border: 1px solid #6176AF;
+          transform: skewX(-38deg);
+          background-color: rgba(0, 77, 103,85%);
+          z-index: -1;
+        }
+      }
+      .device-active{
+        // color: #0efcff;
+        &::before{
+          border-color: #0efcff;
+          box-shadow: 1px 1px 3px 1px #0efcff inset;
+        }
+      }
+    }
+    .enter-detail{
+      color: #fff;
+      cursor: pointer;
+      position: absolute;
+      right: 150px;
+      top: -10px;
+      padding: 5px;
+      // border: 1px transparent solid;
+      border-radius: 5px;
+      margin-left: 8px;
+      margin-right: 8px;
+      width: auto;
+      // height: 40px;
+      // border: 1px solid #65dbea;
+      height: 33px !important;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      color: #fff;
+      padding: 5px 15px 5px 15px;
+      cursor: pointer;
+      &:hover {
+        background: linear-gradient(#2cd1ff55, #1eb0ff55);
+      }
+      &::before {
+        width: calc(100% - 6px);
+        height: 27px;
+        content: '';
+        position: absolute;
+        top: 3px;
+        right: 0;
+        left: 3px;
+        bottom: 0;
+        z-index: -1;
+        border-radius: inherit; /*important*/
+        background: linear-gradient(#1fa6cb, #127cb5);
+      }
+      &::after {
+        width: calc(100% + 32px);
+        height: 10px;
+        content: '';
+        position: absolute;
+        top: 35px;
+        right: 0;
+        left: -16px;
+        bottom: 0;
+        z-index: -1;
+        border-radius: inherit; /*important*/
+        background: url('/@/assets/images/vent/short-light.png') no-repeat;
+        background-position: center;
+        background-size: 100%;
+        z-index: 999;
+      }
+    }
+  }
+  @keyframes treeShow {
+    0% {
+      left: -400px;
+      opacity: 0;
+    }
+    100% {
+      left: 10px;
+      opacity: 1;
+    }
+  }
+  @keyframes treeHide {
+    0% {
+      left: 10px;
+      opacity: 1;
+    }
+    100% {
+      left: -400px;
+      opacity: 0;
+    }
+  }
+  
   :deep(.@{ventSpace}-tabs-tabpane-active) {
     overflow: auto;
     // height: 100%;

+ 126 - 52
src/views/vent/monitorManager/deviceMonitor/modal/dust.modal.vue

@@ -10,67 +10,78 @@
         <div class="right-top">
           <div class="top-item">
             <div class="icon">
-              <SvgIcon class="icon-style max-temperature" size="38" name="max-temperature.svg" />
+              <SvgIcon class="icon-style max-temperature" size="30" name="hd-wd" />
             </div>
             <div class="item-container">
               <div class="title">巷道温度</div>
-              <div class="value">{{ dustMonitor.temperature }} <span>℃</span> </div>
+              <div class="value"><span class="data">{{ dustMonitor.temperature }}</span> <span>℃</span> </div>
             </div>
           </div>
           <div class="top-item">
             <div class="icon">
-              <SvgIcon class="icon-style min-temperature" size="38" name="min-temperature" />
+              <SvgIcon class="icon-style min-temperature" size="30" name="dust-nd" />
             </div>
             <div class="item-container">
               <div class="title">粉尘浓度</div>
-              <div class="value">{{ dustMonitor.humidity }} <span>mg/m³</span></div>
+              <div class="value"><span class="data">{{ dustMonitor.humidity }}</span> <span>mg/m³</span></div>
             </div>
           </div>
           <div class="top-item">
             <div class="icon">
-              <SvgIcon class="icon-style aveg-temperature" size="38" name="aveg-temperature" />
+              <SvgIcon class="icon-style aveg-temperature" size="30" name="pw-sy" />
             </div>
             <div class="item-container">
               <div class="title">喷雾水压</div>
-              <div class="value">{{ dustMonitor.waterPressure }} <span>MPa</span></div>
+              <div class="value"><span class="data">{{ dustMonitor.waterPressure }}</span> <span>MPa</span></div>
             </div>
           </div>
           <div class="top-item warning-box">
             <div class="icon">
-              <SvgIcon class="icon-style" size="38" name="risk-level" />
+              <SvgIcon class="icon-style" size="30" name="pw-zz" />
             </div>
             <div class="item-container">
               <div class="title">喷雾装置</div>
               <div class="warning-value">低风险</div>
             </div>
           </div>
+          <div class="top-item warning-box">
+            <div class="icon">
+              <SvgIcon class="icon-style" size="40" name="kg" />
+            </div>
+            <div class="item-container">
+              <div class="title">喷雾开关</div>
+              <div class="warning-value">
+                <a-switch checked-children="开" un-checked-children="关" v-model:checked="dustSwitch" />
+              </div>
+            </div>
+          </div>
         </div>
         <div class="right-center">
           <span class="base-title">粉尘实时监测</span>
           <div class="dust-group">
             <div class="dust-item">
-              <div>粉尘浓度(实时)</div>
-              <div>{{ dustMonitor.breathWeighted }}</div>
+              <div class="title">粉尘浓度(实时)</div>
+              <div class="value">{{ dustMonitor.breathWeighted }}<span>mg/m³</span></div>
             </div>
             <div class="dust-item">
-              <div>总尘浓度(时间加权)</div>
-              <div>{{ dustMonitor.totalDust }}</div>
+              <div class="title">总尘浓度(时间加权)</div>
+              <div class="value">{{ dustMonitor.totalDust }}<span>mg/m³</span></div>
             </div>
             <div class="dust-item">
-              <div>呼吸加权容许浓度</div>
-              <div>{{ dustMonitor.breathWeighted }}</div>
+              <div class="title">呼吸加权容许浓度</div>
+              <div class="value">{{ dustMonitor.breathWeighted }}<span>mg/m³</span></div>
             </div>
             <div class="dust-item">
-              <div>爆炸浓度(煤尘)</div>
-              <div>{{ dustMonitor.dustval }}</div>
+              <div class="title">爆炸浓度(煤尘)</div>
+              <div class="value">{{ dustMonitor.dustval }}<span>mg/m³</span></div>
             </div>
           </div> 
         </div>
         <div class="right-bottom">
-          <span class="base-title">测点监测曲线</span>
+          <span class="base-title">粉尘预测曲线</span>
           <div class="echarts-box">
             <BarAndLine
-              xAxisPropType="pos"
+              xAxisPropType="readTime"
               :dataSource="posList"
               height="100%"
               :chartsColumns="chartsColumns"
@@ -104,6 +115,7 @@ export default defineComponent({
     const deviceList = ref<any[]>([])
     const posList = ref<any[]>([])
     const dustMonitor = shallowRef({})
+    const dustSwitch = ref(false)
 
     const echatsOption = {
       grid: {
@@ -120,16 +132,40 @@ export default defineComponent({
 
     const chartsColumns = [
       {
-        legend: '测点温度',
-        seriesName: '()',
-        ymax: 200,
-        yname: '',
+        legend: '粉尘平均浓度',
+        seriesName: '(mg/m³)',
+        ymax: 5,
+        yname: 'mg/m³',
         linetype: 'line',
         yaxispos: 'left',
         color: '#FDB146',
         sort: 1,
         xRotate: 0,
-        dataIndex: 'value',
+        dataIndex: 'hourAvg',
+      },
+      {
+        legend: '粉尘最大浓度',
+        seriesName: '(mg/m³)',
+        ymax: 5,
+        yname: 'mg/m³',
+        linetype: 'line',
+        yaxispos: 'left',
+        color: '#EE6666',
+        sort: 1,
+        xRotate: 0,
+        dataIndex: 'hourMax',
+      },
+      {
+        legend: '粉尘最小浓度',
+        seriesName: '(mg/m³)',
+        ymax: 5,
+        yname: 'mg/m³',
+        linetype: 'line',
+        yaxispos: 'left',
+        color: '#9BCB75',
+        sort: 1,
+        xRotate: 0,
+        dataIndex: 'hourMin',
       },
     ]
 
@@ -217,14 +253,19 @@ export default defineComponent({
       newDataSource?.forEach((item:any, index) => {
         if((!activeDeviceID.value && index == 0) || item.deviceID === activeDeviceID.value){
           activeDeviceID.value = item.deviceID
-          // const list = JSON.parse(item.readData.fibreTemperature)
-          // if(list.length > 0) posList.value = list
+          const list = item.summaryHour
+          list.filter(data => {
+            const date = new Date();     //1. js获取当前时间
+            const min = date.getMinutes();  //2. 获取当前分钟
+            return Object.assign(data, data.dustval, { readTime: (dayjs(date.setMinutes(min + 10))).format('YYYY-MM-DD HH:mm:ss') })
+          })
+          if(list.length > 0) posList.value = list
           dustMonitor.value = item.readData
         }
       })
     })
 
-    return { register, model: modelRef, currentTime, handleVisibleChange, selectDevice, deviceList, activeDeviceID, dustMonitor, echatsOption, posList, chartsColumns, columns, warningConfig };
+    return { register, model: modelRef, currentTime, dustSwitch, handleVisibleChange, selectDevice, deviceList, activeDeviceID, dustMonitor, echatsOption, posList, chartsColumns, columns, warningConfig };
   },
   
 });
@@ -232,7 +273,7 @@ export default defineComponent({
 <style lang="less" scoped>
   .fiber-modal{
     width: 100%;
-    height: 650px;
+    height: 600px;
     display: flex;
     flex-direction: row;
     justify-content: space-between;
@@ -290,51 +331,57 @@ export default defineComponent({
         display: flex;
         flex-direction: row;
         justify-content: space-between;
-        margin-bottom: 10px;
+        margin-bottom: 30px;
+        padding: 0 10px;
         .top-item{
-          width: 200px;
-          height: 80px;
+          width: 155px;
+          height: 60px;
           display: flex;
           flex-direction: row;
           justify-content: center;
-          border: 1px solid rgba(25,237,255,.4);
-          box-shadow: inset 0 0 10px rgba(0,197,255,.6);
-          background: rgba(0,0,0,.06666666666666667);
+          align-items: center;
+          background: url('/@/assets/images/vent/model_image/dust-monitor-bg.png') no-repeat;
           padding-top: 16px;
           .icon{
-            margin-right: 10px;
-            margin-top: 5px;
-            color: #FDB146;
+            width: 58px;
+            height: 60px;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            position: relative;
+            top: -8px;
           }
           .item-container{
             width: 100px;
             display: flex;
             flex-direction: column;
-            justify-content: center;
+            // justify-content: start;
             div{
-              text-align: center;
+              padding-left: 8px;
             }
             .title{
-              font-size: 18px;
+              font-size: 14px;
+              margin-bottom: 8px;
             }
             .value{
-              text-shadow: 0 0 25px #00fbfe;
-              background: linear-gradient( 0deg,#45d3fd, #45d3fd, #61ddb1,#61ddb1);
-              font-style: normal;
-              background-size: cover;
-              font-family: electronicFont;
-              font-size: 30px;
-              -webkit-background-clip: text;
-              background-clip: text;
-              -webkit-text-fill-color: transparent;
               position: relative;
+              width: 110px;
               top: -8px;
+              .data{
+                display: inline-block;
+                width: 50px;
+                font-family: douyuFont;
+                font-weight: 600;
+                font-size: 14px;
+                -webkit-background-clip: text;
+                background-clip: text;
+                color: #28DCE4;
+              }
               span{
                 font-family: Arial, Helvetica, sans-serif;
-                font-size: 18px;
-                color: aliceblue;
+                font-size: 14px;
+                color: #ffffffdd;
               }
-              
             }
             
           }
@@ -347,7 +394,11 @@ export default defineComponent({
               color: #FDB146;
             }
           }
+          .title{
+            padding-top: 0px;
+          }
           .warning-value{
+            font-family: electronicFont;
             font-size: 18px;
             color: #61ddb1;
           }
@@ -362,7 +413,30 @@ export default defineComponent({
           .dust-item{
             width: 238px;
             height: 148px;
-            background: url('/@/assets/images/vent/model_image/dust-bg.png');
+            background: url('/@/assets/images/vent/model_image/dust-bg.png') no-repeat;
+            scale: 0.9;
+            .title{
+              position: absolute;
+              top: 80px;
+              left: 70px;
+              font-size: 16px;
+            }
+            .value{
+              position: absolute;
+              top: 50px;
+              left: 50px;
+              font-family: 'douyuFont';
+              color: #20dbfd;
+              text-shadow: 0 0 25px #00d8ff;
+              font-size: 18px;
+              font-weight: bolder;
+              span{
+                font-family: Arial, Helvetica, sans-serif;
+                font-size: 16px;
+                color: aliceblue;
+                margin-left: 8px;
+              }
+            }
           }
         }
       }
@@ -370,7 +444,7 @@ export default defineComponent({
         margin-top: 20px;
         .echarts-box{
           width: 100%;
-          height: 230px;
+          height: 270px;
         }
       }
 

+ 5 - 3
src/views/vent/monitorManager/deviceMonitor/modal/fiber.modal.vue

@@ -10,7 +10,7 @@
         <div class="right-top">
           <div class="top-item">
             <div class="icon">
-              <SvgIcon class="icon-style max-temperature" size="38" name="max-temperature.svg" />
+              <SvgIcon class="icon-style max-temperature" size="38" name="max-temperature" />
             </div>
             <div class="item-container">
               <div class="title">最高温度</div>
@@ -227,8 +227,10 @@ export default defineComponent({
       newDataSource?.forEach((item:any, index) => {
         if((!activeDeviceID.value && index == 0) || item.deviceID === activeDeviceID.value){
           activeDeviceID.value = item.deviceID
-          const list = JSON.parse(item.readData.fibreTemperature)
-          if(list.length > 0) posList.value = list
+          if(item.readData.fibreTemperature){
+            const list = JSON.parse(item.readData.fibreTemperature)
+            if (list.length > 0) posList.value = list
+          }
           posMonitor.value = item.readData
         }
       })

+ 2 - 2
src/views/vent/monitorManager/fanLocalMonitor/index.vue

@@ -91,12 +91,12 @@
         </a-tab-pane>
         <a-tab-pane key="3" tab="历史数据">
           <div class="tab-item">
-            <HistoryTable columns-type="fanlocal_history" device-type="fanlocal" :device-list-api="baseList" designScope="fanlocal-history" />
+            <HistoryTable columns-type="fanlocal" device-type="fanlocal" :device-list-api="baseList" designScope="fanlocal-history" />
           </div>
         </a-tab-pane>
         <a-tab-pane key="4" tab="报警历史">
           <div class="tab-item">
-            <AlarmHistoryTable columns-type="alarm_history" device-type="fanlocal" :device-list-api="baseList" designScope="alarm-history" />
+            <AlarmHistoryTable columns-type="alarm" device-type="fanlocal" :device-list-api="baseList" designScope="alarm-history" />
           </div>
         </a-tab-pane>
         <a-tab-pane key="5" tab="操作历史">

+ 3 - 3
src/views/vent/monitorManager/fiberMonitor/fiber.ds.threejs.ts

@@ -5,9 +5,9 @@ import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
 import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js';
 import { GammaCorrectionShader } from 'three/examples/jsm/shaders/GammaCorrectionShader.js';
 import { CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
-import * as dat from 'dat.gui';
-const gui = new dat.GUI();
-gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
+// import * as dat from 'dat.gui';
+// const gui = new dat.GUI();
+// gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
 
 class GrottoFiber {
   model;

+ 2 - 2
src/views/vent/monitorManager/fiberMonitor/index.vue

@@ -69,13 +69,13 @@
         </a-tab-pane>
         <a-tab-pane key="3" tab="历史数据">
           <div class="tab-item">
-            <HistoryTable columns-type="fibre_history" device-type="fiber" :device-list-api="baseList"
+            <HistoryTable columns-type="fibre" device-type="fiber" :device-list-api="baseList"
               designScope="fiber-history" />
           </div>
         </a-tab-pane>
         <a-tab-pane key="4" tab="报警历史">
           <div class="tab-item">
-            <AlarmHistoryTable columns-type="alarm_history" device-type="fiber" :device-list-api="baseList"
+            <AlarmHistoryTable columns-type="alarm" device-type="fiber" :device-list-api="baseList"
               designScope="alarm-history" />
           </div>
         </a-tab-pane>

+ 2 - 2
src/views/vent/monitorManager/gateMonitor/index.vue

@@ -126,12 +126,12 @@
         </a-tab-pane>
         <a-tab-pane key="3" tab="历史数据">
           <div class="tab-item">
-            <HistoryTable columns-type="gate_history" device-type="gate" :device-list-api="getTableList" designScope="gate-history" />
+            <HistoryTable columns-type="gate" device-type="gate" :device-list-api="getTableList" designScope="gate-history" />
           </div>
         </a-tab-pane>
         <a-tab-pane key="4" tab="报警历史">
           <div class="tab-item">
-            <AlarmHistoryTable columns-type="alarm_history" device-type="gate" :device-list-api="getTableList" designScope="alarm-history" />
+            <AlarmHistoryTable columns-type="alarm" device-type="gate" :device-list-api="getTableList" designScope="alarm-history" />
           </div>
         </a-tab-pane>
         <a-tab-pane key="5" tab="操作历史">

+ 2 - 2
src/views/vent/monitorManager/mainFanMonitor/index.vue

@@ -164,12 +164,12 @@
         </a-tab-pane> -->
         <a-tab-pane key="3" tab="历史数据">
           <div class="tab-item">
-            <HistoryTable columns-type="fanmain_history" device-type="fanmain" :device-list-api="baseList" designScope="fanmain-history" />
+            <HistoryTable columns-type="fanmain" device-type="fanmain" :device-list-api="baseList" designScope="fanmain-history" />
           </div>
         </a-tab-pane>
         <a-tab-pane key="4" tab="报警历史">
           <div class="tab-item">
-            <AlarmHistoryTable columns-type="alarm_history" device-type="fanmain" :device-list-api="baseList" designScope="alarm-history" />
+            <AlarmHistoryTable columns-type="alarm" device-type="fanmain" :device-list-api="baseList" designScope="alarm-history" />
           </div>
         </a-tab-pane>
         <a-tab-pane key="5" tab="操作历史">

+ 0 - 87
src/views/vent/monitorManager/nitrogen/components/bottomMenu.vue

@@ -1,87 +0,0 @@
-<template>
-  <div class="bottom-btn-group">
-    <div v-for="item in navList" :key="item.pathName" class="vent-row-center btn-item" @click="setBtn('click', item)"
-      @mouseenter="setBtn('over', item)" @mouseleave="setBtn('leave', item)">
-      <dv-decoration11
-        :color="isBtnActive === item.pathName ? activeColors : item.isHover ? activeColors : noActiveColors"
-        style="width:200px;height:60px;">
-        {{ item.title }}
-      </dv-decoration11>
-    </div>
-  </div>
-</template>
-<script setup lang="ts">
-import { ref } from 'vue'
-import { useRouter } from 'vue-router'
-import { Decoration5, Decoration11 as DvDecoration11} from '@kjgl77/datav-vue3'
-
-const router = useRouter()
-const isBtnActive = ref('nitrogen_page_lh')
-const activeColors = ['#009BFF', '#28DBE4']
-const noActiveColors = ['#aaa', '#aaa']
-const navList = ref([
-  {
-    title: '监控界面',
-    pathName: 'nitrogen_page_lh',
-    isHover: true
-  },
-  {
-    title: '关键节点监测',
-    pathName: 'critical_node',
-    isHover: false
-  },
-  {
-    title: '实时曲线',
-    pathName: 'yfj_monitor_echarts',
-    isHover: false
-  },
-  {
-    title: '压风机历史记录',
-    pathName: 'yfj_history',
-    isHover: false
-  },
-  {
-    title: '操作历史记录',
-    pathName: 'yfj_handler_history',
-    isHover: false
-  },
-  {
-    title: '故障诊断历史记录',
-    pathName: 'yfj_faultRecord',
-    isHover: false
-  }
-])
-
-
-function setBtn(type, activeObj) {
-  if (type === 'over') {
-    activeObj.isHover = true
-  } else if (type === 'leave') {
-    activeObj.isHover = false
-  } else if (type === 'click') {
-    isBtnActive.value = activeObj.pathName
-  }
-  // router.push('')
-}
-
-</script>
-<style lang="less" scoped>
-.bottom-btn-group {
-    display: flex;
-    position: fixed;
-    width: calc(100% - 400px);
-    height: 100px;
-    bottom: 20px;
-    align-items: center;
-    justify-content: center;
-
-    .btn-item {
-      width: 200px;
-      height: 60px;
-      margin: 10px;
-      color: #fff;
-      cursor: pointer;
-      pointer-events: auto;
-    }
-  }
-</style>

+ 1 - 1
src/views/vent/monitorManager/nitrogen/components/nitrogenAlarmHistory.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="alarm-history">
-     <AlarmHistoryTable columns-type="alarm_history" device-type="pressurefan" :device-list-api="getTableList.bind(null, { devicekind: 'pressurefan' })" designScope="alarm-history" />
+     <AlarmHistoryTable columns-type="alarm" device-type="pressurefan" :device-list-api="getTableList.bind(null, { devicekind: 'pressurefan' })" designScope="alarm-history" />
   </div>
 </template>
 <script setup lang="ts">

+ 1 - 1
src/views/vent/monitorManager/nitrogen/components/nitrogenHistory.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="nitrogen-history">
-     <HistoryTable columns-type="pressurefan_history" device-type="pressurefan" :device-list-api="getTableList.bind(null, {devicekind :'pressurefan'})" designScope="pressurefan_history" />
+     <HistoryTable columns-type="pressurefan" device-type="pressurefan" :device-list-api="getTableList.bind(null, {devicekind :'pressurefan'})" designScope="pressurefan_history" />
   </div>
 </template>
 <script setup lang="ts">

+ 0 - 5
src/views/vent/monitorManager/nitrogen/components/nitrogenHome.vue

@@ -121,10 +121,6 @@
                 </div>
               </div>
             </div>
-            <!-- <div class="item" >
-              <assembly-flv ref="video" class="video-box" height="250px"  :url="videoUrl" :destroy="isDestroyVideo" ></assembly-flv>
-            </div> -->
-
           </div>
         </div>
       </div>
@@ -307,7 +303,6 @@ onUnmounted(() => {
       flex-direction: row;
       width: auto;
       margin-bottom: 3px;
-
       .monitor-val {
         color: #ffb700;
         display: flex;

+ 12 - 34
src/views/vent/monitorManager/nitrogen/index.vue

@@ -4,21 +4,12 @@
       <Decoration5 class="header-icon" :dur="2" :color="['#21437F', '#2CF7FE']" style="width:500px;height:40px;" />
       <div class="header-text">智能压风管控系统</div>
     </div>
-    <nitrogenHome v-if="isBtnActive == 'nitrogen_page'" />
-    <nitrogenEcharts v-if="isBtnActive == 'yfj_monitor_echarts'"/>
-    <nitrogenHistory v-if="isBtnActive == 'yfj_history'"/>
-    <nitrogenHandleHistory v-if="isBtnActive == 'yfj_handler_history'"/>
-    <nitrogenAlarmHistory v-if="isBtnActive == 'yfj_faultRecord'"/>
-    <div class="bottom-btn-group">
-      <div v-for="item in navList" :key="item.pathName" class="vent-row-center btn-item" @click="setBtn('click', item)"
-        @mouseenter="setBtn('over', item)" @mouseleave="setBtn('leave', item)">
-        <dv-decoration11
-          :color="isBtnActive === item.pathName ? activeColors : item.isHover ? activeColors : noActiveColors"
-          style="width:200px;height:60px;">
-          {{ item.title }}
-        </dv-decoration11>
-      </div>
-    </div>
+    <nitrogenHome v-if="btnActive == 'nitrogen_page'" />
+    <nitrogenEcharts v-if="btnActive == 'yfj_monitor_echarts'"/>
+    <nitrogenHistory v-if="btnActive == 'yfj_history'"/>
+    <nitrogenHandleHistory v-if="btnActive == 'yfj_handler_history'"/>
+    <nitrogenAlarmHistory v-if="btnActive == 'yfj_faultRecord'"/>
+    <BottomMenu :nav-list="navList" @change="changeActive"/>
   </div>
   
 </template>
@@ -29,29 +20,23 @@ import nitrogenEcharts from './components/nitrogenEcharts.vue'
 import nitrogenHistory from './components/nitrogenHistory.vue'
 import nitrogenHandleHistory from './components/nitrogenHandleHistory.vue'
 import nitrogenAlarmHistory from './components/nitrogenAlarmHistory.vue'
-import {  Decoration11 as DvDecoration11, Decoration5 } from '@kjgl77/datav-vue3'
+import { Decoration5 } from '@kjgl77/datav-vue3'
+import BottomMenu from '/@/views/vent/comment/components/bottomMenu.vue';
 
-const isBtnActive = ref('nitrogen_page')
-const activeColors = ['#009BFF', '#28DBE4']
-const noActiveColors = ['#aaa', '#aaa']
+const btnActive = ref('nitrogen_page')
 const navList = ref([
   {
     title: '监控界面',
     pathName: 'nitrogen_page',
     isHover: true
   },
-  // {
-  //   title: '关键节点监测',
-  //   pathName: 'critical_node',
-  //   isHover: false
-  // },
   {
     title: '实时曲线',
     pathName: 'yfj_monitor_echarts',
     isHover: false
   },
   {
-    title: '压风机历史记录',
+    title: '历史监测记录',
     pathName: 'yfj_history',
     isHover: false
   },
@@ -68,15 +53,8 @@ const navList = ref([
 ])
 
 
-function setBtn(type, activeObj) {
-  if (type === 'over') {
-    activeObj.isHover = true
-  } else if (type === 'leave') {
-    activeObj.isHover = false
-  } else if (type === 'click') {
-    isBtnActive.value = activeObj.pathName
-  }
-
+function changeActive(activeValue) {
+  btnActive.value = activeValue
 }
 
 </script>

+ 28 - 25
src/views/vent/monitorManager/nitrogen/nitrogen.dishang.threejs.ts

@@ -1,14 +1,13 @@
 import * as THREE from 'three';
 import { getTextCanvas, addEnvMap, setModalCenter } from '/@/utils/threejs/util';
 import { CSS3DSprite } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
-import * as dat from 'dat.gui';
-const gui = new dat.GUI();
-gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
+// import * as dat from 'dat.gui';
+// const gui = new dat.GUI();
+// gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
 
 class Nitrogen {
   model;
-  modelName = 'nitrogen';
-  // modelName = 'glass';
+  modelName = 'compressor';
   group: THREE.Object3D = new THREE.Object3D();
   animationTimer;
   isLRAnimation = true;
@@ -134,29 +133,33 @@ class Nitrogen {
         const nitrogenModal = this.group.getObjectByName('nitrogenModal' + i) as THREE.Object3D;
         if (!nitrogenModal.getObjectByName('monitorNitrogenText')) {
           const element = document.getElementById('nitrogenMonitor' + (i + 1)) as HTMLElement;
-          element.style.top = '0px';
-          element.style.left = '0px';
-          const nitrogenMonitorCSS3D = new CSS3DSprite(element);
-          nitrogenMonitorCSS3D.name = 'monitorNitrogenText';
-          nitrogenMonitorCSS3D.scale.set(0.003, 0.003, 0.003);
-          if (i == 0) nitrogenMonitorCSS3D.position.set(-0.89, 0.31, 0);
-          if (i == 1) nitrogenMonitorCSS3D.position.set(-0.89, 0.31, 0.04);
-          if (i == 2) nitrogenMonitorCSS3D.position.set(-0.89, 0.31, 0.08);
-          if (i == 3) nitrogenMonitorCSS3D.position.set(-0.89, 0.31, 0.12);
-          nitrogenModal.add(nitrogenMonitorCSS3D);
+          if (element) {
+            element.style.top = '0px';
+            element.style.left = '0px';
+            const nitrogenMonitorCSS3D = new CSS3DSprite(element);
+            nitrogenMonitorCSS3D.name = 'monitorNitrogenText';
+            nitrogenMonitorCSS3D.scale.set(0.003, 0.003, 0.003);
+            if (i == 0) nitrogenMonitorCSS3D.position.set(-0.89, 0.31, 0);
+            if (i == 1) nitrogenMonitorCSS3D.position.set(-0.89, 0.31, 0.04);
+            if (i == 2) nitrogenMonitorCSS3D.position.set(-0.89, 0.31, 0.08);
+            if (i == 3) nitrogenMonitorCSS3D.position.set(-0.89, 0.31, 0.12);
+            nitrogenModal.add(nitrogenMonitorCSS3D);
+          }
         }
         if (!nitrogenModal.getObjectByName('cqgMonitorText')) {
           const element = document.getElementById('cqgMonitor' + (i + 1)) as HTMLElement;
-          element.style.top = '0px';
-          element.style.left = '0px';
-          const cqgMonitorCSS3D = new CSS3DSprite(element);
-          cqgMonitorCSS3D.name = 'cqgMonitorText';
-          cqgMonitorCSS3D.scale.set(0.003, 0.003, 0.003);
-          if (i == 0) cqgMonitorCSS3D.position.set(1.24, 0.49, 0.0);
-          if (i == 1) cqgMonitorCSS3D.position.set(1.24, 0.49, 0.04);
-          if (i == 2) cqgMonitorCSS3D.position.set(1.24, 0.49, 0.08);
-          if (i == 3) cqgMonitorCSS3D.position.set(1.24, 0.49, 0.12);
-          nitrogenModal.add(cqgMonitorCSS3D);
+          if (element) {
+            element.style.top = '0px';
+            element.style.left = '0px';
+            const cqgMonitorCSS3D = new CSS3DSprite(element);
+            cqgMonitorCSS3D.name = 'cqgMonitorText';
+            cqgMonitorCSS3D.scale.set(0.003, 0.003, 0.003);
+            if (i == 0) cqgMonitorCSS3D.position.set(1.24, 0.49, 0.0);
+            if (i == 1) cqgMonitorCSS3D.position.set(1.24, 0.49, 0.04);
+            if (i == 2) cqgMonitorCSS3D.position.set(1.24, 0.49, 0.08);
+            if (i == 3) cqgMonitorCSS3D.position.set(1.24, 0.49, 0.12);
+            nitrogenModal.add(cqgMonitorCSS3D);
+          }
         }
       }
     }

+ 1 - 1
src/views/vent/monitorManager/nitrogen/nitrogen.threejs.ts

@@ -77,7 +77,7 @@ export const setModelType = (type) => {
           // { x: -0.24658823766780538, y: 35.50352092191473, z: 83.90511756512278 },
           // { x: 1.5582599568763913, y: -3.2828007511721147, z: 2.2606374587827234 },
           { x: -0.03221356849453339, y: 60.58380705766696, z: 66.35361856273981 },
-          { x: -0.04856971136953342, y: 0.6442166711669518, z: 0.7632993277398138 },
+          { x: 0, y: 0, z: 0 },
           model,
           0.8
         );

+ 3 - 3
src/views/vent/monitorManager/sensorMonitor/index.vue

@@ -50,7 +50,7 @@
       <a-tab-pane key="2" tab="历史数据">
         <div class="tab-item table-box box-bg padding-0">
           <HistoryTable
-            columns-type="modelsensor_history"
+            columns-type="modelsensor"
             device-type="modelsensor"
             :device-list-api="baseList"
             @change="historyDataSourceChange"
@@ -72,7 +72,7 @@
       </a-tab-pane>
       <a-tab-pane key="3" tab="报警历史">
         <div class="tab-item box-bg">
-          <AlarmHistoryTable columns-type="alarm_history" device-type="modelsensor" :device-list-api="baseList" designScope="alarm-history" />
+          <AlarmHistoryTable columns-type="alarm" device-type="modelsensor" :device-list-api="baseList" designScope="alarm-history" />
         </div>
       </a-tab-pane>
       <a-tab-pane key="4" tab="操作历史">
@@ -315,7 +315,7 @@
   }
   .sensor-container {
     position: relative;
-    top: 20px;
+    top: 65px;
     padding: 10px;
     z-index: 999;
     max-height: calc(100vh - 150px);

+ 2 - 2
src/views/vent/monitorManager/windowMonitor/index.vue

@@ -92,12 +92,12 @@
         </a-tab-pane>
         <a-tab-pane key="3" tab="历史数据">
           <div class="tab-item">
-            <HistoryTable columns-type="window_history" device-type="window" :device-list-api="baseList" designScope="window-history" />
+            <HistoryTable columns-type="window" device-type="window" :device-list-api="baseList" designScope="window-history" />
           </div>
         </a-tab-pane>
         <a-tab-pane key="4" tab="报警历史">
           <div class="tab-item">
-            <AlarmHistoryTable columns-type="alarm_history" device-type="window" :device-list-api="baseList" designScope="alarm-history" />
+            <AlarmHistoryTable columns-type="alarm" device-type="window" :device-list-api="baseList" designScope="alarm-history" />
           </div>
         </a-tab-pane>
         <a-tab-pane key="5" tab="操作历史">

+ 67 - 41
src/views/vent/monitorManager/windrectMonitor/duishe.threejs.ts

@@ -10,6 +10,7 @@ class dsWindRect {
   model;
   modelName = 'dscf';
   group: THREE.Object3D = new THREE.Object3D();
+  deviceType;
   animationTimer;
   isLRAnimation = true;
   direction = 1;
@@ -23,6 +24,24 @@ class dsWindRect {
     this.player1 = playerVal1;
     this.group.name = this.modelName;
   }
+  setModelType(deviceType) {
+    this.deviceType = deviceType;
+    const dsgdObj = this.group.getObjectByName('dsgd');
+    const dsmoveObj = this.group.getObjectByName('dsmove');
+    if (deviceType == 'move') {
+      if (dsgdObj) dsgdObj.visible = false;
+      if (dsmoveObj) dsmoveObj.visible = true;
+    } else {
+      if (dsgdObj) dsgdObj.visible = true;
+      if (dsmoveObj) dsmoveObj.visible = false;
+      if (deviceType == 'four' && dsgdObj) {
+        dsgdObj.getObjectByName('fout_ceasourment_01').visible = true;
+      }
+      if (deviceType == 'two' && dsgdObj) {
+        dsgdObj.getObjectByName('fout_ceasourment_01').visible = false;
+      }
+    }
+  }
 
   addLight() {
     const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
@@ -55,7 +74,7 @@ class dsWindRect {
 
   // 设置模型位置
   setModalPosition() {
-    this.group?.scale.set(27, 27, 27);
+    this.group?.scale.set(22, 22, 22);
     this.group?.position.set(-10, 25, 20);
   }
 
@@ -145,8 +164,8 @@ class dsWindRect {
         const planeGeometry = new THREE.PlaneGeometry(5.6, 3.46); // 平面3维几何体PlaneGeometry
         const planeMesh = new THREE.Mesh(planeGeometry, textMaterial);
         planeMesh.name = 'monitorText';
-        planeMesh.scale.set(0.2, 0.2, 0.2);
-        planeMesh.position.set(-3.06, 0.058, -0.42);
+        planeMesh.scale.set(0.26, 0.26, 0.26);
+        planeMesh.position.set(-2.52, 0.038, -0.42);
         this.group?.add(planeMesh);
       }
     });
@@ -170,26 +189,13 @@ class dsWindRect {
 
   /* 提取风门序列帧,初始化前后门动画 */
   initAnimation() {
-    const windGroup = new THREE.Group();
-    windGroup.name = 'dsTanTou';
-    let line;
-    if (this.group && this.group?.children.length > 0) {
-      for (let i = this.group?.children.length - 1; i >= 0; i--) {
-        const obj = this.group?.children[i];
-        if (obj.type === 'Mesh' && obj.name && obj.name.includes('Tantou')) {
-          const mesh = obj.clone();
-          if (mesh.name === 'Tantouxian') {
-            line = mesh;
-          }
-          windGroup.add(mesh);
-          obj.removeFromParent();
-          this.group?.remove(obj);
-        }
-      }
-    }
-    this.group?.add(windGroup);
+    const dsmove = this.group.getObjectByName('dsmove');
+    const dsmoveLine = dsmove?.getObjectByName('probe');
+    let line = dsmoveLine?.getObjectByName('line_');
+
     if (line) {
       line.material.side = THREE.DoubleSide;
+      line.material.opacity = 1;
       line.material.depthWrite = true;
 
       this.lineLight = gsap.to(line.material, {
@@ -202,6 +208,24 @@ class dsWindRect {
       });
       this.lineLight.play();
     }
+
+    const dsgdObj = this.group.getObjectByName('dsgd');
+    const dsgdLine = dsgdObj?.getObjectByName('fout_ceasourment_01')?.getObjectByName('cea08');
+    if (dsgdLine) {
+      dsgdLine.material.side = THREE.DoubleSide;
+      dsgdLine.material.opacity = 1;
+      dsgdLine.material.depthWrite = true;
+
+      const gdLine = gsap.to(dsgdLine.material, {
+        opacity: 0,
+        duration: 0.3,
+        ease: 'easeQutQuad',
+        repeat: -1,
+        yoyo: true,
+        paused: true,
+      });
+      gdLine.play();
+    }
   }
 
   /* 点击风窗,风窗全屏 */
@@ -244,46 +268,47 @@ class dsWindRect {
 
   // 播放动画
   play(flag, isDirect = false) {
-    const dsTanTou = this.group?.getObjectByName('dsTanTou') as THREE.Group;
+    if (this.deviceType !== 'move') return;
+    const dsmove = this.group?.getObjectByName('dsmove') as THREE.Object3D;
+    const dsTanTou = dsmove?.getObjectByName('probe') as THREE.Object3D;
+    dsTanTou.position.setY(0.45);
+
     if (!dsTanTou && flag != 'start' && flag != 'moni') return;
     if (flag == 'moni') {
       gsap.to(dsTanTou['position'], {
-        y: -0.49,
-        duration: Math.abs(dsTanTou['position']['y'] - 0.49) * 21,
+        y: -0.32,
+        duration: Math.abs(dsTanTou['position']['y'] - 0.32) * 21,
         overwrite: true,
         onComplete: function () {
           setTimeout(() => {
             gsap.to(dsTanTou['position'], {
-              id: 'dsUp',
-              y: 0,
-              duration: Math.abs(dsTanTou['position']['y']) * 21,
+              y: 0.45,
+              duration: 0.77 * 21,
               overwrite: true,
             });
-          }, 2000);
+          }, 5000);
         },
       });
     } else {
       if (!isDirect) {
         if (this.isRun) return;
-        dsTanTou.position.setY(0);
+        dsTanTou.position.setY(0.45);
         this.isRun = true;
         gsap.to(dsTanTou['position'], {
-          id: 'dsDown',
-          y: -0.49,
-          duration: Math.abs(dsTanTou['position']['y'] - 0.49) * 21,
+          y: -0.32,
+          duration: Math.abs(dsTanTou['position']['y'] - 0.32) * 21,
           overwrite: true,
           onComplete: function () {
             setTimeout(() => {
               gsap.to(dsTanTou['position'], {
-                id: 'dsUp',
-                y: 0,
-                duration: Math.abs(dsTanTou['position']['y']) * 21,
+                y: 0.45,
+                duration: 0.77 * 21,
                 overwrite: true,
                 // onComplete: function () {
                 //   _this.isRun = false;
                 // },
               });
-            }, 2000);
+            }, 5000);
           },
         });
       } else {
@@ -306,8 +331,9 @@ class dsWindRect {
 
   mountedThree() {
     return new Promise((resolve) => {
-      this.model.setModel([this.modelName]).then((gltf) => {
-        this.group = gltf[0];
+      this.model.setModel([this.modelName, 'dsgd', 'dsmove'], this.group).then((gltf) => {
+        this.group.name = this.modelName;
+        // this.group = gltf[0];
         this.setModalPosition();
         this.initAnimation();
         this.addLight();
@@ -325,11 +351,11 @@ class dsWindRect {
                 font: 'normal 40px Arial',
                 color: '#009900',
                 strokeStyle: '#002200',
-                x: 170,
+                x: 370,
                 y: 40,
               },
             ];
-            getTextCanvas(560, 346, textArr, '').then((canvas: HTMLCanvasElement) => {
+            getTextCanvas(580, 346, textArr, '').then((canvas: HTMLCanvasElement) => {
               const textMap = new THREE.CanvasTexture(canvas); // 关键一步
               const textMaterial = new THREE.MeshBasicMaterial({
                 map: textMap, // 设置纹理贴图
@@ -344,7 +370,7 @@ class dsWindRect {
                 const planeGeometry = new THREE.PlaneGeometry(100, 100); // 平面3维几何体PlaneGeometry
                 const planeMesh = new THREE.Mesh(planeGeometry, textMaterial);
                 planeMesh.name = 'noPlayer';
-                planeMesh.scale.set(0.012, 0.009, 0.012);
+                planeMesh.scale.set(0.014, 0.009, 0.012);
                 planeMesh.position.set(2.25, -0.34, -0.39);
                 this.group?.add(planeMesh);
               }

+ 22 - 4
src/views/vent/monitorManager/windrectMonitor/index.vue

@@ -7,7 +7,7 @@
     <div class="top-box">
       <div class="top-center row">
         <!-- <div class="button-box" @click="start(0)">复位</div> -->
-        <!-- <div class="button-box" @click="testPlay('')">模拟动画</div> -->
+        <div class="button-box" @click="testPlay('')">模拟动画</div>
         <div class="button-box" @click="clearPlay()">自动清洁</div>
         <div class="button-box" @click="startRun()">启动测风</div>
         <!-- <div class="button-box" @click="testPlay('up')">上</div>
@@ -89,7 +89,7 @@
         </a-tab-pane>
         <a-tab-pane key="3" tab="历史数据">
           <div class="tab-item">
-            <HistoryTable columns-type="windrect_history" device-type="windrect" :device-list-api="baseList" designScope="windrect-history" >
+            <HistoryTable columns-type="windrect" device-type="windrect" :device-list-api="baseList" designScope="windrect-history" >
               <template #filterCell="{ column, record }">
                 <a-tag v-if="column.dataIndex === 'warnFlag'" :color="record.warnFlag == 0 ? 'green' : record.warnFlag == 1 ? '#FF5812' : 'gray'"> {{
                   record.warnFlag == 0 ? '正常' : record.warnFlag == 1 ? '报警' : record.warnFlag == 2 ? '断开' : '未监测'
@@ -100,7 +100,7 @@
         </a-tab-pane>
         <a-tab-pane key="4" tab="报警历史">
           <div class="tab-item">
-            <AlarmHistoryTable columns-type="alarm_history" device-type="windrect" :device-list-api="baseList" designScope="alarm-history" />
+            <AlarmHistoryTable columns-type="alarm" device-type="windrect" :device-list-api="baseList" designScope="alarm-history" />
           </div>
         </a-tab-pane>
         <a-tab-pane key="5" tab="操作历史">
@@ -547,7 +547,25 @@
       loading.value = true;
       selectRowIndex.value = index;
       // Object.assign(selectData, selectRow);
-      const type = selectRow.deviceType == 'windrect_rect' ? 'lmWindRect' : selectRow.deviceType == 'windrect_fold' ? 'zdWindRect' : selectRow.deviceType == 'windrect_rect_single' ? 'lmWindSide': 'dsWindRect';
+      let type = ''
+      if(selectRow.deviceType == 'windrect_rect') {
+        type = 'lmWindRect'
+      }
+      if (selectRow.deviceType == 'windrect_fold') {
+        type = 'zdWindRect'
+      }
+      if (selectRow.deviceType == 'windrect_rect_single') {
+        type = 'lmWindSide'
+      }
+      if (selectRow.deviceType == 'windrect_ds') {
+        type = 'dsWindRect_move'
+      }
+      if (selectRow.deviceType == 'windrect_ds_four') {
+        type = 'dsWindRect_four'
+      }
+      if (selectRow.deviceType == 'windrect_ds_two') {
+        type = 'dsWindRect_two'
+      }
       // const type = selectRowIndex.value >= 1 ? 'lmWindRect' : selectRowIndex.value <= 3 ? 'zdWindRect' : 'dsWindRect';
       await setModelType(type);
       loading.value = false;

+ 13 - 8
src/views/vent/monitorManager/windrectMonitor/windrect.threejs.ts

@@ -33,7 +33,7 @@ const startAnimation = () => {
       lmWindRectObj.mouseUpModel.call(lmWindRectObj);
     } else if (windRectType === 'zdWindRect') {
       zdWindRectObj.mouseUpModel.call(zdWindRectObj);
-    } else if (windRectType === 'dsWindRect') {
+    } else if (windRectType.startsWith('dsWindRect')) {
       dsWindRectObj.mouseUpModel.call(dsWindRectObj);
     } else if (windRectType === 'lmWindSide') {
       lmWindRectSideObj.mouseUpModel.call(lmWindRectSideObj);
@@ -53,14 +53,14 @@ const mouseEvent = (event) => {
     -((-model.canvasContainer.getBoundingClientRect().top + event.clientY) / (model.canvasContainer.clientHeight * heightScale)) * 2 + 1;
   (model.rayCaster as THREE.Raycaster).setFromCamera(model.mouse, model.camera as THREE.Camera);
   if (group) {
-    const intersects = model.rayCaster?.intersectObjects(group.children, false) as THREE.Intersection[];
+    const intersects = model.rayCaster?.intersectObjects(group.children, true) as THREE.Intersection[];
     if (intersects.length > 0) {
       // 单道、 双道
       if (windRectType === 'lmWindRect') {
         lmWindRectObj.mousedownModel.call(lmWindRectObj, intersects);
       } else if (windRectType === 'zdWindRect') {
         zdWindRectObj.mousedownModel.call(zdWindRectObj, intersects);
-      } else if (windRectType === 'dsWindRect') {
+      } else if (windRectType.startsWith('dsWindRect')) {
         dsWindRectObj.mousedownModel.call(dsWindRectObj, intersects);
       } else if (windRectType === 'lmWindSide') {
         lmWindRectSideObj.mousedownModel.call(lmWindRectSideObj, intersects);
@@ -75,7 +75,7 @@ export const addFmText = (selectData) => {
     return lmWindRectObj.addFmText.call(lmWindRectObj, selectData);
   } else if (windRectType === 'zdWindRect') {
     return zdWindRectObj.addFmText.call(zdWindRectObj, selectData);
-  } else if (windRectType === 'dsWindRect') {
+  } else if (windRectType.startsWith('dsWindRect')) {
     return dsWindRectObj.addFmText.call(dsWindRectObj, selectData);
   } else if (windRectType === 'lmWindSide') {
     lmWindRectSideObj.addFmText.call(lmWindRectSideObj, selectData);
@@ -87,7 +87,7 @@ export const play = (flag, isDirect = false) => {
     return lmWindRectObj.play.call(lmWindRectObj, flag, isDirect);
   } else if (windRectType === 'zdWindRect') {
     return zdWindRectObj.play.call(zdWindRectObj, flag, isDirect);
-  } else if (windRectType === 'dsWindRect') {
+  } else if (windRectType.startsWith('dsWindRect')) {
     return dsWindRectObj.play.call(dsWindRectObj, flag, isDirect);
   } else if (windRectType === 'lmWindSide') {
     lmWindRectSideObj.play.call(lmWindRectSideObj, flag, isDirect);
@@ -177,12 +177,17 @@ export const setModelType = (type) => {
           0.8
         );
       }, 300);
-    } else if (windRectType === 'dsWindRect') {
+    } else if (windRectType.startsWith('dsWindRect')) {
+      const type = windRectType.split('_')[1];
       // dsWindRectObj.isRun = false;
       model.startAnimation = dsWindRectObj.render.bind(dsWindRectObj);
       group = dsWindRectObj.group;
-      const dsTanTou = dsWindRectObj.group?.getObjectByName('dsTanTou') as THREE.Group;
-      dsTanTou.position.setY(0);
+      dsWindRectObj.setModelType(type); // 设置对射类型
+
+      const dsmove = dsWindRectObj.group?.getObjectByName('dsmove') as THREE.Object3D;
+      const dsTanTou = dsmove?.getObjectByName('probe') as THREE.Object3D;
+      dsTanTou.position.setY(0.45);
+
       if (model.scene.getObjectByName('lmcf')) {
         model.scene.remove(lmWindRectObj.group);
       }