Преглед на файлове

[Fix 0000] 修复注氮机详情框位置及数量异常的问题

houzekong преди 4 дни
родител
ревизия
3c3dea1cf8

+ 2 - 2
src/utils/threejs/useThree.ts

@@ -579,7 +579,6 @@ class UseThree {
     this.renderer?.getRenderTarget()?.dispose();
 
     if (this.renderer && this.canvasContainer) this.canvasContainer.innerHTML = '';
-    if (this.CSSCanvasContainer && this.css3dRender) this.CSSCanvasContainer.innerHTML = '';
 
     // if (this.renderer) this.renderer.domElement = null;
     this.renderer?.clear();
@@ -588,7 +587,8 @@ class UseThree {
     if (this.css2dRender) this.css2dRender.domElement = null;
 
     if (this.canvasContainer) this.canvasContainer.innerHTML = '';
-    if (this.CSSCanvasContainer) this.CSSCanvasContainer.innerHTML = '';
+    // CSS 容器(如 #nitrogenCss3D)是 Vue 渲染的节点,里面的详情框等元素归 Vue 管理,这里不能清空它:
+    // 清空会把 Vue 的 DOM 物理删除,vdom 与 DOM 就此脱节(重进页面/切场景后详情框消失)
 
     this.camera = null;
     this.orbitControls = null;

+ 6 - 15
src/views/vent/monitorManager/compressor/components/nitrogenHome.vue

@@ -302,23 +302,14 @@
   }
 
   async function getDataSource(systemID) {
+    if (!systemID) return;
     const res = await list({ devicetype: 'sys', systemID, type: 'all' });
-    const result = res.msgTxt;
-    if (!result || result.length < 1) return;
-    result.forEach((item) => {
-      if (item.type === 'nitrogen_auto') {
-        let netStatus = 0;
-        monitorData.value = item['datalist'].filter((data) => {
-          if (data['netStatus'] == 1) {
-            netStatus = 1;
-          }
-          const item = data.readData;
-          return Object.assign(data, item);
-        });
-        monitorNetStatus.value = netStatus;
-      }
-    });
+    // 数据与机数一次提交:没绑注氮设备的场景一并归零,不残留上一个场景的机器;
+    // 设备类型统一按 nitrogen 前缀匹配(nitrogen_auto 等)
+    const nitrogenItem = (res?.msgTxt || []).find((item) => item?.type?.startsWith('nitrogen'));
+    monitorData.value = (nitrogenItem?.['datalist'] || []).map((data) => Object.assign(data, data.readData || {}));
     monitorDataGroupNum.value = monitorData.value.length;
+    monitorNetStatus.value = monitorData.value.some((data) => data['netStatus'] == 1) ? 1 : 0;
   }
 
   function handlerDevice(data) {

+ 36 - 45
src/views/vent/monitorManager/compressor/components/nitrogenHome_bet.vue

@@ -376,52 +376,43 @@
 
   async function getDataSource(systemID, flag = false) {
     const res = await getDevice({ devicetype: 'sys', systemID, type: 'all' });
-    if (res) {
-      const result = res;
-      if (!result || result.msgTxt.length < 1) return;
-      result.msgTxt.forEach((item) => {
-        if (item.type && item.type.startsWith('nitrogen')) {
-          airCompressorState.length = 0;
-          let netStatus = 0;
-          monitorData.value = item['datalist'].filter((data) => {
-            const readData = data.readData;
-            if (data['netStatus'] == 1) {
-              netStatus = 1;
-            }
-            airCompressorState.push({
-              id: data.deviceID,
-              deviceType: data.deviceType,
-              HMIReset: readData.HMIReset,
-              HMIStartStop: readData.HMIStartStop,
-            });
-            return Object.assign(data, readData);
-          });
-          monitorNetStatus.value = netStatus;
-          // console.log(monitorData,'monitorData.value---===')
-          const airCompressor = {
-            readTime: monitorData.value[0]['readTime'] ? monitorData.value[0]['readTime'].substring(11) : dayjs().format('HH:mm:ss'),
-          };
-          const dataArr = cloneDeep(echartData.value);
-          //图表数据
-          if (dataArr.length <= 5) {
-            monitorData.value.forEach((el, index) => {
-              airCompressor[`InputFlux${index + 1}`] = el['InputFlux'] || 0;
-              airCompressor['InputFlux'] = el['InputFlux'] || 0;
-            });
-            dataArr.push(airCompressor);
-          } else {
-            dataArr.shift();
-            dataArr.push(airCompressor);
-          }
-          echartData.value = dataArr;
-        }
-      });
-      monitorDataGroupNum.value = monitorData.value.length;
-      refresh.value = true;
-      nextTick(() => {
-        refresh.value = false;
+    if (!res) return;
+
+    // 数据、机数、网络状态、控制状态一次提交:
+    // 没绑注氮设备的场景一并归零(不残留上一个场景的机器),也不会出现「机数更新了、数据没更新」的脱节
+    const nitrogenItem = (res.msgTxt || []).find((item) => item?.type?.startsWith('nitrogen'));
+    monitorData.value = (nitrogenItem?.['datalist'] || []).map((data) => Object.assign(data, data.readData || {}));
+    monitorDataGroupNum.value = monitorData.value.length;
+    monitorNetStatus.value = monitorData.value.some((data) => data['netStatus'] == 1) ? 1 : 0;
+
+    airCompressorState.length = 0;
+    monitorData.value.forEach((data) => {
+      airCompressorState.push({ id: data.deviceID, deviceType: data.deviceType, HMIReset: data.HMIReset, HMIStartStop: data.HMIStartStop });
+    });
+
+    // 图表数据:没有机数时不追加点(避免空场景把曲线拉平)
+    if (monitorData.value.length) {
+      const airCompressor = {
+        readTime: monitorData.value[0]?.['readTime'] ? String(monitorData.value[0]['readTime']).substring(11) : dayjs().format('HH:mm:ss'),
+      };
+      monitorData.value.forEach((el, index) => {
+        airCompressor[`InputFlux${index + 1}`] = el['InputFlux'] || 0;
+        airCompressor['InputFlux'] = el['InputFlux'] || 0;
       });
+      const dataArr = cloneDeep(echartData.value);
+      if (dataArr.length <= 5) {
+        dataArr.push(airCompressor);
+      } else {
+        dataArr.shift();
+        dataArr.push(airCompressor);
+      }
+      echartData.value = dataArr;
     }
+
+    refresh.value = true;
+    nextTick(() => {
+      refresh.value = false;
+    });
   }
 
   function handlerDevice(data, bol) {
@@ -511,7 +502,7 @@
     await mountedThree().then(() => {
       loading.value = false;
     });
-    await getCamera(deviceId, playerRef, renderPlayer);
+    await getCamera(props.deviceId, playerRef, renderPlayer);
   });
 
   onUnmounted(() => {

+ 20 - 12
src/views/vent/monitorManager/compressor/nitrogen.flex.threejs.ts

@@ -50,6 +50,8 @@ class NitrogenFlex {
   private cameraDir = { x: 0.18, y: 0.85, z: 1.35 };
   /** 机顶气泡再往上的高度 */
   private spriteTopOffset = 0.34;
+  /** 下风侧监测框精灵(DOM 节点被重建时会重新挂载) */
+  private downWindSprite?: CSS3DSprite;
 
   constructor(model) {
     this.model = model;
@@ -224,11 +226,9 @@ class NitrogenFlex {
     this.addCssText();
   }
 
-  /** 挂载数据气泡:三台机的监测框 + 下风侧监测框 */
+  /** 挂载数据气泡:各注氮机的详情框 + 下风侧监测框 */
   addCssText = () => {
     this.unitGroups.forEach((unit, i) => {
-      if (!unit) return;
-      if (unit.getObjectByName('monitorNitrogenText')) return;
       const element = document.getElementById('nitrogenMonitor' + (i + 1)) as HTMLElement;
       if (!element) return;
 
@@ -254,10 +254,20 @@ class NitrogenFlex {
    * 这里按基底包围盒归一化锚点定位,默认放在管路的下风侧一端。
    */
   private attachDownWindMonitor() {
-    if (this.group.getObjectByName('downWindMonitor')) return;
+    // 没有注氮机时不存在下风侧监测
+    if (this.nitrogenNum <= 0) return;
     const element = document.getElementById('downWindMonitor') as HTMLElement;
     if (!element) return;
 
+    // 同一个 DOM 节点才复用:机数为 0 时模板 v-if 会把这块节点整块重建,
+    // 复用旧精灵会挂在一个已经离开页面的节点上(新节点则裸露在左上角)
+    if (this.downWindSprite && this.downWindSprite.element === element) {
+      this.downWindSprite.visible = true;
+      this.cssSprites.push(this.downWindSprite);
+      return;
+    }
+    if (this.downWindSprite) this.downWindSprite.visible = false;
+
     const base = this.group.getObjectByName(this.baseName);
     if (!base) return;
     const box = new THREE.Box3().setFromObject(base);
@@ -274,20 +284,18 @@ class NitrogenFlex {
     // 挂在 group 上而非某台机体,避免机体变换影响该框
     this.group.add(sprite);
     this.cssSprites.push(sprite);
+    this.downWindSprite = sprite;
   }
 
   clearCssText = () => {
+    // ── 只隐藏,不把 sprite 从场景图里移除 ──
+    // CSS3DObject 被移除时会把手里的 element 从 DOM 中删掉,之后再 addCssText 就永远找不到该元素
+    // (切换场景后详情框消失的根因)。气泡随旧机体一起被丢弃即可,DOM 节点始终留在页面上。
     this.cssSprites.forEach((s) => {
-      s.parent?.remove(s);
+      s.visible = false;
+      (s.element as HTMLElement).style.display = 'none';
     });
     this.cssSprites = [];
-    // 兜底清理可能残留的精灵节点
-    this.unitGroups.forEach((u) => {
-      const old = u.getObjectByName('monitorNitrogenText');
-      if (old) u.remove(old);
-    });
-    const dw = this.group.getObjectByName('downWindMonitor');
-    if (dw) this.group.remove(dw);
   };
 
   /** 与既有类保持一致的接口(本模型无需额外处理) */

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

@@ -96,7 +96,6 @@ export const setModelType = (type, nitrogenNum?) => {
       model?.scene?.add(nitrogenObj.group);
       let newCameraPosition = { x: 0, y: 0, z: 0 },
         newControlsPosition = { x: 0, y: 0, z: 0 };
-      debugger;
       if (group.children.length == 5) {
         newCameraPosition = { x: 3.4434042980363104, y: 34.06459454762187, z: 106.31900957493957 };
         newControlsPosition = { x: 3.060603700582905, y: -10.818677071155214, z: 6.036159227572685 };