Browse Source

[Mod 0000] 新增三个风筒的主风机模型

hongrunxia 1 day ago
parent
commit
24226651e3

BIN
src/assets/images/vent/lr-tab-bg.png


+ 33 - 18
src/views/vent/monitorManager/comment/GroupMonitorTable.vue

@@ -109,8 +109,8 @@
       width: 40,
       align: 'center',
       customCell: (_, index) => {
-        if (index % 2 == 0) {
-          return { rowSpan: 2 };
+        if (index % 3 == 0) {
+          return { rowSpan: 3 };
         } else {
           return { rowSpan: 0 };
         }
@@ -122,14 +122,14 @@
       width: 80,
       align: 'center',
       customCell: (_, index) => {
-        if (index % 2 == 0) {
-          return { rowSpan: 2 };
+        if (index % 3 == 0) {
+          return { rowSpan: 3 };
         } else {
           return { rowSpan: 0 };
         }
       },
       customRender: function ({ index }) {
-        return index / 2 + 1;
+        return index / 3 + 1;
       },
     };
     const runDevice = {
@@ -150,8 +150,8 @@
     });
     if (strinstallpos) {
       strinstallpos.customCell = (_, index) => {
-        if (index % 2 == 0) {
-          return { rowSpan: 2 };
+        if (index % 3 == 0) {
+          return { rowSpan: 3 };
         } else {
           return { rowSpan: 0 };
         }
@@ -160,8 +160,8 @@
     columns.value.forEach((item) => {
       if (item.dataIndex === 'strinstallpos' || item.dataIndex === 'strname' || item.dataIndex.endsWith('_merge')) {
         item.customCell = (_, index) => {
-          if (index % 2 == 0) {
-            return { rowSpan: 2 };
+          if (index % 3 == 0) {
+            return { rowSpan: 3 };
           } else {
             return { rowSpan: 0 };
           }
@@ -186,8 +186,8 @@
           align: 'center',
           slots: { customRender: 'operation' },
           customCell: (_, index) => {
-            if (index % 2 == 0) {
-              return { rowSpan: 2 };
+            if (index % 3 == 0) {
+              return { rowSpan: 3 };
             } else {
               return { rowSpan: 0 };
             }
@@ -226,8 +226,10 @@
       const list: unknown[] = [];
       newVal.forEach((item) => {
         const data: any = toRaw(item);
+        const modalTyoe = data.modalTyoe; ///
         const resultData1 = {};
         const resultData2 = {};
+        const resultData3 = {};
         // 将主风机、备风机的数据进行拆分
         columns.value.forEach((column) => {
           const columnKey = column.dataIndex;
@@ -235,37 +237,46 @@
             if (columnKey.startsWith('Fan')) {
               const key1 = columnKey.replace('Fan', 'Fan1');
               const key2 = columnKey.replace('Fan', 'Fan2');
+              const key3 = columnKey.replace('Fan', 'Fan3');
               if (columnKey.endsWith('_merge')) {
-                resultData1[columnKey] = data[key1] == 0 || data[key1] == null || data[key1] == undefined ? data[key2] : data[key1];
+                resultData1[columnKey] = data[key1] == 0 || data[key1] == null || data[key1] == undefined ? data[key2] : data[key1] || data[key3];
               } else {
                 if (columnKey.startsWith('FanStartStatus')) {
                   resultData1[columnKey] = data[key1];
                   resultData2[columnKey] = data[key2];
+                  resultData3[columnKey] = data[key3];
                 } else {
                   resultData1[columnKey] = data['Fan1StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key1];
                   resultData2[columnKey] = data['Fan2StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key2];
+                  resultData3[columnKey] = data['Fan3StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key3];
                 }
                 if (resultData1[columnKey] == undefined && resultData2[columnKey] == undefined) {
                   resultData1[columnKey] = data[columnKey];
                   resultData2[columnKey] = data[columnKey];
+                  resultData3[columnKey] = data[columnKey];
                 }
               }
             } else if (columnKey.startsWith('fan')) {
               const key1 = columnKey.replace('fan', 'fan1');
               const key2 = columnKey.replace('fan', 'fan2');
+              const key3 = columnKey.replace('fan', 'fan3');
               if (columnKey.endsWith('_merge')) {
-                resultData1[columnKey] = !data[key1] || data[key1] == 0 || data[key1] == null || data[key1] == undefined ? data[key2] : data[key1];
+                resultData1[columnKey] =
+                  !data[key1] || data[key1] == 0 || data[key1] == null || data[key1] == undefined ? data[key2] : data[key1] || data[key3];
               } else {
                 if (columnKey.startsWith('fanStartStatus')) {
                   resultData1[columnKey] = data[key1];
                   resultData2[columnKey] = data[key2];
+                  resultData3[columnKey] = data[key3];
                 } else {
                   resultData1[columnKey] = data['fan1StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key1];
                   resultData2[columnKey] = data['fan2StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key2];
+                  resultData3[columnKey] = data['fan3StartStatus'] == '0' && globalConfig?.simulatedPassword ? '-' : data[key3];
                 }
                 if (resultData1[columnKey] == undefined && resultData2[columnKey] == undefined) {
                   resultData1[columnKey] = data[columnKey];
                   resultData2[columnKey] = data[columnKey];
+                  resultData3[columnKey] = data[columnKey];
                 }
               }
             } else if (columnKey.endsWith('_merge')) {
@@ -282,13 +293,17 @@
         } else {
           resultData1['runDevice'] = '1#风机';
           resultData2['runDevice'] = '2#风机';
+          resultData3['runDevice'] = '3#风机';
+          resultData1['modalTyoe'] = modalTyoe;
+          resultData2['modalTyoe'] = modalTyoe;
+          resultData3['modalTyoe'] = modalTyoe;
+        }
+        if (modalTyoe === 'lijing_3') {
+          list.push(resultData1, resultData2, resultData3);
+        } else {
+          list.push(resultData1, resultData2);
         }
-        list.push(resultData1, resultData2);
       });
-      // if (oldVal.length < 1 && selectRowIndex.value == -1) {
-      //   // 第一次
-      //   setSelectedRowKeys(list[0]['deviceID']);
-      // }
 
       dataTableSource.value = list;
       loading.value = false;

File diff suppressed because it is too large
+ 768 - 576
src/views/vent/monitorManager/mainFanMonitor/index.vue


+ 2 - 2
src/views/vent/monitorManager/mainFanMonitor/main.data.ts

@@ -1159,8 +1159,8 @@ export const initData1 = () => {
 
 // 大柳塔武当沟
 export const initData = (deviceType?) => {
-  // const { sysOrgCode } = useGlobSetting();
-  const sysOrgCode = 'sdtljtdhzmk';
+  const { sysOrgCode } = useGlobSetting();
+  // const sysOrgCode = 'sdtljtdhzmk';
   if (sysOrgCode == 'sdmtjtdltmk') {
     return initDataDlt(deviceType);
   } else if (sysOrgCode == 'sdmtjtswmk') {

+ 252 - 99
src/views/vent/monitorManager/mainFanMonitor/main.threejs.ts

@@ -4,7 +4,9 @@ import UseThree from '../../../../utils/threejs/useThree';
 import mainWindRect from './mainWind.threejs';
 import mainXjWindRect from './mainWind.xj.threejs';
 import mainLjWindRect from './mainWind.lj.threejs';
+import mainWindLj3 from './mainWind.li3.threejs';
 import useEvent from '../../../../utils/threejs/useEvent';
+import { getDictItemsByCode } from '/@/utils/dict';
 
 // import * as dat from 'dat.gui';
 // const gui = new dat.GUI();
@@ -17,6 +19,7 @@ let model: UseThree | undefined, //
   mainWindObj: mainWindRect | undefined,
   mainXjWindObj: mainXjWindRect | undefined,
   mainLjWindObj: mainLjWindRect | undefined,
+  mainLj3WindObj: mainWindLj3 | undefined,
   modalType = 'mainWindRect',
   explosionVentClose = -1,
   explosionVentOpen = -1;
@@ -73,6 +76,8 @@ const mouseEvent = (event) => {
         mainWindObj?.mousedownModel.call(mainWindObj, intersects);
       } else if (modalType === 'mainXjWindRect' && mainXjWindObj) {
         mainXjWindObj?.mousedownModel.call(mainXjWindObj, intersects);
+      } else if (modalType === 'mainWindRect3' && mainLj3WindObj) {
+        mainLj3WindObj?.mousedownModel.call(mainLj3WindObj, intersects);
       }
     });
   }
@@ -97,6 +102,8 @@ export const addText = () => {
     return mainXjWindObj.addCssText.call(mainXjWindObj);
   } else if (modalType === 'mainLjWindRect' && mainLjWindObj) {
     return mainLjWindObj.addCssText.call(mainLjWindObj);
+  } else if (modalType === 'mainWindRect3' && mainLj3WindObj) {
+    return mainLj3WindObj.addCssText.call(mainLj3WindObj);
   }
 };
 
@@ -109,6 +116,8 @@ export const resetEcharts = (selectData) => {
     return mainXjWindObj.addEcharts.call(mainXjWindObj);
   } else if (modalType === 'mainLjWindRect' && mainLjWindObj) {
     return mainLjWindObj.addEcharts.call(mainLjWindObj);
+  } else if (modalType === 'mainWindRect3' && mainLj3WindObj) {
+    return mainLj3WindObj.addEcharts.call(mainLj3WindObj);
   }
 };
 
@@ -129,6 +138,8 @@ export const play = (controlType, deviceType, frequencyVal?, state?, smokeDirect
     return mainXjWindObj.playSmoke.call(mainXjWindObj, controlType, deviceType, frequencyVal, state, smokeDirection);
   } else if (modalType === 'mainLjWindRect' && mainLjWindObj) {
     return mainLjWindObj.playSmoke.call(mainLjWindObj, controlType, deviceType, frequencyVal, state, smokeDirection);
+  } else if (modalType === 'mainWindRect3' && mainLj3WindObj) {
+    return mainLj3WindObj.playSmoke.call(mainLj3WindObj, controlType, deviceType, frequencyVal, state, smokeDirection);
   }
 };
 
@@ -142,6 +153,8 @@ export const playAnimate1 = async (selectData, duration?) => {
     mainObj = mainXjWindObj;
   } else if (modalType === 'mainLjWindRect') {
     mainObj = mainLjWindObj;
+  } else if (modalType === 'mainWindRect3') {
+    mainObj = mainLj3WindObj;
   }
   if (selectData && mainObj) {
     if (selectData.Fan1WindowOpen !== undefined) {
@@ -224,7 +237,7 @@ export const playAnimate = async (selectData, duration?) => {
   // if (Number(selectData.Fan2FreqHz) < 0) selectData.Fan2FreqHz = Math.abs(Number(selectData.Fan2FreqHz));
   if (!mainWindObj) return;
 
-  let mainObj: mainWindRect | mainXjWindRect | undefined;
+  let mainObj: mainWindRect | mainXjWindRect | mainWindLj3 | undefined;
 
   if (modalType === 'mainWindRect') {
     mainObj = mainWindObj;
@@ -232,97 +245,181 @@ export const playAnimate = async (selectData, duration?) => {
     mainObj = mainXjWindObj;
   } else if (modalType === 'mainLjWindRect') {
     mainObj = mainLjWindObj;
+  } else if (modalType === 'mainWindRect3') {
+    mainObj = mainLj3WindObj;
   }
   if (selectData && mainObj) {
     if (selectData['Fan1FreqHz'] == undefined || selectData['Fan1FreqHz'] == null || selectData['Fan1FreqHz'] == '') selectData['Fan1FreqHz'] = 50;
     if (selectData['Fan2FreqHz'] == undefined || selectData['Fan2FreqHz'] == null || selectData['Fan2FreqHz'] == '') selectData['Fan2FreqHz'] = 50;
-    mainObj.resetSmokeParam('front', selectData.Fan2FreqHz, duration);
-    mainObj.resetSmokeParam('back', selectData.Fan1FreqHz, duration);
-    if (selectData.Fan2StartStatus == 1) {
-      // 主风机开启
-      mainObj?.lookMotor('front', 'open', duration);
-      mainObj?.openOrCloseValve('front', 'open', duration);
-      // 1. 已经运行,首次切入动画
-      // 2. 在页面上,切换动画
-      if (selectData.Fan2FreqForwardRun == 1 && selectData.Fan2FreqReverseRun == 0) {
-        // 主风机正转
-        if (mainObj['airChu2'] && !mainObj['airChu2'].visible) {
-          mainObj['airJin1'].visible = false;
-          mainObj['airJin2'].visible = false;
-          mainObj['airChu1'].visible = false;
-          mainObj['airChu2'].visible = true;
-        }
-        mainObj.startGearAnimation('front', 'open', 'tubPositivePath', selectData.Fan2FreqHz, duration);
-        await mainObj.setSmokeDirection('front', 'tubPositivePath');
-      } else if (selectData.Fan2FreqReverseRun == 1 && selectData.Fan2FreqForwardRun == 0) {
-        // 主风机反转
-        if (mainObj['airJin2'] && !mainObj['airJin2'].visible) {
-          mainObj['airJin1'].visible = false;
-          mainObj['airJin2'].visible = true;
-          mainObj['airChu1'].visible = false;
-          mainObj['airChu2'].visible = false;
+    if (selectData['Fan3FreqHz'] == undefined || selectData['Fan3FreqHz'] == null || selectData['Fan3FreqHz'] == '') selectData['Fan3FreqHz'] = 50;
+    if (modalType === 'mainWindRect3') {
+      mainObj.resetSmokeParam('front', selectData.Fan1FreqHz, duration);
+      mainObj.resetSmokeParam('center', selectData.Fan2FreqHz, duration);
+      mainObj.resetSmokeParam('back', selectData.Fan3FreqHz, duration);
+      if (selectData.Fan1StartStatus == 1) {
+        // 主风机开启
+        mainObj.lookMotor('front', 'open', duration);
+        mainObj.openOrCloseValve('front', 'open', duration);
+        // 1. 已经运行,首次切入动画
+        // 2. 在页面上,切换动画
+        if (selectData.Fan1FreqForwardRun == 1 && selectData.Fan1FreqReverseRun == 0) {
+          // 主风机正转
+          // 主风机正转
+          mainObj.startGearAnimation('front', 'open', 'tubPositivePath', selectData.Fan1FreqHz, duration);
+          await mainObj.setSmokeDirection('front', 'tubPositivePath');
+        } else if (selectData.Fan1FreqReverseRun == 1 && selectData.Fan1FreqForwardRun == 0) {
+          mainObj.startGearAnimation('front', 'open', 'tubInversePath', selectData.Fan1FreqHz, duration);
+          await mainObj.setSmokeDirection('front', 'tubInversePath');
+        } else {
+          mainObj.startGearAnimation('front', 'open', 'tubPositivePath', selectData.Fan1FreqHz, duration);
+          await mainObj.setSmokeDirection('front', 'tubPositivePath');
         }
-        mainObj.startGearAnimation('front', 'open', 'tubInversePath', selectData.Fan2FreqHz, duration);
-        await mainObj.setSmokeDirection('front', 'tubInversePath');
+
+        if (!mainObj?.frontSmoke?.frameId) mainObj?.frontSmoke?.startSmoke(duration);
       } else {
-        // 默认主风机正转
-        if (mainObj['airChu2'] && !mainObj['airChu2'].visible) {
-          mainObj['airJin1'].visible = false;
-          mainObj['airJin2'].visible = false;
-          mainObj['airChu1'].visible = false;
-          mainObj['airChu2'].visible = true;
-        }
-        mainObj.startGearAnimation('front', 'open', 'tubPositivePath', selectData.Fan2FreqHz, duration);
-        await mainObj.setSmokeDirection('front', 'tubPositivePath');
+        // 主风机停止
+        mainObj.closeDevice('front');
       }
 
-      if (!mainObj?.frontSmoke?.frameId) mainObj?.frontSmoke?.startSmoke(duration);
-    } else {
-      // 主风机停止
-      mainObj.closeDevice('front');
-    }
-    if (selectData.Fan1StartStatus == 1) {
-      // 主风机开启
-      mainObj.lookMotor('back', 'open', duration);
-      mainObj.openOrCloseValve('back', 'open', duration);
-      // 1. 已经运行,首次切入动画
-      // 2. 在页面上,切换动画
-      if (selectData.Fan1FreqForwardRun == 1 && selectData.Fan1FreqReverseRun == 0) {
-        // 主风机正转
-        // 主风机正转
-        if (mainObj['airChu1'] && !mainObj['airChu1'].visible) {
-          mainObj['airJin1'].visible = false;
-          mainObj['airJin2'].visible = false;
-          mainObj['airChu1'].visible = true;
-          mainObj['airChu2'].visible = false;
+      if (selectData.Fan2StartStatus == 1) {
+        // 主风机开启
+        mainObj?.lookMotor('center', 'open', duration);
+        mainObj?.openOrCloseValve('center', 'open', duration);
+        // 1. 已经运行,首次切入动画
+        // 2. 在页面上,切换动画
+        if (selectData.Fan2FreqForwardRun == 1 && selectData.Fan2FreqReverseRun == 0) {
+          // 主风机正转
+          mainObj.startGearAnimation('center', 'open', 'tubPositivePath', selectData.Fan2FreqHz, duration);
+          await mainObj.setSmokeDirection('center', 'tubPositivePath');
+        } else if (selectData.Fan2FreqReverseRun == 1 && selectData.Fan2FreqForwardRun == 0) {
+          // 主风机反转
+          mainObj.startGearAnimation('center', 'open', 'tubInversePath', selectData.Fan2FreqHz, duration);
+          await mainObj.setSmokeDirection('center', 'tubInversePath');
+        } else {
+          // 默认主风机正转
+          mainObj.startGearAnimation('center', 'open', 'tubPositivePath', selectData.Fan2FreqHz, duration);
+          await mainObj.setSmokeDirection('center', 'tubPositivePath');
         }
-        mainObj.startGearAnimation('back', 'open', 'tubPositivePath', selectData.Fan1FreqHz, duration);
-        await mainObj.setSmokeDirection('back', 'tubPositivePath');
-      } else if (selectData.Fan1FreqReverseRun == 1 && selectData.Fan1FreqForwardRun == 0) {
-        // 主风机反转
-        if (mainObj['airJin1'] && !mainObj['airJin1'].visible) {
-          mainObj['airJin1'].visible = true;
-          mainObj['airJin2'].visible = false;
-          mainObj['airChu1'].visible = false;
-          mainObj['airChu2'].visible = false;
+
+        if (!mainObj?.centerSmoke?.frameId) mainObj?.centerSmoke?.startSmoke(duration);
+      } else {
+        // 主风机停止
+        mainObj.closeDevice('center');
+      }
+      if (selectData.Fan3StartStatus == 1) {
+        // 主风机开启
+        mainObj?.lookMotor('back', 'open', duration);
+        mainObj?.openOrCloseValve('back', 'open', duration);
+        // 1. 已经运行,首次切入动画
+        // 2. 在页面上,切换动画
+        if (selectData.Fan2FreqForwardRun == 1 && selectData.Fan2FreqReverseRun == 0) {
+          // 主风机正转
+          mainObj.startGearAnimation('back', 'open', 'tubPositivePath', selectData.Fan2FreqHz, duration);
+          await mainObj.setSmokeDirection('back', 'tubPositivePath');
+        } else if (selectData.Fan2FreqReverseRun == 1 && selectData.Fan2FreqForwardRun == 0) {
+          // 主风机反转
+          mainObj.startGearAnimation('back', 'open', 'tubInversePath', selectData.Fan2FreqHz, duration);
+          await mainObj.setSmokeDirection('back', 'tubInversePath');
+        } else {
+          // 默认主风机正转
+          mainObj.startGearAnimation('back', 'open', 'tubPositivePath', selectData.Fan2FreqHz, duration);
+          await mainObj.setSmokeDirection('back', 'tubPositivePath');
         }
-        mainObj.startGearAnimation('back', 'open', 'tubInversePath', selectData.Fan1FreqHz, duration);
-        await mainObj.setSmokeDirection('back', 'tubInversePath');
+
+        if (!mainObj?.backSmoke?.frameId) mainObj?.backSmoke?.startSmoke(duration);
       } else {
-        if (mainObj['airChu1'] && !mainObj['airChu1'].visible) {
-          mainObj['airJin1'].visible = false;
-          mainObj['airJin2'].visible = false;
-          mainObj['airChu1'].visible = true;
-          mainObj['airChu2'].visible = false;
+        // 主风机停止
+        mainObj.closeDevice('back');
+      }
+    } else {
+      mainObj.resetSmokeParam('front', selectData.Fan2FreqHz, duration);
+      mainObj.resetSmokeParam('back', selectData.Fan1FreqHz, duration);
+      if (selectData.Fan2StartStatus == 1) {
+        // 主风机开启
+        mainObj?.lookMotor('front', 'open', duration);
+        mainObj?.openOrCloseValve('front', 'open', duration);
+        // 1. 已经运行,首次切入动画
+        // 2. 在页面上,切换动画
+        if (selectData.Fan2FreqForwardRun == 1 && selectData.Fan2FreqReverseRun == 0) {
+          // 主风机正转
+          if (mainObj['airChu2'] && !mainObj['airChu2'].visible) {
+            mainObj['airJin1'].visible = false;
+            mainObj['airJin2'].visible = false;
+            mainObj['airChu1'].visible = false;
+            mainObj['airChu2'].visible = true;
+          }
+          mainObj.startGearAnimation('front', 'open', 'tubPositivePath', selectData.Fan2FreqHz, duration);
+          await mainObj.setSmokeDirection('front', 'tubPositivePath');
+        } else if (selectData.Fan2FreqReverseRun == 1 && selectData.Fan2FreqForwardRun == 0) {
+          // 主风机反转
+          if (mainObj['airJin2'] && !mainObj['airJin2'].visible) {
+            mainObj['airJin1'].visible = false;
+            mainObj['airJin2'].visible = true;
+            mainObj['airChu1'].visible = false;
+            mainObj['airChu2'].visible = false;
+          }
+          mainObj.startGearAnimation('front', 'open', 'tubInversePath', selectData.Fan2FreqHz, duration);
+          await mainObj.setSmokeDirection('front', 'tubInversePath');
+        } else {
+          // 默认主风机正转
+          if (mainObj['airChu2'] && !mainObj['airChu2'].visible) {
+            mainObj['airJin1'].visible = false;
+            mainObj['airJin2'].visible = false;
+            mainObj['airChu1'].visible = false;
+            mainObj['airChu2'].visible = true;
+          }
+          mainObj.startGearAnimation('front', 'open', 'tubPositivePath', selectData.Fan2FreqHz, duration);
+          await mainObj.setSmokeDirection('front', 'tubPositivePath');
         }
-        mainObj.startGearAnimation('back', 'open', 'tubPositivePath', selectData.Fan1FreqHz, duration);
-        await mainObj.setSmokeDirection('back', 'tubPositivePath');
+
+        if (!mainObj?.frontSmoke?.frameId) mainObj?.frontSmoke?.startSmoke(duration);
+      } else {
+        // 主风机停止
+        mainObj.closeDevice('front');
       }
+      if (selectData.Fan1StartStatus == 1) {
+        // 主风机开启
+        mainObj.lookMotor('back', 'open', duration);
+        mainObj.openOrCloseValve('back', 'open', duration);
+        // 1. 已经运行,首次切入动画
+        // 2. 在页面上,切换动画
+        if (selectData.Fan1FreqForwardRun == 1 && selectData.Fan1FreqReverseRun == 0) {
+          // 主风机正转
+          // 主风机正转
+          if (mainObj['airChu1'] && !mainObj['airChu1'].visible) {
+            mainObj['airJin1'].visible = false;
+            mainObj['airJin2'].visible = false;
+            mainObj['airChu1'].visible = true;
+            mainObj['airChu2'].visible = false;
+          }
+          mainObj.startGearAnimation('back', 'open', 'tubPositivePath', selectData.Fan1FreqHz, duration);
+          await mainObj.setSmokeDirection('back', 'tubPositivePath');
+        } else if (selectData.Fan1FreqReverseRun == 1 && selectData.Fan1FreqForwardRun == 0) {
+          // 主风机反转
+          if (mainObj['airJin1'] && !mainObj['airJin1'].visible) {
+            mainObj['airJin1'].visible = true;
+            mainObj['airJin2'].visible = false;
+            mainObj['airChu1'].visible = false;
+            mainObj['airChu2'].visible = false;
+          }
+          mainObj.startGearAnimation('back', 'open', 'tubInversePath', selectData.Fan1FreqHz, duration);
+          await mainObj.setSmokeDirection('back', 'tubInversePath');
+        } else {
+          if (mainObj['airChu1'] && !mainObj['airChu1'].visible) {
+            mainObj['airJin1'].visible = false;
+            mainObj['airJin2'].visible = false;
+            mainObj['airChu1'].visible = true;
+            mainObj['airChu2'].visible = false;
+          }
+          mainObj.startGearAnimation('back', 'open', 'tubPositivePath', selectData.Fan1FreqHz, duration);
+          await mainObj.setSmokeDirection('back', 'tubPositivePath');
+        }
 
-      if (!mainObj?.backSmoke?.frameId) mainObj?.backSmoke?.startSmoke(duration);
-    } else {
-      // 主风机停止
-      mainObj.closeDevice('back');
+        if (!mainObj?.backSmoke?.frameId) mainObj?.backSmoke?.startSmoke(duration);
+      } else {
+        // 主风机停止
+        mainObj.closeDevice('back');
+      }
     }
 
     // 防爆门动画
@@ -358,10 +455,10 @@ export const setModelType = (type) => {
     // 停止气流动画
     mainWindObj?.stopSmoke();
     mainXjWindObj?.stopSmoke();
-
+    mainLj3WindObj?.stopSmoke();
+    mainLjWindObj?.stopSmoke();
     if (group) model?.scene?.remove(group);
     if (modalType === 'mainWindRect' && mainWindObj && mainWindObj.group) {
-      mainXjWindObj?.clearCssText();
       (<UseThree>model).startAnimation = mainWindObj.render.bind(mainWindObj);
       group = mainWindObj.group;
       setTimeout(async () => {
@@ -380,7 +477,6 @@ export const setModelType = (type) => {
         if (group) model?.scene?.add(group);
       }, 300);
     } else if (modalType === 'mainXjWindRect' && mainXjWindObj && mainXjWindObj.group) {
-      mainWindObj?.clearCssText();
       (<UseThree>model).startAnimation = mainXjWindObj.render.bind(mainXjWindObj);
       group = mainXjWindObj.group;
       setTimeout(async () => {
@@ -399,7 +495,6 @@ export const setModelType = (type) => {
         if (group) model?.scene?.add(group);
       }, 300);
     } else if (modalType === 'mainLjWindRect' && mainLjWindObj && mainLjWindObj.group) {
-      mainWindObj?.clearCssText();
       (<UseThree>model).startAnimation = mainLjWindObj.render.bind(mainLjWindObj);
       group = mainLjWindObj.group;
       setTimeout(async () => {
@@ -417,6 +512,23 @@ export const setModelType = (type) => {
         );
         if (group) model?.scene?.add(group);
       }, 300);
+    } else if (modalType === 'mainWindRect3' && mainLj3WindObj && mainLj3WindObj.group) {
+      (<UseThree>model).startAnimation = mainLj3WindObj.render.bind(mainLj3WindObj);
+      group = mainLj3WindObj.group;
+      setTimeout(async () => {
+        resolve(null);
+        const position = new THREE.Vector3(2.815, -7.014, -5.985);
+        const oldCameraPosition = { x: -332.39, y: 283.47, z: 438.61 };
+        await animateCamera(
+          oldCameraPosition,
+          { x: -3.41, y: -29.01, z: 8.84 },
+          { x: 5.128, y: 72.363, z: 93.655 },
+          { x: position.x, y: position.y, z: position.z },
+          model,
+          0.8
+        );
+        if (group) model?.scene?.add(group);
+      }, 300);
     }
   });
 };
@@ -436,25 +548,66 @@ export const mountedThree = (playerVal1) => {
       bgGroup = gltf[0] as THREE.Object3D;
       bgGroup.position.set(3.43, 27.13, 22.0);
       model?.scene?.add(bgGroup);
-      mainWindObj = new mainWindRect(model, playerVal1);
-      await mainWindObj.mountedThree();
-      mainXjWindObj = new mainXjWindRect(model, playerVal1);
-      await mainXjWindObj.mountedThree();
-      mainLjWindObj = new mainLjWindRect(model, playerVal1);
-      await mainLjWindObj.mountedThree();
+
+      // 这里根据字典判断
+      const dictCodes = getDictItemsByCode('mainFanType');
+      if (dictCodes && dictCodes.length > 0) {
+        for (let i = 0; i < dictCodes.length; i++) {
+          const dict = dictCodes[i];
+          switch (dict.value) {
+            case 'lijing':
+              modalType = 'mainWindRect';
+              mainWindObj = new mainWindRect(model, playerVal1);
+              await mainWindObj.mountedThree();
+              break;
+            case 'xiejing':
+              modalType = 'mainXjWindRect';
+              mainXjWindObj = new mainXjWindRect(model, playerVal1);
+              await mainXjWindObj.mountedThree();
+              break;
+            case 'lijing1':
+              modalType = 'mainLjWindRect';
+              mainLjWindObj = new mainLjWindRect(model, playerVal1);
+              await mainLjWindObj.mountedThree();
+              break;
+            case 'lijing_3':
+              modalType = 'mainWindRect3';
+              mainLj3WindObj = new mainWindLj3(model, playerVal1);
+              await mainLj3WindObj.mountedThree();
+              break;
+          }
+        }
+      } else {
+        mainWindObj = new mainWindRect(model, playerVal1);
+        await mainWindObj.mountedThree();
+      }
+
       model?.animate();
       resolve(null);
-      if (mainWindObj.airJin1) mainWindObj.airJin1.visible = false;
-      if (mainWindObj.airJin2) mainWindObj.airJin2.visible = false;
-      if (mainWindObj.airChu1) mainWindObj.airChu1.visible = false;
-      if (mainWindObj.airChu2) mainWindObj.airChu2.visible = false;
-      if (mainXjWindObj.airJin1) mainXjWindObj.airJin1.visible = false;
-      if (mainXjWindObj.airJin2) mainXjWindObj.airJin2.visible = false;
-      if (mainXjWindObj.airChu1) mainXjWindObj.airChu1.visible = false;
-      if (mainLjWindObj.airChu2) mainLjWindObj.airChu2.visible = false;
-      if (mainLjWindObj.airJin1) mainLjWindObj.airJin1.visible = false;
-      if (mainLjWindObj.airJin2) mainLjWindObj.airJin2.visible = false;
-      if (mainLjWindObj.airChu1) mainLjWindObj.airChu1.visible = false;
+      if (mainWindObj) {
+        if (mainWindObj.airJin1) mainWindObj.airJin1.visible = false;
+        if (mainWindObj.airJin2) mainWindObj.airJin2.visible = false;
+        if (mainWindObj.airChu1) mainWindObj.airChu1.visible = false;
+        if (mainWindObj.airChu2) mainWindObj.airChu2.visible = false;
+      }
+      if (mainXjWindObj) {
+        if (mainXjWindObj.airJin1) mainXjWindObj.airJin1.visible = false;
+        if (mainXjWindObj.airJin2) mainXjWindObj.airJin2.visible = false;
+        if (mainXjWindObj.airChu1) mainXjWindObj.airChu1.visible = false;
+        if (mainXjWindObj.airChu2) mainXjWindObj.airChu2.visible = false;
+      }
+      if (mainLjWindObj) {
+        if (mainLjWindObj.airChu2) mainLjWindObj.airChu2.visible = false;
+        if (mainLjWindObj.airJin1) mainLjWindObj.airJin1.visible = false;
+        if (mainLjWindObj.airJin2) mainLjWindObj.airJin2.visible = false;
+        if (mainLjWindObj.airChu1) mainLjWindObj.airChu1.visible = false;
+      }
+      if (mainLj3WindObj) {
+        if (mainLj3WindObj.airChu2) mainLj3WindObj.airChu2.visible = false;
+        if (mainLj3WindObj.airJin1) mainLj3WindObj.airJin1.visible = false;
+        if (mainLj3WindObj.airJin2) mainLj3WindObj.airJin2.visible = false;
+        if (mainLj3WindObj.airChu1) mainLj3WindObj.airChu1.visible = false;
+      }
     });
     startAnimation();
   });

+ 787 - 0
src/views/vent/monitorManager/mainFanMonitor/mainWind.li3.threejs.ts

@@ -0,0 +1,787 @@
+import * as THREE from 'three';
+import { CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
+import Smoke from '/@/views/vent/comment/threejs/Smoke';
+import { PathPointList, PathGeometry } from 'three.path';
+import gsap from 'gsap';
+
+class mainWindLj3 {
+  model;
+  modelName = 'main';
+  group: THREE.Group | null = null; // 主通风机场景
+  motorGroup1: THREE.Group | null = null; //电机
+  motorGroup2: THREE.Group | null = null; //电机
+  motorGroup3: THREE.Group | null = null; //电机
+  airJin1: THREE.Mesh | null = null; //风向箭头
+  airJin2: THREE.Mesh | null = null; //风向箭头
+  airChu1: THREE.Mesh | null = null; //风向箭头
+  airChu2: THREE.Mesh | null = null; //风向箭头
+  gearFront = {
+    gear1: null, //扇叶
+    gear2: null, //扇叶
+    gear1Direction: -1,
+    gear2Direction: 1,
+    gearFrameId: undefined,
+    gearRotateFactor: 0.5,
+    endGearRotateFactor: 3,
+  };
+  gearCenter = {
+    gear1: null, //扇叶
+    gear2: null, //扇叶
+    gear1Direction: -1, // 扇叶转动方向
+    gear2Direction: 1, // 扇叶转动方向
+    gearFrameId: undefined,
+    gearRotateFactor: 0.5, // 扇叶转动因素
+    endGearRotateFactor: 3, // 扇叶最终转动速度因素
+  };
+  gearBack = {
+    gear1: null, //扇叶
+    gear2: null, //扇叶
+    gear1Direction: -1, // 扇叶转动方向
+    gear2Direction: 1, // 扇叶转动方向
+    gearFrameId: undefined,
+    gearRotateFactor: 0.5, // 扇叶转动因素
+    endGearRotateFactor: 3, // 扇叶最终转动速度因素
+  };
+  oldMaterial: THREE.Material = new THREE.MeshStandardMaterial();
+  // smoke;
+  frontSmoke: Smoke | null = null; // 前面风流对象
+  centerSmoke: Smoke | null = null; // 前面风流对象
+  backSmoke: Smoke | null = null; // 后面风流对象
+  player1; // 视频播放器
+  playerStartClickTime1 = new Date().getTime();
+  frontWindowGroup;
+  backWindowGroup;
+  windowAngle = 0;
+  clock = new THREE.Clock();
+  material;
+  airTexture;
+  offset = 0;
+  direction = 0; // -1 代表反向,1代表正向
+  arrowMesh;
+  constructor(model, playerVal1) {
+    this.model = model;
+    this.player1 = playerVal1;
+  }
+  // 添加 cssObject
+  addCssText() {
+    if (!this.group) {
+      return;
+    }
+
+    const mainWindLj3 = this.group?.getObjectByName('mainWindLj3');
+    const fengji = mainWindLj3?.getObjectByName('FengJi_SanFengTong');
+    const fengji1 = fengji?.getObjectByName('Feng1_1');
+    const fengji2 = fengji?.getObjectByName('Feng2_1');
+    const fengji3 = fengji?.getObjectByName('Feng3_2');
+
+    // #1
+    if (!this.group.getObjectByName('monitorText1')) {
+      const worldPosition = new THREE.Vector3();
+      fengji1?.getObjectByName('Feng1_7')?.getWorldPosition(worldPosition);
+      const element = document.getElementById('inputBox') as HTMLElement;
+      if (element) {
+        const mainCSS3D = new CSS3DObject(element);
+        mainCSS3D.name = 'monitorText1';
+        mainCSS3D.scale.set(0.09, 0.09, 0.09);
+        mainCSS3D.position.set(worldPosition.x + 12, worldPosition.y - 20, worldPosition.z - 20);
+        mainCSS3D.lookAt(worldPosition.x + 12, worldPosition.y - 0, worldPosition.z + 2);
+        this.group.add(mainCSS3D);
+      }
+    }
+    debugger;
+    //#2
+    if (!this.group.getObjectByName('monitorText2')) {
+      const worldPosition = new THREE.Vector3();
+      fengji2?.getObjectByName('Feng2_44')?.getWorldPosition(worldPosition);
+      const element = document.getElementById('inputBox1') as HTMLElement;
+      if (element) {
+        const mainCSS3D = new CSS3DObject(element);
+        mainCSS3D.name = 'monitorText2';
+        mainCSS3D.scale.set(0.09, 0.09, 0.09);
+        mainCSS3D.position.set(worldPosition.x + 12, worldPosition.y - 20, worldPosition.z - 20);
+        mainCSS3D.lookAt(worldPosition.x + 12, worldPosition.y - 0, worldPosition.z + 2);
+        this.group.add(mainCSS3D);
+      }
+    }
+    // #3
+    if (!this.group.getObjectByName('monitorText3')) {
+      const worldPosition = new THREE.Vector3();
+      fengji3?.getObjectByName('Feng3_43')?.getWorldPosition(worldPosition);
+      const element = document.getElementById('inputBox2') as HTMLElement;
+      if (element) {
+        const mainCSS3D = new CSS3DObject(element);
+        mainCSS3D.name = 'monitorText3';
+        mainCSS3D.scale.set(0.09, 0.09, 0.09);
+        mainCSS3D.position.set(worldPosition.x + 12, worldPosition.y - 20, worldPosition.z - 20);
+        mainCSS3D.lookAt(worldPosition.x + 12, worldPosition.y - 0, worldPosition.z + 2);
+        this.group.add(mainCSS3D);
+      }
+    }
+  }
+
+  clearCssText() {
+    if (this.group) {
+      const mainCSS3D1 = this.group.getObjectByName('monitorText1');
+      const mainCSS3D2 = this.group.getObjectByName('monitorText2');
+      const mainCSS3D3 = this.group.getObjectByName('monitorText3');
+      if (mainCSS3D1) this.group.remove(mainCSS3D1);
+      if (mainCSS3D2) this.group.remove(mainCSS3D2);
+      if (mainCSS3D3) this.group.remove(mainCSS3D3);
+    }
+  }
+
+  addEcharts() {
+    const echartsBox = document.getElementById('fan-echarts');
+    if (echartsBox) {
+      const canvasObj = echartsBox.getElementsByTagName('canvas')[0];
+      // 将canvas 纹理转换为材质
+      const echartsMap = new THREE.CanvasTexture(canvasObj); // 关键一步
+      const echartsMaterial = new THREE.MeshBasicMaterial({
+        map: echartsMap, // 设置纹理贴图
+        transparent: true,
+        side: THREE.FrontSide, // 这里是双面渲染的意思
+      });
+      echartsMaterial.blending = THREE.CustomBlending;
+      const monitorPlane = this.group?.getObjectByName('monitorEcharts');
+      if (monitorPlane) {
+        monitorPlane.material = echartsMaterial;
+      } else {
+        const planeGeometry = new THREE.PlaneGeometry(17.6, 9.9); // 平面3维几何体PlaneGeometry
+        const planeMesh = new THREE.Mesh(planeGeometry, echartsMaterial);
+        planeMesh.name = 'monitorEcharts';
+        planeMesh.scale.set(1, 1, 1);
+        planeMesh.position.set(-47.38, 13.227, -21.79);
+        this.group?.add(planeMesh);
+      }
+    }
+  }
+
+  /* 更新动画 */
+  render() {
+    if (!this.model) {
+      return;
+    }
+    if (this.airTexture) {
+      this.airTexture.offset.x = this.offset;
+      this.offset -= this.clock.getDelta() * 2;
+    }
+  }
+
+  /* 点击风窗,风窗全屏 */
+  mousedownModel(intersects: THREE.Intersection<THREE.Object3D<THREE.Event>>[]) {
+    // 判断是否点击到视频
+    intersects.find((intersect) => {
+      const mesh = intersect.object;
+      if (mesh.name === 'player1') {
+        if (new Date().getTime() - this.playerStartClickTime1 < 400) {
+          // 双击,视频放大
+          if (this.player1) {
+            this.player1.requestFullscreen();
+          }
+        }
+        this.playerStartClickTime1 = new Date().getTime();
+        return true;
+      }
+      return false;
+    });
+  }
+
+  mouseUpModel() {}
+
+  async setDeviceFrequency(deviceType, state, frequencyVal?) {
+    // 调节频率
+    if (frequencyVal) {
+      this.resetSmokeParam(deviceType, frequencyVal, 0);
+    }
+    this.openOrCloseValve(deviceType, state, 0);
+    this.startGearAnimation(deviceType, state, '', 0);
+    if (deviceType === 'front') {
+      this.frontSmoke?.startSmoke();
+    } else if (deviceType === 'center') {
+      this.centerSmoke?.startSmoke();
+    } else {
+      this.backSmoke?.startSmoke();
+    }
+    setTimeout(() => {
+      this.lookMotor(deviceType, state, 10);
+    }, 2000);
+  }
+
+  async openDevice(deviceType, smokeDirection, frequencyVal, duration?) {
+    if (smokeDirection) {
+      this.setSmokeDirection(deviceType, smokeDirection);
+    }
+    let smoke;
+    if (deviceType === 'front') {
+      smoke = this.frontSmoke;
+    } else if (deviceType === 'center') {
+      smoke = this.centerSmoke;
+    } else {
+      smoke = this.backSmoke;
+    }
+    if (!smoke.frameId) {
+      await this.lookMotor(deviceType, 'open', duration);
+      await this.openOrCloseValve(deviceType, 'open', duration);
+      this.startGearAnimation(deviceType, 'open', smokeDirection, frequencyVal, duration);
+      smoke.startSmoke(duration);
+    }
+  }
+
+  async closeDevice(deviceType, flag = true) {
+    let smoke;
+    if (deviceType === 'front') {
+      smoke = this.frontSmoke;
+    } else if (deviceType === 'back') {
+      smoke = this.backSmoke;
+    } else {
+      smoke = this.centerSmoke;
+    }
+    if (smoke && smoke.frameId) {
+      if (flag) {
+        smoke.stopSmoke();
+        await this.openOrCloseValve(deviceType, 'close');
+        this.startGearAnimation(deviceType, 'close', '', null);
+        await this.lookMotor(deviceType, 'close');
+      } else {
+        smoke.stopSmoke(0);
+        await this.openOrCloseValve(deviceType, 'close', 0);
+        this.startGearAnimation(deviceType, 'close', '', null, 0);
+        await this.lookMotor(deviceType, 'close', 0);
+      }
+    }
+  }
+
+  async setSmokeDirection(deviceType, smokeDirection) {
+    let smoke;
+    const pathPoints: THREE.Vector3[] = [];
+    const windowPositivePath = [
+      {
+        path0: new THREE.Vector3(4.441, 20.267, 3.614),
+        path1: new THREE.Vector3(5.041, 6.806, 3.614),
+        isSpread: true,
+        spreadDirection: -1, //
+      },
+      {
+        path0: new THREE.Vector3(7.441, 0.806, 3.614),
+        path1: new THREE.Vector3(41.583, 1.485, 3.614),
+        isSpread: false,
+        spreadDirection: 0, //
+      },
+      {
+        path0: new THREE.Vector3(41.583, 1.485, 3.614),
+        path1: new THREE.Vector3(42.741, 5.364, 3.614),
+        isSpread: false,
+        spreadDirection: 0,
+      },
+      {
+        path0: new THREE.Vector3(42.741, 5.364, 3.614),
+        path1: new THREE.Vector3(44.741, 17.267, 3.614),
+        isSpread: true,
+        spreadDirection: 1, // 1是由小变大(出),-1是由大变小(进)
+      },
+    ];
+    const windowInversePath = [
+      {
+        path0: new THREE.Vector3(44.741, 17.267, 3.614),
+        path1: new THREE.Vector3(42.741, 5.364, 3.614),
+        isSpread: true,
+        spreadDirection: -1, //
+      },
+      {
+        path0: new THREE.Vector3(42.741, 5.364, 3.614),
+        path1: new THREE.Vector3(41.583, 1.485, 3.614),
+        isSpread: false,
+        spreadDirection: 0, //
+      },
+      {
+        path0: new THREE.Vector3(41.583, 1.485, 3.614),
+        path1: new THREE.Vector3(7.441, 0.806, 3.614),
+        isSpread: false,
+        spreadDirection: 0, // 1是由小变大,-1是由大变小
+      },
+      {
+        path0: new THREE.Vector3(4.441, 17.267, 3.614),
+        path1: new THREE.Vector3(5.041, 6.806, 3.614),
+        isSpread: true,
+        spreadDirection: 1, //
+      },
+    ];
+    const tubPositivePath = [
+      {
+        path0: new THREE.Vector3(7.441, 0.806, 3.614),
+        path1: new THREE.Vector3(44.583, 1.485, 3.614),
+        isSpread: false,
+        spreadDirection: 0, //
+      },
+      {
+        path0: new THREE.Vector3(44.583, 1.485, 3.614),
+        path1: new THREE.Vector3(45.741, 5.364, 3.614),
+        isSpread: false,
+        spreadDirection: 0,
+      },
+      {
+        path0: new THREE.Vector3(45.741, 5.364, 3.614),
+        path1: new THREE.Vector3(47.741, 17.267, 3.614),
+        isSpread: true,
+        spreadDirection: 1, // 1是由小变大(出),-1是由大变小(进)
+      },
+    ];
+    const tubInversePath = [
+      {
+        path0: new THREE.Vector3(47.741, 17.267, 3.614),
+        path1: new THREE.Vector3(45.741, 5.364, 3.614),
+        isSpread: true,
+        spreadDirection: -1, //
+      },
+      {
+        path0: new THREE.Vector3(45.741, 5.364, 3.614),
+        path1: new THREE.Vector3(44.583, 1.485, 3.614),
+        isSpread: false,
+        spreadDirection: 0, //
+      },
+      {
+        path0: new THREE.Vector3(44.583, 1.485, 3.614),
+        path1: new THREE.Vector3(7.441, 0.806, 3.614),
+        isSpread: false,
+        spreadDirection: 0, // 1是由小变大,-1是由大变小
+      },
+    ];
+    const getPathPoint = () => {
+      this.arrowMesh = this.group?.getObjectByName('arrow');
+      if (this.arrowMesh) return;
+      pathPoints.push(new THREE.Vector3(16.441, 1.485, 2.614), new THREE.Vector3(35.583, 1.485, 2.614));
+      const pathPointList = new PathPointList();
+      const up = new THREE.Vector3(0, 0, 1);
+      pathPointList.set(pathPoints, 0, 0, up, false);
+      const geometry = new PathGeometry(pathPoints.length, false);
+      geometry.update(pathPointList, {
+        width: 2,
+        arrow: false,
+      });
+
+      this.arrowMesh = new THREE.Mesh(geometry, this.material);
+      this.arrowMesh.name = 'arrow';
+      this.group?.add(this.arrowMesh);
+    };
+
+    if (deviceType === 'front') {
+      smoke = this.frontSmoke;
+    } else if (deviceType === 'back') {
+      smoke = this.backSmoke;
+    } else {
+      smoke = this.centerSmoke;
+    }
+    switch (smokeDirection) {
+      case 'tubPositivePath': // 风筒正
+        smoke.setPath(tubPositivePath);
+        if (this.direction !== 1) {
+          this.direction = 1;
+          this.airTexture.repeat.x = 1;
+        }
+        break;
+      case 'tubInversePath': // 风筒反
+        smoke.setPath(tubInversePath);
+        if (this.direction !== -1) {
+          this.direction = -1;
+          this.airTexture.repeat.x = -1;
+        }
+        break;
+      case 'windowPositivePath': // 风窗正
+        smoke.setPath(windowPositivePath);
+        if (this.direction !== 1) {
+          this.direction = 1;
+          this.airTexture.repeat.x = 1;
+        }
+        break;
+      case 'windowInversePath': // 风窗反
+        smoke.setPath(windowInversePath);
+        if (this.direction !== -1) {
+          this.direction = -1;
+          this.airTexture.repeat.x = -1;
+        }
+        break;
+    }
+    getPathPoint();
+    if (deviceType === 'front') {
+      if (this.arrowMesh && this.arrowMesh.position.z !== 2.31) this.arrowMesh.position.set(-6.48, 5.51, 13.25);
+    } else if (deviceType === 'center') {
+      if (this.arrowMesh && this.arrowMesh.position.z !== -12.99) this.arrowMesh.position.set(-6.48, 5.51, -0.02);
+    } else {
+      if (this.arrowMesh && this.arrowMesh.position.z !== -12.99) this.arrowMesh.position.set(-6.48, 5.51, -14.67);
+    }
+  }
+
+  /* 播放气流动画 */
+  /**
+   *
+   * @param controlType // 设备控制类型
+   * @param deviceType //前后风机
+   * @param frequencyVal // 风机运行频率
+   * @param state // 打开、关闭状态
+   */
+  async playSmoke(controlType, deviceType, frequencyVal, state, smokeDirection) {
+    if (frequencyVal) {
+      this.resetSmokeParam(deviceType, frequencyVal);
+    }
+    if (controlType === 'startSmoke') {
+      if (state === 'stop') {
+        await this.closeDevice(deviceType);
+      } else {
+        // 开启时需要设置方向
+        await this.openDevice(deviceType, smokeDirection, frequencyVal);
+      }
+    } else if (controlType === 'changeDirection') {
+      // 改变扇叶转动方向、反风
+      this.startGearAnimation(deviceType, 'changeDirection', smokeDirection, frequencyVal);
+      let smoke;
+      if (deviceType === 'front') {
+        smoke = this.frontSmoke;
+      } else if (deviceType === 'center') {
+        smoke = this.centerSmoke;
+      } else {
+        smoke = this.backSmoke;
+      }
+      if (smoke && smoke.frameId) {
+        await smoke.stopSmoke();
+        await this.setSmokeDirection(deviceType, smokeDirection);
+        smoke.startSmoke();
+      }
+    } else if (controlType === 'frequency') {
+      this.startGearAnimation(deviceType, 'frequency', smokeDirection, frequencyVal);
+    } else if (controlType === 'initiatePlay') {
+      this.openDevice(deviceType, smokeDirection, frequencyVal, 0);
+    } else if (controlType === 'changeSmoke') {
+      //
+    }
+  }
+  stopSmoke() {
+    this.closeDevice('front', false);
+    this.closeDevice('back', false);
+    this.closeDevice('center', false);
+  }
+
+  /* 打开或关闭蝶阀 */
+  openOrCloseValve(deviceType, flag, duration = 3) {
+    const ztfjGroup = this.group?.getObjectByName('ztfj');
+    return new Promise((resolve) => {
+      let diefa;
+      if (deviceType == 'front') {
+        diefa = ztfjGroup?.getObjectByName('butterfly_valve001') as THREE.Mesh;
+      } else if (deviceType == 'center') {
+        diefa = ztfjGroup?.getObjectByName('butterfly_valve001') as THREE.Mesh;
+      } else {
+        diefa = ztfjGroup?.getObjectByName('butterfly_valve002') as THREE.Mesh;
+      }
+      let rotationY;
+      if (flag == 'open') {
+        rotationY = 0;
+      } else {
+        rotationY = Math.PI / 2;
+      }
+      if (diefa) {
+        gsap.to(diefa.rotation, {
+          y: rotationY,
+          duration: duration,
+          ease: 'none',
+          onComplete: function () {
+            resolve(null);
+          },
+        });
+      }
+    });
+  }
+
+  /* 风流调频, 范围1-50 */
+  // opacityFactor (0.4 300)
+  // life 最小 300, 最大 50
+  // speedFactor 最大0, 最小100
+  resetSmokeParam(deviceType, frequency, duration = 5) {
+    if (frequency < 1) frequency = 1;
+    if (frequency > 50) frequency = 50;
+    let smoke;
+    if (deviceType === 'front') {
+      smoke = this.frontSmoke;
+    } else if (deviceType === 'center') {
+      smoke = this.centerSmoke;
+    } else {
+      smoke = this.backSmoke;
+    }
+    const opacityFactor = (frequency / 50) * 0.8;
+    duration = (Number(Math.abs(smoke.opacityFactor - opacityFactor).toFixed(1)) / 0.8) * 5;
+    const life = (-250 / 50) * frequency + 300;
+    gsap.to(smoke, {
+      opacityFactor: opacityFactor,
+      life: life,
+      duration: duration,
+      ease: 'easeInCirc',
+      overwrite: true,
+    });
+  }
+
+  /* 显示电机 */
+  lookMotor(deviceType, flag, duration = 5) {
+    return new Promise((resolve) => {
+      const mainWindLj3 = this.group?.getObjectByName('mainWindLj3');
+      const fengji = mainWindLj3?.getObjectByName('FengJi_SanFengTong');
+      const fengji1 = fengji?.getObjectByName('Feng1_1');
+      const fengji2 = fengji?.getObjectByName('Feng2_1');
+      const fengji3 = fengji?.getObjectByName('Feng3_2');
+
+      let mesh, mesh1, mesh2, mesh3, motorGroup;
+      mesh1 = fengji1?.getObjectByName('Feng1_97'); //前
+      mesh2 = fengji2?.getObjectByName('Feng2_94'); //中
+      mesh3 = fengji3?.getObjectByName('Feng1_97'); //后
+      if (deviceType == 'front') {
+        mesh = mesh1;
+        motorGroup = this.motorGroup1;
+      } else if (deviceType == 'center') {
+        mesh = mesh2;
+        motorGroup = this.motorGroup2;
+      } else {
+        mesh = mesh3;
+        motorGroup = this.motorGroup3;
+      }
+      if (mesh && motorGroup) {
+        if (flag == 'open') {
+          mesh.material.depthWrite = false;
+          mesh.material.depthTest = false;
+
+          motorGroup.visible = true;
+          gsap.to(mesh.material, {
+            opacity: 0.1,
+            duration: duration,
+            overwrite: true,
+            onComplete: function () {
+              // mesh.material.color = '#000';
+              resolve(null);
+            },
+          });
+        } else {
+          const opacity = mesh.material.opacity;
+          Object.assign(mesh.material, this.oldMaterial, { opacity: opacity });
+          mesh.material.depthWrite = true;
+          mesh.material.depthTest = true;
+          gsap.to(mesh.material, {
+            opacity: 1,
+            duration: 1,
+            overwrite: true,
+            onComplete: function () {
+              resolve(null);
+            },
+          });
+        }
+      }
+    });
+  }
+
+  /* 齿轮转动动画 1 - 50  最大3 */
+  startGearAnimation(deviceType, flag, smokeDirection, frequencyVal, duration = 8) {
+    let gearObj, gearDirection;
+    if (deviceType === 'front') {
+      gearObj = this.gearFront;
+    } else if (deviceType === 'center') {
+      gearObj = this.gearCenter;
+    } else {
+      gearObj = this.gearBack;
+    }
+    if (smokeDirection === 'tubPositivePath') {
+      gearDirection = 1;
+    } else if (smokeDirection === 'tubInversePath') {
+      gearDirection = -1;
+    }
+    if (frequencyVal) {
+      const endGearRotateFactor = (3 / 50) * frequencyVal;
+      duration = (8 / 3) * Math.abs(gearObj.endGearRotateFactor - endGearRotateFactor);
+      gearObj.endGearRotateFactor = endGearRotateFactor;
+    }
+
+    const gearAnimation = () => {
+      gsap.to(gearObj, {
+        gearRotateFactor: gearObj.endGearRotateFactor,
+        duration: duration,
+        ease: 'easeInCubic',
+        repeat: 0,
+        overwrite: true,
+      });
+
+      const clock = new THREE.Clock(); // 时钟
+      const h = () => {
+        if (gearObj.gear1 && gearObj.gear2) {
+          gearObj.gearFrameId = requestAnimationFrame(h);
+
+          const dt = clock.getDelta();
+          gearObj.gear1.rotation.x += dt * gearObj.gearRotateFactor * gearObj.gear1Direction;
+          gearObj.gear2.rotation.x += dt * gearObj.gearRotateFactor * gearObj.gear2Direction;
+        }
+      };
+      h();
+    };
+    if (flag === 'changeDirection') {
+      if (gearDirection == -1 * gearObj.gear1Direction) {
+        // 齿轮正在转,需要停止后再反方向转
+        gsap.to(gearObj, {
+          gearRotateFactor: 0,
+          duration: duration,
+          ease: 'easeInCubic',
+          repeat: 0,
+          onComplete: function () {
+            window.cancelAnimationFrame(gearObj.gearFrameId);
+            gearObj.gearFrameId = undefined;
+            gearObj.gear1Direction = -1 * gearObj.gear1Direction;
+            gearObj.gear2Direction = -1 * gearObj.gear2Direction;
+            gearAnimation();
+          },
+        });
+      }
+    } else if (flag === 'open') {
+      gearObj.gear1Direction = gearDirection;
+      gearObj.gear2Direction = -1 * gearDirection;
+      gearAnimation();
+    } else if (flag === 'close') {
+      gsap.to(gearObj, {
+        gearRotateFactor: 0,
+        duration: duration,
+        ease: 'easeInCubic',
+        repeat: 0,
+        overwrite: true,
+        onComplete: function () {
+          window.cancelAnimationFrame(gearObj.gearFrameId);
+          gearObj.gearFrameId = undefined;
+        },
+      });
+    } else if (flag === 'frequency') {
+      gsap.to(gearObj, {
+        gearRotateFactor: gearObj.endGearRotateFactor,
+        duration: duration,
+        ease: 'easeInCubic',
+        repeat: 0,
+        overwrite: true,
+      });
+    }
+  }
+
+  /* 初始化口上面的气体 */
+  initSmokeMass() {
+    if (!this.frontSmoke) {
+      this.frontSmoke = new Smoke('/model/img/texture-smoke.png', '#ffffff', 0, 0.4, 1.8, 100);
+    }
+    if (!this.centerSmoke) {
+      this.centerSmoke = new Smoke('/model/img/texture-smoke.png', '#ffffff', 0, 0.4, 1.8, 100);
+    }
+    if (!this.backSmoke) {
+      this.backSmoke = new Smoke('/model/img/texture-smoke.png', '#ffffff', 0, 0.4, 1.8, 100);
+    }
+  }
+
+  /* 设置气流位置 */
+  async setSmokePosition() {
+    if (this.frontSmoke) {
+      await this.frontSmoke.setPoints();
+      this.frontSmoke.points.name = 'frontSmoke';
+      this.group?.add(this.frontSmoke.points);
+      this.frontSmoke.points.position.set(-11.75, 4.15, 14.39);
+    }
+    if (this.centerSmoke) {
+      await this.centerSmoke.setPoints();
+      this.centerSmoke.points.name = 'centerSmoke';
+      this.group?.add(this.centerSmoke.points);
+      this.centerSmoke.points.position.set(-11.75, 4.15, -0.69);
+    }
+    if (this.backSmoke) {
+      await this.backSmoke.setPoints();
+      this.backSmoke.points.name = 'backSmoke';
+      this.group?.add(this.backSmoke.points);
+      this.backSmoke.points.position.set(-11.75, 4.15, -15.51);
+    }
+  }
+
+  /** 初始化电机 */
+  async initMotor() {
+    const mainWindLj3 = this.group?.getObjectByName('mainWindLj3');
+    const fengji = mainWindLj3?.getObjectByName('FengJi_SanFengTong');
+    // 前电机
+    this.motorGroup1 = fengji?.getObjectByName('Feng1_1');
+    this.gearFront.gear1 = this.motorGroup1?.getObjectByName('Feng1_33');
+    this.gearFront.gear2 = this.motorGroup1?.getObjectByName('Feng1_44');
+
+    // 中间电机
+    this.motorGroup2 = fengji?.getObjectByName('Feng2_1');
+    this.gearCenter.gear1 = this.motorGroup1?.getObjectByName('Feng2_10');
+    this.gearCenter.gear2 = this.motorGroup1?.getObjectByName('Feng2_29');
+
+    // 后电机
+    this.motorGroup3 = fengji?.getObjectByName('Feng3_2');
+    this.gearBack.gear1 = this.motorGroup1?.getObjectByName('Feng3_10');
+    this.gearBack.gear2 = this.motorGroup1?.getObjectByName('Feng3_28');
+  }
+
+  mountedThree() {
+    this.group = new THREE.Group();
+    return new Promise(async (resolve) => {
+      this.model.setGLTFModel(['bg1', 'mainWindLj3'], this.group).then(async () => {
+        // this.group = gltf[0];
+
+        console.log(this.group);
+        this.group?.position.set(-0.44, 19.88, 22.37);
+        const mainWindLj3 = this.group?.getObjectByName('mainWindLj3') as THREE.Group;
+        mainWindLj3.position.set(0, 1.48, 2.94);
+        mainWindLj3.scale.set(2.5, 2.5, 2.5);
+        this.initSmokeMass();
+        await this.setSmokePosition();
+
+        const ztfjGroup = mainWindLj3?.getObjectByName('FengJi_SanFengTong');
+        const fegnji = ztfjGroup?.getObjectByName('Feng1_1');
+
+        const mesh = fegnji?.getObjectByName('Feng1_97') as THREE.Mesh; //前
+        if (mesh && mesh.material) this.oldMaterial = mesh.material as THREE.MeshStandardMaterial;
+        await this.initMotor();
+        resolve(null);
+
+        const loader = new THREE.TextureLoader();
+        this.airTexture = loader.load('/model/img/air.png');
+        this.airTexture.wrapS = THREE.RepeatWrapping;
+        this.airTexture.repeat.set(1, 1.2);
+        this.airTexture.offset.y = 0;
+        this.airTexture.matrix.scale(0.5, 0.5);
+        this.airTexture.needsUpdate = true;
+        this.material = new THREE.MeshBasicMaterial({
+          map: this.airTexture,
+          transparent: true,
+          side: THREE.FrontSide,
+        });
+        this.clock.start();
+      });
+    });
+  }
+
+  destroy() {
+    if (this.frontSmoke) this.frontSmoke.clearSmoke();
+    if (this.centerSmoke) this.centerSmoke.clearSmoke();
+    if (this.backSmoke) this.backSmoke.clearSmoke();
+
+    this.model.clearGroup(this.motorGroup1);
+    this.model.clearGroup(this.motorGroup2);
+    this.model.clearGroup(this.group);
+
+    this.motorGroup1 = undefined;
+    this.motorGroup2 = undefined;
+
+    this.gearFront.gear1 = undefined;
+    this.gearFront.gear2 = undefined;
+
+    this.gearCenter.gear1 = undefined;
+    this.gearCenter.gear2 = undefined;
+
+    this.gearBack.gear1 = undefined;
+    this.gearBack.gear2 = undefined;
+
+    this.frontSmoke = undefined;
+    this.centerSmoke = undefined;
+    this.backSmoke = undefined;
+
+    this.model = undefined;
+    this.group = undefined;
+  }
+}
+
+export default mainWindLj3;

Some files were not shown because too many files changed in this diff