Просмотр исходного кода

Merge branch 'master' of http://39.97.59.228:8013/hrx/mky-vent-base

bobo04052021@163.com 1 месяц назад
Родитель
Сommit
b17dfaa3ba

+ 1 - 1
build/script/buildTag.ts

@@ -24,7 +24,7 @@ function createTag(params: CreateTagParams) {
       // last commit's SHA
       commit: execSync('git rev-parse --short HEAD').toString().replace('\n', ''),
       buildtime: dayjs().format('YYYY-MM-DD_HH:mm:ss'),
-      version: execSync('npm pkg get version').toString().replace('\n', ''),
+      version: execSync('npm pkg get projectVersion').toString().replace('\n', ''),
     };
     // Ensure that the variable will not be modified
     const evalExp = `

+ 7 - 2
src/assets/images/home-container/configurable/preset/syswind-icon-spd.svg

@@ -1,9 +1,14 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="29.905" height="20.273" viewBox="0 0 29.905 20.273">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="26.422" height="16.021" viewBox="0 0 26.422 16.021">
   <defs>
     <linearGradient id="linear-gradient" x1="0.295" x2="0.946" y2="0.843" gradientUnits="objectBoundingBox">
       <stop offset="0" stop-color="#83e4ff"/>
       <stop offset="1" stop-color="#fff"/>
     </linearGradient>
   </defs>
-  <path id="路径_57944" data-name="路径 57944" d="M54.586,213.407l.059.123,6.987,15.652a1.311,1.311,0,0,1-2.349,1.161l-.046-.092-1.994-4.469H47.234l-2,4.469a1.311,1.311,0,0,1-2.433-.974l.038-.1,6.987-15.652a2.636,2.636,0,0,1,4.755-.123Zm14.373,13.031a1.311,1.311,0,0,1,.1,2.62l-.1,0H65.025a1.311,1.311,0,0,1-.1-2.62l.1,0ZM52.233,214.592l-.007.007L48.4,223.158h7.667L52.25,214.6a.013.013,0,0,0-.017-.007ZM70.27,219.88a1.311,1.311,0,0,1,.1,2.62l-.1,0H62.4a1.311,1.311,0,0,1-.1-2.62l.1,0Zm-5.246-6.557a1.311,1.311,0,0,1,.1,2.62l-.1,0H59.779a1.311,1.311,0,0,1-.1-2.62l.1,0Z" transform="translate(-42.184 -211.32)" stroke="rgba(0,0,0,0)" stroke-miterlimit="10" stroke-width="1" fill="url(#linear-gradient)"/>
+  <g id="组_16684" data-name="组 16684" transform="translate(-20.302 -27.786)">
+    <path id="路径_57945" data-name="路径 57945" d="M238.933,68.267h3.929l2.483,7.755c.582,1.765.962,3.359,1.569,5.149h.129c.582-1.79,1.011-3.384,1.6-5.149l2.427-7.755h3.8L249.121,84.2h-4.457Z" transform="translate(-218.631 -40.48)" fill="url(#linear-gradient)"/>
+    <path id="路径_57946" data-name="路径 57946" d="M.828,0H9.675V2.9H0Z" transform="translate(37.049 28.327)" fill="url(#linear-gradient)"/>
+    <path id="路径_57947" data-name="路径 57947" d="M.828,0H9.675V2.9H0Z" transform="translate(35.114 35.1)" fill="url(#linear-gradient)"/>
+    <path id="路径_57948" data-name="路径 57948" d="M.828,0H9.675V2.9H0Z" transform="translate(33.179 40.905)" fill="url(#linear-gradient)"/>
+  </g>
 </svg>

+ 2 - 4
src/assets/images/home-container/configurable/preset/syswind-icon-vol.svg

@@ -1,11 +1,9 @@
-<svg id="组_16687" data-name="组 16687" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20.467" height="23.701" viewBox="0 0 20.467 23.701">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="26.353" height="23.814" viewBox="0 0 26.353 23.814">
   <defs>
     <linearGradient id="linear-gradient" x1="0.295" x2="0.946" y2="0.843" gradientUnits="objectBoundingBox">
       <stop offset="0" stop-color="#3df6ff"/>
       <stop offset="1" stop-color="#fff"/>
     </linearGradient>
   </defs>
-  <path id="路径_57940" data-name="路径 57940" d="M248.889,544m1.436,0h.359a1.269,1.269,0,0,1,1.436,1.436v7.9a1.27,1.27,0,0,1-1.436,1.436h-.359a1.27,1.27,0,0,1-1.436-1.436v-7.9A1.269,1.269,0,0,1,250.325,544Z" transform="translate(-248.889 -531.073)" fill="url(#linear-gradient)"/>
-  <path id="路径_57941" data-name="路径 57941" d="M504.889,288m1.436,0h.359a1.27,1.27,0,0,1,1.436,1.436v16.518a1.27,1.27,0,0,1-1.436,1.436h-.359a1.27,1.27,0,0,1-1.436-1.436V289.436A1.27,1.27,0,0,1,506.325,288Z" transform="translate(-496.271 -283.691)" fill="url(#linear-gradient)"/>
-  <path id="路径_57942" data-name="路径 57942" d="M760.889,160m1.436,0h.359a1.27,1.27,0,0,1,1.436,1.436v20.827a1.27,1.27,0,0,1-1.436,1.436h-.359a1.27,1.27,0,0,1-1.436-1.436V161.436A1.27,1.27,0,0,1,762.325,160Z" transform="translate(-743.654 -160)" fill="url(#linear-gradient)"/>
+  <path id="路径_57950" data-name="路径 57950" d="M459.1,110.272a.638.638,0,0,1-.449-.186.632.632,0,0,1-.186-.449v-1.266a.638.638,0,0,1,.186-.449.632.632,0,0,1,.449-.186h17.112a1.266,1.266,0,0,0,0-2.533h-5.7a.638.638,0,0,1-.449-.186.632.632,0,0,1-.186-.449V103.3a.634.634,0,0,1,.635-.635h5.7a3.8,3.8,0,0,1,0,7.605Zm-3.8,5.069a.638.638,0,0,1-.449-.186.632.632,0,0,1-.186-.449V113.44a.634.634,0,0,1,.635-.635h15.211a.638.638,0,0,1,.449.186.632.632,0,0,1,.186.449v1.266a.638.638,0,0,1-.186.449.632.632,0,0,1-.449.186Zm6.335,5.073a.638.638,0,0,1-.449-.186.632.632,0,0,1-.186-.449v-1.266a.638.638,0,0,1,.186-.449.632.632,0,0,1,.449-.186h3.8a.638.638,0,0,1,.449.186.632.632,0,0,1,.186.449v1.266a.634.634,0,0,1-.635.635h-3.8Zm6.339-2.536h8.24a3.8,3.8,0,0,1,0,7.605h-5.7a.639.639,0,0,1-.449-.186.632.632,0,0,1-.186-.449v-1.266a.639.639,0,0,1,.186-.449.632.632,0,0,1,.449-.186h5.7a1.266,1.266,0,0,0,0-2.533h-8.24a.638.638,0,0,1-.449-.186.632.632,0,0,1-.186-.449v-1.266a.634.634,0,0,1,.635-.635Zm0,0" transform="translate(-454.167 -102.168)" stroke="rgba(0,0,0,0)" stroke-miterlimit="10" stroke-width="1" fill="url(#linear-gradient)"/>
 </svg>

BIN
src/assets/images/home-container/configurable/preset/syswind-space-red.png


+ 0 - 1
src/views/vent/home/configurable/belt/belt.vue

@@ -71,7 +71,6 @@ const filterDataById = (sourceData, clickId: string | number) => {
 
 function refresh() {
   fetchConfigs('belt').then(() => {
-    // 🔥 关键:只有为空时才赋值,不重复覆盖!
     if (!configs.value || configs.value.length === 0) {
       configs.value = testBeltLaneFire;
     }

+ 21 - 15
src/views/vent/home/configurable/belt/threejs/MonitorPanel.vue

@@ -2,62 +2,61 @@
 <template>
   <!-- 外层动画包裹层 -->
   <div class="panel-wrapper">
-    <div class="monitor-panel" ref="panelRef" :class="{ alarm: hasAlarm }">
-      <div class="panel-title">{{ sensorData.positionName || 'XXXXX位置' }}</div>
+    <div class="monitor-panel" ref="panelRef" :class="{ alarm: monitorData.alarmLevel > 102 }">
+      <div class="panel-title">{{ monitorData.positionName || 'XXXXX位置' }}</div>
       <div class="panel-grid">
         <div class="panel-item">
           <span class="item-label">▸ 微震测声</span>
           <span class="item-value" :class="getStatusClass('microseism')">
-            {{ sensorData.microseism ?? 'XXXX' }}
+            {{ monitorData.microseism ?? '-' }}
           </span>
         </div>
         <div class="panel-item">
           <span class="item-label">▸ 光纤测温</span>
           <span class="item-value" :class="getStatusClass('fiberTemp')">
-            {{ sensorData.fiberTemp ?? 'XXXX' }}
+            {{ monitorData.fiberTemp ?? '-' }}
           </span>
         </div>
         <div class="panel-item">
           <span class="item-label">▸ 温度</span>
           <span class="item-value" :class="getStatusClass('temperature')">
-            {{ sensorData.temperature ?? 'XXXX' }}
+            {{ monitorData.temperature ?? '-' }}
           </span>
         </div>
         <div class="panel-item">
           <span class="item-label">▸ 火焰</span>
           <span class="item-value" :class="getStatusClass('flame')">
-            {{ sensorData.flame ?? 'XXXX' }}
+            {{ monitorData.flame ?? '-' }}
           </span>
         </div>
-        <div class="panel-item item-full">
+        <!-- <div class="panel-item item-full">
           <span class="item-label ai-label">▸ AI视频火焰识别</span>
           <span class="item-value" :class="getStatusClass('aiFlame')">
-            {{ sensorData.aiFlame ?? 'XXXX' }}
+            {{ sensorData.aiFlame ?? '-' }}
           </span>
-        </div>
-
+        </div> -->
         <div class="panel-item">
           <span class="item-label">▸ HCl</span>
           <span class="item-value" :class="getStatusClass('hcl')">
-            {{ sensorData.hcl ?? 'XXXX' }}
+            {{ monitorData.hcl ?? '-' }}
           </span>
         </div>
         <div class="panel-item">
           <span class="item-label">▸ CO</span>
           <span class="item-value" :class="getStatusClass('co')">
-            {{ sensorData.co ?? 'XXXX' }}
+            {{ monitorData.co ?? '-' }}
           </span>
         </div>
         <div class="panel-item">
           <span class="item-label">▸ 烟雾</span>
           <span class="item-value" :class="getStatusClass('smoke')">
-            {{ sensorData.smoke ?? 'XXXX' }}
+            {{ monitorData.smoke ?? '-' }}
           </span>
         </div>
         <div class="panel-item">
           <span class="item-label">▸ 多参数</span>
           <span class="item-value" :class="getStatusClass('multiParam')">
-            {{ sensorData.multiParam ?? 'XXXX' }}
+            {{ monitorData.multiParam ?? '-' }}
           </span>
         </div>
       </div>
@@ -94,6 +93,7 @@
     flame?: number;
     multiParam?: number;
     aiFlame?: number;
+    alarmLevel: number;
   }
 
   const props = defineProps({
@@ -125,6 +125,7 @@
 
   const panelRef = ref<HTMLElement | null>(null);
   const cssObject = ref<CSS3DObject | null>(null);
+  const monitorData = ref<SensorData>(props.sensorData);
 
   // 默认阈值
   const defaultThreshold: Required<AlarmThreshold> = {
@@ -150,7 +151,7 @@
     const value = props.sensorData[key];
     if (value == null) return 'normal';
     const threshold = currentThreshold.value[key]!;
-    if (value > threshold) return 'alarm';
+    if (threshold > 102) return 'alarm';
     return 'normal';
   };
 
@@ -172,6 +173,10 @@
     }
   };
 
+  const updateMonitorData = (data: SensorData) => {
+    monitorData.value = data;
+  };
+
   onMounted(() => {
     if (!panelRef.value) return;
     cssObject.value = new CSS3DObject(panelRef.value);
@@ -204,6 +209,7 @@
     cssObject: cssObject,
     update,
     destroy,
+    updateMonitorData,
   });
 </script>
 

+ 96 - 28
src/views/vent/home/configurable/belt/threejs/belt.threejs.ts

@@ -5,6 +5,8 @@ import { ref, watch } from 'vue';
 import { modelMouseHandler } from '/@/utils/threejs/useEvent';
 import { panelManager } from './PanelManager';
 import { Ref } from 'vue';
+import { defHttp } from '/@/utils/http/axios';
+import { animateCamera } from '/@/utils/threejs/util';
 
 const gateList = ref([]);
 const panelApp = [];
@@ -13,8 +15,10 @@ const normalColor = new THREE.Color(0xff0000);
 const warningColor = new THREE.Color(0xfc5f2e);
 const color = new THREE.Color(0x00ff00);
 let clickSelecteObject;
+const modalData = ref(null);
+const warningPartitionIndex = ref('-1');
 
-export function modalAnimate(modal, modalMonitorData: Ref<any, any>) {
+export async function modalAnimate(modal, modalMonitorData: Ref<any, any>) {
   // const data = modalMonitorData.value;
   const warningPartition: THREE.Object3D[] = [];
 
@@ -29,12 +33,34 @@ export function modalAnimate(modal, modalMonitorData: Ref<any, any>) {
   const { inGates, outGates } = getGateModal(beltModal);
   // 绘制风流路径
   const { jinfenghangPath, huifenghangPath, jinfenglianhangPath, huifenglianhangPath, pidaihangPath } = getTunPath(beltModal);
-  const { partitionList, blinkAnimationList } = drawPartition(beltModal, 100, 5000);
+
+  // const api = '/ventanaly-device/monitor/disaster/findDeviceInfoBySystem';
+  // const res = await defHttp.post({ url: api, params: { sysId: '2028657172566073346' } });
+  // modalData.value = res?.device;
+  // const len = Object.keys(res?.device).length;
+  const { partitionList, blinkAnimationList } = drawPartition(beltModal, 100, 2000);
 
   watch(
     modalMonitorData,
-    (data) => {
+    async (data) => {
       gateList.value = data.deviceInfo['gate']?.datalist as [];
+
+      const api = '/ventanaly-device/monitor/disaster/findDeviceInfoBySystem';
+      const res = await defHttp.post({ url: api, params: { sysId: '2028657172566073346' } });
+      modalData.value = res?.device;
+      updateMonitorPanel3D();
+      const alarminfo = res?.alarminfo;
+      if (Object.keys(alarminfo).length > 0) {
+        for (const key in alarminfo) {
+          if (!Object.hasOwn(alarminfo, key)) continue;
+          if (alarminfo[key] > 102) {
+            if (modalData.value && modalData.value[key]) modalData.value[key]['alarmLevel'] = alarminfo[key];
+            warningPartitionIndex.value = key;
+            setPartitionAnimate();
+            break;
+          }
+        }
+      }
       // 根据监测数据进行风门模型动画控制(前提条件:模型上的风门与实际风门设备建立了映射关系)
       handleGateAnimate(gateList.value);
     },
@@ -44,11 +70,6 @@ export function modalAnimate(modal, modalMonitorData: Ref<any, any>) {
   // 添加鼠标拾取
   initMouseEvent(modal, beltModal, partitionList);
 
-  setTimeout(() => {
-    // 添加风门模型
-    setPartitionAnimate([12]);
-  }, 3000);
-
   // setTimeout(() => {
   //   // 添加风门模型
   //   setPartitionAnimate([]);
@@ -65,7 +86,6 @@ export function modalAnimate(modal, modalMonitorData: Ref<any, any>) {
 
       const houmen1 = houmenObj?.getObjectByName(`${fengmenName}FengMen2_1`) as THREE.Object3D;
       const houmen2 = houmenObj?.getObjectByName(`${fengmenName}FengMen2_4`) as THREE.Object3D;
-      debugger;
       const frontState = gateData['readData']['frontGateOpen'] == 1 ? true : gateData['readData']['frontGateClose'] == 1 ? false : null;
       const backState = gateData['readData']['rearGateOpen'] == 1 ? true : gateData['readData']['rearGateClose'] == 1 ? false : null;
       if (qianmen1 && qianmen2 && houmen1 && houmen2) {
@@ -197,14 +217,14 @@ export function modalAnimate(modal, modalMonitorData: Ref<any, any>) {
     handlePathAnimate(jinfenghangPath, huifenghangPath, jinfenglianhangPath, huifenglianhangPath, jinfenglianhangList, huifenglianhangList);
   }
 
-  function setPartitionAnimate(partitionIndexList: number[]) {
+  function setPartitionAnimate() {
+    if (Number(warningPartitionIndex.value) > -1) panelManager.destroyPanel(`partition${Number(warningPartitionIndex.value)}`);
     warningPartition.length = 0;
-
     partitionList.forEach((partition, index) => {
       const solidBox = partition.getObjectByName(partition.name + '_solid') as THREE.Mesh;
       const line = partition.getObjectByName(partition.name + '_line') as THREE.LineSegments;
       if (solidBox && line) {
-        if (partitionIndexList.includes(index + 1)) {
+        if (Number(warningPartitionIndex.value) == index + 1) {
           if (!solidBox.material.color.equals(warningColor)) solidBox.material.color.setHex(0xfc5f2e);
           if (solidBox.material.opacity !== 0.3) solidBox.material.opacity = 0.3;
           if (!line.material.color.equals(warningColor)) line.material.color.setHex(0xfc5f2e);
@@ -223,7 +243,7 @@ export function modalAnimate(modal, modalMonitorData: Ref<any, any>) {
     const warningOpacity = 0.9;
     const normalOpacity = 0.05;
     for (let i = 0; i < blinkAnimationList.length; i++) {
-      if (partitionIndexList.includes(i + 1)) {
+      if (Number(warningPartitionIndex.value) == i + 1) {
         // 开始动画
         if (!blinkAnimationList[i]) {
           const partition = partitionList[i];
@@ -245,7 +265,25 @@ export function modalAnimate(modal, modalMonitorData: Ref<any, any>) {
             },
           });
 
-          createMonitorPanel3D(modal, partition);
+          const pos = createMonitorPanel3D(modal, partition);
+
+          // 这里进行重新定位
+          console.log(pos);
+          gsap.fromTo(
+            modal.camera.position,
+            { x: modal.camera.position.x, y: modal.camera.position.y, z: modal.camera.position.z },
+            {
+              x: pos.x,
+              y: modal.camera.position.y,
+              z: pos.y,
+              duration: 1,
+              onUpdate: () => {
+                modal.orbitControls.target.set(modal.camera.position.x, pos.z, -modal.camera.position.z);
+                modal.orbitControls.update();
+                modal.renderer?.render(modal.scene, modal.camera);
+              },
+            }
+          );
         }
       } else {
         // 停止动画
@@ -297,18 +335,48 @@ function createMonitorPanel3D(modal, partition) {
   const box = new THREE.Box3();
   box.setFromObject(partition);
   const center = box.getCenter(new THREE.Vector3());
+  const partitionIndex = partition.name.split('_')[0];
+  const index = Number(partitionIndex.split('partition')[1]) + 1;
+  const data = modalData.value[index + ''];
+  if (data) {
+    panelManager.createPanel(modal.scene, {
+      instanceId: partition.name,
+      sensorData: {
+        positionName: `分区#${index}`,
+        temperature: data['温度传感器'] ? data['温度传感器'][0]?.value : null,
+        smoke: data['烟雾传感器'] ? data['烟雾传感器'][0]?.value : null,
+        co: data['CO传感器'] ? data['CO传感器'][0]?.value : null,
+        microseism: data['微震测声传感器'] ? data['微震测声传感器'][0]?.value : null,
+        fiberTemp: data['光纤测温'] ? data['光纤测温'][0]?.value : null,
+        flame: data['火焰传感器'] ? data['火焰传感器'][0]?.value : null,
+        hcl: data['HCl传感器'] ? data['HCl传感器'][0]?.value : null,
+        alarmLevel: data['alarmLevel'] ? data['alarmLevel'] : null,
+      },
+      threshold: {
+        temperature: data['温度传感器'] ? data['温度传感器'][0]?.alarmLevel : null,
+        smoke: data['烟雾传感器'] ? data['烟雾传感器'][0]?.alarmLevel : null,
+        co: data['CO传感器'] ? data['CO传感器'][0]?.alarmLevel : null,
+        microseism: data['微震测声传感器'] ? data['微震测声传感器'][0]?.alarmLevel : null,
+        fiberTemp: data['光纤测温'] ? data['光纤测温'][0]?.alarmLevel : null,
+        flame: data['火焰传感器'] ? data['火焰传感器'][0]?.alarmLevel : null,
+        hcl: data['HCl传感器'] ? data['HCl传感器'][0]?.alarmLevel : null,
+      },
+      position: [center.x, center.y, center.z],
+      scale: 0.0125,
+    });
+  }
+  return center;
+}
 
-  panelManager.createPanel(modal.scene, {
-    instanceId: partition.name,
-    sensorData: {
-      positionName: '分区#X',
-      temperature: 80,
-      smoke: 0,
-      co: 0,
-    },
-    threshold: { temperature: 70 },
-    position: [center.x, center.y, center.z],
-    scale: 0.0125,
+function updateMonitorPanel3D() {
+  panelManager.getAllPanelIds().forEach((id) => {
+    const instance = panelManager.getPanel(id);
+    if (instance?.vm?.update && modalData.value) {
+      const partitionIndex = id.split('_')[0];
+      const index = Number(partitionIndex.split('partition')[1]) + 1;
+      const data = modalData.value[index + ''];
+      instance.vm.updateMonitorData(data);
+    }
   });
 }
 
@@ -513,7 +581,7 @@ function getTunPath(beltModal) {
         pathPointList.set(posList, 0, 0, up, false);
         const geometry = new PathGeometry(posList.length, false);
         geometry.update(pathPointList, {
-          width: 60,
+          width: 40,
           arrow: false,
         });
         const mesh = new THREE.Mesh(geometry, tubeMaterial.clone());
@@ -522,10 +590,10 @@ function getTunPath(beltModal) {
         beltModal.add(mesh);
         if (objName == 'pidaihang') {
           (mesh.material as THREE.MeshPhongMaterial).visible = true;
-          mesh.position.z = 30;
+          mesh.position.z = -5;
           mesh.position.y = -20;
         } else {
-          mesh.position.z = 30;
+          mesh.position.z = -5;
         }
       } else {
         break;

+ 4 - 2
src/views/vent/home/configurable/components/preset/SysWindCard.vue

@@ -159,14 +159,16 @@
       background-repeat: no-repeat;
       background-position: bottom left;
       width: 208px;
-      height: 30px;
+      height: 28px;
+      line-height: 28px;
     }
     .syswind__card__spd_space {
       background-image: var(--image-syswind-space-blue);
       background-repeat: no-repeat;
       background-position: bottom left;
       width: 208px;
-      height: 30px;
+      height: 28px;
+      line-height: 28px;
     }
     .syswind__card__vol_wrapper {
       background-image: var(--image-syswind-border-green);

+ 8 - 8
src/views/vent/home/configurable/configurable.data.ts

@@ -6352,7 +6352,7 @@ export const testConfigVent182: Config[] = [
       background: {
         show: true,
         type: 'video',
-        link: '/video/mainFan.mp4',
+        link: 'http://182.92.126.35:8092/modelreq/sys/common/static/webfile/mainFan.mp4',
       },
       layout: {
         direction: 'column',
@@ -6423,7 +6423,7 @@ export const testConfigVent182: Config[] = [
       background: {
         show: true,
         type: 'video',
-        link: '/video/fanLocal.mp4',
+        link: 'http://182.92.126.35:8092/modelreq/sys/common/static/webfile/fanLocal.mp4',
       },
       layout: {
         direction: 'column',
@@ -6494,7 +6494,7 @@ export const testConfigVent182: Config[] = [
       background: {
         show: true,
         type: 'video',
-        link: '/video/gate.mp4',
+        link: 'http://182.92.126.35:8092/modelreq/sys/common/static/webfile/gate.mp4',
       },
       layout: {
         direction: 'row',
@@ -6556,13 +6556,13 @@ export const testConfigVent182: Config[] = [
           config: {
             title: '${strinstallpos}',
             volumns: [
-              { label: '风量', value: '${readData.m3}', lowerLimit: '100' },
-              { label: '需风量', value: '100' },
+              { label: '风量', value: '${readData.m3}', lowerLimit: '${needq}' },
+              { label: '需风量', value: '${needq}' },
             ],
             speeds: [
-              { label: '风速', value: '${readData.va}', lowerLimit: '2', upperLimit: '100' },
-              { label: '规程最大值', value: '100' },
-              { label: '规程最小值', value: '2' },
+              { label: '风速', value: '${readData.va}', lowerLimit: '${deviceRegulation.fmin}', upperLimit: '${deviceRegulation.fmax}' },
+              { label: '规程最大值', value: '${deviceRegulation.fmax}' },
+              { label: '规程最小值', value: '${deviceRegulation.fmin}' },
             ],
             prop: 'string',
           },

+ 2 - 2
src/views/vent/home/configurable/fireDoorMonitor.vue

@@ -109,11 +109,11 @@
   //   }
   // );
 
-  function initModalAnimate(modal) {
+  async function initModalAnimate(modal) {
     console.log('初始化模型', modal);
     modal.isRender = true;
 
-    modalAnimate(modal);
+    await modalAnimate(modal);
   }
 
   onMounted(() => {

+ 1 - 1
src/views/vent/monitorManager/mainFanMonitor/components/entryThree.vue

@@ -6,7 +6,7 @@
       class="threejs-Object-CSS"
       style="width: 100%; height: 100%; position: absolute; pointer-events: none; overflow: hidden; z-index: 1; top: 0"
     >
-      <div style="position: relative" v-if="selectData['modalTyoe']">
+      <div style="position: relative" v-if="selectData['modalTyoe'] && selectData['modalTyoe'] !== 'mainWindRect-Inverse'">
         <div class="elementTag" id="inputBox1" v-if="backMonitorIsShow">
           <div class="elementContent elementContent-r">
             <!-- <div class="element-item"><span class="data-title">风机气压(Pa):</span><span>{{ selectData.DataPa ? selectData.DataPa : '-' }}</span></div> -->

+ 5 - 1
src/views/vent/monitorManager/mainFanMonitor/index.vue

@@ -1102,7 +1102,11 @@
               ? 'mainWindRect3'
               : selectData['modalTyoe'] === 'lijing_1'
                 ? 'mainLjDtWindRect'
-                : 'mainWindRect';
+                : selectData['modalTyoe'] === 'lijing'
+                  ? 'mainWindRect'
+                  : selectData['modalTyoe']
+                    ? selectData['modalTyoe']
+                    : 'mainWindRect';
 
       frontMonitorIsShow.value = false;
       centerMonitorIsShow.value = false;

+ 98 - 9
src/views/vent/monitorManager/mainFanMonitor/main.threejs.ts

@@ -74,7 +74,7 @@ const mouseEvent = (event) => {
   if (event.button == 0) {
     model?.canvasContainer?.addEventListener('mousemove', mousemove);
     mouseDownFn(<UseThree>model, <THREE.Object3D>group, event, (intersects) => {
-      if (modalType === 'mainWindRect' && mainWindObj) {
+      if (modalType.includes('mainWindRect') && mainWindObj) {
         mainWindObj?.mousedownModel.call(mainWindObj, intersects);
       } else if (modalType === 'mainXjWindRect' && mainXjWindObj) {
         mainXjWindObj?.mousedownModel.call(mainXjWindObj, intersects);
@@ -100,7 +100,7 @@ const mousemove = () => {
 /* 添加监控数据 */
 export const addText = () => {
   if (!mainWindObj) return;
-  if (modalType === 'mainWindRect' && mainWindObj) {
+  if (modalType.includes('mainWindRect') && mainWindObj) {
     return mainWindObj.addCssText.call(mainWindObj);
   } else if (modalType === 'mainXjWindRect' && mainXjWindObj) {
     return mainXjWindObj.addCssText.call(mainXjWindObj);
@@ -116,7 +116,7 @@ export const addText = () => {
 /* 刷新echarts曲线图 */
 export const resetEcharts = (selectData) => {
   if (!mainWindObj) return;
-  if (modalType === 'mainWindRect' && mainWindObj) {
+  if (modalType.includes('mainWindRect') && mainWindObj) {
     return mainWindObj.addEcharts.call(mainWindObj);
   } else if (modalType === 'mainXjWindRect' && mainXjWindObj) {
     return mainXjWindObj.addEcharts.call(mainXjWindObj);
@@ -138,7 +138,7 @@ export const resetEcharts = (selectData) => {
  */
 export const play = (controlType, deviceType, frequencyVal?, state?, smokeDirection?) => {
   if (!mainWindObj) return;
-  if (modalType === 'mainWindRect' && mainWindObj) {
+  if (modalType.includes('mainWindRect') && mainWindObj) {
     return mainWindObj.playSmoke.call(mainWindObj, controlType, deviceType, frequencyVal, state, smokeDirection);
   } else if (modalType === 'mainXjWindRect' && mainXjWindObj) {
     return mainXjWindObj.playSmoke.call(mainXjWindObj, controlType, deviceType, frequencyVal, state, smokeDirection);
@@ -155,7 +155,7 @@ export const playAnimate1 = async (selectData, duration?) => {
   if (!mainWindObj) return;
   let mainObj: mainWindRect | mainXjWindRect | undefined;
 
-  if (modalType === 'mainWindRect') {
+  if (modalType.includes('mainWindRect')) {
     mainObj = mainWindObj;
   } else if (modalType === 'mainXjWindRect') {
     mainObj = mainXjWindObj;
@@ -249,7 +249,7 @@ export const playAnimate = async (selectData, duration?) => {
 
   let mainObj: mainWindRect | mainXjWindRect | mainWindLj3 | mainWindLjDt | undefined;
 
-  if (modalType === 'mainWindRect') {
+  if (modalType.includes('mainWindRect')) {
     mainObj = mainWindObj;
   } else if (modalType === 'mainXjWindRect') {
     mainObj = mainXjWindObj;
@@ -345,6 +345,95 @@ export const playAnimate = async (selectData, duration?) => {
       }
     } else if (modalType === 'mainLjDtWindRect') {
       (mainObj as mainWindLjDt).playSmoke(selectData.Fan1StartStatus == 1, selectData.Fan2FreqForwardRun == 1, selectData.Fan2FreqReverseRun == 1);
+    } else if (modalType === 'mainWindRect-Inverse') {
+      mainObj.resetSmokeParam('back', selectData.Fan2FreqHz, duration);
+      mainObj.resetSmokeParam('front', selectData.Fan1FreqHz, duration);
+      if (selectData.Fan1StartStatus == 1) {
+        // 主风机开启
+        mainObj?.lookMotor('front', 'open', duration);
+        mainObj?.openOrCloseValve('front', 'open', duration);
+        // 1. 已经运行,首次切入动画
+        // 2. 在页面上,切换动画
+        if (selectData.Fan1FreqForwardRun == 1 && selectData.Fan1FreqReverseRun == 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.Fan1FreqHz, duration);
+          await mainObj.setSmokeDirection('front', 'tubPositivePath');
+        } else if (selectData.Fan1FreqReverseRun == 1 && selectData.Fan1FreqForwardRun == 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.Fan1FreqHz, 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.Fan1FreqHz, duration);
+          await mainObj.setSmokeDirection('front', 'tubPositivePath');
+        }
+
+        if (!mainObj?.frontSmoke?.frameId) mainObj?.frontSmoke?.startSmoke(duration);
+      } else {
+        // 主风机停止
+        mainObj.closeDevice('front');
+      }
+      if (selectData.Fan2StartStatus == 1) {
+        // 主风机开启
+        mainObj.lookMotor('back', 'open', duration);
+        mainObj.openOrCloseValve('back', 'open', duration);
+        // 1. 已经运行,首次切入动画
+        // 2. 在页面上,切换动画
+        if (selectData.Fan2FreqForwardRun == 1 && selectData.Fan2FreqReverseRun == 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.Fan2FreqHz, duration);
+          await mainObj.setSmokeDirection('back', 'tubPositivePath');
+        } else if (selectData.Fan2FreqReverseRun == 1 && selectData.Fan2FreqForwardRun == 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.Fan2FreqHz, 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.Fan2FreqHz, duration);
+          await mainObj.setSmokeDirection('back', 'tubPositivePath');
+        }
+
+        if (!mainObj?.backSmoke?.frameId) mainObj?.backSmoke?.startSmoke(duration);
+      } else {
+        // 主风机停止
+        mainObj.closeDevice('back');
+      }
     } else {
       mainObj.resetSmokeParam('front', selectData.Fan2FreqHz, duration);
       mainObj.resetSmokeParam('back', selectData.Fan1FreqHz, duration);
@@ -437,7 +526,7 @@ export const playAnimate = async (selectData, duration?) => {
     }
 
     // 防爆门动画
-    if (modalType === 'mainWindRect' && selectData['ExplosionVentOpen'] == 1 && explosionVentOpen !== 1) {
+    if (modalType.includes('mainWindRect') && selectData['ExplosionVentOpen'] == 1 && explosionVentOpen !== 1) {
       if (explosionVentOpen == -1) {
         // 直接打开
         mainObj.playAnimation('open', 0);
@@ -447,7 +536,7 @@ export const playAnimate = async (selectData, duration?) => {
       explosionVentOpen = 1;
       explosionVentClose = 0;
     }
-    if (modalType === 'mainWindRect' && selectData['ExplosionVentClose'] == 1 && explosionVentClose !== 1) {
+    if (modalType.includes('mainWindRect') && selectData['ExplosionVentClose'] == 1 && explosionVentClose !== 1) {
       if (explosionVentOpen == -1) {
         // 直接关闭
         mainObj.playAnimation('close', 0);
@@ -473,7 +562,7 @@ export const setModelType = (type) => {
     mainFanLjDtObj?.stopSmoke();
     mainLjWindObj?.stopSmoke();
     if (group) model?.scene?.remove(group);
-    if (modalType === 'mainWindRect' && mainWindObj && mainWindObj.group) {
+    if (modalType.includes('mainWindRect') && mainWindObj && mainWindObj.group) {
       (<UseThree>model).startAnimation = mainWindObj.render.bind(mainWindObj);
       group = mainWindObj.group;
       setTimeout(async () => {

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

@@ -799,7 +799,6 @@ class mainWindRect {
     this.group = new THREE.Group();
     return new Promise(async (resolve) => {
       this.model.setGLTFModel(['bg1', 'fbm', 'ztfj', 'ztfj-fc'], this.group).then(async () => {
-        // this.group = gltf[0];
         this.group?.position.set(-0.44, 19.88, 22.37);
         this.initSmokeMass();
         await this.setSmokePosition();