Jelajahi Sumber

[Mod 0000]新增一套可调节风门、主风机模型替换

hongrunxia 1 Minggu lalu
induk
melakukan
f3c55d3e3d

+ 100 - 85
src/components/chart/BarAndLine.vue

@@ -129,6 +129,7 @@
             }
             console.log(option.series[index], '000===');
             option.series[index].data = props.dataSource.map((item) => Number(item[propType.dataIndex]) || 0);
+            debugger;
             // console.log('nnn', option.series[index].data);
             // 这里动态计算echarts y轴最大值
             const max = Math.max(...option.series[index].data);
@@ -136,94 +137,108 @@
             const digitCount = Math.ceil(Number(max));
             const minDigitCount = Math.floor(Number(min));
 
-            if (props.chartsType === 'history') {
-              const disLen = Math.abs(max - min);
-              propType.ymax = digitCount + disLen / 3;
-              propType.ymin = minDigitCount - disLen / 3 > 0 || minDigitCount < 0 ? minDigitCount - disLen / 3 : 0;
-            } else {
-              let yMax = 0,
-                yMin = 0;
-              if (digitCount < 2) {
-                if (max < 0.5) {
-                  yMax = 1;
-                } else if (max < 0.9) {
-                  yMax = 1.5;
-                } else if (max < 5) {
-                  yMax = 5;
-                } else if (max < 10) {
-                  yMax = 10;
-                }
-              } else if (digitCount < 3) {
-                const n = Number((Number(max.toFixed(0)) / 10).toFixed(0));
-                if (max < n * 10 + 5) {
-                  yMax = (n + 1) * 10;
-                } else {
-                  yMax = (n + 2) * 10;
-                }
-              } else if (digitCount < 4) {
-                const n = Number((Number(max.toFixed(0)) / 100).toFixed(0));
-                if (max < n * 100 + 50) {
-                  yMax = (n + 1) * 100;
-                } else {
-                  yMax = (n + 2) * 100;
-                }
-              } else if (digitCount < 5) {
-                const n = Number((Number(max.toFixed(0)) / 1000).toFixed(0));
-                if (max < n * 1000 + 500) {
-                  yMax = (n + 1) * 1000;
-                } else {
-                  yMax = (n + 1) * 1000 + 500;
-                }
-              } else if (digitCount < 6) {
-                const n = Number((Number(max.toFixed(0)) / 10000).toFixed(0));
-                if (max < n * 10000 + 5000) {
-                  yMax = (n + 1) * 10000;
-                } else {
-                  yMax = (n + 1) * 10000 + 5000;
-                }
-              }
+            // if (props.chartsType === 'history') {
+            //   const disLen = Math.abs(max - min);
+            //   propType.ymax = digitCount + disLen / 3;
+            //   propType.ymin = minDigitCount - disLen / 3 > 0 || minDigitCount < 0 ? minDigitCount - disLen / 3 : 0;
+            // } else {
+            //   let yMax = 0,
+            //     yMin = 0;
+            //   if (digitCount < 2) {
+            //     if (max < 0.5) {
+            //       yMax = 1;
+            //     } else if (max < 0.9) {
+            //       yMax = 1.5;
+            //     } else if (max < 5) {
+            //       yMax = 5;
+            //     } else if (max < 10) {
+            //       yMax = 10;
+            //     }
+            //   } else if (digitCount < 3) {
+            //     const n = Number((Number(max.toFixed(0)) / 10).toFixed(0));
+            //     if (max < n * 10 + 5) {
+            //       yMax = (n + 1) * 10;
+            //     } else {
+            //       yMax = (n + 2) * 10;
+            //     }
+            //   } else if (digitCount < 4) {
+            //     const n = Number((Number(max.toFixed(0)) / 100).toFixed(0));
+            //     if (max < n * 100 + 50) {
+            //       yMax = (n + 1) * 100;
+            //     } else {
+            //       yMax = (n + 2) * 100;
+            //     }
+            //   } else if (digitCount < 5) {
+            //     const n = Number((Number(max.toFixed(0)) / 1000).toFixed(0));
+            //     if (max < n * 1000 + 500) {
+            //       yMax = (n + 1) * 1000;
+            //     } else {
+            //       yMax = (n + 1) * 1000 + 500;
+            //     }
+            //   } else if (digitCount < 6) {
+            //     const n = Number((Number(max.toFixed(0)) / 10000).toFixed(0));
+            //     if (max < n * 10000 + 5000) {
+            //       yMax = (n + 1) * 10000;
+            //     } else {
+            //       yMax = (n + 1) * 10000 + 5000;
+            //     }
+            //   }
 
-              if (minDigitCount < 2) {
-                if (min > 1.5) {
-                  yMin = 1.0;
-                } else if (min > 5) {
-                  yMin = 5;
-                } else {
-                  yMin = 0;
-                }
-              } else if (minDigitCount < 3) {
-                const n = Number((Number(min.toFixed(0)) / 10).toFixed(0));
-                if (n > 1) {
-                  yMin = (n - 1) * 10;
-                } else {
-                  yMin = 10;
-                }
-              } else if (digitCount < 4) {
-                const n = Number((Number(min.toFixed(0)) / 100).toFixed(0));
-                if (n > 1) {
-                  yMin = (n - 1) * 100;
-                } else {
-                  yMin = 100;
-                }
-              } else if (digitCount < 5) {
-                const n = Number((Number(min.toFixed(0)) / 1000).toFixed(0));
-                if (n > 1) {
-                  yMin = (n - 1) * 1000;
-                } else {
-                  yMin = 1000;
-                }
-              } else if (digitCount < 6) {
-                const n = Number((Number(min.toFixed(0)) / 10000).toFixed(0));
-                if (n > 1) {
-                  yMin = (n - 1) * 10000;
-                } else {
-                  yMin = 10000;
-                }
-              }
+            //   if (minDigitCount < 2) {
+            //     if (min > 1.5) {
+            //       yMin = 1.0;
+            //     } else if (min > 5) {
+            //       yMin = 5;
+            //     } else {
+            //       yMin = 0;
+            //     }
+            //   } else if (minDigitCount < 3) {
+            //     const n = Number((Number(min.toFixed(0)) / 10).toFixed(0));
+            //     if (n > 1) {
+            //       yMin = (n - 1) * 10;
+            //     } else {
+            //       yMin = 10;
+            //     }
+            //   } else if (digitCount < 4) {
+            //     const n = Number((Number(min.toFixed(0)) / 100).toFixed(0));
+            //     if (n > 1) {
+            //       yMin = (n - 1) * 100;
+            //     } else {
+            //       yMin = 100;
+            //     }
+            //   } else if (digitCount < 5) {
+            //     const n = Number((Number(min.toFixed(0)) / 1000).toFixed(0));
+            //     if (n > 1) {
+            //       yMin = (n - 1) * 1000;
+            //     } else {
+            //       yMin = 1000;
+            //     }
+            //   } else if (digitCount < 6) {
+            //     const n = Number((Number(min.toFixed(0)) / 10000).toFixed(0));
+            //     if (n > 1) {
+            //       yMin = (n - 1) * 10000;
+            //     } else {
+            //       yMin = 10000;
+            //     }
+            //   }
 
-              propType.ymax = yMax;
-              propType.ymin = yMin;
+            //   propType.ymax = yMax;
+            //   propType.ymin = yMin;
+            // }
+            const disLen = Math.abs(max - min);
+            if (propType.ymax && propType.ymin >= 0) {
+              if (max > propType.ymax || min < propType.ymin) {
+                propType.ymax = digitCount + disLen / 3;
+                propType.ymin = minDigitCount - disLen / 3 > 0 || minDigitCount < 0 ? minDigitCount - disLen / 3 : 0;
+              }
+            } else {
+              propType.ymax = digitCount + disLen / 3;
+              propType.ymin = minDigitCount - disLen / 3 > 0 || minDigitCount < 0 ? minDigitCount - disLen / 3 : 0;
             }
+            if (propType.ymax == propType.ymin && propType.ymin == 0) {
+              propType.ymax = 10;
+            }
+
             return true;
           });
           // debugger;

+ 48 - 47
src/router/index.ts

@@ -23,54 +23,55 @@ export const router = createRouter({
 
 // TODO 【QQYUN-4517】【表单设计器】记录分享路由守卫测试
 // 存储当前页面的browseId(用于关联离开/进入日志)
-let currentBrowseId = '';
+const currentBrowseId = '';
 router.beforeEach(async (to, from, next) => {
-  const url = '/sys/log/addBrowseLog';
-  const currentPath = to.fullPath;
-  // 生成时间戳函数
-  const formatTimestamp = () => {
-    const date = new Date();
-    return [
-      date.getFullYear(),
-      String(date.getMonth() + 1).padStart(2, '0'),
-      String(date.getDate()).padStart(2, '0'),
-      String(date.getHours()).padStart(2, '0'),
-      String(date.getMinutes()).padStart(2, '0'),
-      String(date.getSeconds()).padStart(2, '0'),
-      String(date.getMilliseconds()).padStart(3, '0'),
-    ].join('');
-  };
-  // 1. 如果存在上一个页面的browseId,发送离开日志
-  if (currentBrowseId && from.fullPath !== '/') {
-    try {
-      await defHttp.post({
-        url,
-        params: {
-          browseId: currentBrowseId,
-          isEnd: true,
-          method: from.fullPath,
-        },
-      });
-      console.log('离开页面日志记录成功');
-    } catch (e) {
-      console.error('离开页面日志记录失败:', e);
-    }
-  }
-
-  // 2. 记录新页面进入日志
-  currentBrowseId = formatTimestamp();
-  try {
-    await defHttp.post({
-      url,
-      params: {
-        browseId: currentBrowseId,
-        isEnd: false,
-        method: to.fullPath,
-      },
-    });
-    console.log('进入页面日志记录成功');
-  } catch (e) {
-    console.error('进入页面日志记录失败:', e);
+  if (to.path === '/sys/log/addBrowseLog') {
+    // const url = '/sys/log/addBrowseLog';
+    // const currentPath = to.fullPath;
+    // // 生成时间戳函数
+    // const formatTimestamp = () => {
+    //   const date = new Date();
+    //   return [
+    //     date.getFullYear(),
+    //     String(date.getMonth() + 1).padStart(2, '0'),
+    //     String(date.getDate()).padStart(2, '0'),
+    //     String(date.getHours()).padStart(2, '0'),
+    //     String(date.getMinutes()).padStart(2, '0'),
+    //     String(date.getSeconds()).padStart(2, '0'),
+    //     String(date.getMilliseconds()).padStart(3, '0'),
+    //   ].join('');
+    // };
+    // // 1. 如果存在上一个页面的browseId,发送离开日志
+    // if (currentBrowseId && from.fullPath !== '/') {
+    //   try {
+    //     await defHttp.post({
+    //       url,
+    //       params: {
+    //         browseId: currentBrowseId,
+    //         isEnd: true,
+    //         method: from.fullPath,
+    //       },
+    //     });
+    //     console.log('离开页面日志记录成功');
+    //   } catch (e) {
+    //     console.error('离开页面日志记录失败:', e);
+    //   }
+    // }
+    // // 2. 记录新页面进入日志
+    // currentBrowseId = formatTimestamp();
+    // try {
+    //   await defHttp.post({
+    //     url,
+    //     params: {
+    //       browseId: currentBrowseId,
+    //       isEnd: false,
+    //       method: to.fullPath,
+    //     },
+    //   });
+    //   console.log('进入页面日志记录成功');
+    // } catch (e) {
+    //   console.error('进入页面日志记录失败:', e);
+    // }
   }
 
   next();

+ 2 - 2
src/views/vent/home/configurable/components/ModuleBDDual.vue

@@ -148,8 +148,8 @@
     (d) => {
       initA(d);
       initB(d);
-      selectedDeviceIDA.value = optionsA.value[0]?.value;
-      selectedDeviceIDB.value = optionsB.value[0]?.value;
+      if (!selectedDeviceIDA.value) selectedDeviceIDA.value = optionsA.value[0]?.value;
+      if (!selectedDeviceIDB.value) selectedDeviceIDB.value = optionsB.value[0]?.value;
     },
     {
       immediate: true,

+ 327 - 0
src/views/vent/home/configurable/configurable.api.ts

@@ -0,0 +1,327 @@
+import { floor, isArray, random, slice } from 'lodash-es';
+import { defHttp } from '/@/utils/http/axios';
+import { get } from '../billboard/utils';
+
+enum Api {
+  list = '/safety/ventanalyDevice/homedata2',
+  getHomeData = '/safety/ventanalyDevice/homedata',
+  getDisHome = '/monitor/disaster/getDisHome',
+  getBDDustData = '/monitor/disaster/getDisDustHome',
+  getBDFireData = '/monitor/disaster/getDisFireHome',
+}
+
+// 搞这个缓存是由于:目前代码上的设计是多个模块发出多次请求,每个模块自己负责消费前者的响应。
+// 这会导致相同的请求被同时发送多次。
+const cache = new Map<string, Promise<any>>();
+
+/**
+ * 列表接口,5.5专用,和6.0的getHomeData基本一致
+ * @param params
+ */
+export const list = (params) => {
+  const key = `${Api.list}?${JSON.stringify(params)}`;
+  if (!cache.has(key)) {
+    cache.set(
+      key,
+      defHttp.post({ url: Api.list, params }).finally(() => {
+        cache.delete(key);
+      })
+    );
+  }
+  return (cache.get(key) as Promise<any>).then((res) => {
+    if (res.fanmain) {
+      // 处理频率字段,为了兼容旧版保留,现配置项已支持一级动态字段
+      res.fanmain.forEach((e) => {
+        if (e.readData.Fan2StartStatus === '1') {
+          e.current = '二号';
+          e.readData.FanFreqHz = e.readData.Fan2FreqHz;
+        } else {
+          e.current = '一号';
+          e.readData.FanFreqHz = e.readData.Fan1FreqHz;
+        }
+      });
+    }
+    if (res.fanlocal) {
+      res.fanlocal.forEach((e) => {
+        e.chartData = [
+          {
+            x: '吸风量',
+            yRealtime: e.readData.windQuantity1,
+            yMock: floor(parseFloat(e.inletAirVolume_merge) * random(0.98, 1, false), 2),
+            y: e.inletAirVolume_merge,
+          },
+          {
+            x: '供风量',
+            yRealtime: e.readData.windQuantity2,
+            yMock: floor(parseFloat(e.ductOutletAirVolume_merge) * random(0.98, 1, false), 2),
+            y: e.ductOutletAirVolume_merge,
+          },
+        ];
+        if (e.readData.Fan2StartStatus === '1') {
+          e.current = '二号';
+          e.readData.FanfHz = e.readData.Fan2fHz;
+        } else {
+          e.current = '一号';
+          e.readData.FanfHz = e.readData.Fan1fHz;
+        }
+      });
+    }
+    if (res.sys_majorpath) {
+      res.sys_majorpath.forEach((e) => {
+        const { drag_1, drag_2, drag_3, drag_total } = e.majorpath;
+        const { fy_merge = { value: '1' } } = e.readData;
+        const drag_merge = parseInt(fy_merge.value);
+        // const m3_merge = parseInt(retM3_merge.value);
+
+        e.piechart = [
+          { val: drag_1, valMock: floor((drag_1 / drag_total) * drag_merge), label: '进风区(Pa)' },
+          { val: drag_2, valMock: floor((drag_2 / drag_total) * drag_merge), label: '用风区(Pa)' },
+          { val: drag_3, valMock: floor((drag_3 / drag_total) * drag_merge), label: '回风区(Pa)' },
+        ];
+        e.readData.dengjikong_merge = get(res, 'midinfo[0].sysinfo.equalarea');
+        e.readData.fy_merge_int = drag_merge;
+        // e.dengjikong_merge = floor((1.19 * (m3_merge / 60)) / Math.sqrt(drag_merge), 2);
+      });
+    }
+    if (res.sys_surface_caimei) {
+      res.sys_surface_caimei.forEach((e) => {
+        if (isArray(e.history)) {
+          e.history = slice(e.history, e.history.length - 30, e.history.length);
+        }
+        if (isArray(e.history_report)) {
+          e.history_report = slice(e.history_report, e.history_report.length - 30, e.history_report.length);
+        }
+      });
+    }
+    if (res.device_arr) {
+      res.device_arr = Object.values(res.device);
+    }
+    if (res.sys_wind) {
+      res.sys_wind.forEach((e) => {
+        if (e.readData.m3) {
+          e.readData.m3 = e.readData.m3.replace('-', '');
+        }
+        if (e.readData.va) {
+          e.readData.va = e.readData.va.replace('-', '');
+        }
+      });
+    }
+    if (res.windrect) {
+      res.windrect.forEach((e) => {
+        if (e.readData.m3) {
+          e.readData.m3 = e.readData.m3.replace('-', '');
+        }
+        if (e.readData.va) {
+          e.readData.va = e.readData.va.replace('-', '');
+        }
+      });
+    }
+
+    return res;
+  });
+};
+
+export const getHomeData = (params) => {
+  const key = `${Api.getHomeData}?${JSON.stringify(params)}`;
+  if (!cache.has(key)) {
+    cache.set(
+      key,
+      defHttp.post({ url: Api.getHomeData, params }).finally(() => {
+        cache.delete(key);
+      })
+    );
+  }
+  return (cache.get(key) as Promise<any>).then((res) => {
+    res.fanmain.forEach((e) => {
+      if (e.readData.Fan2StartStatus === '1') {
+        e.current = '二号';
+        e.readData.FanFreqHz = e.readData.Fan2FreqHz;
+      } else {
+        e.current = '一号';
+        e.readData.FanFreqHz = e.readData.Fan1FreqHz;
+      }
+    });
+    res.fanlocal.forEach((e) => {
+      e.chartData = [
+        {
+          x: '吸风量',
+          y: e.readData.windQuantity1,
+        },
+        {
+          x: '供风量',
+          y: e.readData.windQuantity2,
+        },
+      ];
+      if (e.readData.Fan2StartStatus === '1') {
+        e.current = '二号';
+        e.readData.FanfHz = e.readData.Fan2fHz;
+      } else {
+        e.current = '一号';
+        e.readData.FanfHz = e.readData.Fan1fHz;
+      }
+    });
+    res.sys_majorpath.forEach((e) => {
+      e.piechart = [
+        { val: e.majorpath.drag_1, label: '进风区' },
+        { val: e.majorpath.drag_2, label: '用风区' },
+        { val: e.majorpath.drag_3, label: '回风区' },
+      ];
+    });
+
+    return res;
+  });
+};
+
+export const getBDDustData = (params) => {
+  const key = `${Api.getBDDustData}?${JSON.stringify(params)}`;
+  if (!cache.has(key)) {
+    cache.set(
+      key,
+      defHttp.post({ url: Api.getBDDustData, params }).finally(() => {
+        cache.delete(key);
+      })
+    );
+  }
+  return cache.get(key) as Promise<any>;
+};
+
+export const getBDFireData = (params) => {
+  const key = `${Api.getBDFireData}?${JSON.stringify(params)}`;
+  if (!cache.has(key)) {
+    cache.set(
+      key,
+      defHttp.post({ url: Api.getBDFireData, params }).finally(() => {
+        cache.delete(key);
+      })
+    );
+  }
+  return (cache.get(key) as Promise<any>).then((res) => {
+    res.pdArray.forEach((e) => {
+      e.arrayFiber.forEach((j) => {
+        j.fibreTemperatureArr = JSON.parse(j.fibreTemperature);
+      });
+    });
+    res.sgGxObj.devGxcw.forEach((e) => {
+      e.fibreTemperatureArr = JSON.parse(e.fibreTemperature);
+    });
+    res.sgGxObj.devSgjc.forEach((e) => {
+      e.o2val = e.o2Val || 0;
+      e.coval = e.coVal || 0;
+      e.gasval = e.gasVal || 0;
+      e.ch2val = e.ch2Val || 0;
+      e.chval = e.chVal || 0;
+    });
+    return res;
+  });
+};
+
+export const getDisHome = (params) => {
+  const key = `${Api.getDisHome}?${JSON.stringify(params)}`;
+  if (!cache.has(key)) {
+    cache.set(
+      key,
+      defHttp.post({ url: Api.getDisHome, params }).finally(() => {
+        cache.delete(key);
+      })
+    );
+  }
+  return (cache.get(key) as Promise<any>).then((res) => {
+    if (res.pdArray) {
+      res.pdArray.forEach((e) => {
+        e.arrayFiber.forEach((j) => {
+          j.fibreTemperatureArr = JSON.parse(j.fibreTemperature);
+        });
+      });
+    }
+    if (res.sgGxObj) {
+      res.sgGxObj.devGxcw.forEach((e) => {
+        e.fibreTemperatureArr = JSON.parse(e.fibreTemperature);
+      });
+      res.sgGxObj.devSgjc.forEach((e) => {
+        e.o2val = e.o2Val || 0;
+        e.coval = e.coVal || 0;
+        e.gasval = e.gasVal || 0;
+        e.ch2val = e.ch2Val || 0;
+        e.chval = e.chVal || 0;
+      });
+    }
+    if (res.obfObj) {
+      res.obfObj.obfObjModded = [
+        {
+          objType: '氧气',
+          arrayDev: res.obfObj.arrayDev.map((e) => {
+            return {
+              strinstallpos: e.strinstallpos,
+              val: e.o2Val || 0,
+            };
+          }),
+        },
+        {
+          objType: '甲烷',
+          arrayDev: res.obfObj.arrayDev.map((e) => {
+            return {
+              strinstallpos: e.strinstallpos,
+              val: e.ch4Val || 0,
+            };
+          }),
+        },
+        {
+          objType: '一氧化碳',
+          arrayDev: res.obfObj.arrayDev.map((e) => {
+            return {
+              strinstallpos: e.strinstallpos,
+              val: e.coVal || 0,
+            };
+          }),
+        },
+        {
+          objType: '乙炔',
+          arrayDev: res.obfObj.arrayDev.map((e) => {
+            return {
+              strinstallpos: e.strinstallpos,
+              val: e.c2h2Val || 0,
+            };
+          }),
+        },
+        {
+          objType: '二氧化碳',
+          arrayDev: res.obfObj.arrayDev.map((e) => {
+            return {
+              strinstallpos: e.strinstallpos,
+              val: e.co2Val || 0,
+            };
+          }),
+        },
+
+        {
+          objType: '乙烯',
+          arrayDev: res.obfObj.arrayDev.map((e) => {
+            return {
+              strinstallpos: e.strinstallpos,
+              val: e.c2h4Val || 0,
+            };
+          }),
+        },
+        {
+          objType: '压差',
+          arrayDev: res.obfObj.arrayDev.map((e) => {
+            return {
+              strinstallpos: e.strinstallpos,
+              val: e.dpVal || 0,
+            };
+          }),
+        },
+        {
+          objType: '温度',
+          arrayDev: res.obfObj.arrayDev.map((e) => {
+            return {
+              strinstallpos: e.strinstallpos,
+              val: e.tempVal || 0,
+            };
+          }),
+        },
+      ];
+    }
+    return res;
+  });
+};

+ 2 - 2
src/views/vent/monitorManager/compressor/nitrogen.data.ts

@@ -213,8 +213,8 @@ export const zhudanOption = reactive({
 });
 
 export function getMonitorComponent() {
-  const { sysOrgCode } = useGlobSetting();
-  // const sysOrgCode = 'sdmtjtbltmk';
+  // const { sysOrgCode } = useGlobSetting();
+  const sysOrgCode = 'sdmtjtbdmk';
   let nitrogenHome;
   switch (sysOrgCode) {
     case 'sdmtjtdltmk': //dltj sdmtjtdltmk

+ 61 - 7
src/views/vent/monitorManager/gateMonitor/gate.threejs.ts

@@ -8,6 +8,7 @@ import FmTwoSs from './gate.threejs.two.ss';
 import FmThreeTl from './gate.threejs.three.tl';
 import FmDc from './gate.threejs.window';
 import FmDcHJG from './gate.threejs.window.hjg';
+import FmDcZHQ from './gate.threejs.window.zhq';
 import { animateCamera } from '/@/utils/threejs/util';
 import useEvent from '../../../../utils/threejs/useEvent';
 import { getDictItemsByCode } from '/@/utils/dict';
@@ -22,6 +23,7 @@ let model,
   fmTwoSs, //
   fmThreeTl, // 三道推拉
   fmWindowHjg, // 带风窗
+  fmWindowZhq, // 带风窗 沼和泉
   fmWindow, // 带风窗
   group: THREE.Object3D,
   fmType = '',
@@ -63,6 +65,8 @@ const startAnimation = () => {
       fmWindow.mouseUpModel.call(fmWindow);
     } else if (fmType === 'fmWindowHjg') {
       fmWindowHjg.mouseUpModel();
+    } else if (fmType === 'fmWindowZhq') {
+      fmWindowZhq.mouseUpModel();
     }
   });
 };
@@ -87,6 +91,8 @@ const mouseEvent = (event) => {
         fmWindow.mousedownModel.call(fmWindow, intersects);
       } else if (fmType === 'fmWindowHjg' && fmWindowHjg) {
         fmWindowHjg.mousedownModel(intersects);
+      } else if (fmType === 'fmWindowZhq' && fmWindowZhq) {
+        fmWindowZhq.mousedownModel(intersects);
       }
     });
     console.log('摄像头控制信息', model.orbitControls, model.camera);
@@ -110,6 +116,8 @@ export const addMonitorText = (selectData) => {
     fmWindow.addMonitorText.call(fmWindow, selectData);
   } else if (fmType === 'fmWindowHjg' && fmWindowHjg) {
     fmWindowHjg.addMonitorText(selectData);
+  } else if (fmType === 'fmWindowZhq' && fmWindowZhq) {
+    fmWindowZhq.addMonitorText(selectData);
   }
 };
 
@@ -134,6 +142,8 @@ export const play = (handlerState, flag?) => {
     return fmWindow.play.call(fmWindow, handlerState, flag);
   } else if (fmType === 'fmWindowHjg' && fmWindowHjg) {
     return fmWindowHjg.play.call(fmWindowHjg, handlerState, flag);
+  } else if (fmType === 'fmWindowZhq' && fmWindowZhq) {
+    return fmWindowZhq.play.call(fmWindowZhq, handlerState, flag);
   } else if (fmType === 'fm3' && fm3) {
     return fm3.play.call(fm3, handlerState, flag);
   } else if (fmType === 'fmXr' && fmXr) {
@@ -161,7 +171,10 @@ export function computePlay(data, maxarea, isFirst = false) {
   // data['frontArea'] = 70;
   // data['rearArea'] = 40;
 
-  if (fmType === 'fmWindowHjg' && (data.rearPresentValue1 || data.frontPresentValue1 || data.rearPresentValue2 || data.frontPresentValue2)) {
+  if (
+    (fmType === 'fmWindowHjg' || fmType === 'fmWindowZhq') &&
+    (data.rearPresentValue1 || data.frontPresentValue1 || data.rearPresentValue2 || data.frontPresentValue2)
+  ) {
     maxarea = 90;
     rotationParam.frontLeftDeg0 = (90 / maxarea) * Number(isFirst ? 0 : data.frontPresentValue1);
     rotationParam.frontRightDeg0 = (90 / maxarea) * Number(isFirst ? 0 : data.rearPresentValue1);
@@ -172,12 +185,18 @@ export function computePlay(data, maxarea, isFirst = false) {
     rotationParam.backLeftDeg1 = (90 / maxarea) * Number(data.frontPresentValue2) || 0;
     rotationParam.backRightDeg1 = (90 / maxarea) * Number(data.rearPresentValue2) || 0;
 
-    // rotationParam.backLeftDeg1 = 90;
-
-    fmWindowHjg.playWindow(rotationParam, 1);
-    fmWindowHjg.playWindow(rotationParam, 2);
-    fmWindowHjg.playWindow(rotationParam, 3);
-    fmWindowHjg.playWindow(rotationParam, 4);
+    rotationParam.backLeftDeg1 = 90;
+    if (fmType === 'fmWindowHjg') {
+      fmWindowHjg.playWindow(rotationParam, 1);
+      fmWindowHjg.playWindow(rotationParam, 2);
+      fmWindowHjg.playWindow(rotationParam, 3);
+      fmWindowHjg.playWindow(rotationParam, 4);
+    } else {
+      fmWindowZhq.playWindow(rotationParam, 1);
+      fmWindowZhq.playWindow(rotationParam, 2);
+      fmWindowZhq.playWindow(rotationParam, 3);
+      fmWindowZhq.playWindow(rotationParam, 4);
+    }
   } else if (fmType === 'fmWindow' && data.frontPresentValue1 && data.frontPresentValue2 && data.rearPresentValue1 && data.rearPresentValue2) {
     maxarea = 90;
     rotationParam.frontLeftDeg0 = (90 / maxarea) * Number(isFirst ? 0 : data.frontPresentValue1);
@@ -323,6 +342,35 @@ export const setModelType = (type) => {
           0.6
         );
       }, 300);
+    } else if (fmType === 'fmWindowZhq' && fmWindowZhq && fmWindowZhq.group) {
+      if (fmWindowZhq.clipActionArr.frontDoor && fmWindowZhq.clipActionArr.backDoor) {
+        fmWindowZhq.clipActionArr.frontDoor.reset();
+        fmWindowZhq.clipActionArr.frontDoor.time = 0.5;
+        fmWindowZhq.clipActionArr.backDoor.reset();
+        fmWindowZhq.clipActionArr.backDoor.time = 0.5;
+
+        fmWindowZhq.clipActionArr.frontDoor.stop();
+        fmWindowZhq.clipActionArr.backDoor.stop();
+      }
+
+      model.startAnimation = fmWindowZhq.render.bind(fmWindowZhq);
+      model.scene.remove(group);
+      group = fmWindowZhq.group;
+      const oldCameraPosition = { x: -761, y: 569, z: 871 };
+      setTimeout(async () => {
+        resolve(null);
+        model.scene.add(fmWindowZhq.group);
+        const position = { x: -2.28, y: -0.91, z: -5.68 };
+
+        await animateCamera(
+          oldCameraPosition,
+          { x: -2.27, y: -0.91, z: -5.67 },
+          { x: 66.257, y: 57.539, z: 94.313 },
+          { x: position.x, y: position.y, z: position.z },
+          model,
+          0.6
+        );
+      }, 300);
     } else if (fmType === 'fmThreeTl' && fmThreeTl && fmThreeTl.group) {
       if (fmThreeTl.clipActionArr.frontDoor && fmThreeTl.clipActionArr.backDoor && fmThreeTl.clipActionArr.centerDoor) {
         fmThreeTl.clipActionArr.frontDoor.reset();
@@ -555,6 +603,10 @@ export const mountedThree = (playerDom) => {
                 fmWindow = new FmDc(model);
                 await fmWindow.mountedThree();
                 break;
+              case 'fm_fc_zhq': //fmWindowZhq
+                fmWindowZhq = new FmDcZHQ(model);
+                await fmWindowZhq.mountedThree();
+                break;
             }
           }
           resolve(null);
@@ -592,6 +644,7 @@ export const destroy = () => {
     if (fmXr) fmXr.destroy();
     if (fmTwoSs) fmTwoSs.destroy();
     if (fmWindowHjg) fmWindowHjg.destroy();
+    if (fmWindowZhq) fmWindowZhq.destroy();
     if (fmWindow) fmWindow.destroy();
     if (fmThreeTl) fmThreeTl.destroy();
     fm1 = null;
@@ -600,6 +653,7 @@ export const destroy = () => {
     fmXr = null;
     fmWindow = null;
     fmWindowHjg = null;
+    fmWindowZhq = null;
     fmThreeTl = null;
     fmTwoSs = null;
     group = null;

+ 547 - 0
src/views/vent/monitorManager/gateMonitor/gate.threejs.window.zhq.ts

@@ -0,0 +1,547 @@
+import * as THREE from 'three';
+import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js';
+import { getTextCanvas, renderVideo } from '/@/utils/threejs/util';
+import gsap from 'gsap';
+import { drawHot } from '/@/utils/threejs/util';
+import { useAppStore } from '/@/store/modules/app';
+
+// import * as dat from 'dat.gui';
+// const gui = new dat.GUI();
+// gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
+
+class FmDcZHQ {
+  modelName = 'fmDc';
+  model; //
+  group;
+  isLRAnimation = true; // 是否开启左右摇摆动画
+  direction = 1; // 摇摆方向
+  animationTimer: NodeJS.Timeout | null = null; // 摇摆开启定时器
+  player1;
+  player2;
+  deviceDetailCSS3D;
+  playerStartClickTime1 = new Date().getTime();
+  playerStartClickTime2 = new Date().getTime();
+
+  fmClock = new THREE.Clock();
+  mixers: THREE.AnimationMixer | undefined;
+  appStore = useAppStore();
+
+  // backLeftDamperOpenMesh;
+  // backLeftDamperClosedMesh;
+  // frontLeftDamperOpenMesh;
+  // frontLeftDamperClosedMesh;
+  // backRightDamperOpenMesh;
+  // backRightDamperClosedMesh;
+  // frontRightDamperOpenMesh;
+  // frontRightDamperClosedMesh;
+
+  clipActionArr = {
+    frontDoor: null as unknown as THREE.AnimationAction,
+    backDoor: null as unknown as THREE.AnimationAction,
+  };
+  windowsActionArr = {
+    frontLeftWindow: <THREE.Mesh[]>[],
+    backLeftWindow: <THREE.Mesh[]>[],
+    frontRightWindow: <THREE.Mesh[]>[],
+    backRightWindow: <THREE.Mesh[]>[],
+  };
+
+  constructor(model) {
+    this.model = model;
+  }
+
+  addLight() {}
+  // 重置摄像头
+  resetCamera() {
+    this.model.camera.far = 274;
+    this.model.orbitControls?.update();
+    this.model.camera.updateProjectionMatrix();
+  }
+  // 设置模型位置
+  setModalPosition() {
+    this.group?.scale.set(22, 22, 22);
+    this.group?.position.set(-20, 20, 9);
+  }
+
+  /* 添加监控数据 */
+  addMonitorText(selectData) {
+    if (!this.group) {
+      return;
+    }
+    const screenDownText = VENT_PARAM['modalText']
+      ? VENT_PARAM['modalText']
+      : History_Type['type'] == 'remote'
+      ? `国能神东煤炭集团监制`
+      : '煤炭科学技术研究院有限公司研制';
+
+    const screenDownTextX = 80 - (screenDownText.length - 10) * 6;
+
+    const textArr = [
+      {
+        text: `远程控制自动风门`,
+        font: 'normal 30px Arial',
+        color: '#00FF00',
+        strokeStyle: '#007400',
+        x: 120,
+        y: 100,
+      },
+      {
+        text: `净通行高度(m):`,
+        font: 'normal 30px Arial',
+        color: '#00FF00',
+        strokeStyle: '#007400',
+        x: 0,
+        y: 155,
+      },
+      {
+        text: `${selectData.fclearheight ? selectData.fclearheight : '-'}`,
+        font: 'normal 30px Arial',
+        color: '#00FF00',
+        strokeStyle: '#007400',
+        x: 290,
+        y: 155,
+      },
+      {
+        text: `净通行宽度(m): `,
+        font: 'normal 30px Arial',
+        color: '#00FF00',
+        strokeStyle: '#007400',
+        x: 0,
+        y: 215,
+      },
+      {
+        text: ` ${selectData.fclearwidth ? selectData.fclearwidth : '-'}`,
+        font: 'normal 30px Arial',
+        color: '#00FF00',
+        strokeStyle: '#007400',
+        x: 280,
+        y: 215,
+      },
+      {
+        text: `故障诊断:`,
+        font: 'normal 30px Arial',
+        color: '#00FF00',
+        strokeStyle: '#007400',
+        x: 0,
+        y: 275,
+      },
+      {
+        text: `${selectData.warnLevel_str ? selectData.warnLevel_str : '-'}`,
+        font: 'normal 30px Arial',
+        color: '#00FF00',
+        strokeStyle: '#007400',
+        x: 280,
+        y: 275,
+      },
+      {
+        text: screenDownText,
+        font: 'normal 28px Arial',
+        color: '#00FF00',
+        strokeStyle: '#007400',
+        x: screenDownTextX,
+        y: 325,
+      },
+    ];
+    //
+    getTextCanvas(526, 346, textArr, '').then((canvas: HTMLCanvasElement) => {
+      const textMap = new THREE.CanvasTexture(canvas); // 关键一步
+      textMap.colorSpace = THREE.SRGBColorSpace;
+      const textMaterial = new THREE.MeshBasicMaterial({
+        // 关于材质并未讲解 实操即可熟悉                 这里是漫反射类似纸张的材质,对应的就有高光类似金属的材质.
+        map: textMap, // 设置纹理贴图
+        transparent: true,
+        side: THREE.FrontSide, // 这里是双面渲染的意思
+      });
+      textMaterial.blending = THREE.CustomBlending;
+      const monitorPlane = this.group.getObjectByName('monitorText');
+      if (monitorPlane) {
+        monitorPlane.material = textMaterial;
+      } else {
+        const planeGeometry = new THREE.PlaneGeometry(526, 346); // 平面3维几何体PlaneGeometry
+        const planeMesh = new THREE.Mesh(planeGeometry, textMaterial);
+        planeMesh.name = 'monitorText';
+        planeMesh.scale.set(0.002, 0.002, 0.002);
+        planeMesh.position.set(4.025, 0.67, -0.27);
+        this.group.add(planeMesh);
+      }
+      textMap.dispose();
+    });
+  }
+
+  /** 添加热点 */
+  drawHots() {
+    const hotPositions = [
+      { x: -0.37, y: 0.26, z: -0.32 },
+      { x: 0.28, y: -0.2, z: -0.43 },
+      { x: 0.55, y: -0.22, z: -0.38 },
+    ];
+    for (let i = 0; i < 3; i++) {
+      const hotPoint = drawHot(0.1);
+      const position = hotPositions[i];
+      hotPoint.scale.set(0.1, 0.1, 0.1);
+      hotPoint.position.set(position.x, position.y, position.z);
+      hotPoint.name = 'hotPoint' + i;
+      this.group?.add(hotPoint);
+    }
+  }
+
+  /* 风门动画 */
+  render() {
+    if (!this.model) {
+      return;
+    }
+
+    if (this.mixers && this.fmClock.running) {
+      this.mixers.update(2);
+    }
+  }
+
+  /* 点击风窗,风窗全屏 */
+  mousedownModel(intersects: THREE.Intersection<THREE.Object3D<THREE.Event>>[]) {
+    if (this.animationTimer) {
+      clearTimeout(this.animationTimer);
+      this.animationTimer = null;
+    }
+  }
+
+  mouseUpModel() {}
+
+  /* 提取风门序列帧,初始化前后门动画 */
+  initAnimation() {
+    const fmGroup = this.group?.getObjectByName('fm-window-zhq');
+    if (fmGroup) {
+      const tracks = fmGroup.animations[0].tracks;
+      const fontTracks: any[] = [],
+        backTracks: any[] = [];
+      for (let i = 0; i < tracks.length; i++) {
+        const track = tracks[i];
+        if (track.name.includes('_3') || track.name.includes('_4')) {
+          fontTracks.push(track);
+        } else {
+          backTracks.push(track);
+        }
+      }
+      const parentGroup = fmGroup.getObjectByName('MenChuangYiTi');
+      // const frontGroup = parentGroup.getObjectByName('FengMen2');
+      // const backGroup = parentGroup.getObjectByName('FengMen1');
+      this.mixers = new THREE.AnimationMixer(parentGroup);
+
+      const frontDoor = new THREE.AnimationClip('frontDoor', 2.5, fontTracks);
+      const frontClipAction = this.mixers.clipAction(frontDoor, parentGroup);
+      frontClipAction.clampWhenFinished = true;
+      frontClipAction.loop = THREE.LoopOnce;
+      this.clipActionArr.frontDoor = frontClipAction;
+
+      const backDoor = new THREE.AnimationClip('backDoor', 2.5, backTracks);
+      const backClipAction = this.mixers.clipAction(backDoor, parentGroup);
+      backClipAction.clampWhenFinished = true;
+      backClipAction.loop = THREE.LoopOnce;
+      this.clipActionArr.backDoor = backClipAction;
+    }
+    // 编写风窗
+  }
+  /* 提取风门序列帧,初始化前后门动画 */
+  initWindowAnimation() {
+    const meshArr01: THREE.Object3D[] = []; //front left
+    const meshArr02: THREE.Object3D[] = []; //front right
+    const meshArr03: THREE.Object3D[] = []; //back left
+    const meshArr04: THREE.Object3D[] = []; //back right
+    const windowGroup = new THREE.Group();
+    windowGroup.name = 'hiddenGroup';
+    const fmGroup = this.group?.getObjectByName('fm-window-zhq');
+    const parentGroup = fmGroup.getObjectByName('MenChuangYiTi');
+    const frontGroup = parentGroup.getObjectByName('Men_hou');
+    const backGroup = parentGroup.getObjectByName('Men_qian');
+    const frontLeftObj = frontGroup.getObjectByName('men_3');
+    const frontRightObj = frontGroup.getObjectByName('men_4');
+    const backLeftObj = backGroup.getObjectByName('men_1');
+    const backRightObj = backGroup.getObjectByName('men_2');
+    frontLeftObj.traverse((obj) => {
+      if (obj.type === 'Mesh' && obj.name && obj.name.startsWith('men')) {
+        obj.rotateOnAxis(new THREE.Vector3(0, 1, 0), 0);
+        meshArr01.push(obj);
+      }
+    });
+    frontRightObj.traverse((obj) => {
+      if (obj.type === 'Mesh' && obj.name && obj.name.startsWith('men')) {
+        obj.rotateOnAxis(new THREE.Vector3(0, 1, 0), 0);
+        meshArr02.push(obj);
+      }
+    });
+    backLeftObj.traverse((obj) => {
+      if (obj.type === 'Mesh' && obj.name && obj.name.startsWith('men')) {
+        obj.rotateOnAxis(new THREE.Vector3(0, 1, 0), 0);
+        meshArr03.push(obj);
+      }
+    });
+    backRightObj.traverse((obj) => {
+      if (obj.type === 'Mesh' && obj.name && obj.name.startsWith('men')) {
+        obj.rotateOnAxis(new THREE.Vector3(0, 1, 0), 0);
+        meshArr04.push(obj);
+      }
+    });
+
+    this.windowsActionArr.frontLeftWindow = meshArr01;
+    this.windowsActionArr.frontRightWindow = meshArr02;
+    this.windowsActionArr.backLeftWindow = meshArr03;
+    this.windowsActionArr.backRightWindow = meshArr04;
+    this.group?.add(windowGroup);
+  }
+
+  deviceDetailCard(position = { x: 0, y: 0, z: 0 }) {
+    const element = document.getElementById('deviceCard') as HTMLElement;
+    if (element) {
+      this.deviceDetailCSS3D = new CSS2DObject(element);
+      this.deviceDetailCSS3D.name = 'deviceCard';
+      this.deviceDetailCSS3D.position.set(position.x, position.y, position.z);
+      this.deviceDetailCSS3D.visible = false;
+      // this.model.scene.add(this.deviceDetailCSS3D);
+      this.group.add(this.deviceDetailCSS3D);
+    }
+  }
+
+  // 播放动画
+  play(handlerState, timeScale = 0.01) {
+    let handler = () => {};
+    if (this.clipActionArr.frontDoor && this.clipActionArr.backDoor) {
+      switch (handlerState) {
+        case 1: // 打开前门
+          handler = () => {
+            this.clipActionArr.frontDoor.paused = true;
+            this.clipActionArr.frontDoor.reset();
+            this.clipActionArr.frontDoor.time = 0;
+            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 = 2.5;
+            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 = 0;
+            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 = 2.5;
+            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;
+        default:
+      }
+      handler();
+    }
+  }
+
+  playWindow(rotationParam, flag) {
+    if (
+      !this.windowsActionArr.frontLeftWindow ||
+      !this.windowsActionArr.frontRightWindow ||
+      !this.windowsActionArr.backLeftWindow ||
+      !this.windowsActionArr.backRightWindow ||
+      this.windowsActionArr.frontLeftWindow.length <= 0 ||
+      this.windowsActionArr.frontRightWindow.length <= 0 ||
+      this.windowsActionArr.backLeftWindow.length <= 0 ||
+      this.windowsActionArr.backRightWindow.length <= 0
+    ) {
+      return;
+    }
+    if (flag === 1) {
+      // 前门左风窗动画
+      this.windowsActionArr.frontLeftWindow.forEach((mesh) => {
+        gsap.to(mesh.rotation, {
+          y: THREE.MathUtils.degToRad(rotationParam.frontLeftDeg1),
+          duration: (1 / 9) * Math.abs(rotationParam.frontLeftDeg1 - mesh.rotation.y),
+          overwrite: true,
+        });
+      });
+    } else if (flag === 2) {
+      // 后门左风窗动画
+      this.windowsActionArr.backLeftWindow.forEach((mesh) => {
+        gsap.to(mesh.rotation, {
+          y: THREE.MathUtils.degToRad(rotationParam.backLeftDeg1),
+          duration: (1 / 9) * Math.abs(rotationParam.backLeftDeg1 - mesh.rotation.y),
+          overwrite: true,
+        });
+      });
+    } else if (flag === 3) {
+      // 前门右风窗动画
+      this.windowsActionArr.frontRightWindow.forEach((mesh) => {
+        gsap.to(mesh.rotation, {
+          y: THREE.MathUtils.degToRad(rotationParam.frontRightDeg1),
+          duration: (1 / 9) * Math.abs(rotationParam.frontRightDeg1 - mesh.rotation.y),
+          overwrite: true,
+        });
+      });
+    } else if (flag === 4) {
+      // 后门右风窗动画
+      this.windowsActionArr.backRightWindow.forEach((mesh) => {
+        gsap.to(mesh.rotation, {
+          y: THREE.MathUtils.degToRad(rotationParam.backRightDeg1),
+          duration: (1 / 9) * Math.abs(rotationParam.backRightDeg1 - mesh.rotation.y),
+          overwrite: true,
+        });
+      });
+    } else if (flag === 0) {
+      (
+        [
+          ...this.windowsActionArr.frontLeftWindow,
+          ...this.windowsActionArr.frontRightWindow,
+          ...this.windowsActionArr.backLeftWindow,
+          ...this.windowsActionArr.backRightWindow,
+        ] as THREE.Mesh[]
+      ).forEach((mesh) => {
+        gsap.to(mesh.rotation, {
+          y: 0,
+          overwrite: true,
+        });
+      });
+    }
+  }
+
+  async initCamera(dom1) {
+    const videoPlayer1 = dom1;
+    this.player1 = dom1;
+    let monitorPlane: THREE.Mesh | null = null;
+    if (!videoPlayer1) {
+      const textArr = [
+        {
+          text: `无信号输入`,
+          font: 'normal 40px Arial',
+          color: '#009900',
+          strokeStyle: '#002200',
+          x: 170,
+          y: 40,
+        },
+      ];
+      const canvas = await getTextCanvas(320, 180, '', 'noSinge.png');
+
+      let textMaterial: THREE.MeshBasicMaterial | null = null;
+      if (canvas) {
+        const textMap = new THREE.CanvasTexture(canvas); // 关键一步
+        textMaterial = new THREE.MeshBasicMaterial({
+          map: textMap, // 设置纹理贴图
+          transparent: true,
+          side: THREE.DoubleSide, // 这里是双面渲染的意思
+        });
+        textMaterial.blending = THREE.CustomBlending;
+
+        const planeGeometry = new THREE.PlaneGeometry(100, 100); // 平面3维几何体PlaneGeometry
+        monitorPlane = new THREE.Mesh(planeGeometry, textMaterial);
+
+        textMaterial.dispose();
+        planeGeometry.dispose();
+        textMap.dispose();
+      }
+    }
+    const player1 = this.group.getObjectByName('player1');
+    if (player1) {
+      this.model.clearMesh(player1);
+      this.group.remove(player1);
+    }
+    const noPlayer1 = this.group.getObjectByName('noPlayer1');
+    if (noPlayer1) {
+      this.model.clearMesh(noPlayer1);
+      this.group.remove(noPlayer1);
+    }
+    if (!videoPlayer1 && videoPlayer1 === null) {
+      if (monitorPlane && !this.group.getObjectByName('noPlayer1')) {
+        const planeMesh = monitorPlane.clone();
+        planeMesh.name = 'noPlayer1';
+        planeMesh.scale.set(0.0085, 0.0055, 0.012);
+        planeMesh.position.set(-3.64, 0.01, -0.41);
+        this.group?.add(planeMesh.clone());
+      }
+    } else if (videoPlayer1) {
+      try {
+        const mesh = renderVideo(this.group, videoPlayer1, 'player1');
+        if (mesh) {
+          mesh?.scale.set(-0.0275, 0.028, 1);
+          mesh?.position.set(-3.643, 0.02, -0.4);
+          mesh.rotation.y = -Math.PI;
+          this.group.add(mesh);
+        }
+      } catch (error) {
+        console.log('视频信号异常');
+      }
+    }
+  }
+
+  mountedThree(playerDom) {
+    this.group = new THREE.Object3D();
+    this.group.name = this.modelName;
+    return new Promise((resolve) => {
+      this.model.setGLTFModel(['fm-window-zhq'], this.group).then(() => {
+        console.log('带风窗风门模型----->', this.group);
+        this.setModalPosition();
+        // 初始化左右摇摆动画;
+        this.initAnimation();
+        this.initWindowAnimation();
+        // this.drawHots();
+        this.addLight();
+        // this.deviceDetailCard();
+        this.model.animate();
+
+        resolve(this.model);
+      });
+    });
+  }
+
+  destroy() {
+    if (this.model) {
+      if (this.mixers) {
+        this.mixers.uncacheClip(this.clipActionArr.frontDoor.getClip());
+        this.mixers.uncacheClip(this.clipActionArr.backDoor.getClip());
+        this.mixers.uncacheAction(this.clipActionArr.frontDoor.getClip(), this.group);
+        this.mixers.uncacheAction(this.clipActionArr.backDoor.getClip(), this.group);
+        this.mixers.uncacheRoot(this.group);
+
+        if (this.model.animations[0]) this.model.animations[0].tracks = [];
+      }
+      this.model.clearGroup(this.group);
+      this.clipActionArr.backDoor = undefined;
+      this.clipActionArr.frontDoor = undefined;
+
+      this.windowsActionArr.frontWindow = undefined;
+      this.windowsActionArr.backWindow = undefined;
+
+      this.mixers = undefined;
+    }
+  }
+}
+export default FmDcZHQ;

+ 3 - 0
src/views/vent/monitorManager/gateMonitor/index.vue

@@ -511,6 +511,9 @@
         case 'fm_fc_hjg':
           type = 'fmWindowHjg';
           break;
+        case 'fm_fc_zhq':
+          type = 'fmWindowZhq';
+          break;
       }
     } else {
       type = selectData.nwindownum == 1 ? 'singleWindow' : 'doubleWindow';

+ 13 - 12
src/views/vent/monitorManager/mainFanMonitor/mainWind.lj.threejs.ts

@@ -63,7 +63,7 @@ class mainXjWindRect {
 
     if (!this.group.getObjectByName('monitorText1')) {
       const worldPosition = new THREE.Vector3();
-      ztfjGroup?.getObjectByName('pian20')?.getWorldPosition(worldPosition);
+      ztfjGroup?.getObjectByName('pian22')?.getWorldPosition(worldPosition);
       const element = document.getElementById('inputBox') as HTMLElement;
       if (element) {
         const mainCSS3D = new CSS3DObject(element);
@@ -76,7 +76,7 @@ class mainXjWindRect {
     }
     if (!this.group.getObjectByName('monitorText2')) {
       const worldPosition = new THREE.Vector3();
-      ztfjGroup?.getObjectByName('pian22')?.getWorldPosition(worldPosition);
+      ztfjGroup?.getObjectByName('pian20')?.getWorldPosition(worldPosition);
       const element = document.getElementById('inputBox1') as HTMLElement;
       if (element) {
         const mainCSS3D = new CSS3DObject(element);
@@ -386,9 +386,9 @@ class mainXjWindRect {
     }
     getPathPoint();
     if (deviceType === 'front') {
-      if (this.arrowMesh && this.arrowMesh.position.z !== 2.31) this.arrowMesh.position.set(-46.18, 28.13, 62.31);
-    } else {
       if (this.arrowMesh && this.arrowMesh.position.z !== -12.99) this.arrowMesh.position.set(-46.18, 28.13, 46.76);
+    } else {
+      if (this.arrowMesh && this.arrowMesh.position.z !== 2.31) this.arrowMesh.position.set(-46.18, 28.13, 62.31);
     }
   }
 
@@ -445,9 +445,9 @@ class mainXjWindRect {
     return new Promise((resolve) => {
       let diefa;
       if (deviceType == 'front') {
-        diefa = ztfjGroup?.getObjectByName('Cylinder1206') as THREE.Mesh;
-      } else {
         diefa = ztfjGroup?.getObjectByName('Cylinder1041') as THREE.Mesh;
+      } else {
+        diefa = ztfjGroup?.getObjectByName('Cylinder1206') as THREE.Mesh;
       }
       let rotationY;
       if (flag == 'open') {
@@ -499,8 +499,8 @@ class mainXjWindRect {
       const ztfjGroup = this.group?.getObjectByName('ztfj-lj');
       let mesh, motorGroup;
 
-      const mesh1 = ztfjGroup?.getObjectByName('pian22'); //前
-      const mesh2 = ztfjGroup?.getObjectByName('pian20'); //后
+      const mesh1 = ztfjGroup?.getObjectByName('pian20'); //前
+      const mesh2 = ztfjGroup?.getObjectByName('pian22'); //后
       if (deviceType == 'front') {
         mesh = mesh1;
         motorGroup = this.motorGroup2;
@@ -644,14 +644,15 @@ class mainXjWindRect {
       this.frontSmoke.points.name = 'frontSmoke';
       this.group?.add(this.frontSmoke.points);
       // this.frontSmoke.points.position.set(-2.51, 2.51, 8.25);
-      this.frontSmoke.points.position.set(-35.93, 24.59, 60.0);
+      this.frontSmoke.points.position.set(-35.93, 24.59, 43.53);
     }
     if (this.backSmoke) {
       await this.backSmoke.setPoints();
       this.backSmoke.points.name = 'backSmoke';
       this.group?.add(this.backSmoke.points);
       // this.backSmoke.points.position.set(-2.2, 3.13, -7.8);
-      this.backSmoke.points.position.set(-35.93, 24.59, 43.53);
+
+      this.backSmoke.points.position.set(-35.93, 24.59, 60.0);
     }
   }
 
@@ -661,8 +662,8 @@ class mainXjWindRect {
     // const motorGltf1 = await this.model.setGLTFModel('dj1');
     // this.motorGroup1 = motorGltf1[0] as THREE.Group;
     // this.motorGroup1?.position.set(10, 1, -6);
-    this.motorGroup1 = this.group?.getObjectByName('ztfj-lj')?.getObjectByName('dj1');
-    this.motorGroup2 = this.group?.getObjectByName('ztfj-lj')?.getObjectByName('dj2');
+    this.motorGroup1 = this.group?.getObjectByName('ztfj-lj')?.getObjectByName('dj2');
+    this.motorGroup2 = this.group?.getObjectByName('ztfj-lj')?.getObjectByName('dj1');
     if (this.motorGroup1 && this.motorGroup2) {
       this.gearBack.gear1 = this.motorGroup2.getObjectByName('polySurface113');
       this.gearBack.gear2 = this.motorGroup2.getObjectByName('polySurface127');