Browse Source

修改了模型缓存方式、修改部署方式

hongrunxia 1 year ago
parent
commit
b412fc5a24
58 changed files with 1118 additions and 660 deletions
  1. 2 2
      .env.development
  2. 3 2
      .env.production
  3. 0 1
      build/vite/proxy.ts
  4. 2 5
      index.html
  5. BIN
      public/model/glft/cf/ddcf_2023-12-09.glb
  6. BIN
      public/model/glft/cf/dscf_2023-06-02.glb
  7. BIN
      public/model/glft/cf/dsgd_2023-06-02.glb
  8. BIN
      public/model/glft/cf/dsmove_2023-06-02.glb
  9. BIN
      public/model/glft/cf/fixedCf_2023-11-29.glb
  10. BIN
      public/model/glft/cf/lmcfSide_2023-06-02.glb
  11. BIN
      public/model/glft/cf/lmcf_2023-06-02.glb
  12. BIN
      public/model/glft/cf/zdcf_2023-06-02.glb
  13. BIN
      public/model/glft/fc/sdFc_2023-10-19.glb
  14. BIN
      public/model/glft/fm/Fm-door_2023-11-29.glb
  15. BIN
      public/model/glft/fm/Fm-wall-qd_2023-11-28.glb
  16. BIN
      public/model/glft/fm/Fm-wall_2023-11-29.glb
  17. BIN
      public/model/glft/fm/Fm-wire-qd_2023-11-28.glb
  18. BIN
      public/model/glft/fm/Fm-wire_2023-11-29.glb
  19. BIN
      public/model/glft/fm/fmThreeBase_2023-07-25.glb
  20. BIN
      public/model/glft/fm/fmThree_2023-07-25.glb
  21. BIN
      public/model/glft/fm/quickObfurage-door_2023-06-02.glb
  22. BIN
      public/model/glft/fm/quickObfurage-wall_2023-06-02.glb
  23. BIN
      public/model/glft/fm/quickObfurage-wire_2023-06-02.glb
  24. 10 10
      src/components/vent/micro/needAir.vue
  25. 9 10
      src/components/vent/micro/ventModal.vue
  26. 2 2
      src/hooks/system/useCamera.ts
  27. 6 4
      src/qiankun/apps.ts
  28. 19 20
      src/qiankun/index.ts
  29. 5 3
      src/qiankun/state.ts
  30. 52 55
      src/utils/threejs/loadModel.worker.js
  31. 32 26
      src/utils/threejs/main.worker.ts
  32. 32 10
      src/utils/threejs/useThree.ts
  33. 29 3
      src/utils/threejs/util.ts
  34. 2 2
      src/views/vent/deviceManager/comment/pointTabel/point.data.ts
  35. 2 2
      src/views/vent/home/colliery/index.vue
  36. 6 4
      src/views/vent/monitorManager/balancePressMonitor1/balancePress.three.ts
  37. 2 2
      src/views/vent/monitorManager/compressor/index.vue
  38. 2 2
      src/views/vent/monitorManager/deviceMonitor/components/device/index.vue
  39. 131 114
      src/views/vent/monitorManager/fanLocalMonitor/index.vue
  40. 1 1
      src/views/vent/monitorManager/gateMonitor/gate.threejs.qd.ts
  41. 100 99
      src/views/vent/monitorManager/gateMonitor/gate.threejs.three.ts
  42. 98 25
      src/views/vent/monitorManager/gateMonitor/gate.threejs.ts
  43. 114 112
      src/views/vent/monitorManager/gateMonitor/gate.threejs.yy.ts
  44. 10 7
      src/views/vent/monitorManager/gateMonitor/index.vue
  45. 366 59
      src/views/vent/monitorManager/groutMonitor/components/groutHome.vue
  46. 2 2
      src/views/vent/monitorManager/safetyMonitor/index.vue
  47. 7 8
      src/views/vent/monitorManager/windowMonitor/dandaoFc.threejs.ts
  48. 10 8
      src/views/vent/monitorManager/windowMonitor/index.vue
  49. 14 13
      src/views/vent/monitorManager/windowMonitor/shuangdaoFc.threejs.ts
  50. 3 4
      src/views/vent/monitorManager/windowMonitor/window.threejs.ts
  51. 2 3
      src/views/vent/monitorManager/windrectMonitor/dantou.threejs.ts
  52. 4 6
      src/views/vent/monitorManager/windrectMonitor/duishe.threejs.ts
  53. 1 1
      src/views/vent/monitorManager/windrectMonitor/duisheFixed.threejs.ts
  54. 1 1
      src/views/vent/monitorManager/windrectMonitor/longmen.threejs.ts
  55. 1 1
      src/views/vent/monitorManager/windrectMonitor/longmenSide.threejs.ts
  56. 10 10
      src/views/vent/monitorManager/windrectMonitor/windrect.threejs.ts
  57. 1 1
      src/views/vent/monitorManager/windrectMonitor/zhedie.threejs.ts
  58. 25 20
      src/views/vent/monitorManager/workFaceMonitor/components/workFaceHistory.vue

+ 2 - 2
.env.development

@@ -6,7 +6,7 @@ VITE_PUBLIC_PATH = /
 
 # 跨域代理,您可以配置多个 ,请注意,没有换行符
 #VITE_PROXY = [["/jeecgboot","http://localhost:8080/jeecg-boot"],["/upload","http://localhost:3300/upload"]]
-VITE_PROXY = [["/jeecgsystem","http://182.92.126.35:9999"],["/upload","http://localhost:3300/upload"]]
+VITE_PROXY = [["/jeecgsystem","http://182.92.126.35:9999"],["/upload","http://localhost:3300/upload"],["/documents", "http://182.92.126.35:9050"],["/modelreq", "http://182.92.126.35:9999"]]
 #VITE_PROXY = [["/jeecgsystem","http://192.168.1.8:9999"],["/upload","http://localhost:3300/upload"]]
 
 # 控制台不输出
@@ -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/", "vent-model"], ["micro-need-air", "//localhost:8099/", "micro-need-air"], ["micro-fire-front", "//localhost:8090/", "fire-Micro"]]
+VITE_APP_SUB_APP = [["micro-vent-3dModal", "//localhost:8091/", "micro-vent-3dModal"], ["micro-need-air", "//localhost:8099/", "micro-need-air"], ["micro-fire-front", "//localhost:8090/", "fire-Micro"]]
 # VITE_APP_SUB_APP = [["micro-vent-3dModal", "//localhost:8091/"], ["micro-need-air", "//localhost:8099/"], ["micro-fire-front", "//localhost:8090/"]]

+ 3 - 2
.env.production

@@ -17,7 +17,7 @@ VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
 #VITE_PROXY = [["/jeecgsystem","http://10.248.223.116:9999"],["/upload","http://localhost:3300/upload"]]
 #VITE_PROXY = [["/jeecgsystem","http://10.248.210.152:9999"],["/upload","http://10.248.210.152:9999/upload"]]
 #VITE_PROXY = [["/jeecgsystem","http://182.92.126.35:9999"],["/upload","http://182.92.126.35:9999/upload"]]
-VITE_PROXY = [["/jeecgsystem","http://172.16.41.171:9999"],["/upload","http://172.16.41.171:9999/upload"]]
+VITE_PROXY = [["/jeecgsystem","http://172.16.41.171:9999"],["/upload","http://172.16.41.171:9999/upload"], ["/documents", "http://182.92.126.35:9050"]]
 #VITE_PROXY = [["/jeecgsystem","http://172.16.41.171:9999"],["/upload","http://172.16.41.171:9999/upload"]]
 #VITE_PROXY = [["/jeecgsystem","http://10.120.120.163:9999"],["/upload","http://10.120.120.163:9999/upload"]]
 #VITE_PROXY = [["/jeecgsystem","http://192.168.1.4:9999"],["/upload","http://localhost:3300/upload"]]
@@ -62,7 +62,8 @@ VITE_LEGACY = false
 #VITE_APP_SUB_APP = [["micro-need-air", "//10.120.120.163:8093/"], ["micro-vent-3dModal", "//10.120.120.163:8091/"]] #查哈素
 #VITE_APP_SUB_APP = [["micro-need-air", "//182.92.126.35:8093/"], ["micro-vent-3dModal", "//182.92.126.35:8091/"]]
 # VITE_APP_SUB_APP = [["micro-need-air", ":8093/"], ["micro-vent-3dModal", ":8091/"]]
-VITE_APP_SUB_APP = [["micro-vent-3dModal", ":8091/", "vent-model"], ["micro-need-air", ":8093/", "micro-need-air"]]
+VITE_APP_SUB_APP = [["micro-vent-3dModal", ":8091/", "micro-vent-3dModal"], ["micro-need-air", ":8093/", "micro-need-air"]]
+#VITE_APP_SUB_APP = [["micro-vent-3dModal", "/models/"], ["micro-need-air", "/vent-need-air/"]] #[name, entry, container]
 #VITE_APP_SUB_APP = [["micro-need-air", "//172.16.41.171:7123/"], ["micro-vent-3dModal", "//172.16.41.171:7121/"]]
 #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/"]]

+ 0 - 1
build/vite/proxy.ts

@@ -18,7 +18,6 @@ const httpsRE = /^https:\/\//;
 export function createProxy(list: ProxyList = []) {
   const ret: ProxyTargetList = {};
   for (const [prefix, target] of list) {
-    
     // if(process.env.NODE_ENV == 'production'){
 
     // }else{

+ 2 - 5
index.html

@@ -6,19 +6,17 @@
     <meta name="renderer" content="webkit" />
     <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0" />
     <title><%= title %></title>
-    <!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" /> -->
-    <!-- <link rel="preload" as="script" href="/js/config.js"> -->
     <link rel="icon" id="faviconIcon" href="/logo.png" />
     <!-- 全局配置 -->
     <script src="/js/config.js"></script>
     <script src="/js/liveplayer-lib.min.js"></script>
     <script src="/js/webrtcstreamer.js"></script>
     <script src="/js/adapter.min.js"></script>
-    <script type="text/javascript" src="http://182.92.126.35:9050/web-apps/apps/api/documents/api.js"></script>
+    <script type="text/javascript" src="/documents/web-apps/apps/api/documents/api.js"></script>
   </head>
   <body>
     <script>
-      (() => {
+      (async() => {
         var htmlRoot = document.getElementById('htmlRoot');
         var theme = window.localStorage.getItem('__APP__DARK__MODE__');
         if (htmlRoot && theme) {
@@ -27,7 +25,6 @@
         }
       })();
     </script>
-    
     <div id="app">
       <style lang="less">
         html[data-theme='dark'] .app-loading {

BIN
public/model/glft/cf/ddcf_2023-12-09.glb


BIN
public/model/glft/cf/dscf_2023-06-02.glb


BIN
public/model/glft/cf/dsgd_2023-06-02.glb


BIN
public/model/glft/cf/dsmove_2023-06-02.glb


BIN
public/model/glft/cf/fixedCf_2023-11-29.glb


BIN
public/model/glft/cf/lmcfSide_2023-06-02.glb


BIN
public/model/glft/cf/lmcf_2023-06-02.glb


BIN
public/model/glft/cf/zdcf_2023-06-02.glb


BIN
public/model/glft/fc/sdFc_2023-10-19.glb


BIN
public/model/glft/fm/Fm-door_2023-11-29.glb


BIN
public/model/glft/fm/Fm-wall-qd_2023-11-28.glb


BIN
public/model/glft/fm/Fm-wall_2023-11-29.glb


BIN
public/model/glft/fm/Fm-wire-qd_2023-11-28.glb


BIN
public/model/glft/fm/Fm-wire_2023-11-29.glb


BIN
public/model/glft/fm/fmThreeBase_2023-07-25.glb


BIN
public/model/glft/fm/fmThree_2023-07-25.glb


BIN
public/model/glft/fm/quickObfurage-door_2023-06-02.glb


BIN
public/model/glft/fm/quickObfurage-wall_2023-06-02.glb


BIN
public/model/glft/fm/quickObfurage-wire_2023-06-02.glb


+ 10 - 10
src/components/vent/micro/needAir.vue

@@ -2,21 +2,21 @@
   <div id="micro-need-air"></div>
 </template>
 <script lang="ts">
-  import { onMounted, onBeforeUnmount, defineComponent } from 'vue'
-  import { unmountMicroApps, mountMicroApp } from '/@/qiankun'
+  import { onMounted, onBeforeUnmount, defineComponent } from 'vue';
+  import { unmountMicroApps, mountMicroApp } from '/@/qiankun';
   import { resetMicroContentWH } from '/@/utils/domUtils';
   export default defineComponent({
     name: 'NeedAir',
     setup() {
       onMounted(() => {
-        mountMicroApp('/micro-need-air')
-        resetMicroContentWH('micro-need-air')
-      })
+        mountMicroApp('/micro-need-air');
+        resetMicroContentWH('micro-need-air');
+      });
 
       onBeforeUnmount(async () => {
-        unmountMicroApps(['/micro-need-air'])
-      })
-    }
-  })
+        unmountMicroApps(['/micro-need-air']);
+      });
+    },
+  });
 </script>
-<style lang="less" scoped></style>
+<style lang="less" scoped></style>

+ 9 - 10
src/components/vent/micro/ventModal.vue

@@ -1,8 +1,7 @@
 <template>
-  <div id="vent-model"></div>
+  <div id="micro-vent-3dModal"></div>
 </template>
-<script lang="ts" >
-
+<script lang="ts">
   import { onMounted, onBeforeUnmount, defineComponent } from 'vue';
   import { unmountMicroApps, mountMicroApp } from '/@/qiankun';
   import { resetMicroContentWH } from '/@/utils/domUtils';
@@ -11,14 +10,14 @@
     name: 'VentModel',
     setup() {
       onMounted(() => {
-        mountMicroApp('/micro-vent-3dModal')
-        resetMicroContentWH('vent-model')
-      })
+        mountMicroApp('/micro-vent-3dModal');
+        resetMicroContentWH('micro-vent-3dModal');
+      });
 
       onBeforeUnmount(async () => {
-        unmountMicroApps(['/micro-vent-3dModal'])
-      })
-    }
-  })
+        unmountMicroApps(['/micro-vent-3dModal']);
+      });
+    },
+  });
 </script>
 <style lang="less" scoped></style>

+ 2 - 2
src/hooks/system/useCamera.ts

@@ -17,7 +17,7 @@ export function useCamera() {
     }
     const res = await cameraList({ deviceid });
     const cameras: [] = res.records || [];
-    let cameraAddrs: any[] = [],
+    const cameraAddrs: any[] = [],
       cameraNames: string[] = [];
     if (cameras.length > 0) {
       cameras.forEach((item) => {
@@ -225,4 +225,4 @@ export function useCamera() {
     playerDoms,
     deviceCameraInit,
   };
-}
+}

+ 6 - 4
src/qiankun/apps.ts

@@ -11,18 +11,20 @@ for (const key in import.meta.env) {
   if (key === 'VITE_APP_SUB_APP') {
     const appList = JSON.parse(import.meta.env[key].replace(/'/g, '"'));
     appList.forEach((app) => {
-      const name = app[0];
+      // const name = app[0];
       let utlStr;
       if (import.meta.env.PROD) {
+        // 多端口请求
         utlStr = VUE_APP_URL.baseUrl.split(':')[1] + app[1];
+        // utlStr = app[1];
       } else {
         utlStr = app[1];
       }
       const obj = {
-        name,
+        name: app[0],
         entry: utlStr,
-        container: `#${app[2]}`,
-        activeRule: name,
+        container: `#${app[0]}`,
+        activeRule: app[0],
       };
       _apps.push(obj);
     });

+ 19 - 20
src/qiankun/index.ts

@@ -1,11 +1,11 @@
 /**
  * qiankun配置
  */
-import { loadMicroApp  } from 'qiankun';
+import { loadMicroApp } from 'qiankun';
 import { apps } from './apps';
 import { getProps } from './state';
 
-const activeApps = {}
+const activeApps = {};
 /**
  * 重构apps
  */
@@ -17,39 +17,38 @@ function filterApps() {
 
     //微应用触发的路由规则
     // @ts-ignore
-    item.activeRule = item.activeRule.startsWith('/')? item.activeRule : `/${item.activeRule}`;
+    item.activeRule = item.activeRule.startsWith('/') ? item.activeRule : `/${item.activeRule}`;
   });
   return apps;
 }
 
 const mountMicroApp = (path, toPath?) => {
-  const microApps = filterApps()
-  const app = microApps.find(item => path.startsWith(item['activeRule']))
+  const microApps = filterApps();
+  const app = microApps.find((item) => path.startsWith(item['activeRule']));
   if (app) {
-    const instance = activeApps[app['activeRule']]
+    const instance = activeApps[app['activeRule']];
+    console.log('子应用实例--------------->', instance);
     if (instance) {
-      instance.update()
+      instance.update();
     } else {
-      if(toPath){
-        app['props']['data']['publicPath'] = toPath
+      if (toPath) {
+        app['props']['data']['publicPath'] = toPath;
       }
-      activeApps[app['activeRule']] = loadMicroApp(app) // 手动加载子应用
+      activeApps[app['activeRule']] = loadMicroApp(app); // 手动加载子应用
     }
   }
-}
+};
 
 // 卸载app的方法
-const unmountMicroApps = async multipleApp => { 
+const unmountMicroApps = async (multipleApp) => {
   for (const key in activeApps) {
-    const isExist = multipleApp.some(
-      name => name == key
-    )
+    const isExist = multipleApp.some((name) => name == key);
     if (isExist) {
-      activeApps[key].unmount()
-      activeApps[key] = null
-      delete activeApps[key]
+      activeApps[key].unmount();
+      activeApps[key] = null;
+      delete activeApps[key];
     }
   }
-}
+};
 
-export { mountMicroApp, unmountMicroApps }
+export { mountMicroApp, unmountMicroApps };

+ 5 - 3
src/qiankun/state.ts

@@ -16,7 +16,7 @@ export function getProps() {
       token: getToken(),
       store: store,
       router,
-      isMounted: false
+      isMounted: false,
     },
   };
 }
@@ -25,7 +25,9 @@ export function getProps() {
  * 定义全局状态,并返回通信方法,在主应用使用,微应用通过 props 获取通信方法。
  * @param state 主应用穿的公共数据
  */
-export function initGlState(info: any = { token: '', userInfo: {}, isMounted: false, locationObj: null, locationId: '', pageObj: null,  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);
@@ -36,7 +38,7 @@ export function initGlState(info: any = { token: '', userInfo: {}, isMounted: fa
     pageObj: {},
     widthScale: 1,
     heightScale: 1,
-    url: {}
+    url: {},
   });
   // 注册 观察者 函数 - 响应 globalState 变化,在 globalState 发生改变时触发该 观察者 函数。
   actions.onGlobalStateChange((newState, prev) => {

+ 52 - 55
src/utils/threejs/loadModel.worker.js

@@ -1,10 +1,9 @@
 import * as THREE from 'three';
 import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
 import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
-import { genGroupStruct, genAnimations } from './modalParse'
+import { genGroupStruct, genAnimations } from './modalParse';
 import Dexie from 'dexie';
 
-
 const gltfLoader = new GLTFLoader();
 const dracoLoader = new DRACOLoader();
 dracoLoader.setDecoderPath('/model/draco/gltf/');
@@ -13,62 +12,60 @@ dracoLoader.preload();
 gltfLoader.setDRACOLoader(dracoLoader);
 gltfLoader.setPath('/model/glft/');
 
-
 async function loadModel(data) {
-    let { modalValue, modalName, message } = data
-    if (!modalValue) {
-        const db = new Dexie('DB');
-        if (db.modal){
-            const modalArr = await db.modal.where('modalName').equals(modalName).toArray();
-            modalValue = modalArr[0].modalVal;
-        }
+  let { modalValue, modalName, message } = data;
+  if (!modalValue) {
+    const db = new Dexie('DB');
+    if (db.modal) {
+      const modalArr = await db.modal.where('modalName').equals(modalName).toArray();
+      modalValue = modalArr[0].modalVal;
     }
-    if (modalValue){
-        gltfLoader.parse(
-            modalValue,
-            '/model/glft/',
-            (gltf) => {
-                
-                const object = gltf.scene;
-                object.traverse((obj) => {
-                    if (obj instanceof THREE.Mesh) {
-                        obj.material.emissiveIntensity = 1;
-                        // obj.material.emissiveMap = obj.material.map;
-                        obj.material.blending = THREE.CustomBlending;
-                        if (obj.material.opacity < 1) {
-                            obj.material.transparent = true;
-                        }
-                        obj.renderOrder = 1;
-                        // if (obj.name !== 'buxiugangse') {
-                        //   obj.receiveShadow = true;
-                        // }
-                        // obj.castShadow = true;
-                    }
-                });
-                object.name = modalName;
-                dracoLoader.dispose();
-                self.postMessage({
-                    modalName,
-                    work_type: "parseModel",
-                    ...genGroupStruct(object),
-                    sceneAnimations: genAnimations(gltf.animations),
-                });
-                self.close();
-            },
-            (err) => {
-                console.log(err);
-                self.postMessage({ message: 'end', data: null });
-                self.close();
+  }
+  if (modalValue) {
+    gltfLoader.parse(
+      modalValue,
+      '/model/glft/',
+      (gltf) => {
+        const object = gltf.scene;
+        object.traverse((obj) => {
+          if (obj instanceof THREE.Mesh) {
+            obj.material.emissiveIntensity = 1;
+            // obj.material.emissiveMap = obj.material.map;
+            obj.material.blending = THREE.CustomBlending;
+            if (obj.material.opacity < 1) {
+              obj.material.transparent = true;
             }
-        )
-    }
+            obj.renderOrder = 1;
+            // if (obj.name !== 'buxiugangse') {
+            //   obj.receiveShadow = true;
+            // }
+            // obj.castShadow = true;
+          }
+        });
+        object.name = modalName;
+        dracoLoader.dispose();
+        self.postMessage({
+          modalName,
+          work_type: 'parseModel',
+          ...genGroupStruct(object),
+          sceneAnimations: genAnimations(gltf.animations),
+        });
+        self.close();
+      },
+      (err) => {
+        console.log(err);
+        self.postMessage({ message: 'end', data: null });
+        self.close();
+      }
+    );
+  }
 }
 
 self.addEventListener(
-    'message',
-    async function (e) {
-        const data = e.data
-        await loadModel(data)
-    },
-    false
-);
+  'message',
+  async function (e) {
+    const data = e.data;
+    await loadModel(data);
+  },
+  false
+);

+ 32 - 26
src/utils/threejs/main.worker.ts

@@ -11,32 +11,38 @@ export function initModalWorker() {
     version: string;
   };
   const modalUrlArr = [
-    'fm/fm_2023-06-02.glb',
-    'fm/Fm-door_2023-11-29.glb',
-    'fm/Fm-wire_2023-11-29.glb',
-    'fm/Fm-wire-qd_2023-11-28.glb',
-    'fm/Fm-wall_2023-11-29.glb',
-    'fm/Fm-wall-qd_2023-11-28.glb',
-    'fm/fmThree_2023-07-25.glb',
-    'fm/fmThreeBase_2023-07-25.glb',
-
-    'fm/quickObfurage-door_2023-06-02.glb',
-    'fm/quickObfurage-wire_2023-06-02.glb',
-    'fm/quickObfurage-wall_2023-06-02.glb',
-
-    'fc/wall_2023-10-11.glb',
-    // 'fc/ddFc_2023-10-11.glb',
-    // 'fc/sdFc_2023-10-19.glb',
-    'fc/ddFc_2023-06-02.glb',
-    'fc/sdFc_2023-06-02.glb',
-    'cf/lmcf_2023-06-02.glb',
-    'cf/lmcfSide_2023-06-02.glb',
-    'cf/zdcf_2023-06-02.glb',
-    'cf/dscf_2023-06-02.glb',
-    'cf/dsgd_2023-06-02.glb',
-    'cf/ddcf_2023-12-09.glb',
-    'cf/dsmove_2023-06-02.glb',
-    'cf/fixedCf_2023-11-29.glb',
+    // 'fm/fm_2023-06-02.glb',
+    // 'fm/Fm-door_2023-11-29.glb',
+    // 'fm/Fm-wire_2023-11-29.glb',
+    // 'fm/Fm-wire-qd_2023-11-28.glb',
+    // 'fm/Fm-wall_2023-11-29.glb',
+    // 'fm/Fm-wall-qd_2023-11-28.glb',
+    // 'fm/fmThree_2023-07-25.glb',
+    // 'fm/fmThreeBase_2023-07-25.glb',
+
+    // 'fm/fmXr-door_2023-12-28.glb',
+    // 'fm/fmXr-wire_2023-12-29.glb',
+    // 'fm/fmXr-wall_2023-12-29.glb',
+
+    // 'fm/quickObfurage-door_2023-06-02.glb',
+    // 'fm/quickObfurage-wire_2023-06-02.glb',
+    // 'fm/quickObfurage-wall_2023-06-02.glb',
+
+    // 'fc/wall_2023-10-11.glb',
+    // // 'fc/ddFc_2023-10-11.glb',
+    // // 'fc/sdFc_2023-10-19.glb',
+    // 'fc/ddFc_2023-06-02.glb',
+    // 'fc/sdFc_2023-06-02.glb',
+
+    // 'cf/lmcf_2023-06-02.glb',
+    // 'cf/lmcfSide_2023-06-02.glb',
+    // 'cf/zdcf_2023-06-02.glb',
+    // 'cf/dscf_2023-06-02.glb',
+    // 'cf/dsgd_2023-06-02.glb',
+    // 'cf/ddcf_2023-12-09.glb',
+    // 'cf/dsmove_2023-06-02.glb',
+    // 'cf/fixedCf_2023-11-29.glb',
+
     'jbfj/jbfj-hd_2023-12-12.glb',
     'jbfj/jbfj-fm_2023-06-02.glb',
     'jbfj/jbfj-fc_2023-06-02.glb',

+ 32 - 10
src/utils/threejs/useThree.ts

@@ -12,8 +12,13 @@ import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
 import Stats from 'three/examples/jsm/libs/stats.module.js';
 import { useModelStore } from '/@/store/modules/threejs';
 import TWEEN from 'three/examples/jsm/libs/tween.module.js';
-
 import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
+import { useGlobSetting } from '/@/hooks/setting';
+import { getList } from '@/views/vent/sys/resources/file.api';
+import { saveModel } from '/@/utils/threejs/util';
+
+const globSetting = useGlobSetting();
+const baseApiUrl = globSetting.domainUrl;
 
 // import * as dat from 'dat.gui';
 // const gui = new dat.GUI();
@@ -199,33 +204,28 @@ class UseThree {
         dracoLoader.setDecoderConfig({ type: 'js' }); //使用兼容性强的draco_decoder.js解码器
         dracoLoader.preload();
         gltfLoader.setDRACOLoader(dracoLoader);
-        gltfLoader.setPath('/model/glft/');
 
         const db = window['CustomDB'];
         const resolvePromise: Promise<any>[] = [];
 
-        let modalNameArr = Object.prototype.toString.call(modalNames) === '[object Array]' ? modalNames : [modalNames];
-        let len = modalNameArr.length;
+        const modalNameArr = Object.prototype.toString.call(modalNames) === '[object Array]' ? modalNames : [modalNames];
+        const len = modalNameArr.length;
 
         for (let i = 0; i < len; i++) {
           resolvePromise[i] = new Promise(async (childResolve, reject) => {
             try {
               // 解析模型
               const modalNameStr = modalNameArr[i];
-              let data = modelStore.modelArr.get(modalNameStr) || null;
+              const data = modelStore.modelArr.get(modalNameStr) || null;
               let modalValue;
               if (!data) {
                 const modalArr = await db.modal.where('modalName').equals(modalNameStr).toArray();
                 if (modalArr.length > 0) {
                   modalValue = modalArr[0].modalVal;
-                } else {
-                  // 开启线程下载
-                  console.log('需要开启线程下载模型资源。。。。。');
                 }
               } else {
                 modalValue = data.modalVal;
               }
-
               if (modalValue) {
                 gltfLoader.parse(
                   modalValue,
@@ -272,6 +272,28 @@ class UseThree {
                     console.log(err);
                   }
                 );
+              } else {
+                // 开启线程下载
+                console.log('需要开启线程下载模型资源。。。。。');
+                const result = (await getList({ fileName: modalNameStr })) || [];
+                const file = result['records'][0];
+                if (file && file.path) {
+                  gltfLoader.load(`${baseApiUrl}/sys/common/static/${file.path}`, async (glft) => {
+                    if (glft) {
+                      const object = glft.scene;
+                      object.name = modalNameStr;
+                      if (glft.animations.length > 0) {
+                        object.animations = glft.animations;
+                      }
+                      group?.add(object);
+                      childResolve(object);
+                      const modalArr = await db.modal.where('modalName').equals(modalNameStr).toArray();
+                      if (modalArr.length < 1) {
+                        saveModel(modalNameStr, file.path, file.version);
+                      }
+                    }
+                  });
+                }
               }
             } catch (error) {
               console.log(error);
@@ -396,7 +418,7 @@ class UseThree {
     new RGBELoader().setPath('/model/hdr/').load(hdr + '.hdr', (texture) => {
       texture.colorSpace = THREE.SRGBColorSpace;
       texture.mapping = THREE.EquirectangularReflectionMapping;
-      (this.scene as THREE.Scene).environment = texture;
+      if (this.scene) (this.scene as THREE.Scene).environment = texture;
       texture.dispose();
     });
   }

+ 29 - 3
src/utils/threejs/util.ts

@@ -10,6 +10,9 @@ import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
 import gsap from 'gsap';
 import { useAppStore } from '/@/store/modules/app';
 import UseThree from './useThree';
+import { useGlobSetting } from '/@/hooks/setting';
+const globSetting = useGlobSetting();
+const baseApiUrl = globSetting.domainUrl;
 // import * as dat from "dat.gui";
 
 /* 设置模型居中 */
@@ -488,11 +491,11 @@ export const addEnvMap = (hdr, modal) => {
 };
 
 export const setTag3D = (text, className) => {
-  var div = document.createElement('div') as HTMLElement;
+  const div = document.createElement('div') as HTMLElement;
   div.innerHTML = text;
   div.classList.add(className);
   //div元素包装为CSS3模型对象CSS3DObject
-  var label = new CSS3DObject(div);
+  const label = new CSS3DObject(div);
   div.style.pointerEvents = 'none'; //避免HTML标签遮挡三维场景的鼠标事件
   // 设置HTML元素标签在three.js世界坐标中位置
   // label.position.set(x, y, z);
@@ -522,7 +525,8 @@ const pad = function (s) {
 };
 
 export const gradientColors = function (start, end, steps, gamma) {
-  let i, j,
+  let i,
+    j,
     ms,
     me,
     output = [],
@@ -543,3 +547,25 @@ export const gradientColors = function (start, end, steps, gamma) {
   }
   return output;
 };
+
+export function saveModel(fileName, path, version) {
+  const db = window['CustomDB'];
+  const loader = new THREE.FileLoader();
+  loader.setResponseType('arraybuffer');
+  loader.setRequestHeader({});
+  loader.setWithCredentials(false);
+  try {
+    loader.load(`${baseApiUrl}/sys/common/static/${path}`, async (data) => {
+      const model = {
+        modalName: fileName,
+        modalVal: data,
+        versionStr: version,
+      };
+      const modalArr = await db.modal.where('modalName').equals(fileName).toArray();
+      if (modalArr.length > 0) {
+        db.modal.delete(fileName);
+      }
+      await db.modal.add(model);
+    });
+  } catch (error) {}
+}

+ 2 - 2
src/views/vent/deviceManager/comment/pointTabel/point.data.ts

@@ -66,7 +66,7 @@ export const columns: BasicColumn[] = [
     //     },
     //   };
     // },
-    width: 100,
+    width: 200,
   },
   {
     title: '关联字段',
@@ -96,7 +96,7 @@ export const columns: BasicColumn[] = [
     editRow: true,
     // ifShow: false,
     defaultHidden: true,
-    width: 100,
+    width: 200,
   },
 ];
 

+ 2 - 2
src/views/vent/home/colliery/index.vue

@@ -108,8 +108,8 @@
   let deviceData = ref<any>({}); //设备监测数据
   let navList = reactive([
     { name: '总风量(m³/min)', isShow: true, valList: [] },
-    // { name: '需风量(m³/min)', isShow: true, valList: [] },
-    { name: '有效风量(m³/min)', isShow: true, valList: [] },
+    { name: '需风量(m³/min)', isShow: true, valList: [] },
+    // { name: '有效风量(m³/min)', isShow: true, valList: [] },
     { name: '等积孔(m²)', isShow: true, valList: [] },
     { name: '外部漏风率', isShow: false, val: 0 },
     { name: '有效风量率', isShow: false, val: '0%' },

+ 6 - 4
src/views/vent/monitorManager/balancePressMonitor1/balancePress.three.ts

@@ -99,10 +99,12 @@ const setModalPosition = () => {
 };
 
 const setControls = () => {
-  model.orbitControls.panSpeed = 0.5;
-  model.orbitControls.rotateSpeed = 0.5;
-  model.orbitControls.maxPolarAngle = Math.PI / 2.4;
-  model.orbitControls.minPolarAngle = Math.PI / 3;
+  if (model && model.orbitControls) {
+    model.orbitControls.panSpeed = 0.5;
+    model.orbitControls.rotateSpeed = 0.5;
+    model.orbitControls.maxPolarAngle = Math.PI / 2.4;
+    model.orbitControls.minPolarAngle = Math.PI / 3;
+  }
 };
 
 // 切换局部通风机类型

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

@@ -2,8 +2,8 @@
   <div class="nitrogen-box">
     <customHeader :fieldNames="{ label: 'systemname', value: 'id', options: 'children' }" :options = 'options' @change="getSelectRow" :optionValue="optionValue">智能注氮管控系统</customHeader>
     <!-- <nitrogenHome v-if="activeKey == 'nitrogen_page' && optionValue && optionValue !='1702602347296399361'" :device-id="optionValue" :modal-type="modalType" /> -->
-    <!-- <nitrogenHome1 v-if="activeKey == 'nitrogen_page' && optionValue" :device-id="optionValue" :modal-type="modalType" /> -->
-    <nitrogenHome2 v-if="activeKey == 'nitrogen_page' && optionValue" :device-id="optionValue" :modal-type="modalType" />
+    <nitrogenHome1 v-if="activeKey == 'nitrogen_page' && optionValue" :device-id="optionValue" :modal-type="modalType" />
+    <!-- <nitrogenHome2 v-if="activeKey == 'nitrogen_page' && optionValue" :device-id="optionValue" :modal-type="modalType" /> -->
     <nitrogenEcharts v-if="activeKey == 'yfj_monitor_echarts'"/>
     <nitrogenHistory ref="historyTable" :device-id="optionValue" :device-type="optionType" v-if="activeKey == 'yfj_history'"/>
     <nitrogenHandleHistory ref="alarmHistoryTable" v-if="activeKey == 'yfj_handler_history'"/>

+ 2 - 2
src/views/vent/monitorManager/deviceMonitor/components/device/index.vue

@@ -251,7 +251,7 @@
             <div class="tab-item" :sysId="systemID" :columns-type="`${deviceType}`">
               <HistoryTable ref="historyTable" v-if="activeKey == '2'"
                 :device-type="deviceType"
-                :device-list-api="getDeviceList.bind(null, { devicekind: deviceType, sysId: systemID })"
+                :device-list-api="getDeviceList.bind(null, { devicekind: deviceType, sysId: systemID, pageSize: 10000 })"
                 designScope="device-history" :scroll="scroll" />
             </div>
           </a-tab-pane>
@@ -259,7 +259,7 @@
             <div class="tab-item">
               <AlarmHistoryTable ref="alarmHistoryTable" v-if="activeKey == '3'" :sysId="systemID" columns-type="alarm"
                 :device-type="deviceType"
-                :device-list-api="getDeviceList.bind(null, { devicekind: deviceType, sysId: systemID })" :scroll="scroll"
+                :device-list-api="getDeviceList.bind(null, { devicekind: deviceType, sysId: systemID, pageSize: 10000 })" :scroll="scroll"
                 designScope="alarm-history" />
             </div>
           </a-tab-pane>

+ 131 - 114
src/views/vent/monitorManager/fanLocalMonitor/index.vue

@@ -44,7 +44,7 @@
   <div class="scene-box">
     <div class="top-box" v-if="!loading">
       <div class="top-center row">
-        <div class="vent-flex-row" id="fanLocalSelectDom" v-if="getDictItemsByCode('fanlocaltype') && !globalConfig?.simulatedPassword">
+        <div class="vent-flex-row" id="fanLocalSelectDom" v-if="getDictItemsByCode('fanlocaltype')">
           <span style="color: #00f5fe; margin-left: 5px">风机类型:</span>
           <JDictSelectTag
             v-model:value="devicekide"
@@ -55,17 +55,18 @@
           />
         </div>
         <!-- fanlocal_systeml_zj 模拟局部风机,不显示操作按钮 -->
-        <div
-          v-if="selectData.deviceType != 'fanlocal_systeml_zj'"
-          class="button-box"
-          v-for="(item, index) in modalTypeArr.leftBtnArr"
-          :key="index"
-          @click="showModal(item)"
-          >{{ item.value }}</div
-        >
+        <template v-for="(item, index) in modalTypeArr.leftBtnArr" :key="index">
+          <div v-if="hasPermission(item.permission)" :class="{ 'button-box': btnClick, 'button-disable': !btnClick }" @click="showModal(item)">{{
+            item.value
+          }}</div>
+        </template>
       </div>
       <div class="top-right row">
-        <div class="button-box" v-for="(item, index) in modalTypeArr.rightBtnArr" :key="index" @click="showModal(item)">{{ item.value }}</div>
+        <template v-for="(item, index) in modalTypeArr.rightBtnArr" :key="index">
+          <div v-if="hasPermission(item.permission)" :class="{ 'button-box': btnClick, 'button-disable': !btnClick }" @click="showModal(item)">{{
+            item.value
+          }}</div>
+        </template>
       </div>
     </div>
     <div class="title-text">
@@ -324,15 +325,15 @@
         </div>
       </div>
       <!-- 调频 -->
-      <!-- <div class="vent-flex-row input-box" v-if="modalType == 'Fan1Frequency'">
+      <div class="vent-flex-row input-box" v-if="modalType == 'Fan1Frequency'">
         <div class="label">主风机运行频率(Hz):</div>
-        <a-input-number size="small" v-model:value="fan1FrequencyVal" :min="30" :max="50" :step="0.1" />
+        <a-input-number size="small" v-model:value="fan1FrequencyVal" :min="20" :max="50" :step="0.1" />
       </div>
       <div class="vent-flex-row input-box" v-if="modalType == 'Fan2Frequency'">
         <div class="label">备风机运行频率(Hz):</div>
-        <a-input-number size="small" v-model:value="fan2FrequencyVal" :min="30" :max="50" :step="0.1" />
-      </div> -->
-      <!-- <div class="vent-flex-row input-box" v-if="modalType == 'needAir'">
+        <a-input-number size="small" v-model:value="fan2FrequencyVal" :min="20" :max="50" :step="0.1" />
+      </div>
+      <div class="vent-flex-row input-box" v-if="modalType == 'needAir'">
         <div class="label">需风量(单位):</div>
         <a-input-number size="small" v-model:value="frequencyVal" :min="30" :max="50" :step="0.1" />
       </div>
@@ -375,7 +376,7 @@
           <div class="label">风量下限(m³/min):</div>
           <a-input-number size="small" v-model:value="modalTypeArr.rightBtnArr[3].max" :min="0" :max="50" :step="0.1" />
         </div>
-      </div> -->
+      </div>
       <!-- 启动或停止 -->
       <div class="" v-if="modalType == 'startSmoke'"> </div>
       <div v-if="!globalConfig?.simulatedPassword" class="vent-flex-row input-box">
@@ -416,104 +417,97 @@
   import { message } from 'ant-design-vue';
   import { useCamera } from '/@/hooks/system/useCamera';
   import { CaretRightOutlined } from '@ant-design/icons-vue';
+  import { usePermission } from '/@/hooks/web/usePermission';
+  const { hasPermission } = usePermission();
 
   const globalConfig = inject('globalConfig');
 
   const [registerModal, { openModal, closeModal }] = useModal();
   const { currentRoute } = useRouter();
 
-  const modalTypeArr = reactive(
-    VENT_PARAM['simulatedPassword']
-      ? {
-          leftBtnArr: [
-            {
-              key: 'startSmoke',
-              value: '启动风机',
-            },
-            {
-              key: 'changeSmoke',
-              value: '一键倒机',
-            },
-            // {
-            //   key: 'Fan1Frequency',
-            //   value: '主机调频',
-            // },
-            // {
-            //   key: 'Fan2Frequency',
-            //   value: '备机调频',
-            // },
-            {
-              key: 'windPower',
-              value: '风电闭锁',
-            },
-            {
-              key: 'gasPower',
-              value: '瓦斯电闭锁',
-            },
-            {
-              key: 'needAir',
-              value: '需风量',
-            },
-            {
-              key: 'diameter',
-              value: '风筒直径',
-            },
-            {
-              key: 'len',
-              value: '风筒长度',
-            },
-          ],
-          rightBtnArr: [
-            // {
-            //   key: 'fanlocal',
-            //   value: '变频风机',
-            // },
-            // {
-            //   key: 'fanlocaldp',
-            //   value: '定频风机',
-            // },
-            {
-              key: 'frequency',
-              value: '调频',
-            },
-            {
-              key: 'windPowerLimit',
-              value: '风电闭锁限值',
-            },
-            {
-              key: 'gasPowerLimit',
-              value: '瓦斯电闭锁限值',
-            },
-            {
-              key: 'airVolumeAlarm',
-              value: '风量报警',
-              min: 0,
-              max: 100,
-            },
-            {
-              key: 'disAirAlarm',
-              value: '漏风率报警',
-            },
-            {
-              key: 'gasAlarm',
-              value: '瓦斯报警',
-            },
-          ],
-        }
-      : {
-          leftBtnArr: [
-            {
-              key: 'startSmoke',
-              value: '启动风机',
-            },
-            {
-              key: 'changeSmoke',
-              value: '一键倒机',
-            },
-          ],
-          rightBtnArr: [],
-        }
-  );
+  const modalTypeArr = reactive({
+    leftBtnArr: [
+      {
+        key: 'startSmoke',
+        value: '启动风机',
+        permission: 'btn:openclose',
+      },
+      {
+        key: 'changeSmoke',
+        value: '一键倒机',
+        permission: 'btn:openclose',
+      },
+      {
+        key: 'Fan1Frequency',
+        value: '主机调频',
+        permission: 'btn:frequency',
+      },
+      {
+        key: 'Fan2Frequency',
+        value: '备机调频',
+        permission: 'btn:frequency',
+      },
+      {
+        key: 'windPower',
+        value: '风电闭锁',
+        permission: 'fanLocal:control',
+      },
+      {
+        key: 'gasPower',
+        value: '瓦斯电闭锁',
+        permission: 'fanLocal:control',
+      },
+      {
+        key: 'needAir',
+        value: '需风量',
+        permission: 'fanLocal:control',
+      },
+      {
+        key: 'diameter',
+        value: '风筒直径',
+        permission: 'fanLocal:control',
+      },
+      {
+        key: 'len',
+        value: '风筒长度',
+        permission: 'fanLocal:control',
+      },
+    ],
+    rightBtnArr: [
+      {
+        key: 'frequency',
+        value: '调频',
+        permission: 'fanLocal:control',
+      },
+      {
+        key: 'windPowerLimit',
+        value: '风电闭锁限值',
+        permission: 'fanLocal:control',
+      },
+      {
+        key: 'gasPowerLimit',
+        value: '瓦斯电闭锁限值',
+        permission: 'fanLocal:control',
+      },
+      {
+        key: 'airVolumeAlarm',
+        value: '风量报警',
+        permission: 'fanLocal:control',
+        min: 0,
+        max: 100,
+      },
+      {
+        key: 'disAirAlarm',
+        value: '漏风率报警',
+        permission: 'fanLocal:control',
+      },
+      {
+        key: 'gasAlarm',
+        value: '瓦斯报警',
+        permission: 'fanLocal:control',
+      },
+    ],
+  });
   const sensorList = ref<any[]>([
     {
       value: '1',
@@ -568,6 +562,7 @@
     warnLevel_str: '',
     stationname: '',
   };
+  const frequencyVal = ref(0);
   const dataSource = ref([]);
   // 监测数据
   let selectData = reactive(lodash.cloneDeep(initData));
@@ -576,6 +571,7 @@
   const devicekide = ref('fanlocal');
   const deviceType = ref(selectData.deviceType);
   const headElHeight = ref(0);
+  let btnClick = ref(true); // 判断按钮是否可点
 
   const { getCamera, webRtcServer } = useCamera();
 
@@ -752,6 +748,7 @@
 
   // 打开并设置modal的标题
   function showModal(obj) {
+    if (!btnClick.value) return;
     modalType.value = obj.key;
     modalTitle.value = obj.value;
     passWord.value = '';
@@ -785,6 +782,7 @@
       if (mainWindIsShow1.value === 'open' && mainWindIsShow2.value === 'stop') {
         // playSmoke(handType, 'top', frequency, 'open');
         data.paramcode = 'CtrlFan1Start';
+        btnClick.value = false;
         deviceControlApi(data)
           .then(() => {
             if (globalConfig.History_Type == 'remote') {
@@ -793,12 +791,16 @@
               message.success('指令已下发成功!');
             }
             modalTitle.value = '';
-            modalIsShow.value = false;
+            modalIsShow.value = true;
+            btnClick.value = true;
           })
-          .catch((err) => {});
+          .catch((err) => {
+            modalIsShow.value = true;
+          });
       } else if (mainWindIsShow2.value === 'open' && mainWindIsShow1.value === 'stop') {
         // playSmoke(handType, 'down', frequency, 'open');
         data.paramcode = 'CtrlFan2Start';
+        btnClick.value = false;
         deviceControlApi(data)
           .then(() => {
             if (globalConfig.History_Type == 'remote') {
@@ -806,10 +808,13 @@
             } else {
               message.success('指令已下发成功!');
             }
+            btnClick.value = true;
             modalTitle.value = '';
             modalIsShow.value = false;
           })
-          .catch((err) => {});
+          .catch((err) => {
+            btnClick.value = true;
+          });
       } else if (mainWindIsShow1.value === 'stop' && mainWindIsShow2.value === 'stop') {
         // playSmoke(handType, '', frequency, 'stop');
       }
@@ -823,6 +828,7 @@
         data.value = fan2FrequencyVal.value;
       }
 
+      btnClick.value = false;
       deviceControlApi(data)
         .then((res) => {
           if (globalConfig.History_Type == 'remote') {
@@ -832,11 +838,15 @@
           }
           modalTitle.value = '';
           modalIsShow.value = false;
+          btnClick.value = true;
         })
-        .catch((err) => {});
+        .catch((err) => {
+          btnClick.value = true;
+        });
     } else if (handType === 'changeSmoke') {
       if (selectData['Fan1StartStatus'] == 0 || !selectData['Fan1StartStatus']) {
         data.paramcode = 'CtrlFan1Start';
+        btnClick.value = false;
         deviceControlApi(data)
           .then((res) => {
             if (globalConfig.History_Type == 'remote') {
@@ -848,10 +858,14 @@
             modalIsShow.value = false;
             mainWindIsShow1.value = 'stop';
             mainWindIsShow2.value = 'open';
+            btnClick.value = true;
           })
-          .catch((err) => {});
+          .catch((err) => {
+            btnClick.value = true;
+          });
       } else if (selectData['Fan2StartStatus'] == 0 || !selectData['Fan2StartStatus']) {
         data.paramcode = 'CtrlFan2Start';
+        btnClick.value = false;
         deviceControlApi(data)
           .then((res) => {
             if (globalConfig.History_Type == 'remote') {
@@ -863,8 +877,11 @@
             modalIsShow.value = false;
             mainWindIsShow1.value = 'open';
             mainWindIsShow2.value = 'stop';
+            btnClick.value = true;
           })
-          .catch((err) => {});
+          .catch((err) => {
+            btnClick.value = true;
+          });
       }
       // // 一键倒机
       // if (mainWindIsShow1.value === 'open' && mainWindIsShow2.value === 'stop') {

+ 1 - 1
src/views/vent/monitorManager/gateMonitor/gate.threejs.qd.ts

@@ -523,7 +523,7 @@ class Fm3 {
         this.addLight();
         // this.deviceDetailCard();
         this.model.animate();
-
+ 
         this.backDamperOpenMesh = this.group.getObjectByName('Dampler_open_1');
         if (this.backDamperOpenMesh) this.backDamperOpenMesh.visible = false;
         this.backDamperClosedMesh = this.group.getObjectByName('Damper_Closed_1');

+ 100 - 99
src/views/vent/monitorManager/gateMonitor/gate.threejs.three.ts

@@ -1,8 +1,6 @@
-
 import * as THREE from 'three';
 import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js';
 import { getTextCanvas, renderVideo } from '/@/utils/threejs/util';
-import UseThree from '../../../../utils/threejs/useThree';
 import { drawHot } from '/@/utils/threejs/util';
 
 // import * as dat from 'dat.gui';
@@ -317,103 +315,106 @@ class Fm2 {
 
   // 播放动画
   play(handlerState, timeScale = 0.01) {
-    let handler = () => {};
-    switch (handlerState) {
-      case 1: // 打开前门
-        handler = () => {
-          this.clipActionArr.frontDoor.paused = true;
-          this.clipActionArr.frontDoor.reset();
-          this.clipActionArr.frontDoor.time = 1.2;
-          this.clipActionArr.frontDoor.timeScale = timeScale;
-          this.clipActionArr.frontDoor.clampWhenFinished = true;
-          this.clipActionArr.frontDoor.play();
-          this.fmClock.start();
-        };
-        break;
-      case 2: // 关闭前门
-        handler = () => {
-          this.clipActionArr.frontDoor.paused = true;
-          this.clipActionArr.frontDoor.reset(); //
-          this.clipActionArr.frontDoor.time = 4;
-          this.clipActionArr.frontDoor.timeScale = -timeScale;
-          this.clipActionArr.frontDoor.clampWhenFinished = true;
-          this.clipActionArr.frontDoor.play();
-          this.fmClock.start();
-        };
-        break;
-      case 3: // 打开后门
-        handler = () => {
-          this.clipActionArr.backDoor.paused = true;
-          this.clipActionArr.backDoor.reset();
-          this.clipActionArr.backDoor.time = 1.2;
-          this.clipActionArr.backDoor.timeScale = timeScale;
-          this.clipActionArr.backDoor.clampWhenFinished = true;
-          this.clipActionArr.backDoor.play();
-          this.fmClock.start();
-        };
-        break;
-      case 4: // 关闭后门
-        handler = () => {
-          this.clipActionArr.backDoor.paused = true;
-          this.clipActionArr.backDoor.reset();
-          this.clipActionArr.backDoor.time = 4;
-          this.clipActionArr.backDoor.timeScale = -timeScale;
-          this.clipActionArr.backDoor.clampWhenFinished = true;
-          this.clipActionArr.backDoor.play();
-          this.fmClock.start();
-        };
-        break;
-      // case 5: // 打开前后门
-      //   handler = () => {
-      //     this.clipActionArr.backDoor.paused = true;
-      //     this.clipActionArr.frontDoor.paused = true;
-
-      //     this.clipActionArr.frontDoor.reset();
-      //     this.clipActionArr.frontDoor.time = 0;
-      //     this.clipActionArr.frontDoor.timeScale = 0.01;
-      //     this.clipActionArr.frontDoor.clampWhenFinished = true;
-      //     this.clipActionArr.frontDoor.play();
-
-      //     this.clipActionArr.backDoor.reset();
-      //     this.clipActionArr.backDoor.time = 0;
-      //     this.clipActionArr.backDoor.timeScale = 0.01;
-      //     this.clipActionArr.backDoor.clampWhenFinished = true;
-      //     this.clipActionArr.backDoor.play();
-      //     this.fmClock.start();
-      //   };
-      //   break;
-      // case 6: // 关闭前后门
-      //   handler = () => {
-      //     this.clipActionArr.backDoor.paused = true;
-      //     this.clipActionArr.frontDoor.paused = true;
-
-      //     this.clipActionArr.frontDoor.reset();
-      //     this.clipActionArr.frontDoor.time = 4;
-      //     this.clipActionArr.frontDoor.timeScale = -0.01;
-      //     this.clipActionArr.frontDoor.clampWhenFinished = true;
-      //     this.clipActionArr.frontDoor.play();
-      //     this.clipActionArr.backDoor.reset();
-      //     this.clipActionArr.backDoor.time = 4;
-      //     this.clipActionArr.backDoor.timeScale = -0.01;
-      //     this.clipActionArr.backDoor.clampWhenFinished = true;
-      //     this.clipActionArr.backDoor.play();
-      //     this.fmClock.start();
-      //   };
-      //   break;
-      default:
-    }
+    debugger;
+    if (this.clipActionArr.frontDoor && this.clipActionArr.backDoor) {
+      let handler = () => {};
+      switch (handlerState) {
+        case 1: // 打开前门
+          handler = () => {
+            this.clipActionArr.frontDoor.paused = true;
+            this.clipActionArr.frontDoor.reset();
+            this.clipActionArr.frontDoor.time = 1.2;
+            this.clipActionArr.frontDoor.timeScale = timeScale;
+            this.clipActionArr.frontDoor.clampWhenFinished = true;
+            this.clipActionArr.frontDoor.play();
+            this.fmClock.start();
+          };
+          break;
+        case 2: // 关闭前门
+          handler = () => {
+            this.clipActionArr.frontDoor.paused = true;
+            this.clipActionArr.frontDoor.reset(); //
+            this.clipActionArr.frontDoor.time = 4;
+            this.clipActionArr.frontDoor.timeScale = -timeScale;
+            this.clipActionArr.frontDoor.clampWhenFinished = true;
+            this.clipActionArr.frontDoor.play();
+            this.fmClock.start();
+          };
+          break;
+        case 3: // 打开后门
+          handler = () => {
+            this.clipActionArr.backDoor.paused = true;
+            this.clipActionArr.backDoor.reset();
+            this.clipActionArr.backDoor.time = 1.2;
+            this.clipActionArr.backDoor.timeScale = timeScale;
+            this.clipActionArr.backDoor.clampWhenFinished = true;
+            this.clipActionArr.backDoor.play();
+            this.fmClock.start();
+          };
+          break;
+        case 4: // 关闭后门
+          handler = () => {
+            this.clipActionArr.backDoor.paused = true;
+            this.clipActionArr.backDoor.reset();
+            this.clipActionArr.backDoor.time = 4;
+            this.clipActionArr.backDoor.timeScale = -timeScale;
+            this.clipActionArr.backDoor.clampWhenFinished = true;
+            this.clipActionArr.backDoor.play();
+            this.fmClock.start();
+          };
+          break;
+        // case 5: // 打开前后门
+        //   handler = () => {
+        //     this.clipActionArr.backDoor.paused = true;
+        //     this.clipActionArr.frontDoor.paused = true;
+
+        //     this.clipActionArr.frontDoor.reset();
+        //     this.clipActionArr.frontDoor.time = 0;
+        //     this.clipActionArr.frontDoor.timeScale = 0.01;
+        //     this.clipActionArr.frontDoor.clampWhenFinished = true;
+        //     this.clipActionArr.frontDoor.play();
+
+        //     this.clipActionArr.backDoor.reset();
+        //     this.clipActionArr.backDoor.time = 0;
+        //     this.clipActionArr.backDoor.timeScale = 0.01;
+        //     this.clipActionArr.backDoor.clampWhenFinished = true;
+        //     this.clipActionArr.backDoor.play();
+        //     this.fmClock.start();
+        //   };
+        //   break;
+        // case 6: // 关闭前后门
+        //   handler = () => {
+        //     this.clipActionArr.backDoor.paused = true;
+        //     this.clipActionArr.frontDoor.paused = true;
+
+        //     this.clipActionArr.frontDoor.reset();
+        //     this.clipActionArr.frontDoor.time = 4;
+        //     this.clipActionArr.frontDoor.timeScale = -0.01;
+        //     this.clipActionArr.frontDoor.clampWhenFinished = true;
+        //     this.clipActionArr.frontDoor.play();
+        //     this.clipActionArr.backDoor.reset();
+        //     this.clipActionArr.backDoor.time = 4;
+        //     this.clipActionArr.backDoor.timeScale = -0.01;
+        //     this.clipActionArr.backDoor.clampWhenFinished = true;
+        //     this.clipActionArr.backDoor.play();
+        //     this.fmClock.start();
+        //   };
+        //   break;
+        default:
+      }
 
-    handler();
-    // model.clock.start();
-    // const honglvdeng = group.getObjectByName('honglvdeng');
-    // const material = honglvdeng.material;
-    // setTimeout(() => {
-    //   if (handlerState === 2 || handlerState === 4 || handlerState === 6) {
-    //     material.color = new THREE.Color(0x00ff00);
-    //   } else {
-    //     material.color = new THREE.Color(0xff0000);
-    //   }
-    // }, 1000);
+      handler();
+      // model.clock.start();
+      // const honglvdeng = group.getObjectByName('honglvdeng');
+      // const material = honglvdeng.material;
+      // setTimeout(() => {
+      //   if (handlerState === 2 || handlerState === 4 || handlerState === 6) {
+      //     material.color = new THREE.Color(0x00ff00);
+      //   } else {
+      //     material.color = new THREE.Color(0xff0000);
+      //   }
+      // }, 1000);
+    }
   }
 
   async initCamera(dom1?) {
@@ -466,7 +467,7 @@ class Fm2 {
     this.group = new THREE.Object3D();
     this.group.name = this.modelName;
     return new Promise((resolve) => {
-      this.model.setGLTFModel(['fmThree', 'fmThreeBase'], this.group).then(() => {
+      this.model.setGLTFModel(['fmThreeBase', 'fmThree'], this.group).then(() => {
         this.group.name = 'fm2';
         this.setModalPosition();
         // 初始化左右摇摆动画;

+ 98 - 25
src/views/vent/monitorManager/gateMonitor/gate.threejs.ts

@@ -2,6 +2,7 @@ import * as THREE from 'three';
 import UseThree from '../../../../utils/threejs/useThree';
 import Fm1 from './gate.threejs.yy';
 import Fm3 from './gate.threejs.qd';
+import FmXR from './gate.threejs.xr';
 import Fm2 from './gate.threejs.three';
 import { animateCamera } from '/@/utils/threejs/util';
 import useEvent from '../../../../utils/threejs/useEvent';
@@ -11,6 +12,7 @@ let model,
   fm1: Fm1,
   fm2: Fm2,
   fm3: Fm3,
+  fmXr: FmXR,
   group: THREE.Object3D,
   fmType = '';
 
@@ -29,6 +31,8 @@ const startAnimation = () => {
       fm2.mouseUpModel.call(fm2);
     } else if (fmType === 'fm3') {
       fm3.mouseUpModel.call(fm3);
+    } else if (fmType === 'fmXr') {
+      fmXr.mouseUpModel.call(fmXr);
     }
   });
 };
@@ -43,6 +47,8 @@ const mouseEvent = (event) => {
         fm2.mousedownModel.call(fm2, intersects);
       } else if (fmType === 'fm3' && fm3) {
         fm3.mousedownModel.call(fm3, intersects);
+      } else if (fmType === 'fmXr' && fmXr) {
+        fmXr.mousedownModel.call(fmXr, intersects);
       }
     });
     // console.log('摄像头控制信息', model.orbitControls, model.camera);
@@ -56,6 +62,8 @@ export const addMonitorText = (selectData) => {
     return fm2.addMonitorText.call(fm2, selectData);
   } else if (fmType === 'fm3' && fm3) {
     return fm3.addMonitorText.call(fm3, selectData);
+  } else if (fmType === 'fmXr' && fmXr) {
+    return fmXr.addMonitorText.call(fmXr, selectData);
   }
 };
 
@@ -64,6 +72,8 @@ export const deviceDetailCard = () => {
     return fm1.deviceDetailCard.call(fm1);
   } else if (fmType === 'fm3') {
     return fm3.deviceDetailCard.call(fm3);
+  } else if (fmType === 'fmXr') {
+    return fmXr.deviceDetailCard.call(fmXr);
   } else {
     // return fm2.addMonitorText.call(fm2);
   }
@@ -76,6 +86,8 @@ export const play = (handlerState, flag?) => {
     return fm2.play.call(fm2, handlerState, flag);
   } else if (fmType === 'fm3' && fm3) {
     return fm3.play.call(fm3, handlerState, flag);
+  } else if (fmType === 'fmXr' && fmXr) {
+    return fmXr.play.call(fmXr, handlerState, flag);
   }
 };
 
@@ -85,12 +97,14 @@ export const setModelType = (type) => {
   return new Promise((resolve) => {
     // 暂停风门1动画
     if (fmType === 'fm1' && fm1 && fm1.group) {
-      fm1.clipActionArr.frontDoor.reset();
-      fm1.clipActionArr.frontDoor.time = 0.5;
-      fm1.clipActionArr.backDoor.reset();
-      fm1.clipActionArr.backDoor.time = 0.5;
-      fm1.clipActionArr.frontDoor.stop();
-      fm1.clipActionArr.backDoor.stop();
+      if (fm1.clipActionArr.frontDoor && fm1.clipActionArr.backDoor) {
+        fm1.clipActionArr.frontDoor.reset();
+        fm1.clipActionArr.frontDoor.time = 0.5;
+        fm1.clipActionArr.backDoor.reset();
+        fm1.clipActionArr.backDoor.time = 0.5;
+        fm1.clipActionArr.frontDoor.stop();
+        fm1.clipActionArr.backDoor.stop();
+      }
 
       if (fm1.frontDamperOpenMesh) fm1.frontDamperOpenMesh.visible = false;
       if (fm1.frontDamperClosedMesh) fm1.frontDamperClosedMesh.visible = true;
@@ -106,6 +120,9 @@ export const setModelType = (type) => {
       if (model.scene.getObjectByName('fm3')) {
         model.scene.remove(fm3.group);
       }
+      if (model.scene.getObjectByName('fmXr')) {
+        model.scene.remove(fmXr.group);
+      }
       const oldCameraPosition = { x: -1000, y: 100, z: 500 };
       setTimeout(async () => {
         resolve(null);
@@ -120,15 +137,17 @@ export const setModelType = (type) => {
         );
       }, 300);
     } else if (fmType === 'fm2' && fm2 && fm2.group) {
-      fm2.clipActionArr.frontDoor.reset();
-      fm2.clipActionArr.frontDoor.time = 0.5;
-      fm2.clipActionArr.backDoor.reset();
-      fm2.clipActionArr.backDoor.time = 0.5;
-      fm2.clipActionArr.centerDoor.reset();
-      fm2.clipActionArr.centerDoor.time = 0.5;
-      fm2.clipActionArr.frontDoor.stop();
-      fm2.clipActionArr.backDoor.stop();
-      fm2.clipActionArr.centerDoor.stop();
+      if (fm2.clipActionArr.frontDoor && fm2.clipActionArr.backDoor) {
+        fm2.clipActionArr.frontDoor.reset();
+        fm2.clipActionArr.frontDoor.time = 0.5;
+        fm2.clipActionArr.backDoor.reset();
+        fm2.clipActionArr.backDoor.time = 0.5;
+        fm2.clipActionArr.centerDoor.reset();
+        fm2.clipActionArr.centerDoor.time = 0.5;
+        fm2.clipActionArr.frontDoor.stop();
+        fm2.clipActionArr.backDoor.stop();
+        fm2.clipActionArr.centerDoor.stop();
+      }
 
       // 显示单道风窗
       model.startAnimation = fm2.render.bind(fm2);
@@ -139,6 +158,9 @@ export const setModelType = (type) => {
       if (model.scene.getObjectByName('fm3')) {
         model.scene.remove(fm3.group);
       }
+      if (model.scene.getObjectByName('fmXr')) {
+        model.scene.remove(fmXr.group);
+      }
       const oldCameraPosition = { x: -761, y: 569, z: 871 };
       setTimeout(async () => {
         resolve(null);
@@ -154,12 +176,14 @@ export const setModelType = (type) => {
         );
       }, 300);
     } else if (fmType === 'fm3' && fm3 && fm3.group) {
-      fm3.clipActionArr.frontDoor.reset();
-      fm3.clipActionArr.frontDoor.time = 0.5;
-      fm3.clipActionArr.backDoor.reset();
-      fm3.clipActionArr.backDoor.time = 0.5;
-      fm3.clipActionArr.frontDoor.stop();
-      fm3.clipActionArr.backDoor.stop();
+      if (fm3.clipActionArr.frontDoor && fm3.clipActionArr.backDoor) {
+        fm3.clipActionArr.frontDoor.reset();
+        fm3.clipActionArr.frontDoor.time = 0.5;
+        fm3.clipActionArr.backDoor.reset();
+        fm3.clipActionArr.backDoor.time = 0.5;
+        fm3.clipActionArr.frontDoor.stop();
+        fm3.clipActionArr.backDoor.stop();
+      }
 
       if (fm3.frontDamperOpenMesh) fm3.frontDamperOpenMesh.visible = false;
       if (fm3.frontDamperClosedMesh) fm3.frontDamperClosedMesh.visible = true;
@@ -175,6 +199,9 @@ export const setModelType = (type) => {
       if (model.scene.getObjectByName('fm1')) {
         model.scene.remove(fm1.group);
       }
+      if (model.scene.getObjectByName('fmXr')) {
+        model.scene.remove(fmXr.group);
+      }
       const oldCameraPosition = { x: -1000, y: 100, z: 500 };
       setTimeout(async () => {
         resolve(null);
@@ -188,6 +215,46 @@ export const setModelType = (type) => {
           0.8
         );
       }, 300);
+    } else if (fmType === 'fmXr' && fmXr && fmXr.group) {
+      if (fmXr.clipActionArr.frontDoor && fmXr.clipActionArr.backDoor) {
+        fmXr.clipActionArr.frontDoor.reset();
+        fmXr.clipActionArr.frontDoor.time = 0.5;
+        fmXr.clipActionArr.backDoor.reset();
+        fmXr.clipActionArr.backDoor.time = 0.5;
+        fmXr.clipActionArr.frontDoor.stop();
+        fmXr.clipActionArr.backDoor.stop();
+      }
+
+      if (fmXr.frontDamperOpenMesh) fmXr.frontDamperOpenMesh.visible = false;
+      if (fmXr.frontDamperClosedMesh) fmXr.frontDamperClosedMesh.visible = true;
+      if (fmXr.backDamperOpenMesh) fmXr.backDamperOpenMesh.visible = false;
+      if (fmXr.backDamperClosedMesh) fmXr.backDamperClosedMesh.visible = true;
+
+      model.startAnimation = fmXr.render.bind(fmXr);
+      group = fmXr.group;
+      group.rotation.y = 0;
+      if (model.scene.getObjectByName('fm2')) {
+        model.scene.remove(fm2.group);
+      }
+      if (model.scene.getObjectByName('fm1')) {
+        model.scene.remove(fm1.group);
+      }
+      if (model.scene.getObjectByName('fm3')) {
+        model.scene.remove(fm3.group);
+      }
+      const oldCameraPosition = { x: -1000, y: 100, z: 500 };
+      setTimeout(async () => {
+        resolve(null);
+        model.scene.add(fmXr.group);
+        await animateCamera(
+          oldCameraPosition,
+          { x: 0, y: 0, z: 0 },
+          { x: 50.99, y: 69.32, z: 93.61 },
+          { x: -10.04, y: -14.38, z: -31.4 },
+          model,
+          0.8
+        );
+      }, 300);
     }
   });
 };
@@ -199,6 +266,8 @@ export const initCameraCanvas = async (playerVal1) => {
     return fm2.initCamera.call(fm2, playerVal1);
   } else if (fmType === 'fm3' && fm3) {
     return fm3.initCamera.call(fm3, playerVal1);
+  } else if (fmType === 'fmXr' && fmXr) {
+    return fmXr.initCamera.call(fmXr, playerVal1);
   }
 };
 
@@ -206,17 +275,19 @@ export const mountedThree = (playerDom) => {
   return new Promise(async (resolve) => {
     model = new UseThree('#damper3D', '', '#deviceDetail');
     model.setEnvMap('test1');
+    resolve(null);
     model.renderer.toneMappingExposure = 1.0;
     model.camera.position.set(100, 0, 1000);
     // 单道、 双道
     fm1 = new Fm1(model);
-    await fm1.mountedThree(playerDom);
+    fm1.mountedThree(playerDom);
     fm2 = new Fm2(model);
-    await fm2.mountedThree(playerDom);
+    fm2.mountedThree(playerDom);
     fm3 = new Fm3(model);
-    await fm3.mountedThree(playerDom);
+    fm3.mountedThree(playerDom);
+    fmXr = new FmXR(model);
+    fmXr.mountedThree(playerDom);
     model.animate();
-    resolve(null);
     startAnimation();
   });
 };
@@ -227,9 +298,11 @@ export const destroy = () => {
     if (fm1) fm1.destroy();
     if (fm2) fm2.destroy();
     if (fm3) fm3.destroy();
+    if (fmXr) fmXr.destroy();
     fm1 = null;
     fm2 = null;
     fm3 = null;
+    fmXr = null;
     group = null;
     model.mixers = [];
     model.destroy();

+ 114 - 112
src/views/vent/monitorManager/gateMonitor/gate.threejs.yy.ts

@@ -328,119 +328,121 @@ class Fm1 {
 
   // 播放动画
   play(handlerState, timeScale = 0.01) {
-    let handler = () => {};
-    switch (handlerState) {
-      case 1: // 打开前门
-        handler = () => {
-          this.clipActionArr.frontDoor.paused = true;
-          this.clipActionArr.frontDoor.reset();
-          this.clipActionArr.frontDoor.time = 1.2;
-          this.clipActionArr.frontDoor.timeScale = timeScale;
-          // this.clipActionArr.frontDoor.clampWhenFinished = true;
-          this.clipActionArr.frontDoor.play();
-          this.fmClock.start();
-
-          // 显示打开前门文字
-          if (this.frontDamperOpenMesh) this.frontDamperOpenMesh.visible = true;
-          if (this.frontDamperClosedMesh) this.frontDamperClosedMesh.visible = false;
-        };
-        break;
-      case 2: // 关闭前门
-        handler = () => {
-          this.clipActionArr.frontDoor.paused = true;
-          this.clipActionArr.frontDoor.reset(); //
-          this.clipActionArr.frontDoor.time = 4;
-          this.clipActionArr.frontDoor.timeScale = -timeScale;
-          // this.clipActionArr.frontDoor.clampWhenFinished = true;
-          this.clipActionArr.frontDoor.play();
-          this.fmClock.start();
-
-          if (this.frontDamperOpenMesh) this.frontDamperOpenMesh.visible = false;
-          if (this.frontDamperClosedMesh) this.frontDamperClosedMesh.visible = true;
-        };
-        break;
-      case 3: // 打开后门
-        handler = () => {
-          this.clipActionArr.backDoor.paused = true;
-          this.clipActionArr.backDoor.reset();
-          this.clipActionArr.backDoor.time = 1.2;
-          this.clipActionArr.backDoor.timeScale = timeScale;
-          // this.clipActionArr.backDoor.clampWhenFinished = true;
-          this.clipActionArr.backDoor.play();
-          this.fmClock.start();
-
-          if (this.backDamperOpenMesh) this.backDamperOpenMesh.visible = true;
-          if (this.backDamperClosedMesh) this.backDamperClosedMesh.visible = false;
-        };
-        break;
-      case 4: // 关闭后门
-        handler = () => {
-          this.clipActionArr.backDoor.paused = true;
-          this.clipActionArr.backDoor.reset();
-          this.clipActionArr.backDoor.time = 4;
-          this.clipActionArr.backDoor.timeScale = -timeScale;
-          // this.clipActionArr.backDoor.clampWhenFinished = true;
-          this.clipActionArr.backDoor.play();
-          this.fmClock.start();
-
-          if (this.backDamperOpenMesh) this.backDamperOpenMesh.visible = false;
-          if (this.backDamperClosedMesh) this.backDamperClosedMesh.visible = true;
-        };
-        break;
-      // case 5: // 打开前后门
-      //   handler = () => {
-      //     this.clipActionArr.backDoor.paused = true;
-      //     this.clipActionArr.frontDoor.paused = true;
-
-      //     this.clipActionArr.frontDoor.reset();
-      //     this.clipActionArr.frontDoor.time = 0;
-      //     this.clipActionArr.frontDoor.timeScale = 0.01;
-      //     this.clipActionArr.frontDoor.clampWhenFinished = true;
-      //     this.clipActionArr.frontDoor.play();
-
-      //     this.clipActionArr.backDoor.reset();
-      //     this.clipActionArr.backDoor.time = 0;
-      //     this.clipActionArr.backDoor.timeScale = 0.01;
-      //     this.clipActionArr.backDoor.clampWhenFinished = true;
-      //     this.clipActionArr.backDoor.play();
-      //     this.frontClock.start();
-      //     this.backClock.start();
-      //   };
-      //   break;
-      // case 6: // 关闭前后门
-      //   handler = () => {
-      //     debugger;
-      //     this.clipActionArr.backDoor.paused = true;
-      //     this.clipActionArr.frontDoor.paused = true;
-
-      //     this.clipActionArr.frontDoor.reset();
-      //     this.clipActionArr.frontDoor.time = 4;
-      //     this.clipActionArr.frontDoor.timeScale = -0.01;
-      //     this.clipActionArr.frontDoor.clampWhenFinished = true;
-      //     this.clipActionArr.frontDoor.play();
-      //     this.clipActionArr.backDoor.reset();
-      //     this.clipActionArr.backDoor.time = 4;
-      //     this.clipActionArr.backDoor.timeScale = -0.01;
-      //     this.clipActionArr.backDoor.clampWhenFinished = true;
-      //     this.clipActionArr.backDoor.play();
-      //     this.frontClock.start();
-      //     this.backClock.start();
-      //   };
-      //   break;
-      default:
-    }
+    if (this.clipActionArr.frontDoor && this.clipActionArr.backDoor) {
+      let handler = () => {};
+      switch (handlerState) {
+        case 1: // 打开前门
+          handler = () => {
+            this.clipActionArr.frontDoor.paused = true;
+            this.clipActionArr.frontDoor.reset();
+            this.clipActionArr.frontDoor.time = 1.2;
+            this.clipActionArr.frontDoor.timeScale = timeScale;
+            // this.clipActionArr.frontDoor.clampWhenFinished = true;
+            this.clipActionArr.frontDoor.play();
+            this.fmClock.start();
+
+            // 显示打开前门文字
+            if (this.frontDamperOpenMesh) this.frontDamperOpenMesh.visible = true;
+            if (this.frontDamperClosedMesh) this.frontDamperClosedMesh.visible = false;
+          };
+          break;
+        case 2: // 关闭前门
+          handler = () => {
+            this.clipActionArr.frontDoor.paused = true;
+            this.clipActionArr.frontDoor.reset(); //
+            this.clipActionArr.frontDoor.time = 4;
+            this.clipActionArr.frontDoor.timeScale = -timeScale;
+            // this.clipActionArr.frontDoor.clampWhenFinished = true;
+            this.clipActionArr.frontDoor.play();
+            this.fmClock.start();
+
+            if (this.frontDamperOpenMesh) this.frontDamperOpenMesh.visible = false;
+            if (this.frontDamperClosedMesh) this.frontDamperClosedMesh.visible = true;
+          };
+          break;
+        case 3: // 打开后门
+          handler = () => {
+            this.clipActionArr.backDoor.paused = true;
+            this.clipActionArr.backDoor.reset();
+            this.clipActionArr.backDoor.time = 1.2;
+            this.clipActionArr.backDoor.timeScale = timeScale;
+            // this.clipActionArr.backDoor.clampWhenFinished = true;
+            this.clipActionArr.backDoor.play();
+            this.fmClock.start();
+
+            if (this.backDamperOpenMesh) this.backDamperOpenMesh.visible = true;
+            if (this.backDamperClosedMesh) this.backDamperClosedMesh.visible = false;
+          };
+          break;
+        case 4: // 关闭后门
+          handler = () => {
+            this.clipActionArr.backDoor.paused = true;
+            this.clipActionArr.backDoor.reset();
+            this.clipActionArr.backDoor.time = 4;
+            this.clipActionArr.backDoor.timeScale = -timeScale;
+            // this.clipActionArr.backDoor.clampWhenFinished = true;
+            this.clipActionArr.backDoor.play();
+            this.fmClock.start();
+
+            if (this.backDamperOpenMesh) this.backDamperOpenMesh.visible = false;
+            if (this.backDamperClosedMesh) this.backDamperClosedMesh.visible = true;
+          };
+          break;
+        // case 5: // 打开前后门
+        //   handler = () => {
+        //     this.clipActionArr.backDoor.paused = true;
+        //     this.clipActionArr.frontDoor.paused = true;
+
+        //     this.clipActionArr.frontDoor.reset();
+        //     this.clipActionArr.frontDoor.time = 0;
+        //     this.clipActionArr.frontDoor.timeScale = 0.01;
+        //     this.clipActionArr.frontDoor.clampWhenFinished = true;
+        //     this.clipActionArr.frontDoor.play();
+
+        //     this.clipActionArr.backDoor.reset();
+        //     this.clipActionArr.backDoor.time = 0;
+        //     this.clipActionArr.backDoor.timeScale = 0.01;
+        //     this.clipActionArr.backDoor.clampWhenFinished = true;
+        //     this.clipActionArr.backDoor.play();
+        //     this.frontClock.start();
+        //     this.backClock.start();
+        //   };
+        //   break;
+        // case 6: // 关闭前后门
+        //   handler = () => {
+        //     debugger;
+        //     this.clipActionArr.backDoor.paused = true;
+        //     this.clipActionArr.frontDoor.paused = true;
+
+        //     this.clipActionArr.frontDoor.reset();
+        //     this.clipActionArr.frontDoor.time = 4;
+        //     this.clipActionArr.frontDoor.timeScale = -0.01;
+        //     this.clipActionArr.frontDoor.clampWhenFinished = true;
+        //     this.clipActionArr.frontDoor.play();
+        //     this.clipActionArr.backDoor.reset();
+        //     this.clipActionArr.backDoor.time = 4;
+        //     this.clipActionArr.backDoor.timeScale = -0.01;
+        //     this.clipActionArr.backDoor.clampWhenFinished = true;
+        //     this.clipActionArr.backDoor.play();
+        //     this.frontClock.start();
+        //     this.backClock.start();
+        //   };
+        //   break;
+        default:
+      }
 
-    handler();
-    // model.clock.start();
-    // const honglvdeng = group.getObjectByName('honglvdeng');
-    // const material = honglvdeng.material;
-    // setTimeout(() => {
-    //   if (handlerState === 2 || handlerState === 4 || handlerState === 6) {
-    //     material.color = new THREE.Color(0x00ff00);
-    //   } else {
-    //     material.color = new THREE.Color(0xff0000);
-    //   }
-    // }, 1000);
+      handler();
+      // model.clock.start();
+      // const honglvdeng = group.getObjectByName('honglvdeng');
+      // const material = honglvdeng.material;
+      // setTimeout(() => {
+      //   if (handlerState === 2 || handlerState === 4 || handlerState === 6) {
+      //     material.color = new THREE.Color(0x00ff00);
+      //   } else {
+      //     material.color = new THREE.Color(0xff0000);
+      //   }
+      // }, 1000);
+    }
   }
 
   async initCamera(dom1) {

+ 10 - 7
src/views/vent/monitorManager/gateMonitor/index.vue

@@ -68,19 +68,22 @@
               :isShowPagination="true"
             >
               <template #filterCell="{ column, record }">
-                <a-tag v-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 0 && record.frontGateClose == 0" color="red"
+                <a-tag v-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == '0' && record.frontGateClose == '0'" color="red"
                   >正在运行</a-tag
                 >
-                <a-tag v-else-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 0 && record.frontGateClose == 1" color="default"
+                <a-tag v-else-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == '0' && record.frontGateClose == 1" color="default"
                   >关闭</a-tag
                 >
-                <a-tag v-else-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 1 && record.frontGateClose == 0" color="#46C66F"
+                <a-tag v-else-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 1 && record.frontGateClose == '0'" color="#46C66F"
                   >打开</a-tag
                 >
-                <a-tag v-else-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 0 && record.rearGateClose == 1" color="default"
+                <a-tag v-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == '0' && record.rearGateClose == '0'" color="red"
+                  >正在运行</a-tag
+                >
+                <a-tag v-else-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == '0' && record.rearGateClose == 1" color="default"
                   >关闭</a-tag
                 >
-                <a-tag v-else-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 1 && record.rearGateClose == 0" color="default"
+                <a-tag v-else-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 1 && record.rearGateClose == '0'" color="#46C66F"
                   >打开</a-tag
                 >
                 <template v-if="column.dataIndex === 'ndoortype'">
@@ -565,7 +568,7 @@
     }
     if (selectData.frontGateClose == 1 && selectData.frontGateOpen == 0) {
       isFrontCloseRunning = false;
-      if (frontDeviceState == 1) {
+      if (frontDeviceState != 2) {
         // import.meta.env.VITE_GLOB_IS_SIMULATE ? play(2, timeScale) : play(2);
         play(2, timeScale);
         frontDeviceState = 2;
@@ -587,7 +590,7 @@
 
     if (selectData.rearGateClose == 1 && selectData.rearGateOpen == 0) {
       isRearCloseRunning = false;
-      if (rearDeviceState == 3) {
+      if (rearDeviceState != 4) {
         rearDeviceState = 4;
         // import.meta.env.VITE_GLOB_IS_SIMULATE ? play(4, timeScale) : play(4);
         play(4, timeScale);

+ 366 - 59
src/views/vent/monitorManager/groutMonitor/components/groutHome.vue

@@ -1,23 +1,116 @@
 <template>
   <div class="monitor-container">
-    <div class="header-box">
-      <div class="header-container">
-        <div class="device-detail">
-          <div class="device-title">&nbsp</div>
-          <div class="device-val">是否带电</div>
-          <div class="device-val">是否运行</div>
-          <div class="device-val">故障</div>
-        </div>
-        <div v-for="(device, key) in deviceMonitorList" class="device-detail" :key="key">
-          <div class="device-title">{{ device.title }}</div>
-          <div v-for="(detailItem, index) in device.dataList" :key="detailItem.code" class="device-val">
-            <span v-if="index == 0" :style="{color: monitorData[detailItem.code] != 1 ? '#BFBFBF' : '#10BC79'}">{{ monitorData[detailItem.code] == 0 ? '不带电' : monitorData[detailItem.code] == 1 ? '带电' : '-' }}</span>
-            <span v-if="index == 1" :style="{ color: monitorData[detailItem.code] != 1 ? '#BFBFBF' : '#10BC79' }">{{ monitorData[detailItem.code] == 0 ? '未运行' : monitorData[detailItem.code] == 1 ? '运行' : '-' }}</span>
-            <span v-if="index == 2" :style="{ color: monitorData[detailItem.code] == 0 ? '#10BC79' : monitorData[detailItem.code] == 1 ? '#F14C4C' : '#BFBFBF'}">{{ monitorData[detailItem.code] == 0 ? '正常' :  monitorData[detailItem.code] == 1 ? '报警' : '-'}}</span>
-          </div>
-        </div>
+    <div class="lr left-box">
+      <div class="monitor-info item-box">
+        <ventBox1>
+          <template #title>
+            <div>设备信息监测</div>
+          </template>
+          <template #container v-if="dataSource.length > 0 ">
+            <div v-for="(monitor, key) in deviceMonitorData" :key="key" class="monitor-item">
+              <div class="item-title">{{ monitor.text }}</div>
+              <div class="item-val">{{ key.startsWith('1#') ? dataSource[0][key.split('_')[1]]||'-' : key.startsWith('2#') ? dataSource[1][key.split('_')[1]]||'-' : (dataSource[0][key] || '-') }}</div>
+              <div class="item-unit">{{ monitor.unit }}</div>
+            </div>
+          </template>
+        </ventBox1>
+      </div>
+      <div class="warning-group">
+        <ventBox1>
+          <template #title>
+            <div>近一月报警情况</div>
+          </template>
+          <template #container>
+           <dv-scroll-board ref="scrollBoard" :config="warningConfig"
+              style="width: 100%; height: 240px; overflow-y: auto; " />
+          </template>
+        </ventBox1>
+      </div>
+      <div class="item-box vent-margin-t-10">
+        <!-- <LivePlayer id="fm-player1" style="height: 220px;" ref="player1" :videoUrl="flvURL1()" muted live loading controls /> -->
       </div>
     </div>
+    <div class="lr right-box">
+      <div class="control-container item-box">
+        <ventBox1>
+          <template #title>
+            <div>设备设施集中控制</div>
+          </template>
+          <template #container >
+            <div class="control-group">
+              <div class="control-item" v-for="(item, key) in deviceControlData" :key="key">
+                <div class="control-item-title">{{ item }}</div>
+                <div class="control-item-state" v-if="!key.startsWith('2#')">
+                  <a-switch v-model="dataSource[0][key.split('_')[1]]" size="small"  checked-children="开启"
+                    un-checked-children="关闭"
+                    @change="handlerDevice(dataSource[0][key.split('_')[1]])">
+                  </a-switch>
+                </div>
+                <div class="control-item-state" v-else>
+                  <a-switch v-model="dataSource[1][key.split('_')[1]]" size="small"  checked-children="开启"
+                    un-checked-children="关闭"
+                    @change="handlerDevice(dataSource[1][key.split('_')[1]])">
+                  </a-switch>
+                </div>
+              </div>
+            </div>
+            <a-divider style="height: 1px; background-color: #d7d7d755" />
+            <div class="control-btn-group">
+              <div class="control-left-box">
+                <div class="btn-box">
+                  <span @click="handlerDevice({ remote : true})">远程</span>
+                  <span @click="handlerDevice({ remote: false })">就地</span>
+                </div>
+                <div class="icon-box" :class="{'remote-icon-box': true}">
+                  <div class="icon"></div>
+                </div>
+              </div>
+              <div class="control-right-box">
+                <a-button class="btn" type="primary" @click="handlerDevice({run: true})">一键启动</a-button>
+                <a-button type="primary" danger @click="handlerDevice({ run: false })">紧急停止</a-button>
+              </div>
+            </div>
+            <a-divider style="height: 1px; background-color: #d7d7d755" />
+            <div class="parameter-btn-group"> 
+              <a-button type="primary"  @click="openModal('RunParameterModal')">参数设置</a-button>
+              <a-button type="primary"  @click="openModal('WarningParameterModal')">报警设置</a-button>
+            </div>
+          </template>
+        </ventBox1>    
+      </div>
+      <div class="control-container item-box echarts-box">
+        <ventBox1>
+          <template #title>
+            <div>设备实时监测曲线</div>
+          </template>
+          <template #container >
+            <div class="btn-group">
+              <span class="active">注浆流量</span>
+              <span>注浆压力</span>
+              <span>水舱液位</span>
+              <span>注浆筒液位</span>
+            </div>
+            <div class="item-box echarts-container">
+              <div class="echarts-group">
+                <div class="echarts-item">
+                  <BarAndLineCustom xAxisPropType="readTime" :chartData="dataSource" height="240px" :propTypeArr="['flowRate']" :option="zhujiangOption" />
+                </div>
+                <div class="echarts-item">
+                  <BarAndLineCustom xAxisPropType="readTime" :chartData="dataSource" height="240px" :propTypeArr="['pressure']" :option="yaliOption" />
+                </div>
+                <div class="echarts-item">
+                  <BarAndLineCustom xAxisPropType="readTime" :chartData="dataSource" height="240px" :propTypeArr="['flowRate']" :option="zhujiangOption" />
+                </div>
+                <div class="echarts-item">
+                  <BarAndLineCustom xAxisPropType="readTime" :chartData="dataSource" height="240px" :propTypeArr="['flowRate']" :option="zhujiangOption" />
+                </div>
+              </div>
+            </div>
+          </template>
+        </ventBox1>
+      </div>
+
+    </div>
   </div>
   <component v-if="modalVisible" :is="currentModal" v-model:visible="modalVisible" />
 </template>
@@ -30,7 +123,7 @@ import { ScrollBoard as DvScrollBoard } from '@kjgl77/datav-vue3';
 import ventBox1 from '/@/components/vent/ventBox1.vue';
 import RunParameterModal from './runParameter.modal.vue'
 import WarningParameterModal from './warningParameter.modal.vue'
-import { deviceMonitorList } from '../grout.data'
+import { warningConfig, zhujiangOption, yaliOption } from '../grout.data'
 import { list } from '../grout.api';
 import BarAndLineCustom from '/@/components/chart/BarAndLineCustom.vue';
 
@@ -49,7 +142,7 @@ const left: string = "0px";
 const currentModal = shallowRef<Nullable<ComponentOptions>>(null); //模态框
 const modalVisible = ref<Boolean>(false); // 模态框是否可见
 const loading = ref(false);
-const monitorData = ref({})
+
 // 默认初始是第一行
 const dataSource = ref([
   { 
@@ -72,6 +165,26 @@ const dataSource = ref([
   }
 ]); //dusting
 
+const deviceMonitorData = {
+  '1#_waterSupply': { text: '1#制浆机供水流量', unit: 'm³/h' },
+  '1#_beltVla': { text: '1#皮带秤数值', unit: 'T' },
+  '2#_waterSupply': { text: '2#制浆机供水流量', unit: 'm³/h' },
+  '2#_beltVla': { text: '2#皮带秤数值', unit: 'T' },
+  density: {text: '密度' , unit: 'g/cm'},
+  pressure: { text: '压力', unit: 'MPa' },
+  liquidLevel: { text: '缓冲池液位', unit: 'm' },
+  flowRate: { text: '注浆流量', unit: 'm³/h' },
+}
+const deviceControlData = {
+  '1#_waterPump': '1#清水泵',
+  '1#_groutingPump': '1#注浆泵',
+  '1#_pulpingMachine': '1#制浆机',
+  '2#_waterPump': '2#清水泵',
+  '2#_groutingPump': '2#注浆泵',
+  '2#_pulpingMachine': '2#制浆机',
+  'liquidLevelProtect ':'液位保护'
+}
+
 const flvURL1 = () => {
   return `https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv`;
   // return ''
@@ -101,16 +214,13 @@ function getMonitor(flag?) {
 
 async function getDataSource() {
   const res = await list({ devicetype: 'pulping_auto', pagetype: 'normal' });
-  if(res.msgTxt && res.msgTxt[0] && res.msgTxt[0].datalist && res.msgTxt[0].datalist[0]){
-    monitorData.value = Object.assign(res.msgTxt[0].datalist[0], res.msgTxt[0].datalist[0]['readData'])
-  }
-  // const dataList = res.msgTxt[0].datalist || [];
-  // dataSource.value = dataList.filter((data) => {
-  //   const item = data.readData;
-  //   Object.assign(data, item);  
-  //   return item
-  // });
-  // monitorData.value = 
+  const dataList = res.msgTxt[0].datalist || [];
+  dataSource.value = dataList.filter((data) => {
+    const item = data.readData;
+    Object.assign(data, item);
+    return item
+  });
+  
 }
 
 function handlerDevice(param: string | Object) {
@@ -153,50 +263,247 @@ onUnmounted(() => {
   // border: 1px solid #fff;
   margin-top: 40px;
   display: flex;
-  // justify-content: space-between;
-  justify-content: center;
+  justify-content: space-between;
   padding: 0 5px;
   
-  .header-box{
-    // width: 100%;
-    margin-top: 50px;
-    .header-container{
-      height: auto;
+  .lr {
+    width: 350px;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    margin-top: 10px;
+    pointer-events: auto;
+  }
+
+  .right-box {
+    width: 320px;
+    margin-top: 30px;
+    .control-group{
+      display: flex;
+      flex-wrap: wrap;
+      .control-item {
+        
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        padding: 0 2px;
+        .control-item-title{
+          color: #63e0ff;
+          position: relative;
+          top: 5px;
+        }
+        .control-item-state{
+          width: 94px;
+          height: 47px;
+          background: url('/@/assets/images/vent/control-switch-bg.png');
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          color: #fff;
+        }
+      
+        .button-box {
+          position: relative;
+          padding: 5px;
+          border: 1px transparent solid;
+          background-clip: border-box;
+          border-radius: 5px;
+          margin-left: 8px;
+        }
+
+        .a-button {
+          pointer-events: auto;
+        }
+
+        &::v-deep .a-button--mini {
+          padding: 6px 10px;
+        }
+
+        &::v-deep .a-button--mini.is-round {
+          padding: 6px 10px;
+        }
+      }
+
+    }
+    .control-btn-group{
       display: flex;
       flex-direction: row;
-      justify-content: center;
-      color: #fff;
-      box-shadow: 0 0 30px rgb(0, 153, 184) inset;
+      justify-content: space-between;
+      .control-left-box{
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        padding: 0 20px;
+        .btn-box{
+          width: 100px;
+          color: #fff;
+          display: flex;
+          justify-content: space-between;
+          span{
+            display: inline-block;
+            padding: 2px 8px;
+            background: #007099;
+            border-radius: 4px;
+            border: 1px solid rgb(125, 230, 249);
+            cursor: pointer;
+            &:hover{
+              background: #005574;
+            }
+          }
+        }
+        .icon-box{
+          width: 60px;
+          height: 60px;
+          border-radius: 30px;
+          border: 2px solid #00bcdd;
+          box-shadow: 0 0 20px #ffffff88;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          margin-top: 20px;
+             
+          .icon{
+            width: 18px;
+            height: 18px;
+            border-radius: 9px;
+            border: 3px solid #d7f9ff;
+            position: relative;
+            background: #00bcdd;
+            &::before{
+              position: absolute;
+              content: '';
+              width: 2px;
+              height: 12px;
+              background-color: #00bcdd;
+              left: 6px;
+              top: -16px;
+            }
+            &::after{
+              position: absolute;
+              content: '';
+              width: 2px;
+              height: 12px;
+              left: 6px;
+              top: 17px;
+              background-color: #00d9ff;
+            }
+          }
+        }
+        .remote-icon-box{
+          transform: rotate(30deg);
+          animation: iconRotate 1s linear;
+        }
+        .remote-icon-box1{
+          transform: rotate(-30deg);
+          animation: iconRotate1 1s linear;
+        }
+
+        @keyframes iconRotate{
+          from{
+            transform: rotate(-30deg);
+          }
+          to {
+            transform: rotate(30deg);
+          }
+        }
+        @keyframes iconRotate1{
+          from {
+            transform: rotate(30deg);
+          }
+          to {
+            transform: rotate(-30deg);
+          }
+        }
+        
+      }
+      .control-right-box{
+        width: 100px;
+        .btn{
+          margin-bottom: 30px;
+        }
+      }
     }
-    .device-title{
-      width: 110px;
-      text-align: center;
-      border-top: 1px solid #00baffd4;
-      border-left: 1px solid #00baffd4;
-      line-height: 46px;
-      color: #00e5ff;
-      background-color: #00bbff21;
+    .parameter-btn-group{
+      display: flex;
+      justify-content: space-between;
+      padding: 0 20px;
+      margin-bottom: 10px;
     }
-    .device-detail{
-      text-align: center;
-      &:first-child{
-        background-color: #00bbff11;
+    .echarts-box{
+      width: 100%;
+      height: 332px;
+      position: relative;
+      &:deep(.box-container){
+        padding: 0px !important;
       }
-      &:last-child{
-        .device-val, .device-title{
-          border-right: 1px solid #00baffd4;
+      .btn-group{
+        line-height: 30px;
+        color: #fff;
+        text-align: center;
+        margin-top: 3px;
+        span{
+          padding: 3px 5px;
+          margin: 0 2px;
+          border-radius: 2px;
+          background-image: linear-gradient( #32475B, #5b95c7);
+          border: 1px solid #32475B;
+          cursor: pointer;
+        }
+        .active{
+          background-image: linear-gradient( #2E4659, #37A7B4);
+          border-top: 1px solid #3DF6FF;
         }
       }
-      .device-val{
-        line-height: 36px;
-        border-top: 1px solid #00baffd4;
-        border-left: 1px solid #00baffd4;
-        &:last-child{
-          border-bottom: 1px solid #00baffd4;
+      .echarts-container{
+        width: 100%;
+        height: 240px;
+        overflow: hidden;
+        position: relative;
+        .echarts-group{
+          display: flex;
+          flex-direction: row;
+          position: absolute;
+          left: v-bind(left);
+          .echarts-item{
+            width: 305px;
+          }
         }
       }
+      
     }
+    
   }
+
+  .left-box {
+    margin-top: 30px;
+    .monitor-item{
+      display: flex;
+      color: #fff;
+      justify-content: space-between;
+      background-image: linear-gradient(to left, #3df6ff10, #3df6ff00);
+      margin: 10px 0;
+    
+      .item-title{
+        width: 200px;
+        margin-left: 10px;
+      }
+      .item-val{
+        width: 80px;
+        color: #00eefffe;
+      }
+      .item-unit{
+        width: 80px;
+      }
+    }
+    
+  }
+
+  .item-box{
+    margin-bottom: 15px;
+  }
+
 }
 
 :deep(.@{ventSpace}-tabs-tabpane-active) {

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

@@ -140,7 +140,7 @@
             v-if="activeKey == '3'"
             columns-type="alarm"
             :device-type="deviceType"
-            :device-list-api="getDeviceList.bind(null, { devicekind: deviceType })"
+            :device-list-api="getDeviceList.bind(null, { devicekind: deviceType, pageSize: 10000 })"
             designScope="alarm-history"
           />
         </div>
@@ -152,7 +152,7 @@
             v-if="activeKey == '4'"
             columns-type="operator_history"
             :device-type="deviceType"
-            :device-list-api="getDeviceList.bind(null, { devicekind: deviceType })"
+            :device-list-api="getDeviceList.bind(null, { devicekind: deviceType, pageSize: 10000 })"
             designScope="operator-history"
           />
         </div>

+ 7 - 8
src/views/vent/monitorManager/windowMonitor/dandaoFc.threejs.ts

@@ -17,7 +17,7 @@ class singleWindow {
   playerStartClickTime1 = new Date().getTime();
   constructor(model) {
     this.model = model;
-    this.group.name = 'ddFc';
+    // this.group.name = 'ddFc';
   }
   // // 重置摄像头
   // const resetCamera = () => {
@@ -47,7 +47,7 @@ class singleWindow {
         y: 90,
       },
       {
-        text: `过风量(m3/min):`,
+        text: `过风量(m³/min):`,
         font: 'normal 30px Arial',
         color: '#009900',
         strokeStyle: '#002200',
@@ -160,7 +160,7 @@ class singleWindow {
         const planeMesh = new THREE.Mesh(planeGeometry, textMaterial);
         planeMesh.name = 'monitorText';
         planeMesh.scale.set(0.0025, 0.003, 0.002);
-        planeMesh.position.set(3.77, -0.042, -0.23);
+        planeMesh.position.set(3.71, -0.042, -0.23);
         this.group?.add(planeMesh);
       }
     });
@@ -169,7 +169,7 @@ class singleWindow {
   /* 提取风门序列帧,初始化前后门动画 */
   initAnimation() {
     const meshArr01: THREE.Object3D[] = [];
-    this.group?.children.forEach((obj) => {
+    this.group.getObjectByName('ddFc')?.children.forEach((obj) => {
       if (obj.type === 'Mesh' && obj.name && obj.name.startsWith('shanye')) {
         obj.rotateOnAxis(new THREE.Vector3(0, 1, 0), 0);
         meshArr01.push(obj);
@@ -179,7 +179,7 @@ class singleWindow {
   }
 
   play(rotationParam, flag) {
-    if (!this.windowsActionArr.frontWindow) {
+    if (this.windowsActionArr.frontWindow.length <= 0) {
       return;
     }
     if (flag === 1) {
@@ -309,7 +309,7 @@ class singleWindow {
         const mesh = renderVideo(this.group, videoPlayer1, 'player1');
         if (mesh) {
           mesh?.scale.set(0.0382, 0.028, 0.022);
-          mesh?.position.set(-2.008, 0.148, -0.22);
+          mesh?.position.set(-3.008, 0.148, -0.22);
           this.group.add(mesh);
         }
       } catch (error) {
@@ -320,8 +320,7 @@ class singleWindow {
 
   mountedThree(playerDom) {
     return new Promise((resolve) => {
-      this.model.setGLTFModel(['ddFc']).then((gltf) => {
-        this.group = gltf[0];
+      this.model.setGLTFModel(['ddFc'], this.group).then(() => {
         this.setModalPosition();
         this.initAnimation();
         resolve(null);

+ 10 - 8
src/views/vent/monitorManager/windowMonitor/index.vue

@@ -22,23 +22,23 @@
           <span class="input-title">风窗面积:</span>
           <a-input-number size="small" placeholder="0" :min="0" :max="90" :step="1" v-model:value="windowAngle" />
         </div> -->
-        <div v-if="selectData.nwindownum == 2" class="row">
+        <div class="row" v-if="hasPermission('window:control') && selectData.nwindownum > 1">
           <div class="button-box" @click="setArea(1)">设定前窗面积</div>
           <div class="button-box" @click="setArea(2)">设定后窗面积</div>
         </div>
-        <div v-if="selectData.nwindownum == 1" class="row">
+        <div class="row" v-if="hasPermission('window:control') && selectData.nwindownum == 1">
           <div class="button-box" @click="setArea(1)">设定风窗面积</div>
         </div>
       </div>
-      <!-- <div class="top-right row">
-        <div class="control-type row">
+      <div class="top-right row">
+        <!-- <div class="control-type row">
           <div class="control-title">控制模式:</div>
           <a-radio-group v-model:value="controlType">
             <a-radio :value="1">就地</a-radio>
             <a-radio :value="2">远程</a-radio>
           </a-radio-group>
-        </div>
-        <div class="run-type row">
+        </div> -->
+        <!-- <div class="run-type row">
           <div class="control-title">运行状态:</div>
           <a-radio-group v-model:value="controlType">
             <a-radio :value="1">检修</a-radio>
@@ -49,8 +49,8 @@
           <a-radio-group v-model:value="controlType">
             <a-radio :value="1">运行</a-radio>
           </a-radio-group>
-        </div>
-      </div> -->
+        </div> -->
+      </div>
     </div>
     <div class="title-text">
       {{ selectData.strname }}
@@ -163,6 +163,8 @@
   import LivePlayer from '@liveqing/liveplayer-v3';
   import { useModal } from '/@/components/Modal';
   import { useCamera } from '/@/hooks/system/useCamera';
+  import { usePermission } from '/@/hooks/web/usePermission';
+  const { hasPermission } = usePermission();
 
   const globalConfig = inject('globalConfig');
 

+ 14 - 13
src/views/vent/monitorManager/windowMonitor/shuangdaoFc.threejs.ts

@@ -18,11 +18,12 @@ class doubleWindow {
 
   constructor(model) {
     this.model = model;
-    this.group.name = this.modelName;
+    // this.group.name = this.modelName;
   }
 
   // 设置模型位置
   setModalPosition() {
+    this.group.getObjectByName(this.modelName)?.scale.set(9, 9, 9);
     this.group?.scale.set(22, 22, 22);
     this.group?.position.set(-15, 25, 15);
   }
@@ -38,10 +39,10 @@ class doubleWindow {
         color: '#009900',
         strokeStyle: '#002200',
         x: 95,
-        y: 95,
+        y: 97,
       },
       {
-        text: `过风量(m3/min):`,
+        text: `过风量(m³/min):`,
         font: 'normal 28px Arial',
         color: '#009900',
         strokeStyle: '#002200',
@@ -147,8 +148,8 @@ class doubleWindow {
         const planeGeometry = new THREE.PlaneGeometry(570, 346); // 平面3维几何体PlaneGeometry
         const planeMesh = new THREE.Mesh(planeGeometry, textMaterial);
         planeMesh.name = 'monitorText';
-        planeMesh.scale.set(0.0019, 0.002, 0.002);
-        planeMesh.position.set(2.66, 0.158, -0.23);
+        planeMesh.scale.set(0.0018, 0.0018, 0.0018);
+        planeMesh.position.set(3.63, 0.158, -0.2);
         this.group?.add(planeMesh);
       }
       textMap.dispose();
@@ -173,11 +174,12 @@ class doubleWindow {
 
   /* 提取风门序列帧,初始化前后门动画 */
   initAnimation() {
+    debugger;
     const meshArr01: THREE.Object3D[] = [];
     const meshArr02: THREE.Object3D[] = [];
     const windowGroup = new THREE.Group();
     windowGroup.name = 'hiddenGroup';
-    this.group?.children.forEach((obj) => {
+    this.group.getObjectByName('sdFc')?.children.forEach((obj) => {
       if (obj.type === 'Mesh' && obj.name && (obj.name.startsWith('shanye') || obj.name.startsWith('FCshanye'))) {
         if (obj.name.startsWith('FCshanye')) {
           obj.rotateOnAxis(new THREE.Vector3(0, 1, 0), 0);
@@ -217,7 +219,7 @@ class doubleWindow {
   }
 
   play(rotationParam, flag) {
-    if (!this.windowsActionArr.frontWindow || !this.windowsActionArr.backWindow) {
+    if (this.windowsActionArr.frontWindow.length <= 0 || this.windowsActionArr.backWindow.length <= 0) {
       return;
     }
     if (flag === 1) {
@@ -304,8 +306,8 @@ class doubleWindow {
       try {
         const mesh = renderVideo(this.group, videoPlayer1, 'player1');
         if (mesh) {
-          mesh?.scale.set(-0.038, 0.029, 1);
-          mesh?.position.set(-4.302, 0.15, -0.23);
+          mesh?.scale.set(-0.034, 0.024, 1);
+          mesh?.position.set(-3.332, 0.11, -0.23);
           mesh.rotation.y = -Math.PI;
           this.group.add(mesh);
         }
@@ -335,8 +337,8 @@ class doubleWindow {
       try {
         const mesh = renderVideo(this.group, videoPlayer2, 'player2');
         if (mesh) {
-          mesh?.scale.set(-0.028, 0.0285, 1);
-          mesh?.position.set(4.298, 0.02, -0.4);
+          mesh?.scale.set(-0.034, 0.024, 1);
+          mesh?.position.set(-3.332, 0.11, -0.23);
           mesh.rotation.y = -Math.PI;
           this.group.add(mesh);
         }
@@ -348,8 +350,7 @@ class doubleWindow {
 
   mountedThree(playerDom) {
     return new Promise((resolve) => {
-      this.model.setGLTFModel(['sdFc']).then((gltf) => {
-        this.group = gltf[0];
+      this.model.setGLTFModel(['sdFc'], this.group).then(() => {
         this.setModalPosition();
         this.initAnimation();
         resolve(null);

+ 3 - 4
src/views/vent/monitorManager/windowMonitor/window.threejs.ts

@@ -165,15 +165,14 @@ export const mountedThree = (playerDom) => {
     model = new UseThree('#window3D');
     if (!model || !model.renderer || !model.camera) return;
     model.setEnvMap('test1');
+    resolve(null);
     model.camera.position.set(100, 0, 1000);
     // 单道、 双道
     doubleWindowObj = new doubleWindow(model);
     singleWindowObj = new singleWindow(model);
-    await doubleWindowObj.mountedThree(playerDom);
-    await singleWindowObj.mountedThree(playerDom);
-
+    doubleWindowObj.mountedThree(playerDom);
+    singleWindowObj.mountedThree(playerDom);
     model.animate();
-    resolve(null);
     addLight();
     startAnimation();
   });

+ 2 - 3
src/views/vent/monitorManager/windrectMonitor/dantou.threejs.ts

@@ -60,7 +60,7 @@ class ddWindRect {
         y: 95,
       },
       {
-        text: `风量(m3/min):`,
+        text: `风量(m³/min):`,
         font: 'normal 29px Arial',
         color: '#009900',
         strokeStyle: '#002200',
@@ -185,8 +185,7 @@ class ddWindRect {
 
   mountedThree() {
     return new Promise((resolve) => {
-      this.model.setGLTFModel([this.modelName]).then((gltf) => {
-        this.group = gltf[0];
+      this.model.setGLTFModel([this.modelName], this.group).then(() => {
         this.setModalPosition();
         this.addLight();
         resolve(null);

+ 4 - 6
src/views/vent/monitorManager/windrectMonitor/duishe.threejs.ts

@@ -91,7 +91,7 @@ class dsWindRect {
         y: 75,
       },
       {
-        text: `风量(m3/min):`,
+        text: `风量(m³/min):`,
         font: 'normal 29px Arial',
         color: '#009900',
         strokeStyle: '#002200',
@@ -186,11 +186,10 @@ class dsWindRect {
     }
   }
 
-
   initAnimation() {
     const dsmove = this.group.getObjectByName('dsmove');
     const dsmoveLine = dsmove?.getObjectByName('probe');
-    let line = dsmoveLine?.getObjectByName('line_');
+    const line = dsmoveLine?.getObjectByName('line_');
 
     if (line) {
       line.material.side = THREE.DoubleSide;
@@ -382,9 +381,8 @@ class dsWindRect {
 
   mountedThree() {
     return new Promise((resolve) => {
-      this.model.setGLTFModel([this.modelName, 'dsgd', 'dsmove'], this.group).then((gltf) => {
-        this.group.name = this.modelName;
-        // this.group = gltf[0];
+      this.model.setGLTFModel([this.modelName, 'dsgd', 'dsmove'], this.group).then(() => {
+        // this.group.name = this.modelName;
         this.setModalPosition();
         this.initAnimation();
         this.addLight();

+ 1 - 1
src/views/vent/monitorManager/windrectMonitor/duisheFixed.threejs.ts

@@ -61,7 +61,7 @@ class fixedWindRect {
         y: 75,
       },
       {
-        text: `风量(m3/min):`,
+        text: `风量(m³/min):`,
         font: 'normal 29px Arial',
         color: '#009900',
         strokeStyle: '#002200',

+ 1 - 1
src/views/vent/monitorManager/windrectMonitor/longmen.threejs.ts

@@ -74,7 +74,7 @@ class lmWindRect {
         y: 40,
       },
       {
-        text: `风量(m3/min):`,
+        text: `风量(m³/min):`,
         font: 'normal 29px Arial',
         color: '#009900',
         strokeStyle: '#002200',

+ 1 - 1
src/views/vent/monitorManager/windrectMonitor/longmenSide.threejs.ts

@@ -75,7 +75,7 @@ class lmWindRectSide {
         y: 42,
       },
       {
-        text: `风量(m3/min):`,
+        text: `风量(m³/min):`,
         font: 'normal 30px Arial',
         color: '#009900',
         strokeStyle: '#002200',

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

@@ -143,7 +143,7 @@ export const setModelType = (type) => {
       group = lmWindRectObj.group;
 
       const cfTanTou = lmWindRectObj.group?.getObjectByName('lmTanTou') as THREE.Group;
-      cfTanTou.position.setY(0);
+      if (cfTanTou) cfTanTou.position.setY(0);
 
       if (model?.scene?.getObjectByName('zdcf')) {
         model.scene.remove(zdWindRectObj.group);
@@ -218,7 +218,7 @@ export const 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 (dsTanTou) dsTanTou.position.setY(0.45);
 
       if (model.scene?.getObjectByName('lmcf')) {
         model.scene.remove(lmWindRectObj.group);
@@ -253,7 +253,7 @@ export const setModelType = (type) => {
       group = lmWindRectSideObj.group;
 
       const cfTanTou = lmWindRectSideObj.group?.getObjectByName('probe_bar') as THREE.Group;
-      cfTanTou.position.setY(0.377);
+      if (cfTanTou) cfTanTou.position.setY(0.377);
       if (model.scene?.getObjectByName('lmcf')) {
         model.scene.remove(lmWindRectObj.group);
       }
@@ -359,25 +359,25 @@ export const mountedThree = (playerDom) => {
     model = new UseThree('#window3D');
     model.setEnvMap('test1');
     model.renderer.toneMappingExposure = 1.0;
+    resolve(null);
     lmWindRectObj = new lmWindRect(model);
-    await lmWindRectObj.mountedThree();
+    lmWindRectObj.mountedThree();
 
     zdWindRectObj = new zdWindRect(model);
-    await zdWindRectObj.mountedThree();
+    zdWindRectObj.mountedThree();
 
     dsWindRectObj = new dsWindRect(model);
-    await dsWindRectObj.mountedThree();
+    dsWindRectObj.mountedThree();
 
     lmWindRectSideObj = new lmWindRectSide(model);
-    await lmWindRectSideObj.mountedThree();
+    lmWindRectSideObj.mountedThree();
 
     ddWindRectObj = new ddWindRect(model);
-    await ddWindRectObj.mountedThree();
+    ddWindRectObj.mountedThree();
 
     fixedWindRectObj = new fixedWindRect(model);
-    await fixedWindRectObj.mountedThree(playerDom);
+    fixedWindRectObj.mountedThree(playerDom);
 
-    resolve(null);
     model.animate();
     startAnimation();
   });

+ 1 - 1
src/views/vent/monitorManager/windrectMonitor/zhedie.threejs.ts

@@ -68,7 +68,7 @@ class zdWindRect {
         y: 90,
       },
       {
-        text: `风量(m3/min):`,
+        text: `风量(m³/min):`,
         font: 'normal 29px Arial',
         color: '#009900',
         strokeStyle: '#002200',

+ 25 - 20
src/views/vent/monitorManager/workFaceMonitor/components/workFaceHistory.vue

@@ -1,28 +1,33 @@
 <template>
   <div class="history-box">
-    <HistoryTable :columns-type="`${deviceType}`" :device-type="deviceType" :sysId="deviceId"
-      :device-list-api="getDeviceList.bind(null, { devicekind: deviceType, sysId: deviceId })" designScope="pressurefan_history" :scroll="{ y: 650 }"/>
+    <HistoryTable
+      :columns-type="`${deviceType}`"
+      :device-type="deviceType"
+      :sysId="deviceId"
+      :device-list-api="getDeviceList.bind(null, { devicekind: deviceType, sysId: deviceId, pageSize: 10000 })"
+      designScope="pressurefan_history"
+      :scroll="{ y: 650 }"
+    />
   </div>
 </template>
 <script setup lang="ts">
-import { ref, defineProps } from 'vue'
-import HistoryTable from '../../comment/HistoryTable.vue';
-import { getDeviceList } from '../workFace.api'
-
-const props = defineProps({
-  deviceType: {
-    type: String,
-    required: true,
-  },
-  deviceId: {
-    type: String,
-    required: true,
-  }
-})
+  import { ref, defineProps } from 'vue';
+  import HistoryTable from '../../comment/HistoryTable.vue';
+  import { getDeviceList } from '../workFace.api';
 
+  const props = defineProps({
+    deviceType: {
+      type: String,
+      required: true,
+    },
+    deviceId: {
+      type: String,
+      required: true,
+    },
+  });
 </script>
 <style lang="less" scoped>
-.history-box {
-  pointer-events: auto;
-}
-</style>
+  .history-box {
+    pointer-events: auto;
+  }
+</style>