Browse Source

Feat 新增活鸡兔井注浆系统功能页面
Feat 新增补连塔注氮监测系统功能页面
Style 调整总裁工作面中模型瓦斯抽采单元显示问题,修改为只在瓦斯监测与管控中模型才显示瓦斯抽采单元

hongrunxia 1 year ago
parent
commit
3f558a1abe
22 changed files with 3207 additions and 531 deletions
  1. 1 1
      public/js/config.js
  2. BIN
      public/model/glft/fire/balancePress_2024-02-23.glb
  3. BIN
      public/model/glft/workFace/workFace-base_2014-02-04.glb
  4. BIN
      public/model/glft/workFace/workFace-hui_2014-02-04.glb
  5. BIN
      public/model/glft/workFace/workFace-jin_2014-02-04.glb
  6. 1 33
      src/views/vent/monitorManager/compressor/components/nitrogenHome1.vue
  7. 0 3
      src/views/vent/monitorManager/compressor/components/nitrogenHome2.vue
  8. 852 0
      src/views/vent/monitorManager/compressor/components/nitrogenHome_blt.vue
  9. 3 1
      src/views/vent/monitorManager/compressor/index.vue
  10. 372 0
      src/views/vent/monitorManager/compressor/nitrogen.data.blt.ts
  11. 50 91
      src/views/vent/monitorManager/compressor/nitrogen.data.ts
  12. 1 1
      src/views/vent/monitorManager/fanLocalMonitor/index.vue
  13. 394 373
      src/views/vent/monitorManager/groutMonitor/components/groutHome.vue
  14. 180 0
      src/views/vent/monitorManager/groutMonitor/components/groutHomeDlt.vue
  15. 0 0
      src/views/vent/monitorManager/groutMonitor/components/groutHomeJj.vue
  16. 8 2
      src/views/vent/monitorManager/groutMonitor/index.vue
  17. 879 0
      src/views/vent/monitorManager/nitrogen/components/nitrogenHomeBLT.vue
  18. 5 7
      src/views/vent/monitorManager/nitrogen/index.vue
  19. 416 0
      src/views/vent/monitorManager/nitrogen/nitrogen.dataBLT.ts
  20. 10 5
      src/views/vent/monitorManager/workFaceMonitor/index.vue
  21. 15 3
      src/views/vent/monitorManager/workFaceMonitor/wokeFace.threejs.ts
  22. 20 11
      src/views/vent/monitorManager/workFaceMonitor/workFace.threejs.base.ts

+ 1 - 1
public/js/config.js

@@ -11,5 +11,5 @@ const History_Type = {
 const VENT_PARAM = {
   // simulatedPassword: '123456', //(simulatedPassword 为空时有密码输入框弹出,不为空时不弹出密码输入框,无需输入密码)
   simulatedPassword: '',
-  showReport: false
+  showReport: true
 }

BIN
public/model/glft/fire/balancePress_2024-02-23.glb


BIN
public/model/glft/workFace/workFace-base_2014-02-04.glb


BIN
public/model/glft/workFace/workFace-hui_2014-02-04.glb


BIN
public/model/glft/workFace/workFace-jin_2014-02-04.glb


+ 1 - 33
src/views/vent/monitorManager/compressor/components/nitrogenHome1.vue

@@ -193,6 +193,7 @@ import { SvgIcon } from '/@/components/Icon';
 import BarAndLine from '/@/components/chart/BarAndLine.vue';
 import HandleModal from './modal.vue';
 import { deviceControlApi } from '/@/api/vent/index';
+import { groupParameterData, deviceParameterData, downWindData } from '../nitrogen.data'
 import { message } from 'ant-design-vue';
 import lodash from 'lodash';
 const globalConfig = inject('globalConfig');
@@ -240,36 +241,6 @@ const monitorDataGroupNum = ref(0);
 
 let airCompressorState = reactive<any[]>([]);
 
-const groupParameterData = [
-  {
-    FluxTotal1: '累计流量(m³)',
-    InputFlux: '瞬时流量(m³/h)',
-  },
-  {
-    PreMembraneTemperature: '膜前温度(­°C)',
-    NitrogenPurity: '氮气纯度(%)',
-  },
-];
-const deviceParameterData = [
-  {
-    AirCompressor_ExhaustPre: '排气压力(KPa)',
-    AirCompressor_ExhaustTemp: '排气温度(­°C)',
-  },
-  {
-    AirCompressor_RunTime: '运行时间(h)',
-    AirCompressor_LoadTime: '加载时间(h)',
-  },
-];
-const downWindData = [
-  {
-    o2Val: '下风侧氧气(%)',
-    temperature: '下风侧温度(℃)',
-  },
-  {
-    fumes: '下风侧烟雾(­%)',
-  },
-];
-
 const propTypeArr = ref([])
 const chartsColumns = ref([])
 watch(monitorDataGroupNum, () => {
@@ -347,8 +318,6 @@ async function getMonitor(flag?) {
 
 async function getDataSource(systemID) {
   const res = await getDevice({ devicetype: 'sys', systemID, type: 'all' });
-  console.log(res, 'res---------------');
-
   if (res) {
     const result =res;
     if (!result || result.msgTxt.length < 1) return;
@@ -384,7 +353,6 @@ async function getDataSource(systemID) {
           dataArr.push(airCompressor)
         }
         echartData.value = dataArr
-
       }
     });
     monitorDataGroupNum.value = monitorData.value.length;

+ 0 - 3
src/views/vent/monitorManager/compressor/components/nitrogenHome2.vue

@@ -8,8 +8,6 @@
             <div v-for="groupNum in 1" :key="groupNum" class="modal-monitor">
                 <fourBorderBg :class="`kyj${groupNum}`" :id="`nitrogenMonitor${groupNum}`">
                     <div class="title">{{ monitorData[0]['strname'] }} </div>
-
-
                     <div class="monitor-item">
                         <span class="monitor-title">实时流量:</span>
                         <span class="monitor-val" v-if="!refresh"><span class="val">{{
@@ -844,7 +842,6 @@ async function getDataSource(systemID) {
 }
 
 function handlerDevice(data, titles) {
-    console.log(data, 'data===---000')
     kzParam.data = data;
     kzParam.isFw = titles
     switch (titles) {

+ 852 - 0
src/views/vent/monitorManager/compressor/components/nitrogenHome_blt.vue

@@ -0,0 +1,852 @@
+<template>
+  <div>{{ Math.random() }}</div>
+  <div id="nitrogen3D" style="width: 100%; height: 100%; position: absolute; overflow: hidden"></div>
+  <div id="nitrogenCss3D" class="threejs-Object-CSS"
+    style="width: 100%; height: 100%; position: absolute; pointer-events: none; overflow: hidden; z-index: 2; top: 0px; left: 0px">
+    <a-spin :spinning="loading" />
+    <div v-for="groupNum in monitorDataGroupNum" :key="groupNum" class="modal-monitor" >
+      <fourBorderBg :class="`kyj${groupNum}`" :id="`nitrogenMonitor${groupNum}`">
+        <div class="title">{{ monitorData[groupNum - 1]['strname'] }} </div>
+        <template v-for="(preMonitor, preMonitorIndex) in preMonitorList" :key="preMonitorIndex">
+          <div v-if="preMonitor.code !== 'signal'" class="monitor-item">
+            <span class="monitor-title">{{ preMonitor.title }}:</span>
+            <span class="monitor-val"
+              ><span class="val">{{
+                monitorData[groupNum - 1][preMonitor.code]
+                  ? formatNum(monitorData[groupNum - 1][preMonitor.code])
+                  : '-'
+              }}</span
+              ><span class="unit">{{ preMonitor.unit }}</span></span
+            >
+          </div>
+          <div v-else class="signal-item">
+            <div class="signal" v-for="(signal, childIndex) in preMonitor.child" :key="childIndex">
+              <span class="monitor-title">{{ signal.title }}</span>
+              <span
+                v-if="signal.isFault !== -1"
+                :class="{
+                  'signal-round': true,
+                  'signal-round-run': !signal.isFault && monitorData[groupNum - 1][preMonitor.code] == '1',
+                  'signal-round-warning':
+                    signal.isFault && monitorData[groupNum - 1][preMonitor.code] == '1',
+                  'signal-round-gry': monitorData[groupNum - 1][preMonitor.code] != '1',
+                }"
+              ></span>
+              <span style="display: inline-block; width: 30px; text-align: center;" v-else>{{ monitorData[groupNum - 1][preMonitor.code] == '1' ? '加载': monitorData[groupNum - 1][preMonitor.code] == '2' ? '卸载' : '-'}}</span>
+            </div>
+          </div>
+        </template>
+      </fourBorderBg>
+    </div>
+  </div>
+  <div class="nitrogen-home">
+    <div class="nitrogen-container">
+      <div v-if="monitorNetStatus == 0" class="device-state">网络断开</div>
+      <div class="top-box">
+        <!-- 底部区域故障数据 -->
+        <div class="footer-item-box">
+            <div class="device-detail">
+                <div class="device-title">&nbsp</div>
+                <div v-for="groupNum in monitorDataGroupNum" :key="groupNum" class="device-title" >
+                  {{ monitorData[groupNum - 1]['strname'] }}
+                </div>
+                <!-- <div class="device-val">故障</div> -->
+            </div>
+            <div v-for="(device, key) in deviceFault" class="device-detail" :key="key">
+                <div class="device-title">{{ device.title }}</div>
+                <div v-for="groupNum in monitorDataGroupNum" :key="groupNum" class="device-val">
+                    <span :style="{ color: monitorData[groupNum - 1][device.code] != '1' ? '#BFBFBF' : '#10BC79' }">{{
+                        monitorData[groupNum - 1][device.code] == '0' ? '正常' : monitorData[groupNum - 1][device.code] == '1' ?
+                        '故障' :
+                        '-'
+                    }}</span>
+                </div>
+            </div>
+        </div>
+        <!-- 左边监测数据 -->
+        <div class="lr-box left-box">
+          <div class="item item-l" v-for="groupNum in monitorDataGroupNum" :key="groupNum">
+            <ventBox1>
+              <template #title>
+                <div>{{ monitorData[groupNum - 1]['strname'] }}</div>
+              </template>
+              <template #container>
+                <div class="monitor-box">
+                  <!-- <div class="parameter-title group-parameter-title">
+                    <SvgIcon class="icon" size="38" name="device-group-paramer" /><span>机组参数</span>
+                  </div> -->
+                  <div class="monitor-item">
+                     <div class="state-item" v-for="(preFan, index) in preFanMonitorData" :key="index">
+                      <div class="state-title">{{ preFan.title + (preFan.unit !== 'signal' ? `(${preFan.unit})` : '') }}</div>
+                      <div v-if="preFan.unit !== 'signal'" class="state-val">{{
+                        monitorData[groupNum - 1][preFan.code] >= 0
+                          ? formatNum(Number(monitorData[groupNum - 1][preFan.code]))
+                          : '-'
+                      }}</div>
+                      <div
+                        v-else
+                        :class="{
+                          'signal-round': true,
+                          'signal-round-warning': monitorData[groupNum - 1][preFan.code] == '1',
+                          'signal-round-gry': monitorData[groupNum - 1][preFan.code] != '1',
+                        }"
+                      ></div>
+                    </div>
+                  </div>
+                 
+                </div>
+              </template>
+            </ventBox1>
+          </div>
+        </div>
+        <!-- 右边控制状态 -->
+        <div class="lr-box right-box">
+          <ventBox1 class="vent-margin-t-10">
+            <template #title>
+              <div>设备实时监测曲线</div>
+            </template>
+            <template #container>
+              <BarAndLine v-if="chartsColumns.length > 0" xAxisPropType="readTime" :dataSource="echartData" height="340px"
+                :chartsColumns="chartsColumns" chartsType="listMonitor" :option="echatsOption" />
+              <!-- :option="zhudanOption" -->
+            </template>
+          </ventBox1>
+        </div>
+      </div>
+    </div>
+  </div>
+  <HandleModal :modal-is-show="modalIsShow" :modal-title="modalTitle" :modal-type="modalType" @handle-ok="handleOK"
+    @handle-cancel="handleCancel" />
+</template>
+<script lang="ts" setup name="nitrogenHome">
+import { onMounted, onUnmounted, ref, watch, reactive, defineProps, nextTick, inject, computed } from 'vue';
+import ventBox1 from '/@/components/vent/ventBox1.vue';
+import fourBorderBg from '../../../comment/components/fourBorderBg.vue';
+import { mountedThree, destroy, setModelType, addText } from '../nitrogen.threejs';
+import { getDevice } from '../nitrogen.api';
+import { SvgIcon } from '/@/components/Icon';
+import BarAndLine from '/@/components/chart/BarAndLine.vue';
+import HandleModal from './modal.vue';
+import { deviceControlApi } from '/@/api/vent/index';
+import { preMonitorList, preFanMonitorData, deviceFault } from '../nitrogen.data.blt'
+import { message } from 'ant-design-vue';
+import lodash from 'lodash';
+import { formatNum } from '/@/utils/ventutil';
+const globalConfig = inject('globalConfig');
+
+const props = defineProps({
+  deviceId: {
+    type: String,
+    require: true,
+  },
+  modalType: {
+    type: String,
+    require: true,
+  },
+});
+const refresh = ref(false)
+const modalTitle = ref(''); // 模态框标题显示内容,根据设备操作类型决定
+const modalType = ref(''); // 模态框内容显示类型,设备操作类型
+const modalIsShow = ref<boolean>(false); // 是否显示模态框
+const loading = ref(true);
+let kzParam = reactive<any>({
+  data: {},
+  isFw: null,
+});
+
+// const kyjs = ['1号空压机', '1号空压机', '1号空压机', '1号空压机'];
+const flvURL1 = () => {
+  // return `https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv`;
+  return '';
+};
+const colors = ['#FDB146', '#EE6666', '#9BCB75', '#03C2EC', '#DA3914', '#9C83D9']
+const echatsOption = {
+  grid: {
+    top: '35%',
+    left: '15%',
+    right: '20px',
+    bottom: '8%',
+    // containLabel: true
+  },
+  toolbox: {
+    feature: {}
+  }
+}
+const monitorNetStatus = ref(0)
+const monitorDataGroupNum = ref(0);
+
+let airCompressorState = reactive<any[]>([]);
+
+const propTypeArr = ref([])
+const chartsColumns = ref([])
+watch(monitorDataGroupNum, () => {
+
+  const arr = <any[]>[]
+  const item = {
+    legend: '瞬时流量',
+    seriesName: '(m³/h)',
+    ymax: 2000,
+    yname: 'm³/h',
+    linetype: 'line',
+    yaxispos: 'left',
+    color: '#FDB146',
+    sort: 1,
+    xRotate: 0,
+    dataIndex: 'InputFlux',
+  }
+  const propTypeList = []
+  for (let i = 1; i <= monitorDataGroupNum.value; i++) {
+    const lineType = lodash.cloneDeep(item)
+    lineType.legend = `制氮机${i}瞬时流量`;
+    lineType.dataIndex = `InputFlux${i}`
+    lineType.color = colors[i - 1]
+    arr.push(lineType)
+  }
+  chartsColumns.value = arr
+
+})
+
+
+
+const monitorData = ref(
+  new Array(3).fill({
+    // strName: '空压机',
+    // cumulativeFlow: '-',
+    // centerTemperature: '-',
+    // outletTemperature: '-',
+    // Ia: '-',
+    // Ib: '-',
+    // Ic: '-',
+    // Vab: '-',
+    // Vac: '-',
+    // Vbc: '-',
+    // compressGroupName: '',
+    // compressExhaustPressF1: '-',
+    // compressSeparatePressF1: '-',
+    // compressHostTempF1: '-',
+    // compressCrewTempF1: '-',
+    // compressRunTimeF1: '-',
+    // controlModel: 'LOC'
+  })
+);
+
+//图表数据
+let echartData = ref<any>([]);
+
+// https获取监测数据
+let timer: null | NodeJS.Timeout = null;
+async function getMonitor(flag?) {
+  if (Object.prototype.toString.call(timer) === '[object Null]') {
+    timer = await setTimeout(
+      async () => {
+        if (props.deviceId) {
+          await getDataSource(props.deviceId);
+        }
+        if (timer) {
+          timer = null;
+        }
+        await getMonitor();
+      },
+      flag ? 0 : 3000
+    );
+  }
+}
+
+async function getDataSource(systemID) {
+  const res = await getDevice({ devicetype: 'sys', systemID, type: 'all' });
+  console.log(res, 'res---------------');
+
+  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'].substring(11) }
+        const dataArr = lodash.cloneDeep(echartData.value)
+        //图表数据
+        if (dataArr.length <= 5) {
+          monitorData.value.forEach((el, index) => {
+            airCompressor[`InputFlux${index + 1}`] = 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
+    })
+  }
+}
+
+function handlerDevice(data, bol) {
+  console.log(bol, 'bol-------')
+  kzParam.data = data;
+  kzParam.isFw = bol;
+  console.log(kzParam, 'kz--------')
+  if (bol) {
+    modalTitle.value = '一键复位';
+    modalType.value = '1';
+    modalIsShow.value = true;
+    kzParam.data.HMIReset = !data.HMIReset
+  } else {
+    modalTitle.value = '一键启停';
+    modalType.value = '2';
+    modalIsShow.value = true;
+    kzParam.data.HMIStartStop = !data.HMIStartStop;
+  }
+}
+function handleOK(passWord, handlerState) {
+  console.log(kzParam, 'kz----------');
+  // if (passWord !== '123456') {
+  //   message.warning('密码不正确,请重新输入');
+  //   return;
+  // }
+
+  let data = {};
+  if (kzParam.isFw) {
+    data = {
+      deviceid: kzParam.data.id,
+      devicetype: kzParam.data.deviceType,
+      password: passWord,
+      HMIReset: kzParam.data.HMIReset,
+    };
+  } else {
+    data = {
+      deviceid: kzParam.data.id,
+      password: passWord,
+      devicetype: kzParam.data.deviceType,
+      HMIStartStop: kzParam.data.HMIStartStop,
+    };
+  }
+
+  deviceControlApi(data).then((res) => {
+    // 模拟时开启
+    if (res.success) {
+      modalIsShow.value = false;
+      getDataSource(props.deviceId);
+      if (globalConfig.History_Type == 'remote') {
+        message.success('指令已下发至生产管控平台成功!')
+      } else {
+        message.success('指令已下发成功!')
+      }
+    }
+  });
+}
+function handleCancel() {
+  modalIsShow.value = false;
+  modalTitle.value = '';
+  modalType.value = '';
+}
+
+watch([monitorDataGroupNum, loading], ([newMonitorDataGroupNum, newLoading]) => {
+  nextTick(() => {
+    if (newMonitorDataGroupNum && !newLoading) {
+      setModelType(props.modalType, newMonitorDataGroupNum);
+    }
+  });
+});
+
+
+onMounted(async () => {
+  await getMonitor(true);
+  await mountedThree().then(() => {
+    loading.value = false;
+  });
+});
+
+onUnmounted(() => {
+  destroy();
+  if (timer) {
+    clearTimeout(timer);
+    timer = undefined;
+  }
+});
+</script>
+
+<style lang="less" scoped>
+@ventSpace: zxm;
+
+.nitrogen-box {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+}
+
+#nitrogenCss3D {
+  .modal-monitor {
+    width: 200px;
+    position: absolute;
+    left: 0px;
+    top: 0px;
+  }
+
+  &:deep(.win) {
+    margin: 0 !important;
+    background: #00000044;
+  }
+}
+
+.nitrogen-home {
+  width: 100%;
+  height: 100%;
+  position: fixed;
+  z-index: 9999;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  pointer-events: none;
+  top: 20px;
+
+  .nitrogen-container {
+    width: 100%;
+    height: calc(100% - 100px);
+    display: flex;
+    justify-content: space-between;
+    margin-bottom: 100px;
+    .device-state{
+      width: 100%;
+      position: absolute;
+      top: 20px;
+      color: #e90000;
+      display: flex;
+      justify-content: center;
+      font-size: 20px;
+    }
+    .top-box {
+      width: 100%;
+      padding: 10px;
+      overflow: hidden;
+      display: flex;
+      justify-content: space-between;
+      // margin-top: 40px;
+      .footer-item-box {
+        width: calc(100% - 20px);
+        height: auto;
+        position: fixed;
+        bottom: 130px;
+        display: flex;
+        justify-content: center;
+        color: #fff;
+        // box-shadow: 0 0 30px rgb(0, 153, 184) inset;
+        pointer-events: auto;
+
+        .device-detail {
+            text-align: center;
+
+            &:first-child {
+                background-color: #00bbff11;
+            }
+
+            &:last-child {
+
+                .device-val,
+                .device-title {
+                    border-right: 1px solid #00baffd4;
+                }
+            }
+
+            .device-val {
+                line-height: 36px;
+                border-top: 1px solid #00baffd4;
+                border-left: 1px solid #00baffd4;
+
+                &:last-child {
+                    border-bottom: 1px solid #00baffd4;
+                }
+            }
+        }
+
+        .device-title {
+            width: 110px;
+            text-align: center;
+            border-top: 1px solid #00baffd4;
+            border-left: 1px solid #00baffd4;
+            line-height: 36px;
+            color: #00e5ff;
+            background-color: #00bbff21;
+            backdrop-filter: blur(5px);
+            &:last-child {
+              border-bottom: 1px solid #00baffd4;
+            }
+        }
+
+    }
+      .lr-box {
+        height: 100%;
+        display: flex;
+        flex-direction: column;
+        position: relative;
+        // overflow: hidden;
+        z-index: 9999;
+        pointer-events: auto;
+        overflow-y: auto;
+        overflow-x: hidden;
+        height: calc(100% - 70px);
+      }
+
+      .item {
+        width: 285px;
+        height: auto;
+        position: relative;
+        border-radius: 5px;
+        margin-top: 10px;
+        margin-bottom: 0px;
+        pointer-events: auto;
+        color: #fff;
+        // overflow: hidden;
+
+        &:first-child {
+          margin-top: 0px;
+        }
+
+        .base-title {
+          color: #fff;
+          margin-bottom: 8px;
+          padding-left: 10px;
+          position: relative;
+          font-size: 16px;
+
+          &::after {
+            content: '';
+            position: absolute;
+            display: block;
+            width: 4px;
+            height: 12px;
+            top: 7px;
+            left: 0px;
+            background: #45d3fd;
+            border-radius: 4px;
+          }
+        }
+        .monitor-item{
+          width: 100%;
+          display: flex;
+          flex-direction: row;
+          flex-wrap: wrap;
+          .state-item {
+            width: 50%;
+            padding: 5px;
+            display: flex;
+             align-items: center;
+             justify-content: space-between;
+            .state-title {
+              width: 100px;
+              color: #ffffffdd;
+              flex: 9;
+              font-size: 14px;
+              .unit {
+                // color: #ffffffbb;
+              }
+            }
+            .state-val {
+              flex: 1;
+              color: #e4a300;
+              margin-right: 5px;
+              text-align: right;
+              font-size: 14px;
+            }
+          }
+
+        }
+        
+        .signal-box {
+          margin: 5px 0;
+          display: flex;
+          align-items: center;
+
+          .signal-title {
+            color: #7af5ff;
+            margin: 0 5px;
+          }
+
+          &:last-child {
+            margin-right: 0px;
+          }
+        }
+
+        .list-item {
+          padding: 0 10px;
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+
+          .item-data-key {
+            color: #ffffff99;
+          }
+        }
+
+        .item-data-box {
+          color: #fff;
+
+          .state-icon {
+            display: inline-block;
+            width: 12px;
+            height: 12px;
+            border-radius: 12px;
+          }
+
+          .open {
+            border: 5px solid #133a56;
+            background: #4ecb73;
+          }
+
+          .close {
+            border: 5px solid #192961;
+            background: #6d7898;
+          }
+        }
+      }
+
+      .item-l {
+        width: 100%;
+
+        .monitor-box {
+          width: 100%;
+
+          .parameter-title {
+            position: relative;
+            width: 100%;
+            height: 14px;
+            margin-top: 10px;
+
+            .icon,
+            span {
+              position: absolute;
+              top: -10px;
+            }
+          }
+
+          .group-parameter-title {
+            background-image: linear-gradient(to right, #39a3ff50, #39a3ff00);
+
+            .icon {
+              left: -12px;
+              top: -17px;
+            }
+
+            span {
+              left: 18px;
+            }
+
+            .item-col {
+              background-image: linear-gradient(to right, #39a3ff00, #39a3ff10);
+            }
+          }
+
+          .device-parameter-title {
+            background-image: linear-gradient(to right, #3df6ff40, #3df6ff00);
+
+            .icon {
+              left: -10px;
+              top: -14px;
+            }
+
+            span {
+              left: 18px;
+            }
+
+            .item-col {
+              background-image: linear-gradient(to right, #3df6ff10, #3df6ff00);
+            }
+          }
+        }
+      }
+
+      .right-box {
+        width: 330px;
+        margin-top: 50px;
+
+        .control-group {
+          display: flex;
+          // justify-content: space-around;
+          flex-wrap: wrap;
+
+          .control-item {
+            width: 50%; //lxh
+            display: flex;
+            flex-direction: column;
+            justify-content: center;
+            align-items: center;
+            padding: 0 4px;
+
+            .control-item-title {
+              color: #a6dce9;
+              position: relative;
+              top: 5px;
+            }
+
+            .control-item-state {
+              width: 94px;
+              height: 47px;
+              background: url('/@/assets/images/vent/control-switch-bg.png');
+              display: flex;
+              justify-content: center;
+              align-items: center;
+              color: #fff;
+            }
+
+            .button-box {
+              position: relative;
+              padding: 5px;
+              border: 1px transparent solid;
+              background-clip: border-box;
+              border-radius: 5px;
+              margin-left: 8px;
+            }
+
+            .a-button {
+              pointer-events: auto;
+            }
+
+            &::v-deep .a-button--mini {
+              padding: 6px 10px;
+            }
+
+            &::v-deep .a-button--mini.is-round {
+              padding: 6px 10px;
+            }
+          }
+        }
+      }
+
+      .left-box {
+        width: 335px;
+        margin-top: 80px;
+      }
+    }
+
+    &:deep(.win) {
+      width: 100%;
+      margin: 0 !important;
+    }
+  }
+}
+
+&:deep(.main) {
+  .title {
+    height: 34px;
+    text-align: center;
+    font-weight: 600;
+    color: #7af5ff;
+    // background-image: url('../../../assets/img/yfj/light.png');
+    background-repeat: no-repeat;
+    background-position-x: center;
+    background-position-y: 100%;
+    background-size: 80%;
+    font-size: 16px;
+  }
+
+  .monitor-item {
+    width: 200px;
+    display: flex;
+    flex-direction: row;
+    width: auto;
+    margin-bottom: 3px;
+
+    .monitor-val {
+      color: #ffb700;
+      display: flex;
+      width: auto;
+
+      .val {
+        width: 80px;
+        font-size: 14px;
+      }
+
+      .unit {
+        color: #ffffffbb;
+        font-size: 14px;
+      }
+    }
+  }
+
+  .monitor-title {
+    width: 100px;
+    color: #7af5ff;
+    font-weight: 400;
+    font-size: 14px;
+  }
+
+  .signal-item {
+    display: flex;
+    justify-content: space-between;
+
+    // margin-bottom: 5px;
+    .signal-round {
+      display: inline-block;
+      width: 8px;
+      height: 8px;
+      border-radius: 50%;
+      margin: 0 10px;
+      position: relative;
+
+      &::after {
+        display: block;
+        content: '';
+        position: absolute;
+        width: 12px;
+        height: 12px;
+        top: -2px;
+        left: -2px;
+        border-radius: 50%;
+      }
+    }
+
+    .signal-round-gry {
+      background-color: #858585;
+
+      &::after {
+        background-color: #85858544;
+        box-shadow: 0 0 1px 1px #85858599;
+      }
+    }
+
+    .signal-round-run {
+      background-color: #67fc00;
+
+      &::after {
+        background-color: #67fc0044;
+        box-shadow: 0 0 1px 1px #c6ff77;
+      }
+    }
+
+    .signal-round-warning {
+      background-color: #e9170b;
+
+      &::after {
+        background-color: #e9170b44;
+        box-shadow: 0 0 1px 1px #e9170b;
+      }
+    }
+  }
+}
+
+:deep(.zxm-radio-wrapper) {
+  color: #fff !important;
+}
+</style>

+ 3 - 1
src/views/vent/monitorManager/compressor/index.vue

@@ -4,9 +4,10 @@
     <!-- 阿里云 -->
     <!-- <nitrogenHome v-if="activeKey == 'nitrogen_page' && optionValue && optionValue !='1702602347296399361'" :device-id="optionValue" :modal-type="modalType" /> -->
     <!-- 布尔台 -->
-    <nitrogenHome1 v-if="activeKey == 'nitrogen_page' && optionValue" :device-id="optionValue" :modal-type="modalType" />
+    <!-- <nitrogenHome1 v-if="activeKey == 'nitrogen_page' && optionValue" :device-id="optionValue" :modal-type="modalType" /> -->
     <!-- 保德 -->
     <!-- <nitrogenHome2 v-if="activeKey == 'nitrogen_page' && optionValue" :device-id="optionValue" :modal-type="modalType" /> -->
+    <nitrogenHomeBlt v-if="activeKey == 'nitrogen_page' && optionValue" :device-id="optionValue" :modal-type="modalType" />
     <nitrogenEcharts v-if="activeKey == 'yfj_monitor_echarts'"/>
     <nitrogenHistory ref="historyTable" :device-id="optionValue" :device-type="optionType" v-if="activeKey == 'yfj_history'"/>
     <nitrogenHandleHistory ref="alarmHistoryTable" v-if="activeKey == 'yfj_handler_history'"/>
@@ -21,6 +22,7 @@ import customHeader from '/@/views/vent/comment/components/customHeader.vue';
 import nitrogenHome from './components/nitrogenHome.vue'
 import nitrogenHome1 from './components/nitrogenHome1.vue' // 布尔台
 import nitrogenHome2 from './components/nitrogenHome2.vue' // 保德
+import nitrogenHomeBlt from './components/nitrogenHome_blt.vue' // 保德
 import nitrogenEcharts from './components/nitrogenEcharts.vue'
 import nitrogenHistory from './components/nitrogenHistory.vue'
 import nitrogenHandleHistory from './components/nitrogenHandleHistory.vue'

+ 372 - 0
src/views/vent/monitorManager/compressor/nitrogen.data.blt.ts

@@ -0,0 +1,372 @@
+import { ref, reactive } from 'vue';
+import echarts from '/@/utils/lib/echarts';
+
+export const navList = ref([
+  {
+    title: '监控界面',
+    pathName: 'nitrogen_page',
+    isHover: false,
+  },
+  {
+    title: '历史监测记录',
+    pathName: 'yfj_history',
+    isHover: false,
+  },
+  {
+    title: '操作历史记录',
+    pathName: 'yfj_handler_history',
+    isHover: false,
+  },
+  {
+    title: '故障诊断历史记录',
+    pathName: 'yfj_faultRecord',
+    isHover: false,
+  },
+]);
+
+export const preMonitorList = [
+  {
+    title: `累计流量`,
+    code: `FluxTotal`,
+    unit: 'm³',
+    child: [],
+  },
+  {
+    title: `瞬时流量`,
+    code: `InputFlux`,
+    unit: 'm³/min',
+    child: [],
+  },
+  {
+    title: `氮气浓度`,
+    code: `NitrogenPurity`,
+    unit: '%',
+    child: [],
+  },
+  {
+    title: `运行时间`,
+    code: `AirCompressor_RunTime`,
+    unit: 'h',
+    child: [],
+  },
+  {
+    code: 'signal',
+    child: [
+      {
+        title: `加载/卸载`,
+        code: `AirCompressor_LoadorUnload`,
+        isFault: -1,
+      },
+      {
+        title: `重故障`,
+        code: `AirCompressor_TotalFailureSignal`,
+        isFault: true,
+      },
+    ],
+  },
+  {
+    code: 'signal',
+    child: [
+      {
+        title: `电源信号`,
+        code: `AirCompressor_PowerFault`,
+        isFault: false,
+      },
+      {
+        title: `运行信号`,
+        code: `AirCompressor_Status`,
+        isFault: false,
+      },
+    ],
+  },
+  {
+    code: 'signal',
+    child: [
+      {
+        title: '风机过载',
+        code: 'AirCompressor_Fan_OverloadFault',
+        isFault: true,
+      },
+      {
+        title: '排气压力过高',
+        code: 'AirCompressor_ExhaustPreHighFault',
+        isFault: true,
+      },
+    ],
+  },
+];
+export const preFanMonitorData = [
+  {
+    title: '膜前温度',
+    code: 'PreMembraneTemperature',
+    unit: '℃',
+  },
+  {
+    title: '排气温度',
+    code: 'AirCompressor_ExhaustTemp',
+    unit: '℃',
+  },
+  {
+    title: '排气高温',
+    code: 'AirCompressor_ExhaustTemp1',
+    unit: '℃',
+  },
+  {
+    title: '排气压力',
+    code: 'AirCompressor_ExhaustPre',
+    unit: 'Mpa',
+  },
+  {
+    title: '电机电压',
+    code: 'AirCompressor_SysVoltage',
+    unit: 'V',
+  },
+  {
+    title: '电机电压',
+    code: 'AirCompressor_SysVoltage',
+    unit: 'V',
+  },
+  {
+    title: '电机电流',
+    code: 'AirCompressor_MainMotor_Current',
+    unit: 'A',
+  },
+  {
+    title: '三相不平衡',
+    code: 'AirCompressor_UnbalanceFault',
+    unit: 'signal',
+  },
+  {
+    title: ' 断相',
+    code: 'AirCompressor_PhaseFailureFault',
+    unit: 'signal',
+  },
+  {
+    title: '相序故障',
+    code: 'AirCompressor_PhaseSequenceFault',
+    unit: 'signal',
+  },
+  {
+    title: '接线错误',
+    code: 'AirCompressor_PhaseSequenceFault1',
+    unit: 'signal',
+  },
+  {
+    title: '短路故障',
+    code: 'AirCompressor_ShortCutFaul',
+    unit: 'signal',
+  },
+  {
+    title: '主电机高温',
+    code: 'AirCompressor_MainMotor_OverTempFault',
+    unit: 'signal',
+  },
+  {
+    title: '主机过载',
+    code: 'AirCompressor_MainMotor_OverloadFault',
+    unit: 'signal',
+  },
+  {
+    title: '欠压故障',
+    code: 'AirCompressor_LowVoltageFault',
+    unit: 'signal',
+  },
+  {
+    title: '过压故障',
+    code: 'AirCompressor_OverVoltageFault',
+    unit: 'signal',
+  },
+];
+
+export const deviceFault = [
+  {
+    title: '分闸失败',
+    code: 'AirCompressor_OpenFail',
+  },
+  {
+    title: '合闸失败',
+    code: 'AirCompressor_CloseFail',
+  },
+  {
+    title: '油细分离器故障',
+    code: 'AirCompressor_OilGasBarrel_SeparatorFault',
+  },
+  {
+    title: '油压过低',
+    code: 'AirCompressor_OilPressureLowFault',
+  },
+  {
+    title: '油气桶高温',
+    code: 'AirCompressor_OilGasBarrel_OverTempAlarm',
+  },
+  // {
+  //   title: '油气桶高温预警预留',
+  //   code: 'AirCompressor_OilGasBarrel_OverTempAlarm1',
+  // },
+  {
+    title: '油过滤器堵塞',
+    code: 'AirCompressor_OilGasBarrel_FilterBlockageFault',
+  },
+  {
+    title: '油气桶高压',
+    code: 'AirCompressor_OilGasBarrel_HighPressureFault',
+  },
+  {
+    title: '失水故障',
+    code: 'AirCompressor_NoWaterFault',
+  },
+
+  {
+    title: '漏电闭锁故障',
+    code: 'AirCompressor_LeakageLock',
+  },
+
+  {
+    title: '轻故障预留',
+    code: 'AirCompressor_TotalFailureSignal1',
+  },
+];
+
+export const zhudanOption = reactive({
+  tooltip: { trigger: 'axis', axisPointer: { lineStyle: { color: '#fff' } } },
+  legend: {
+    top: '0',
+    icon: 'rect',
+    data: ['瞬时流量'],
+    right: '10px',
+    textStyle: { fontSize: 12, color: '#fff' },
+  },
+  grid: { x: 45, y: 60, x2: 45, y2: 60 },
+  xAxis: {
+    type: 'category',
+    boundaryGap: false,
+    axisLine: { lineStyle: { color: '#57617B' } },
+    axisLabel: {
+      color: '#ffffffcc',
+      formatter: function (params) {
+        const newParamsName = ref(''); // 最终拼接成的字符串
+        const paramsNameNumber = ref(params.length); // 实际标签的个数
+        const provideNumber = ref(10); // 每行能显示的字的个数
+        const rowNumber = Math.ceil(paramsNameNumber.value / provideNumber.value); // 换行的话,需要显示几行,向上取整
+        /**
+         * 判断标签的个数是否大于规定的个数, 如果大于,则进行换行处理 如果不大于,即等于或小于,就返回原标签
+         */
+        // 条件等同于rowNumber>1
+        if (paramsNameNumber.value > provideNumber.value) {
+          /** 循环每一行,p表示行 */
+          for (let p = 0; p < rowNumber; p++) {
+            let tempStr = ''; // 表示每一次截取的字符串
+            const start = p * provideNumber.value; // 开始截取的位置
+            const end = start + provideNumber.value; // 结束截取的位置
+            // 此处特殊处理最后一行的索引值
+            if (p == rowNumber - 1) {
+              // 最后一次不换行
+              tempStr = params.substring(start, paramsNameNumber.value);
+            } else {
+              // 每一次拼接字符串并换行
+              tempStr = params.substring(start, end) + '\n';
+            }
+            newParamsName.value += tempStr; // 最终拼成的字符串
+          }
+        } else {
+          // 将旧标签的值赋给新标签
+          newParamsName.value = params;
+        }
+        //将最终的字符串返回
+        return newParamsName.value;
+      },
+    },
+
+    splitLine: { show: true, lineStyle: { color: '#57617B22', type: 'dashed' } },
+    data: [],
+  },
+  yAxis: [
+    // {
+    //   type: 'value',
+    //   name: 'm³/h',
+    //   max: 6000,
+    //   axisTick: {
+    //     show: false,
+    //   },
+    //   position: 'left',
+    //   axisLine: { lineStyle: { show: true, color: '#57617B' } },
+    //   axisLabel: { margin: 10, fontSize: 12, color: '#ffffffcc' },
+    //   splitLine: { show: true, lineStyle: { color: '#57617B22', type: 'dashed' } },
+    // },
+    {
+      type: 'value',
+      name: 'm³/h',
+      max: 2000,
+      axisTick: {
+        show: false,
+      },
+      position: 'right',
+      axisLine: { lineStyle: { show: true, color: '#57617B' } },
+      axisLabel: { margin: 10, fontSize: 12, color: '#ffffffcc' },
+      splitLine: { show: true, lineStyle: { color: '#57617B22', type: 'dashed' } },
+    },
+  ],
+  series: [
+    // {
+    //   name: '累计流量',
+    //   type: 'line',
+    //   smooth: true,
+    //   lineStyle: { width: 2 },
+    //   yAxisIndex: 0,
+    //   areaStyle: {
+    //     color: new echarts.graphic.LinearGradient(
+    //       0,
+    //       0,
+    //       0,
+    //       1,
+    //       [
+    //         {
+    //           offset: 0,
+    //           color: 'rgba(185,150,248,0.3)',
+    //         },
+    //         {
+    //           offset: 0.8,
+    //           color: 'rgba(185,150,248,0)',
+    //         },
+    //       ],
+    //       false
+    //     ),
+    //     shadowColor: 'rgba(0, 0, 0, 0.1)',
+    //     shadowBlur: 10,
+    //   },
+    //   itemStyle: { color: '#B996F8' },
+    //   data: [],
+    // },
+    {
+      name: '瞬时流量',
+      type: 'line',
+
+      smooth: true,
+      lineStyle: { width: 2 },
+      yAxisIndex: 0,
+      areaStyle: {
+        color: new echarts.graphic.LinearGradient(
+          0,
+          0,
+          0,
+          1,
+          [
+            {
+              offset: 0,
+              color: 'rgba(3, 194, 236, 0.3)',
+            },
+            {
+              offset: 0.8,
+              color: 'rgba(3, 194, 236, 0)',
+            },
+          ],
+          false
+        ),
+        shadowColor: 'rgba(0, 0, 0, 0.1)',
+        shadowBlur: 10,
+      },
+      itemStyle: { color: '#03C2EC' },
+      data: [],
+    },
+  ],
+});

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

@@ -24,39 +24,35 @@ export const navList = ref([
   },
 ]);
 
-
-export const bottomBtnList = ref([
+export const groupParameterData = [
   {
-    text: '监控界面',
-    value: 'nitrogenMonitor',
-    isHover: false,
+    FluxTotal1: '累计流量(m³)',
+    InputFlux: '瞬时流量(m³/h)',
   },
   {
-    text: '关键节点监测',
-    value: 'nitrogenNode',
-    isHover: false,
+    PreMembraneTemperature: '膜前温度(­°C)',
+    NitrogenPurity: '氮气纯度(%)',
   },
+];
+export const deviceParameterData = [
   {
-    text: '实时曲线',
-    value: 'nitrogenEcharts',
-    isHover: false,
+    AirCompressor_ExhaustPre: '排气压力(KPa)',
+    AirCompressor_ExhaustTemp: '排气温度(­°C)',
   },
   {
-    text: '压风机历史记录',
-    value: 'nitrogenHistory',
-    isHover: false,
+    AirCompressor_RunTime: '运行时间(h)',
+    AirCompressor_LoadTime: '加载时间(h)',
   },
+];
+export const downWindData = [
   {
-    text: '操作历史记录',
-    value: 'nitrogenHandleHistory',
-    isHover: false,
+    o2Val: '下风侧氧气(%)',
+    temperature: '下风侧温度(℃)',
   },
   {
-    text: '故障诊断历史记录',
-    value: 'nitrogenWarningHistory',
-    isHover: false,
+    fumes: '下风侧烟雾(­%)',
   },
-]);
+];
 
 export const zhudanOption = reactive({
   tooltip: { trigger: 'axis', axisPointer: { lineStyle: { color: '#fff' } } },
@@ -72,41 +68,42 @@ export const zhudanOption = reactive({
     type: 'category',
     boundaryGap: false,
     axisLine: { lineStyle: { color: '#57617B' } },
-    axisLabel: { color: '#ffffffcc',
-    formatter: function (params) {
-      let newParamsName = ref('')  // 最终拼接成的字符串
-      let paramsNameNumber = ref(params.length) // 实际标签的个数
-      let provideNumber = ref(10)  // 每行能显示的字的个数
-      let rowNumber = Math.ceil(paramsNameNumber.value / provideNumber.value) // 换行的话,需要显示几行,向上取整
-      /**
-       * 判断标签的个数是否大于规定的个数, 如果大于,则进行换行处理 如果不大于,即等于或小于,就返回原标签
-       */
-      // 条件等同于rowNumber>1
-      if (paramsNameNumber.value > provideNumber.value) {
+    axisLabel: {
+      color: '#ffffffcc',
+      formatter: function (params) {
+        const newParamsName = ref(''); // 最终拼接成的字符串
+        const paramsNameNumber = ref(params.length); // 实际标签的个数
+        const provideNumber = ref(10); // 每行能显示的字的个数
+        const rowNumber = Math.ceil(paramsNameNumber.value / provideNumber.value); // 换行的话,需要显示几行,向上取整
+        /**
+         * 判断标签的个数是否大于规定的个数, 如果大于,则进行换行处理 如果不大于,即等于或小于,就返回原标签
+         */
+        // 条件等同于rowNumber>1
+        if (paramsNameNumber.value > provideNumber.value) {
           /** 循环每一行,p表示行 */
-          for (var p = 0; p < rowNumber; p++) {
-              var tempStr = '' // 表示每一次截取的字符串
-              var start = p * provideNumber.value // 开始截取的位置
-              var end = start + provideNumber.value // 结束截取的位置
-              // 此处特殊处理最后一行的索引值
-              if (p == rowNumber - 1) {
-                  // 最后一次不换行
-                  tempStr = params.substring(start, paramsNameNumber.value)
-              } else {
-                  // 每一次拼接字符串并换行
-                  tempStr = params.substring(start, end) + '\n'
-              }
-              newParamsName.value += tempStr // 最终拼成的字符串
+          for (let p = 0; p < rowNumber; p++) {
+            let tempStr = ''; // 表示每一次截取的字符串
+            const start = p * provideNumber.value; // 开始截取的位置
+            const end = start + provideNumber.value; // 结束截取的位置
+            // 此处特殊处理最后一行的索引值
+            if (p == rowNumber - 1) {
+              // 最后一次不换行
+              tempStr = params.substring(start, paramsNameNumber.value);
+            } else {
+              // 每一次拼接字符串并换行
+              tempStr = params.substring(start, end) + '\n';
+            }
+            newParamsName.value += tempStr; // 最终拼成的字符串
           }
-      } else {
+        } else {
           // 将旧标签的值赋给新标签
-          newParamsName.value = params
-      }
-      //将最终的字符串返回
-      return newParamsName.value
-  },
-  },
-  
+          newParamsName.value = params;
+        }
+        //将最终的字符串返回
+        return newParamsName.value;
+      },
+    },
+
     splitLine: { show: true, lineStyle: { color: '#57617B22', type: 'dashed' } },
     data: [],
   },
@@ -200,41 +197,3 @@ export const zhudanOption = reactive({
     },
   ],
 });
-
-      // dataInfo: {
-      //   controlModel: false
-      // };
-      // videoUrl: '',
-      // isDestroyVideo: false,
-      // navList: [
-      //   {
-      //     title: '监控界面',
-      //     pathName: 'nitrogen_page_lh'
-      //   },
-      //   // {
-      //   //   title: '关键节点监测',
-      //   //   pathName: 'critical_node'
-      //   // },
-      //   {
-      //     title: '实时曲线',
-      //     pathName: 'yfj_monitor_echarts_cy'
-      //   },
-      //   {
-      //     title: '压风机历史记录',
-      //     pathName: 'yfj_history'
-      //   },
-      //   {
-      //     title: '操作历史记录',
-      //     pathName: 'yfj_handler_history'
-      //   },
-      //   {
-      //     title: '故障诊断历史记录',
-      //     pathName: 'yfj_faultRecord'
-      //   }
-      // ],
-      // kyjMonitorDataKey: new Map(
-      //   [
-      //     ['压力', 'pressure'],
-      //     ['温度', 'temp'],
-      //   ]
-      // ),

+ 1 - 1
src/views/vent/monitorManager/fanLocalMonitor/index.vue

@@ -44,7 +44,7 @@
   <div class="scene-box">
     <div class="top-box" v-if="!loading">
       <div class="top-center row">
-        <div class="vent-flex-row" id="fanLocalSelectDom" v-if="getDictItemsByCode('fanlocaltype') || !globalConfig?.simulatedPassword">
+        <div class="vent-flex-row" id="fanLocalSelectDom" v-if="!globalConfig?.simulatedPassword && getDictItemsByCode('fanlocaltype')">
           <span style="color: #00f5fe; margin-left: 5px">风机类型:</span>
           <JDictSelectTag
             v-model:value="devicekide"

+ 394 - 373
src/views/vent/monitorManager/groutMonitor/components/groutHome.vue

@@ -6,10 +6,16 @@
           <template #title>
             <div>设备信息监测</div>
           </template>
-          <template #container v-if="dataSource.length > 0 ">
+          <template #container v-if="dataSource.length > 0">
             <div v-for="(monitor, key) in deviceMonitorData" :key="key" class="monitor-item">
               <div class="item-title">{{ monitor.text }}</div>
-              <div class="item-val">{{ key.startsWith('1#') ? dataSource[0][key.split('_')[1]]||'-' : key.startsWith('2#') ? dataSource[1][key.split('_')[1]]||'-' : (dataSource[0][key] || '-') }}</div>
+              <div class="item-val">{{
+                key.startsWith('1#')
+                  ? dataSource[0][key.split('_')[1]] || '-'
+                  : key.startsWith('2#')
+                  ? dataSource[1][key.split('_')[1]] || '-'
+                  : dataSource[0][key] || '-'
+              }}</div>
               <div class="item-unit">{{ monitor.unit }}</div>
             </div>
           </template>
@@ -21,8 +27,7 @@
             <div>近一月报警情况</div>
           </template>
           <template #container>
-           <dv-scroll-board ref="scrollBoard" :config="warningConfig"
-              style="width: 100%; height: 240px; overflow-y: auto; " />
+            <dv-scroll-board ref="scrollBoard" :config="warningConfig" style="width: 100%; height: 240px; overflow-y: auto" />
           </template>
         </ventBox1>
       </div>
@@ -36,21 +41,27 @@
           <template #title>
             <div>设备设施集中控制</div>
           </template>
-          <template #container >
+          <template #container>
             <div class="control-group">
               <div class="control-item" v-for="(item, key) in deviceControlData" :key="key">
                 <div class="control-item-title">{{ item }}</div>
                 <div class="control-item-state" v-if="!key.startsWith('2#')">
-                  <a-switch v-model="dataSource[0][key.split('_')[1]]" size="small"  checked-children="开启"
+                  <a-switch
+                    v-model="dataSource[0][key.split('_')[1]]"
+                    size="small"
+                    checked-children="开启"
                     un-checked-children="关闭"
-                    @change="handlerDevice(dataSource[0][key.split('_')[1]])">
-                  </a-switch>
+                    @change="handlerDevice(dataSource[0][key.split('_')[1]])"
+                  />
                 </div>
                 <div class="control-item-state" v-else>
-                  <a-switch v-model="dataSource[1][key.split('_')[1]]" size="small"  checked-children="开启"
+                  <a-switch
+                    v-model="dataSource[1][key.split('_')[1]]"
+                    size="small"
+                    checked-children="开启"
                     un-checked-children="关闭"
-                    @change="handlerDevice(dataSource[1][key.split('_')[1]])">
-                  </a-switch>
+                    @change="handlerDevice(dataSource[1][key.split('_')[1]])"
+                  />
                 </div>
               </div>
             </div>
@@ -58,32 +69,32 @@
             <div class="control-btn-group">
               <div class="control-left-box">
                 <div class="btn-box">
-                  <span @click="handlerDevice({ remote : true})">远程</span>
+                  <span @click="handlerDevice({ remote: true })">远程</span>
                   <span @click="handlerDevice({ remote: false })">就地</span>
                 </div>
-                <div class="icon-box" :class="{'remote-icon-box': true}">
+                <div class="icon-box" :class="{ 'remote-icon-box': true }">
                   <div class="icon"></div>
                 </div>
               </div>
               <div class="control-right-box">
-                <a-button class="btn" type="primary" @click="handlerDevice({run: true})">一键启动</a-button>
+                <a-button class="btn" type="primary" @click="handlerDevice({ run: true })">一键启动</a-button>
                 <a-button type="primary" danger @click="handlerDevice({ run: false })">紧急停止</a-button>
               </div>
             </div>
             <a-divider style="height: 1px; background-color: #d7d7d755" />
-            <div class="parameter-btn-group"> 
-              <a-button type="primary"  @click="openModal('RunParameterModal')">参数设置</a-button>
-              <a-button type="primary"  @click="openModal('WarningParameterModal')">报警设置</a-button>
+            <div class="parameter-btn-group">
+              <a-button type="primary" @click="openModal('RunParameterModal')">参数设置</a-button>
+              <a-button type="primary" @click="openModal('WarningParameterModal')">报警设置</a-button>
             </div>
           </template>
-        </ventBox1>    
+        </ventBox1>
       </div>
       <div class="control-container item-box echarts-box">
         <ventBox1>
           <template #title>
             <div>设备实时监测曲线</div>
           </template>
-          <template #container >
+          <template #container>
             <div class="btn-group">
               <span class="active">注浆流量</span>
               <span>注浆压力</span>
@@ -93,437 +104,447 @@
             <div class="item-box echarts-container">
               <div class="echarts-group">
                 <div class="echarts-item">
-                  <BarAndLineCustom xAxisPropType="readTime" :chartData="dataSource" height="240px" :propTypeArr="['flowRate']" :option="zhujiangOption" />
+                  <BarAndLineCustom
+                    xAxisPropType="readTime"
+                    :chartData="dataSource"
+                    height="240px"
+                    :propTypeArr="['flowRate']"
+                    :option="zhujiangOption"
+                  />
                 </div>
                 <div class="echarts-item">
-                  <BarAndLineCustom xAxisPropType="readTime" :chartData="dataSource" height="240px" :propTypeArr="['pressure']" :option="yaliOption" />
+                  <BarAndLineCustom
+                    xAxisPropType="readTime"
+                    :chartData="dataSource"
+                    height="240px"
+                    :propTypeArr="['pressure']"
+                    :option="yaliOption"
+                  />
                 </div>
                 <div class="echarts-item">
-                  <BarAndLineCustom xAxisPropType="readTime" :chartData="dataSource" height="240px" :propTypeArr="['flowRate']" :option="zhujiangOption" />
+                  <BarAndLineCustom
+                    xAxisPropType="readTime"
+                    :chartData="dataSource"
+                    height="240px"
+                    :propTypeArr="['flowRate']"
+                    :option="zhujiangOption"
+                  />
                 </div>
                 <div class="echarts-item">
-                  <BarAndLineCustom xAxisPropType="readTime" :chartData="dataSource" height="240px" :propTypeArr="['flowRate']" :option="zhujiangOption" />
+                  <BarAndLineCustom
+                    xAxisPropType="readTime"
+                    :chartData="dataSource"
+                    height="240px"
+                    :propTypeArr="['flowRate']"
+                    :option="zhujiangOption"
+                  />
                 </div>
               </div>
             </div>
           </template>
         </ventBox1>
       </div>
-
     </div>
   </div>
   <component v-if="modalVisible" :is="currentModal" v-model:visible="modalVisible" />
 </template>
 
 <script setup lang="ts">
+  import { onBeforeMount, ref, onMounted, onUnmounted, shallowRef, defineProps, ComponentOptions, reactive } from 'vue';
+  import { mountedThree, destroy, setModelType } from '../grout.threejs';
+  import { ScrollBoard as DvScrollBoard } from '@kjgl77/datav-vue3';
+  import ventBox1 from '/@/components/vent/ventBox1.vue';
+  import RunParameterModal from './runParameter.modal.vue';
+  import WarningParameterModal from './warningParameter.modal.vue';
+  import { warningConfig, zhujiangOption, yaliOption } from '../grout.data';
+  import { list } from '../grout.api';
+  import BarAndLineCustom from '/@/components/chart/BarAndLineCustom.vue';
 
-import { onBeforeMount, ref, onMounted, onUnmounted, shallowRef, defineProps, ComponentOptions, reactive } from 'vue';
-import { mountedThree, destroy, setModelType } from '../grout.threejs';
-import { ScrollBoard as DvScrollBoard } from '@kjgl77/datav-vue3';
-import ventBox1 from '/@/components/vent/ventBox1.vue';
-import RunParameterModal from './runParameter.modal.vue'
-import WarningParameterModal from './warningParameter.modal.vue'
-import { warningConfig, zhujiangOption, yaliOption } from '../grout.data'
-import { list } from '../grout.api';
-import BarAndLineCustom from '/@/components/chart/BarAndLineCustom.vue';
-
+  const props = defineProps({
+    deviceId: {
+      type: String,
+      require: true,
+    },
+    deviceType: {
+      type: String,
+      require: true,
+    },
+  });
+  const left: string = '0px';
+  const currentModal = shallowRef<Nullable<ComponentOptions>>(null); //模态框
+  const modalVisible = ref<Boolean>(false); // 模态框是否可见
+  const loading = ref(false);
 
-const props = defineProps({
-  deviceId: {
-    type: String,
-    require: true
-  },
-  deviceType: {
-    type: String,
-    require: true
-  }
-})
-const left: string = "0px";
-const currentModal = shallowRef<Nullable<ComponentOptions>>(null); //模态框
-const modalVisible = ref<Boolean>(false); // 模态框是否可见
-const loading = ref(false);
+  // 默认初始是第一行
+  const dataSource = ref([
+    {
+      waterSupply: '-',
+      beltVla: '-',
+      density: '-',
+      pressure: '-',
+      liquidLevel: '-',
+      flowRate: '-',
+      readTime: '',
+    },
+    {
+      waterSupply: '-',
+      beltVla: '-',
+      density: '-',
+      pressure: '-',
+      liquidLevel: '-',
+      flowRate: '-',
+      readTime: '',
+    },
+  ]); //dusting
 
-// 默认初始是第一行
-const dataSource = ref([
-  { 
-    waterSupply : '-',
-    beltVla: '-',
-    density: '-',
-    pressure: '-',
-    liquidLevel: '-',
-    flowRate: '-',
-    readTime: '',
-  },
-  {
-    waterSupply: '-',
-    beltVla: '-',
-    density: '-',
-    pressure: '-',
-    liquidLevel: '-',
-    flowRate: '-',
-    readTime: '',
-  }
-]); //dusting
+  const deviceMonitorData = {
+    '1#_waterSupply': { text: '1#制浆机供水流量', unit: 'm³/h' },
+    '1#_beltVla': { text: '1#皮带秤数值', unit: 'T' },
+    '2#_waterSupply': { text: '2#制浆机供水流量', unit: 'm³/h' },
+    '2#_beltVla': { text: '2#皮带秤数值', unit: 'T' },
+    density: { text: '密度', unit: 'g/cm' },
+    pressure: { text: '压力', unit: 'MPa' },
+    liquidLevel: { text: '缓冲池液位', unit: 'm' },
+    flowRate: { text: '注浆流量', unit: 'm³/h' },
+  };
+  const deviceControlData = {
+    '1#_waterPump': '1#清水泵',
+    '1#_groutingPump': '1#注浆泵',
+    '1#_pulpingMachine': '1#制浆机',
+    '2#_waterPump': '2#清水泵',
+    '2#_groutingPump': '2#注浆泵',
+    '2#_pulpingMachine': '2#制浆机',
+    'liquidLevelProtect ': '液位保护',
+  };
 
-const deviceMonitorData = {
-  '1#_waterSupply': { text: '1#制浆机供水流量', unit: 'm³/h' },
-  '1#_beltVla': { text: '1#皮带秤数值', unit: 'T' },
-  '2#_waterSupply': { text: '2#制浆机供水流量', unit: 'm³/h' },
-  '2#_beltVla': { text: '2#皮带秤数值', unit: 'T' },
-  density: {text: '密度' , unit: 'g/cm'},
-  pressure: { text: '压力', unit: 'MPa' },
-  liquidLevel: { text: '缓冲池液位', unit: 'm' },
-  flowRate: { text: '注浆流量', unit: 'm³/h' },
-}
-const deviceControlData = {
-  '1#_waterPump': '1#清水泵',
-  '1#_groutingPump': '1#注浆泵',
-  '1#_pulpingMachine': '1#制浆机',
-  '2#_waterPump': '2#清水泵',
-  '2#_groutingPump': '2#注浆泵',
-  '2#_pulpingMachine': '2#制浆机',
-  'liquidLevelProtect ':'液位保护'
-}
+  const flvURL1 = () => {
+    return `https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv`;
+    // return ''
+  };
+  const openModal = (modalName) => {
+    modalVisible.value = true;
+    if (modalName == 'RunParameterModal') {
+      currentModal.value = RunParameterModal;
+    } else {
+      currentModal.value = WarningParameterModal;
+    }
+  };
 
-const flvURL1 = () => {
-  return `https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv`;
-  // return ''
-};
-const openModal = (modalName) => {
-  modalVisible.value = true
-  if(modalName == 'RunParameterModal'){
-    currentModal.value = RunParameterModal
-  }else{
-    currentModal.value = WarningParameterModal
+  // https获取监测数据
+  let timer: null | NodeJS.Timeout = null;
+  function getMonitor(flag?) {
+    if (Object.prototype.toString.call(timer) === '[object Null]') {
+      timer = setTimeout(
+        async () => {
+          await getDataSource();
+          if (timer) {
+            timer = null;
+          }
+          await getMonitor();
+        },
+        flag ? 0 : 1000
+      );
+    }
   }
-}
 
-// https获取监测数据
-let timer: null | NodeJS.Timeout = null;
-function getMonitor(flag?) {
-  if (Object.prototype.toString.call(timer) === '[object Null]') {
-    timer = setTimeout(async () => {
-      await getDataSource()
-      if (timer) {
-        timer = null;
-      }
-      await getMonitor();
-    }, flag ? 0 : 1000);
+  async function getDataSource() {
+    const res = await list({ devicetype: 'pulping_auto', pagetype: 'normal' });
+    const dataList = res.msgTxt[0].datalist || [];
+    dataSource.value = dataList.filter((data) => {
+      const item = data.readData;
+      Object.assign(data, item);
+      return item;
+    });
   }
-};
-
-async function getDataSource() {
-  const res = await list({ devicetype: 'pulping_auto', pagetype: 'normal' });
-  const dataList = res.msgTxt[0].datalist || [];
-  dataSource.value = dataList.filter((data) => {
-    const item = data.readData;
-    Object.assign(data, item);
-    return item
-  });
-  
-}
 
-function handlerDevice(param: string | Object) {
+  function handlerDevice(param: string | Object) {}
+  function controlDevice(flag) {}
 
-}
-function controlDevice(flag){
+  onBeforeMount(() => {});
 
-}
-
-onBeforeMount(() => {
-
-});
-
-onMounted(() => {
-  loading.value = true;
-  mountedThree().then(async () => {
-    // await setModelType('groutBase');
-    await setModelType('bertaiBase')
-    loading.value = false;
-    timer = null
-    await getMonitor(true)
+  onMounted(() => {
+    loading.value = true;
+    mountedThree().then(async () => {
+      // await setModelType('groutBase');
+      await setModelType('bertaiBase');
+      loading.value = false;
+      timer = null;
+      await getMonitor(true);
+    });
+  });
+  onUnmounted(() => {
+    destroy();
+    if (timer) {
+      clearTimeout(timer);
+      timer = undefined;
+    }
   });
-});
-onUnmounted(() => {
-  destroy();
-  if (timer) {
-    clearTimeout(timer);
-    timer = undefined;
-  }
-});
 </script>
 <style lang="less" scoped>
-@import '/@/design/vent/modal.less';
-@ventSpace: zxm;
+  @import '/@/design/vent/modal.less';
+  @ventSpace: zxm;
 
-.monitor-container {
-  width: 100%;
-  height: 100%;
-  // height: 550px;
-  // border: 1px solid #fff;
-  margin-top: 40px;
-  display: flex;
-  justify-content: space-between;
-  padding: 0 5px;
-  
-  .lr {
-    width: 350px;
+  .monitor-container {
+    width: 100%;
     height: 100%;
+    // height: 550px;
+    // border: 1px solid #fff;
+    margin-top: 40px;
     display: flex;
-    flex-direction: column;
-    margin-top: 10px;
-    pointer-events: auto;
-  }
+    justify-content: space-between;
+    padding: 0 5px;
 
-  .right-box {
-    width: 320px;
-    margin-top: 30px;
-    .control-group{
+    .lr {
+      width: 350px;
+      height: 100%;
       display: flex;
-      flex-wrap: wrap;
-      .control-item {
-        
+      flex-direction: column;
+      margin-top: 10px;
+      pointer-events: auto;
+    }
+
+    .right-box {
+      width: 320px;
+      margin-top: 30px;
+      .control-group {
         display: flex;
-        flex-direction: column;
-        justify-content: center;
-        align-items: center;
-        padding: 0 2px;
-        .control-item-title{
-          color: #63e0ff;
-          position: relative;
-          top: 5px;
-        }
-        .control-item-state{
-          width: 94px;
-          height: 47px;
-          background: url('/@/assets/images/vent/control-switch-bg.png');
+        flex-wrap: wrap;
+        .control-item {
           display: flex;
+          flex-direction: column;
           justify-content: center;
           align-items: center;
-          color: #fff;
-        }
-      
-        .button-box {
-          position: relative;
-          padding: 5px;
-          border: 1px transparent solid;
-          background-clip: border-box;
-          border-radius: 5px;
-          margin-left: 8px;
-        }
+          padding: 0 2px;
+          .control-item-title {
+            color: #63e0ff;
+            position: relative;
+            top: 5px;
+          }
+          .control-item-state {
+            width: 94px;
+            height: 47px;
+            background: url('/@/assets/images/vent/control-switch-bg.png');
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            color: #fff;
+          }
 
-        .a-button {
-          pointer-events: auto;
-        }
+          .button-box {
+            position: relative;
+            padding: 5px;
+            border: 1px transparent solid;
+            background-clip: border-box;
+            border-radius: 5px;
+            margin-left: 8px;
+          }
 
-        &::v-deep .a-button--mini {
-          padding: 6px 10px;
-        }
+          .a-button {
+            pointer-events: auto;
+          }
 
-        &::v-deep .a-button--mini.is-round {
-          padding: 6px 10px;
-        }
-      }
+          &::v-deep .a-button--mini {
+            padding: 6px 10px;
+          }
 
-    }
-    .control-btn-group{
-      display: flex;
-      flex-direction: row;
-      justify-content: space-between;
-      .control-left-box{
-        display: flex;
-        flex-direction: column;
-        justify-content: center;
-        align-items: center;
-        padding: 0 20px;
-        .btn-box{
-          width: 100px;
-          color: #fff;
-          display: flex;
-          justify-content: space-between;
-          span{
-            display: inline-block;
-            padding: 2px 8px;
-            background: #007099;
-            border-radius: 4px;
-            border: 1px solid rgb(125, 230, 249);
-            cursor: pointer;
-            &:hover{
-              background: #005574;
-            }
+          &::v-deep .a-button--mini.is-round {
+            padding: 6px 10px;
           }
         }
-        .icon-box{
-          width: 60px;
-          height: 60px;
-          border-radius: 30px;
-          border: 2px solid #00bcdd;
-          box-shadow: 0 0 20px #ffffff88;
+      }
+      .control-btn-group {
+        display: flex;
+        flex-direction: row;
+        justify-content: space-between;
+        .control-left-box {
           display: flex;
+          flex-direction: column;
           justify-content: center;
           align-items: center;
-          margin-top: 20px;
-             
-          .icon{
-            width: 18px;
-            height: 18px;
-            border-radius: 9px;
-            border: 3px solid #d7f9ff;
-            position: relative;
-            background: #00bcdd;
-            &::before{
-              position: absolute;
-              content: '';
-              width: 2px;
-              height: 12px;
-              background-color: #00bcdd;
-              left: 6px;
-              top: -16px;
-            }
-            &::after{
-              position: absolute;
-              content: '';
-              width: 2px;
-              height: 12px;
-              left: 6px;
-              top: 17px;
-              background-color: #00d9ff;
+          padding: 0 20px;
+          .btn-box {
+            width: 100px;
+            color: #fff;
+            display: flex;
+            justify-content: space-between;
+            span {
+              display: inline-block;
+              padding: 2px 8px;
+              background: #007099;
+              border-radius: 4px;
+              border: 1px solid rgb(125, 230, 249);
+              cursor: pointer;
+              &:hover {
+                background: #005574;
+              }
             }
           }
-        }
-        .remote-icon-box{
-          transform: rotate(30deg);
-          animation: iconRotate 1s linear;
-        }
-        .remote-icon-box1{
-          transform: rotate(-30deg);
-          animation: iconRotate1 1s linear;
-        }
+          .icon-box {
+            width: 60px;
+            height: 60px;
+            border-radius: 30px;
+            border: 2px solid #00bcdd;
+            box-shadow: 0 0 20px #ffffff88;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            margin-top: 20px;
 
-        @keyframes iconRotate{
-          from{
-            transform: rotate(-30deg);
-          }
-          to {
-            transform: rotate(30deg);
+            .icon {
+              width: 18px;
+              height: 18px;
+              border-radius: 9px;
+              border: 3px solid #d7f9ff;
+              position: relative;
+              background: #00bcdd;
+              &::before {
+                position: absolute;
+                content: '';
+                width: 2px;
+                height: 12px;
+                background-color: #00bcdd;
+                left: 6px;
+                top: -16px;
+              }
+              &::after {
+                position: absolute;
+                content: '';
+                width: 2px;
+                height: 12px;
+                left: 6px;
+                top: 17px;
+                background-color: #00d9ff;
+              }
+            }
           }
-        }
-        @keyframes iconRotate1{
-          from {
+          .remote-icon-box {
             transform: rotate(30deg);
+            animation: iconRotate 1s linear;
           }
-          to {
+          .remote-icon-box1 {
             transform: rotate(-30deg);
+            animation: iconRotate1 1s linear;
+          }
+
+          @keyframes iconRotate {
+            from {
+              transform: rotate(-30deg);
+            }
+            to {
+              transform: rotate(30deg);
+            }
+          }
+          @keyframes iconRotate1 {
+            from {
+              transform: rotate(30deg);
+            }
+            to {
+              transform: rotate(-30deg);
+            }
           }
         }
-        
-      }
-      .control-right-box{
-        width: 100px;
-        .btn{
-          margin-bottom: 30px;
+        .control-right-box {
+          width: 100px;
+          .btn {
+            margin-bottom: 30px;
+          }
         }
       }
-    }
-    .parameter-btn-group{
-      display: flex;
-      justify-content: space-between;
-      padding: 0 20px;
-      margin-bottom: 10px;
-    }
-    .echarts-box{
-      width: 100%;
-      height: 332px;
-      position: relative;
-      &:deep(.box-container){
-        padding: 0px !important;
-      }
-      .btn-group{
-        line-height: 30px;
-        color: #fff;
-        text-align: center;
-        margin-top: 3px;
-        span{
-          padding: 3px 5px;
-          margin: 0 2px;
-          border-radius: 2px;
-          background-image: linear-gradient( #32475B, #5b95c7);
-          border: 1px solid #32475B;
-          cursor: pointer;
-        }
-        .active{
-          background-image: linear-gradient( #2E4659, #37A7B4);
-          border-top: 1px solid #3DF6FF;
-        }
+      .parameter-btn-group {
+        display: flex;
+        justify-content: space-between;
+        padding: 0 20px;
+        margin-bottom: 10px;
       }
-      .echarts-container{
+      .echarts-box {
         width: 100%;
-        height: 240px;
-        overflow: hidden;
+        height: 332px;
         position: relative;
-        .echarts-group{
-          display: flex;
-          flex-direction: row;
-          position: absolute;
-          left: v-bind(left);
-          .echarts-item{
-            width: 305px;
+        &:deep(.box-container) {
+          padding: 0px !important;
+        }
+        .btn-group {
+          line-height: 30px;
+          color: #fff;
+          text-align: center;
+          margin-top: 3px;
+          span {
+            padding: 3px 5px;
+            margin: 0 2px;
+            border-radius: 2px;
+            background-image: linear-gradient(#32475b, #5b95c7);
+            border: 1px solid #32475b;
+            cursor: pointer;
+          }
+          .active {
+            background-image: linear-gradient(#2e4659, #37a7b4);
+            border-top: 1px solid #3df6ff;
+          }
+        }
+        .echarts-container {
+          width: 100%;
+          height: 240px;
+          overflow: hidden;
+          position: relative;
+          .echarts-group {
+            display: flex;
+            flex-direction: row;
+            position: absolute;
+            left: v-bind(left);
+            .echarts-item {
+              width: 305px;
+            }
           }
         }
       }
-      
     }
-    
-  }
 
-  .left-box {
-    margin-top: 30px;
-    .monitor-item{
-      display: flex;
-      color: #fff;
-      justify-content: space-between;
-      background-image: linear-gradient(to left, #3df6ff10, #3df6ff00);
-      margin: 10px 0;
-    
-      .item-title{
-        width: 200px;
-        margin-left: 10px;
-      }
-      .item-val{
-        width: 80px;
-        color: #00eefffe;
-      }
-      .item-unit{
-        width: 80px;
+    .left-box {
+      margin-top: 30px;
+      .monitor-item {
+        display: flex;
+        color: #fff;
+        justify-content: space-between;
+        background-image: linear-gradient(to left, #3df6ff10, #3df6ff00);
+        margin: 10px 0;
+
+        .item-title {
+          width: 200px;
+          margin-left: 10px;
+        }
+        .item-val {
+          width: 80px;
+          color: #00eefffe;
+        }
+        .item-unit {
+          width: 80px;
+        }
       }
     }
-    
-  }
 
-  .item-box{
-    margin-bottom: 15px;
+    .item-box {
+      margin-bottom: 15px;
+    }
   }
 
-}
+  :deep(.@{ventSpace}-tabs-tabpane-active) {
+    overflow: auto;
+  }
 
-:deep(.@{ventSpace}-tabs-tabpane-active) {
-  overflow: auto;
-}
+  .input-box {
+    display: flex;
+    align-items: center;
+    padding-left: 10px;
 
-.input-box {
-  display: flex;
-  align-items: center;
-  padding-left: 10px;
+    .input-title {
+      color: #73e8fe;
+      width: auto;
+    }
 
-  .input-title {
-    color: #73e8fe;
-    width: auto;
-  }
+    .@{ventSpace}-input-number {
+      border-color: #ffffff88 !important;
+    }
 
-  .@{ventSpace}-input-number {
-    border-color: #ffffff88 !important;
+    margin-right: 10px;
   }
-
-  margin-right: 10px;
-}
 </style>

+ 180 - 0
src/views/vent/monitorManager/groutMonitor/components/groutHomeDlt.vue

@@ -0,0 +1,180 @@
+<template>
+  <div class="monitor-container">
+    <div class="header-box">
+      <div class="header-container">
+        <div class="device-detail">
+          <div class="device-val">注浆站流量计瞬时流量 :</div>
+          <div class="device-val">注浆站流量计累计流量 :</div>
+          <div class="device-val">注浆站流量计运行时间 :</div>
+        </div>
+        <div class="device-detail">
+          <div class="device-val">
+            <span :style="{ color: '#10BC79' }">{{ monitorData['InputFlux'] !== undefined ? monitorData['InputFlux'] : '-' }}</span>
+          </div>
+          <div class="device-val">
+            <span :style="{ color: '#10BC79' }">{{
+              monitorData['CurrentCumulativeFlow'] !== undefined ? monitorData['CurrentCumulativeFlow'] : '-'
+            }}</span>
+          </div>
+          <div class="device-val">
+            <span :style="{ color: '#10BC79' }">{{
+              monitorData['AccumulateRunDuration'] !== undefined ? monitorData['AccumulateRunDuration'] : '-'
+            }}</span>
+          </div>
+        </div>
+        <div class="device-detail">
+          <div class="device-val">
+            <span :style="{ color: '#BFBFBF' }">m³</span>
+          </div>
+          <div class="device-val">
+            <span :style="{ color: '#BFBFBF' }">m³/min</span>
+          </div>
+          <div class="device-val">
+            <span :style="{ color: '#BFBFBF' }">h</span>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+  import { ref, onMounted, onUnmounted, defineProps } from 'vue';
+  import { mountedThree, destroy, setModelType } from '../grout.threejs';
+  import { list } from '../grout.api';
+
+  const props = defineProps({
+    deviceId: {
+      type: String,
+      require: true,
+    },
+    deviceType: {
+      type: String,
+      require: true,
+    },
+  });
+
+  const loading = ref(false);
+  const monitorData = ref({ InputFlux: undefined });
+
+  // https获取监测数据
+  let timer: null | NodeJS.Timeout = null;
+  function getMonitor(flag?) {
+    if (Object.prototype.toString.call(timer) === '[object Null]') {
+      timer = setTimeout(
+        async () => {
+          await getDataSource();
+          if (timer) {
+            timer = null;
+          }
+          await getMonitor();
+        },
+        flag ? 0 : 1000
+      );
+    }
+  }
+
+  async function getDataSource() {
+    const res = await list({ devicetype: 'pulping_auto', pagetype: 'normal' });
+    if (res.msgTxt && res.msgTxt[0] && res.msgTxt[0].datalist && res.msgTxt[0].datalist[0]) {
+      monitorData.value = Object.assign(res.msgTxt[0].datalist[0], res.msgTxt[0].datalist[0]['readData']);
+    }
+  }
+
+  onMounted(() => {
+    loading.value = true;
+    mountedThree().then(async () => {
+      await setModelType('bertaiBase');
+      loading.value = false;
+      timer = null;
+      await getMonitor(true);
+    });
+  });
+  onUnmounted(() => {
+    destroy();
+    if (timer) {
+      clearTimeout(timer);
+      timer = undefined;
+    }
+  });
+</script>
+<style lang="less" scoped>
+  @import '/@/design/vent/modal.less';
+  @ventSpace: zxm;
+
+  .monitor-container {
+    width: 100%;
+    height: 100%;
+    // height: 550px;
+    // border: 1px solid #fff;
+    margin-top: 40px;
+    display: flex;
+    // justify-content: space-between;
+    justify-content: center;
+    padding: 0 5px;
+
+    .header-box {
+      // width: 100%;
+      margin-top: 50px;
+      .header-container {
+        height: auto;
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+        color: #fff;
+        box-shadow: 0 0 30px rgb(0, 153, 184) inset;
+      }
+      .device-title {
+        width: 110px;
+        text-align: center;
+        border-top: 1px solid #00baffd4;
+        border-left: 1px solid #00baffd4;
+        line-height: 46px;
+        color: #00e5ff;
+        background-color: #00bbff21;
+      }
+      .device-detail {
+        text-align: center;
+        width: 250px;
+        &:first-child {
+          background-color: #00bbff11;
+        }
+        &:last-child {
+          .device-val,
+          .device-title {
+            border-right: 1px solid #00baffd4;
+          }
+        }
+        .device-val {
+          line-height: 36px;
+          border-top: 1px solid #00baffd4;
+          border-left: 1px solid #00baffd4;
+          &:last-child {
+            border-bottom: 1px solid #00baffd4;
+          }
+        }
+      }
+    }
+  }
+
+  :deep(.@{ventSpace}-tabs-tabpane-active) {
+    overflow: auto;
+  }
+
+  .input-box {
+    display: flex;
+    align-items: center;
+    padding-left: 10px;
+
+    .input-title {
+      color: #73e8fe;
+      width: auto;
+    }
+
+    .@{ventSpace}-input-number {
+      border-color: #ffffff88 !important;
+    }
+
+    margin-right: 10px;
+  }
+</style>

+ 0 - 0
src/views/vent/monitorManager/groutMonitor/components/groutHome1.vue → src/views/vent/monitorManager/groutMonitor/components/groutHomeJj.vue


+ 8 - 2
src/views/vent/monitorManager/groutMonitor/index.vue

@@ -19,7 +19,11 @@
   <div class="scene-box">
     <customHeader :fieldNames="{ label: 'strinstallpos', value: 'deviceID', options: 'children' }" :options = 'options' @change="getSelectRow" :optionValue="optionValue">智能注浆系统</customHeader>
     <div class="center-container">
-      <groutHome v-if="activeKey == 'monitor'" :deviceId = 'optionValue' :device-type="currentDeviceType" />
+      <!-- <groutHome v-if="activeKey == 'monitor'" :deviceId = 'optionValue' :device-type="currentDeviceType" /> -->
+      <!-- 锦界 -->
+      <!-- <groutHomeJj v-if="activeKey == 'monitor'" :deviceId = 'optionValue' :device-type="currentDeviceType" /> -->
+      <!-- 大柳塔 -->
+      <groutHomeDlt v-if="activeKey == 'monitor'" :deviceId = 'optionValue' :device-type="currentDeviceType" />
       <div v-else class="history-group">
         <div class="history-container">
           <groutHistory v-if="activeKey == 'monitor_history'" :device-type="currentDeviceType" :device-id="optionValue" ref="historyTable" class="vent-margin-t-20"/>
@@ -35,10 +39,12 @@
 
 <script setup lang="ts">
 import customHeader from '/@/views/vent/comment/components/customHeader.vue';
-import { ref, onMounted, onUnmounted, reactive, nextTick, toRaw } from 'vue';
+import { ref, onMounted, onUnmounted, reactive, toRaw } from 'vue';
 import { list } from './grout.api';
 import BottomMenu from '/@/views/vent/comment/components/bottomMenu.vue';
 import groutHome from './components/groutHome.vue';
+import groutHomeJj from './components/groutHomeJj.vue';
+import groutHomeDlt from './components/groutHomeDlt.vue';
 import groutHistory from './components/groutHistory.vue';
 import groutHandleHistoryVue from './components/groutHandleHistory.vue';
 import groutAlarmHistory from './components/groutAlarmHistory.vue';

+ 879 - 0
src/views/vent/monitorManager/nitrogen/components/nitrogenHomeBLT.vue

@@ -0,0 +1,879 @@
+<template>
+  <div id="compressor3D" style="width: 100%; height: 100%; position: absolute; overflow: hidden"></div>
+  <template v-for="(sysItem, sysIndex) in monitorDataGroupArr" :key="sysIndex">
+    <div
+      :id="`compressorCss3D${sysIndex + 1}`"
+      class="threejs-Object-CSS compressorCss3D-box"
+      style="width: 100%; height: 100%; position: absolute; pointer-events: none; overflow: hidden; z-index: 2; top: 0px; left: 0px"
+    >
+    </div>
+  </template>
+  <div v-for="(sysItem, sysIndex) in monitorDataGroupArr" :key="sysIndex">
+    <div v-show="monitorDataGroupFlag == sysIndex + 1" style="width: 100%; height: 100%; position: absolute; overflow: hidden; z-index: -1">
+      <div v-for="(groupNum, index) in sysItem" :key="index" class="modal-monitor">
+        <fourBorderBg :class="`kyj${groupNum}`" :id="`nitrogenMonitor${groupNum}`">
+          <div class="title">{{ kyjs[index] }} </div>
+          <template v-for="(preMonitor, preMonitorIndex) in preMonitorList" :key="preMonitorIndex">
+            <div v-if="preMonitor.code !== 'signal'" class="monitor-item">
+              <span class="monitor-title">{{ preMonitor.title }}:</span>
+              <span class="monitor-val"
+                ><span class="val">{{
+                  monitorData[preMonitor.code.replace(prefix[0], `${prefix[0]}${groupNum}`)]
+                    ? formatNum(monitorData[preMonitor.code.replace(prefix[0], `${prefix[0]}${groupNum}`)])
+                    : '-'
+                }}</span
+                ><span class="unit">{{ preMonitor.unit }}</span></span
+              >
+            </div>
+            <div v-else class="signal-item">
+              <div class="signal" v-for="(signal, childIndex) in preMonitor.child" :key="childIndex">
+                <span class="monitor-title">{{ signal.title }}</span>
+                <span
+                  :class="{
+                    'signal-round': true,
+                    'signal-round-run': signal.isWaring && monitorData[signal.code.replace(prefix[0], `${prefix[0]}${groupNum}`)] == '1',
+                    'signal-round-warning': !signal.isWaring && monitorData[signal.code.replace(prefix[0], `${prefix[0]}${groupNum}`)] == '1',
+                    'signal-round-gry': monitorData[signal.code.replace(prefix[0], `${prefix[0]}${groupNum}`)] != '1',
+                  }"
+                ></span>
+              </div>
+            </div>
+          </template>
+        </fourBorderBg>
+        <fourBorderBg :class="`cqg${groupNum}`" :id="`cqgMonitor${groupNum}`">
+          <div class="title">{{ cqgs[index] }}</div>
+          <template v-for="(cqgMonitor, cqgMonitorIndex) in cqgMonitorList" :key="cqgMonitorIndex">
+            <div class="monitor-item">
+              <span class="monitor-title">{{ cqgMonitor.title }}:</span>
+              <span class="monitor-val"
+                ><span class="val">{{
+                  monitorData[cqgMonitor.code.replace(prefix[0], `${prefix[1]}${groupNum}`)]
+                    ? formatNum(monitorData[cqgMonitor.code.replace(prefix[1], `${prefix[1]}${groupNum}`)])
+                    : '-'
+                }}</span
+                ><span class="unit">{{ cqgMonitor.unit }}</span></span
+              >
+            </div>
+          </template>
+        </fourBorderBg>
+      </div>
+    </div>
+  </div>
+  <div class="nitrogen-home">
+    <div style="position: absolute; color: #fff; top: 30px; pointer-events: auto; display: flex">
+      <div
+        v-for="(sysItem, sysIndex) in monitorDataGroupArr"
+        :key="sysIndex"
+        class="tab-button-box"
+        :class="{ 'tab-button-box-active': monitorDataGroupFlag == sysIndex + 1 }"
+        @click="setMonitorGroupNum(sysIndex + 1)"
+        >{{ monitorData['deviceType'] === 'forcFan_north' ? '北风井' : '南风井' }} (运行: <p style="padding: 0 5px"></p
+        ><span
+          :class="{
+            'signal-round': true,
+            'signal-round-run':
+              sysIndex + 1 == 1 ? sysStateList[sysIndex] && sysStateList[sysIndex].isRun : sysStateList1[sysIndex] && sysStateList1[sysIndex].isRun,
+            'signal-round-gry':
+              sysIndex + 1 == 1 ? sysStateList[sysIndex] && !sysStateList[sysIndex].isRun : sysStateList1[sysIndex] && !sysStateList1[sysIndex].isRun,
+          }"
+        ></span>
+        <p style="padding: 0 5px"></p>故障:<p style="padding: 0 5px"></p
+        ><span
+          :class="{
+            'signal-round': true,
+            'signal-round-warning':
+              sysIndex + 1 == 1 ? sysStateList[sysIndex] && sysStateList[sysIndex].fault : sysStateList1[sysIndex] && sysStateList1[sysIndex].fault,
+            'signal-round-gry':
+              sysIndex + 1 == 1 ? sysStateList[sysIndex] && !sysStateList[sysIndex].fault : sysStateList1[sysIndex] && !sysStateList1[sysIndex].fault,
+          }"
+        ></span
+        ><p style="padding: 0 5px"></p> )</div
+      >
+    </div>
+    <div class="total-data">
+      <div class="vent-flex-row">
+        <div class="item" v-for="(data, index) in totalData" :key="index"
+          >{{ data.title + '(' + data.unit + ')' }}:<span class="val">{{
+            monitorData[data.code] ? formatNum(monitorData[data.code]) : '-'
+          }}</span></div
+        >
+      </div>
+    </div>
+    <div class="nitrogen-container">
+      <div v-if="monitorData['netStatus'] == 0" class="device-state">网络断开</div>
+      <div class="top-box">
+        <!-- 左边监测数据 -->
+        <div class="lr-box left-right-box">
+          <div class="lr-container">
+            <div class="item item-l" v-for="(groupNum, index) in monitorDataGroup" :key="index">
+              <div class="monitor-box" v-if="groupNum !== 3">
+                <ventBox1>
+                  <template #title>
+                    <div>{{ groupNum }}号压风机</div>
+                  </template>
+                  <template #container>
+                    <div class="state-item">
+                      <div class="item-col" v-for="(preFan, preFanIndex) in preFanMonitorData" :key="preFanIndex">
+                        <span class="state-title">{{ preFan.title + (preFan.unit !== 'signal' ? `(${preFan.unit})` : '') }}</span>
+                        <span v-if="preFan.unit !== 'signal'" class="state-val">{{
+                          monitorData[preFan.code.replace(prefix[2], prefix[2] + groupNum)] >= 0
+                            ? formatNum(Number(monitorData[preFan.code.replace(prefix[2], prefix[2] + groupNum)]))
+                            : '-'
+                        }}</span>
+                        <span
+                          v-else
+                          :class="{
+                            'signal-round': true,
+                            'signal-round-warning': monitorData[preFan.code.replace(prefix[2], `${prefix[2]}${groupNum}`)] == '1',
+                            'signal-round-gry': monitorData[preFan.code.replace(prefix[2], `${prefix[2]}${groupNum}`)] != '1',
+                          }"
+                        ></span>
+                      </div>
+                    </div>
+                  </template>
+                </ventBox1>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="lr-box left-right-box" style="margin-top: 80px">
+          <div class="lr-container">
+            <div class="item item-l" v-for="(groupNum, index) in monitorDataGroup" :key="index">
+              <div class="monitor-box" v-if="groupNum === 3">
+                <ventBox1>
+                  <template #title>
+                    <div>{{ groupNum }}号压风机</div>
+                  </template>
+                  <template #container>
+                    <div class="state-item">
+                      <div class="item-col" v-for="(preFan, preFanIndex) in preFanMonitorData" :key="preFanIndex">
+                        <span class="state-title">{{ preFan.title + (preFan.unit !== 'signal' ? `(${preFan.unit})` : '') }}</span>
+                        <span v-if="preFan.unit !== 'signal'" class="state-val">{{
+                          monitorData[preFan.code.replace(prefix[2], prefix[2] + groupNum)] >= 0
+                            ? formatNum(Number(monitorData[preFan.code.replace(prefix[2], prefix[2] + groupNum)]))
+                            : '-'
+                        }}</span>
+                        <span
+                          v-else
+                          :class="{
+                            'signal-round': true,
+                            'signal-round-warning': monitorData[preFan.code.replace(prefix[2], `${prefix[2]}${groupNum}`)] == '1',
+                            'signal-round-gry': monitorData[preFan.code.replace(prefix[2], `${prefix[2]}${groupNum}`)] != '1',
+                          }"
+                        ></span>
+                      </div>
+                    </div>
+                  </template>
+                </ventBox1>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup name="nitrogenHome">
+  import { onMounted, onUnmounted, ref } from 'vue';
+  import fourBorderBg from '../../../comment/components/fourBorderBg.vue';
+  import { mountedThree, destroy, setModelType } from '../nitrogen.threejs';
+  import { list } from '../nitrogen.api';
+  import ventBox1 from '/@/components/vent/ventBox1.vue';
+  // 补连塔
+  import { monitorDataGroupArr, prefix, getMonitorProperty, getSysState, getSysState1 } from '../nitrogen.dataBLT';
+  import type { State } from '../nitrogen.dataBLT';
+
+  import { formatNum } from '/@/utils/ventutil';
+
+  const loading = ref(true);
+  const monitorDataGroupFlag = ref(0);
+  const monitorDataGroup = ref<Number[]>([]);
+  const kyjs = ref<string[]>([]);
+  const cqgs = ref<string[]>([]);
+  const monitorData = ref<Object | []>({});
+  const sysStateList = ref<State[]>([]);
+  const sysStateList1 = ref<State[]>([]);
+  let preFanMonitorData, preMonitorList, cqgMonitorList, totalData;
+
+  /// forcFan_north 北风井  /// forcFan_south 南风井
+
+  // https获取监测数据
+  let timer: null | NodeJS.Timeout = null;
+  async function getMonitor(flag?) {
+    if (Object.prototype.toString.call(timer) === '[object Null]') {
+      timer = await setTimeout(
+        async () => {
+          await getDataSource();
+          if (timer) {
+            timer = null;
+          }
+          await getMonitor(false);
+        },
+        flag ? 0 : 1000
+      );
+    }
+  }
+
+  async function getDataSource() {
+    const res = await list({ devicetype: 'forcFan', pagetype: 'normal' });
+    if (res.msgTxt[0] && res.msgTxt[0].datalist && res.msgTxt[0].datalist.length > 0) {
+      let dataSource;
+      let dataSourceNorth = res.msgTxt[0].datalist.find((item) => item.deviceType === 'forcFan_north');
+      let dataSourceSouth = res.msgTxt[0].datalist.find((item) => item.deviceType === 'forcFan_south');
+      if (monitorDataGroupFlag.value == 1) {
+        // 北风井
+        dataSource = dataSourceNorth;
+        if (dataSource) {
+          monitorData.value = Object.assign(dataSource, dataSource.readData);
+        }
+      } else if (monitorDataGroupFlag.value == 2) {
+        // 南风井
+        dataSource = dataSourceSouth;
+        if (dataSource) {
+          monitorData.value = Object.assign(dataSource, dataSource.readData);
+        }
+      } else {
+      }
+      sysStateList.value = getSysState(Object.assign(dataSourceNorth, dataSourceNorth.readData));
+      sysStateList1.value = getSysState1(Object.assign(dataSourceSouth, dataSourceSouth.readData));
+    }
+    loading.value = false;
+  }
+
+  function setMonitorGroupNum(flag) {
+    monitorDataGroupFlag.value = flag;
+    const monitorGroup = monitorDataGroupArr[flag - 1];
+    changeGroup(monitorGroup);
+    setModelType('compressor' + (flag - 1));
+    monitorDataGroup.value = monitorGroup;
+    getMonitorPro(flag);
+  }
+
+  function changeGroup(val) {
+    kyjs.value = val.map((item) => `${item}号空压机`);
+    cqgs.value = val.map((item) => `${item}号储气罐`);
+    monitorData.value = new Array(val.length).fill({
+      strName: '空压机',
+      compressGroupName: '',
+      compressExhaustPressF1: '-',
+      compressSeparatePressF1: '-',
+      compressHostTempF1: '-',
+      compressCrewTempF1: '-',
+      compressRunTimeF1: '-',
+      controlModel: 'LOC',
+    });
+  }
+
+  function getMonitorPro(type) {
+    const propertyObj = getMonitorProperty(type);
+    preFanMonitorData = propertyObj.preFanMonitorData;
+    preMonitorList = propertyObj.preMonitorList;
+    cqgMonitorList = propertyObj.cqgMonitorList;
+    totalData = propertyObj.totalData;
+  }
+
+  onMounted(async () => {
+    mountedThree(monitorDataGroupArr).then(async () => {
+      await getMonitor(true);
+      monitorDataGroupFlag.value = 1;
+      setMonitorGroupNum(1);
+      getMonitorPro(1);
+    });
+  });
+
+  onUnmounted(() => {
+    destroy();
+    if (timer) {
+      clearTimeout(timer);
+      timer = undefined;
+    }
+  });
+</script>
+
+<style lang="less" scoped>
+  @ventSpace: zxm;
+
+  .nitrogen-home {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: center;
+    position: relative;
+    .total-data {
+      position: absolute;
+      color: #e4cd00;
+      z-index: 9;
+      top: 50px;
+      right: 30px;
+      // display: flex;
+      font-size: 18px;
+      .item {
+        width: 200px;
+        margin-left: 30px;
+        .val {
+          color: #00d8ff;
+        }
+      }
+    }
+  }
+
+  .compressorCss3D-box {
+    .modal-monitor {
+      position: absolute;
+      left: 0px;
+      top: 0px;
+    }
+
+    &:deep(.win) {
+      margin: 0 !important;
+      background: #00000044;
+    }
+
+    &:deep(.main) {
+      .title {
+        height: 34px;
+        text-align: center;
+        font-weight: 600;
+        color: #7af5ff;
+        // background-image: url('../../../assets/img/yfj/light.png');
+        background-repeat: no-repeat;
+        background-position-x: center;
+        background-position-y: 100%;
+        background-size: 80%;
+        font-size: 16px;
+      }
+
+      .monitor-item {
+        display: flex;
+        flex-direction: row;
+        width: auto;
+        margin-bottom: 3px;
+        .monitor-val {
+          color: #ffb700;
+          display: flex;
+          width: auto;
+
+          .val {
+            width: 80px;
+            font-size: 14px;
+          }
+
+          .unit {
+            color: #ffffffbb;
+            font-size: 14px;
+          }
+        }
+      }
+
+      .monitor-title {
+        width: 100px;
+        color: #7af5ff;
+        font-weight: 400;
+        font-size: 14px;
+      }
+
+      .signal-item {
+        display: flex;
+        justify-content: space-between;
+
+        // margin-bottom: 5px;
+        .signal-round {
+          display: inline-block;
+          width: 8px;
+          height: 8px;
+          border-radius: 50%;
+          margin: 0 10px;
+          position: relative;
+
+          &::after {
+            display: block;
+            content: '';
+            position: absolute;
+            width: 12px;
+            height: 12px;
+            top: -2px;
+            left: -2px;
+            border-radius: 50%;
+          }
+        }
+
+        .signal-round-gry {
+          background-color: #858585;
+
+          &::after {
+            background-color: #85858544;
+            box-shadow: 0 0 1px 1px #85858599;
+          }
+        }
+
+        .signal-round-run {
+          background-color: #67fc00;
+
+          &::after {
+            background-color: #67fc0044;
+            box-shadow: 0 0 1px 1px #c6ff77;
+          }
+        }
+
+        .signal-round-warning {
+          background-color: #e9170b;
+
+          &::after {
+            background-color: #e9170b44;
+            box-shadow: 0 0 1px 1px #e9170b;
+          }
+        }
+      }
+    }
+  }
+
+  .nitrogen-home {
+    width: 100%;
+    height: calc(100% - 100px);
+    position: fixed;
+    z-index: 99;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    pointer-events: none;
+    top: 60px;
+    .nitrogen-container {
+      width: 100%;
+      height: calc(100%);
+      display: flex;
+      justify-content: space-between;
+      margin-bottom: 100px;
+      position: relative;
+      .device-state {
+        width: 100%;
+        position: absolute;
+        top: 20px;
+        color: #e90000;
+        display: flex;
+        justify-content: center;
+        font-size: 20px;
+      }
+      .top-box {
+        width: 100%;
+        padding: 10px;
+        overflow: hidden;
+        display: flex;
+        justify-content: space-between;
+
+        .lr-box {
+          display: flex;
+          flex-direction: column;
+          position: relative;
+          z-index: 9999;
+          pointer-events: auto;
+        }
+
+        .item {
+          width: 285px;
+          height: auto;
+          position: relative;
+          border-radius: 5px;
+          margin-top: 10px;
+          margin-bottom: 0px;
+          pointer-events: auto;
+          color: #fff;
+          overflow: hidden;
+
+          .control-item {
+            height: auto;
+            min-height: 35px;
+            display: flex;
+            flex-direction: row;
+            justify-content: space-between;
+            align-items: center;
+            padding: 5px;
+            margin: 0 10px 0 3px;
+            pointer-events: auto;
+            background: linear-gradient(to right, #0063cd22, #0063cd04);
+
+            margin-bottom: 5px;
+            border-width: 1px;
+            border-style: dashed;
+
+            border-image: linear-gradient(to right, #008ccd66, #0063cd04) 1 1;
+            border-radius: 5px;
+
+            &:last-child {
+              margin-bottom: 0;
+            }
+
+            .control-item-l {
+              display: flex;
+              align-items: center;
+              font-size: 14px;
+
+              .round {
+                display: inline-block;
+                width: 3px;
+                height: 3px;
+                padding: 1px;
+                border-radius: 50%;
+                background-color: #3df6ff;
+                margin-right: 5px;
+                box-shadow: 0 0 1px 1px #64f7ff;
+              }
+            }
+
+            .control-item-r {
+              text-align: right;
+            }
+
+            .button-box {
+              position: relative;
+              padding: 5px;
+              border: 1px transparent solid;
+              background-clip: border-box;
+              border-radius: 5px;
+              margin-left: 8px;
+            }
+
+            .a-button {
+              pointer-events: auto;
+            }
+
+            &::v-deep .a-button--mini {
+              padding: 6px 10px;
+            }
+
+            &::v-deep .a-button--mini.is-round {
+              padding: 6px 10px;
+            }
+          }
+
+          .base-title {
+            width: calc(100% - 60px);
+            text-align: center;
+            color: #00d8ff;
+          }
+
+          .state-item {
+            width: 100%;
+            display: flex;
+            flex-direction: row;
+
+            flex-wrap: wrap;
+            .item-col {
+              width: 50%;
+              display: flex;
+              justify-content: center;
+              align-items: center;
+              padding: 5px;
+              .state-title {
+                color: #ffffffcc;
+                flex: 9;
+                font-size: 14px;
+
+                .unit {
+                  // color: #ffffffbb;
+                }
+              }
+
+              .state-val {
+                flex: 1;
+                color: #e4a300;
+                margin-right: 5px;
+                text-align: right;
+                font-size: 14px;
+              }
+            }
+          }
+
+          .signal-box {
+            margin: 5px 0;
+            display: flex;
+            align-items: center;
+
+            .signal-title {
+              color: #7af5ff;
+              margin: 0 5px;
+            }
+
+            &:last-child {
+              margin-right: 0px;
+            }
+          }
+
+          .list-item {
+            padding: 0 10px;
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+
+            .item-data-key {
+              color: #ffffff99;
+            }
+          }
+
+          .item-data-box {
+            color: #fff;
+
+            .state-icon {
+              display: inline-block;
+              width: 12px;
+              height: 12px;
+              border-radius: 12px;
+            }
+
+            .open {
+              border: 5px solid #133a56;
+              background: #4ecb73;
+            }
+
+            .close {
+              border: 5px solid #192961;
+              background: #6d7898;
+            }
+          }
+        }
+
+        .item-l {
+          width: 335px;
+
+          .monitor-box {
+            // width: 335px;
+            background-color: #ffffff05;
+            // margin-left: 2px;
+            // border-radius: 5px;
+            // backdrop-filter: blur(10px);
+          }
+        }
+
+        .right-box {
+          width: 330px;
+          .control-group {
+            display: flex;
+            // justify-content: space-around;
+            flex-wrap: wrap;
+            .control-item {
+              display: flex;
+              flex-direction: column;
+              justify-content: center;
+              align-items: center;
+              padding: 0 4px;
+              .control-item-title {
+                color: #a6dce9;
+                position: relative;
+                top: 5px;
+              }
+              .control-item-state {
+                width: 94px;
+                height: 47px;
+                background: url('/@/assets/images/vent/control-switch-bg.png');
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                color: #fff;
+              }
+
+              .button-box {
+                position: relative;
+                padding: 5px;
+                border: 1px transparent solid;
+                background-clip: border-box;
+                border-radius: 5px;
+                margin-left: 8px;
+              }
+
+              .a-button {
+                pointer-events: auto;
+              }
+
+              &::v-deep .a-button--mini {
+                padding: 6px 10px;
+              }
+
+              &::v-deep .a-button--mini.is-round {
+                padding: 6px 10px;
+              }
+            }
+          }
+          .control-btn-group {
+            width: 100%;
+            display: flex;
+            flex-direction: row;
+            justify-content: space-between;
+            align-items: center;
+            .control-left-box {
+              display: flex;
+              flex-direction: column;
+              justify-content: center;
+              align-items: center;
+              padding: 0 20px;
+              .btn-box {
+                width: 100px;
+                color: #fff;
+                display: flex;
+                justify-content: space-between;
+                span {
+                  display: inline-block;
+                  padding: 2px 8px;
+                  background: #007099;
+                  border-radius: 4px;
+                  border: 1px solid rgb(125, 230, 249);
+                  cursor: pointer;
+                  &:hover {
+                    background: #005574;
+                  }
+                }
+              }
+              .icon-box {
+                width: 60px;
+                height: 60px;
+                border-radius: 30px;
+                border: 2px solid #00bcdd;
+                box-shadow: 0 0 20px #ffffff88;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                margin-top: 20px;
+
+                .icon {
+                  width: 18px;
+                  height: 18px;
+                  border-radius: 9px;
+                  border: 3px solid #d7f9ff;
+                  position: relative;
+                  background: #00bcdd;
+                  &::before {
+                    position: absolute;
+                    content: '';
+                    width: 2px;
+                    height: 12px;
+                    background-color: #00bcdd;
+                    left: 6px;
+                    top: -16px;
+                  }
+                  &::after {
+                    position: absolute;
+                    content: '';
+                    width: 2px;
+                    height: 12px;
+                    left: 6px;
+                    top: 17px;
+                    background-color: #00d9ff;
+                  }
+                }
+              }
+              .remote-icon-box {
+                transform: rotate(30deg);
+                animation: iconRotate 1s linear;
+              }
+              .remote-icon-box1 {
+                transform: rotate(-30deg);
+                animation: iconRotate1 1s linear;
+              }
+
+              @keyframes iconRotate {
+                from {
+                  transform: rotate(-30deg);
+                }
+                to {
+                  transform: rotate(30deg);
+                }
+              }
+              @keyframes iconRotate1 {
+                from {
+                  transform: rotate(30deg);
+                }
+                to {
+                  transform: rotate(-30deg);
+                }
+              }
+            }
+            .control-right-box {
+              width: 100px;
+              color: #fff;
+              height: 80px;
+              justify-content: space-between;
+              align-items: center;
+              .btn {
+                margin-bottom: 30px;
+              }
+            }
+          }
+        }
+
+        .left-right-box {
+          height: calc(100%);
+          overflow-x: hidden;
+          overflow-y: auto;
+          pointer-events: auto;
+          direction: rtl;
+          .lr-container {
+            direction: ltr;
+          }
+          .control-item {
+            height: 36px;
+          }
+        }
+      }
+    }
+  }
+  .tab-button-box {
+    display: inline-block;
+    position: relative;
+    padding: 5px;
+    // border: 1px transparent solid;
+    border-radius: 5px;
+    margin-left: 8px;
+    margin-right: 8px;
+    width: auto;
+    // height: 40px;
+    // border: 1px solid #65dbea;
+    height: 35px !important;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: #fff;
+    padding: 0 15px 5px 15px;
+    cursor: pointer;
+    &:hover {
+      background: linear-gradient(#2cd1ff55, #1eb0ff55);
+    }
+    &::before {
+      width: calc(100% - 6px);
+      height: 27px;
+      content: '';
+      position: absolute;
+      top: 3px;
+      right: 0;
+      left: 3px;
+      bottom: 0;
+      z-index: -1;
+      border-radius: inherit; /*important*/
+      background: linear-gradient(#1fa6cb, #127cb5);
+    }
+    &::after {
+      width: calc(100% + 32px);
+      height: 10px;
+      content: '';
+      position: absolute;
+      top: 28px;
+      right: 0;
+      left: -16px;
+      bottom: 0;
+      z-index: -1;
+      border-radius: inherit; /*important*/
+      background: url('/@/assets/images/vent/short-light.png') no-repeat;
+      background-position: center;
+      background-size: 100%;
+      z-index: 999;
+    }
+  }
+
+  .tab-button-box-active {
+    border: 1px solid #66989e !important;
+    &:hover {
+      background: none !important;
+    }
+    &::before {
+      background: linear-gradient(#1fa6cbcc, #127cb5cc) !important;
+    }
+  }
+</style>

+ 5 - 7
src/views/vent/monitorManager/nitrogen/index.vue

@@ -1,12 +1,10 @@
 <template>
   <div class="nitrogen-box">
     <customHeader>智能压风管控系统</customHeader>
-    <!-- 锦界 -->
-    <!-- <nitrogenHome v-if="btnActive == 'nitrogen_page'" /> -->
     <!-- 布尔台 -->
-    <nitrogenHome1 v-if="btnActive == 'nitrogen_page'" />
+    <!-- <nitrogenHome1 v-if="btnActive == 'nitrogen_page'" /> -->
     <!-- 补连塔 -->
-    <!-- <nitrogenHomeBLT v-if="btnActive == 'nitrogen_page'" /> -->
+    <nitrogenHomeBLT v-if="btnActive == 'nitrogen_page'" />
     <nitrogenEcharts v-if="btnActive == 'yfj_monitor_echarts'" />
     <nitrogenHistory v-if="btnActive == 'yfj_history'" />
     <nitrogenHandleHistory v-if="btnActive == 'yfj_handler_history'" />
@@ -17,9 +15,9 @@
 <script lang="ts" setup>
   import { ref } from 'vue';
   // import nitrogenHome from './components/nitrogenHome.vue';
-  import nitrogenHome1 from './components/nitrogenHome1.vue';
-  // import nitrogenHomeBLT from './components/nitrogenHomeBLT.vue';
-  // import nitrogenHomeYJ from './components/nitrogenHomeYJ.vue';
+  // import nitrogenHome1 from './components/nitrogenHome1.vue';
+  import nitrogenHomeBLT from './components/nitrogenHomeBLT.vue'; //补连塔
+  // import nitrogenHomeYJ from './components/nitrogenHomeYJ.vue'; //
   import nitrogenEcharts from './components/nitrogenEcharts.vue';
   import nitrogenHistory from './components/nitrogenHistory.vue';
   import nitrogenHandleHistory from './components/nitrogenHandleHistory.vue';

+ 416 - 0
src/views/vent/monitorManager/nitrogen/nitrogen.dataBLT.ts

@@ -0,0 +1,416 @@
+import { ref } from 'vue';
+export const monitorDataGroupArr = [
+  [1, 2],
+  [1, 2, 3],
+];
+export const prefix = ['PRE', 'PRE', 'PRE'];
+export const bottomBtnList = ref([
+  {
+    text: '监控界面',
+    value: 'nitrogenMonitor',
+    isHover: false,
+  },
+  {
+    text: '关键节点监测',
+    value: 'nitrogenNode',
+    isHover: false,
+  },
+  {
+    text: '实时曲线',
+    value: 'nitrogenEcharts',
+    isHover: false,
+  },
+  {
+    text: '压风机历史记录',
+    value: 'nitrogenHistory',
+    isHover: false,
+  },
+  {
+    text: '操作历史记录',
+    value: 'nitrogenHandleHistory',
+    isHover: false,
+  },
+  {
+    text: '故障诊断历史记录',
+    value: 'nitrogenWarningHistory',
+    isHover: false,
+  },
+]);
+export type State = {
+  isRun: boolean;
+  fault: boolean;
+};
+const preMonitorList = [
+  {
+    title: '进气压力',
+    code: 'PRE_CPR_InletPre',
+    unit: 'bar',
+    child: [],
+  },
+  {
+    title: '排气压力',
+    code: 'PRE_CPR_ExhaustPre',
+    unit: 'bar',
+    child: [],
+  },
+  {
+    code: 'signal',
+    child: [
+      {
+        title: `故障信号`,
+        code: `PRE_FaultSignal`,
+        isWaring: true,
+      },
+      {
+        title: `故障信号1`,
+        code: `PRE_FaultSignal1`,
+        isWaring: true,
+      },
+    ],
+  },
+  {
+    code: 'signal',
+    child: [
+      {
+        title: `运行信号`,
+        code: `PRE_CPR_LoadorUnload`,
+        isWaring: false,
+      },
+      {
+        title: `主机本机`,
+        code: `PRE_HostorLoc`,
+        isWaring: false,
+      },
+    ],
+  },
+  {
+    code: 'signal',
+    child: [
+      {
+        title: `A相绕组超温`,
+        code: `PRE_MOT_PhaseAOverTemp`,
+        isWaring: true,
+      },
+      {
+        title: `B相绕组超温`,
+        code: `PRE_MOT_PhaseBOverTemp`,
+        isWaring: true,
+      },
+    ],
+  },
+  {
+    code: 'signal',
+    child: [
+      {
+        title: `C相绕组超温`,
+        code: `PRE1_MOT_PhaseCOverTemp`,
+        isWaring: true,
+      },
+    ],
+  },
+];
+const cqgMonitorList = [
+  {
+    title: `气囊温度`,
+    code: `PRE_VLS_Temp`,
+    unit: '℃',
+    child: [],
+  },
+];
+
+const preFanMonitorData = [
+  {
+    title: '加载压力',
+    code: 'PRE_CPR_LoadPre',
+    unit: 'bar',
+  },
+  {
+    title: '卸载压力',
+    code: 'PRE_CPR_UnLoadPre',
+    unit: 'bar',
+  },
+  {
+    title: `机头温度`,
+    code: `PRE_CPR_HeadTemp`,
+    unit: '℃',
+  },
+  {
+    title: `冷却温度`,
+    code: `PRE_CPR_CoolantTemp`,
+    unit: '℃',
+  },
+  {
+    title: `排气温度`,
+    code: `PRE_CPR_ExhaustTemp`,
+    unit: '℃',
+  },
+  {
+    title: '加载时间',
+    code: 'PRE_CPR_LoadTime',
+    unit: 'h',
+  },
+  {
+    title: '总运行时间',
+    code: 'PRE_MOT_TotalRunTime',
+    unit: 'h',
+  },
+  {
+    title: 'A相绕组温度',
+    code: 'PRE_MOT_PhaseATemp',
+    unit: '℃',
+  },
+  {
+    title: 'B相绕组温度',
+    code: 'PRE_MOT_PhaseBTemp',
+    unit: '℃',
+  },
+  {
+    title: 'C相绕组温度',
+    code: 'PRE_MOT_PhaseCTemp',
+    unit: '℃',
+  },
+];
+const totalData = [
+  {
+    title: '总进风管流量',
+    code: 'TotalInPipeFlow',
+    unit: 'm³/h',
+  },
+  {
+    title: '总出风管压力',
+    code: 'TotalOutPipePre',
+    unit: 'bar',
+  },
+];
+export function getSysState(monitorData) {
+  const stateArr = <State[]>[];
+  monitorDataGroupArr.forEach((group) => {
+    const stateObj = { isRun: false, fault: false };
+    group.forEach((item) => {
+      if (monitorData['PRE_CPR_LoadorUnload'.replace('PRE', 'PRE' + item)]) {
+        stateObj.isRun = monitorData['PRE_CPR_LoadorUnload'.replace('PRE', 'PRE' + item)] == '1';
+      }
+
+      if (
+        monitorData['PRE_FaultSignal'.replace('PRE', 'PRE' + item)] ||
+        monitorData['PRE_FaultSignal1'.replace('PRE', 'PRE' + item)] ||
+        monitorData['PRE_MOT_PhaseAOverTemp'.replace('PRE', 'PRE' + item)] ||
+        monitorData['PRE_MOT_PhaseBOverTemp'.replace('PRE', 'PRE' + item)] ||
+        monitorData['PRE_MOT_PhaseCOverTemp'.replace('PRE', 'PRE' + item)]
+      ) {
+        stateObj.fault = true;
+      }
+    });
+    stateArr.push(stateObj);
+  });
+  return stateArr;
+}
+
+const preMonitorList1 = [
+  {
+    title: '出口压力',
+    code: 'PRE_ExitPressure',
+    unit: 'bar',
+    child: [],
+  },
+  {
+    title: '排气压力',
+    code: 'PRE_CPR_ExhaustPre',
+    unit: 'bar',
+    child: [],
+  },
+  {
+    code: 'signal',
+    child: [
+      {
+        title: `故障信号`,
+        code: `PRE_FaultSignal`,
+        isWaring: true,
+      },
+      {
+        title: `运行信号`,
+        code: `PRE_CPR_LoadorUnload`,
+        isWaring: false,
+      },
+    ],
+  },
+  {
+    code: 'signal',
+    child: [
+      {
+        title: `前轴高温报警`,
+        code: `PRE_MOT_FrontAxleOverTempAlam`,
+        isWaring: true,
+      },
+      {
+        title: `后轴高温报警`,
+        code: `PRE_MOT_BackAxleOverTempAlam`,
+        isWaring: true,
+      },
+    ],
+  },
+  {
+    code: 'signal',
+    child: [
+      {
+        title: `A相绕组超温`,
+        code: `PRE_MOT_PhaseAOverTemp`,
+        isWaring: true,
+      },
+      {
+        title: `B相绕组超温`,
+        code: `PRE_MOT_PhaseBOverTemp`,
+        isWaring: true,
+      },
+    ],
+  },
+  {
+    code: 'signal',
+    child: [
+      {
+        title: `C相绕组超温`,
+        code: `PRE1_MOT_PhaseCOverTemp`,
+        isWaring: true,
+      },
+    ],
+  },
+];
+const cqgMonitorList1 = [
+  {
+    title: `气囊温度`,
+    code: `PRE_VLS_Temp`,
+    unit: '℃',
+    child: [],
+  },
+];
+
+const preFanMonitorData1 = [
+  {
+    title: '加载压力',
+    code: 'PRE_CPR_LoadPre',
+    unit: 'bar',
+  },
+  {
+    title: '卸载压力',
+    code: 'PRE_CPR_UnLoadPre',
+    unit: 'bar',
+  },
+  {
+    title: `机头温度`,
+    code: `PRE_CPR_HeadTemp`,
+    unit: '℃',
+  },
+  {
+    title: `冷却温度`,
+    code: `PRE_CPR_CoolantTemp`,
+    unit: '℃',
+  },
+  {
+    title: `排气温度`,
+    code: `PRE_CPR_ExhaustTemp`,
+    unit: '℃',
+  },
+  {
+    title: '加载时间',
+    code: 'PRE_CPR_LoadTime',
+    unit: 'h',
+  },
+  {
+    title: '总运行时间',
+    code: 'PRE_MOT_TotalRunTime',
+    unit: 'h',
+  },
+  {
+    title: 'A相绕组温度',
+    code: 'PRE_MOT_PhaseATemp',
+    unit: '℃',
+  },
+  {
+    title: 'B相绕组温度',
+    code: 'PRE_MOT_PhaseBTemp',
+    unit: '℃',
+  },
+  {
+    title: 'C相绕组温度',
+    code: 'PRE_MOT_PhaseCTemp',
+    unit: '℃',
+  },
+  {
+    title: '前轴温度',
+    code: 'PRE_MOT_FrontAxleTemp',
+    unit: '℃',
+  },
+  {
+    title: '后轴温度',
+    code: 'PRE_MOT_BackAxleTemp',
+    unit: '℃',
+  },
+  {
+    title: 'A相温度停机报警',
+    code: 'PRE_MOT_PhaseATempStop',
+    unit: 'signal',
+  },
+  {
+    title: 'B相温度停机报警',
+    code: 'PRE_MOT_PhaseBTempStop',
+    unit: 'signal',
+  },
+  {
+    title: 'C相温度停机报警',
+    code: 'PRE_MOT_PhaseCTempStop',
+    unit: 'signal',
+  },
+  {
+    title: '前轴高温停机',
+    code: 'PRE_MOT_FrontAxleOverTempStop',
+    unit: 'signal',
+  },
+  {
+    title: '后轴高温停机',
+    code: 'PRE_MOT_BackAxleOverTempStop',
+    unit: 'signal',
+  },
+];
+
+export function getSysState1(monitorData) {
+  const stateArr = <State[]>[];
+  monitorDataGroupArr.forEach((group) => {
+    const stateObj = { isRun: false, fault: false };
+    group.forEach((item) => {
+      if (monitorData['PRE_CPR_LoadorUnload'.replace('PRE', 'PRE' + item)]) {
+        stateObj.isRun = monitorData['PRE_CPR_LoadorUnload'.replace('PRE', 'PRE' + item)] == '1';
+      }
+      if (
+        monitorData['PRE_FaultSignal'.replace('PRE', 'PRE' + item)] ||
+        monitorData['PRE_FaultSignal1'.replace('PRE', 'PRE' + item)] ||
+        monitorData['PRE_MOT_PhaseAOverTemp'.replace('PRE', 'PRE' + item)] ||
+        monitorData['PRE_MOT_PhaseBOverTemp'.replace('PRE', 'PRE' + item)] ||
+        monitorData['PRE_MOT_PhaseCOverTemp'.replace('PRE', 'PRE' + item)] ||
+        monitorData['PRE_MOT_PhaseATempStop'.replace('PRE', 'PRE' + item)] ||
+        monitorData['PRE_MOT_PhaseBTempStop'.replace('PRE', 'PRE' + item)] ||
+        monitorData['PRE_MOT_PhaseCTempStop'.replace('PRE', 'PRE' + item)] ||
+        monitorData['PRE_MOT_FrontAxleOverTempAlam'.replace('PRE', 'PRE' + item)] ||
+        monitorData['PRE_MOT_BackAxleOverTempAlam'.replace('PRE', 'PRE' + item)] ||
+        monitorData['PRE_MOT_FrontAxleOverTempStop'.replace('PRE', 'PRE' + item)] ||
+        monitorData['PRE_MOT_BackAxleOverTempStop'.replace('PRE', 'PRE' + item)]
+      ) {
+        stateObj.fault = true;
+      }
+    });
+    stateArr.push(stateObj);
+  });
+  return stateArr;
+}
+
+export function getMonitorProperty(type) {
+  if (type == 1) {
+    return { preMonitorList, cqgMonitorList, preFanMonitorData, totalData };
+  } else {
+    return {
+      preMonitorList: preMonitorList1,
+      cqgMonitorList: cqgMonitorList1,
+      preFanMonitorData: preFanMonitorData1,
+      totalData: totalData,
+    };
+  }
+}

+ 10 - 5
src/views/vent/monitorManager/workFaceMonitor/index.vue

@@ -5,7 +5,7 @@
     style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; overflow: hidden">
     <a-spin :spinning="loading" />
     
-    <div id="workFace3D" style="width: 100%; height: 100%; position: absolute; overflow: hidden"> </div>
+    <div id="workFace3D" style="width: 100%; height: 100%; position: absolute; overflow: hidden; z-index: 1; top: 0"> </div>
     <div
           id="workFace3DCSS"
           class="threejs-Object-CSS"
@@ -47,7 +47,7 @@
 
 <script setup lang="ts">
 import { onBeforeMount, ref, onMounted, onUnmounted, nextTick } from 'vue';
-import { mountedThree, destroy, setModelType, clearCss3D } from './wokeFace.threejs';
+import { mountedThree, destroy, setModelType, clearCss3D, showOrHideGasPlane } from './wokeFace.threejs';
 import { getTableList, systemList } from './workFace.api';
 import { monitorNav } from './workFace.data'
 import customHeader from '/@/views/vent/comment/components/customHeader.vue';
@@ -93,7 +93,6 @@ function changeActive(activeValue) {
   loading.value = true
   if(activeKey.value === 'monitor'){
     gasUnitNum.value = Math.ceil(Math.random() * 10)
-    setModelType(modalType, gasUnitNum.value)
     setTimeout(() =>{
       loading.value = false
     }, 600)
@@ -102,6 +101,9 @@ function changeActive(activeValue) {
     loading.value = false
     clearCss3D()
   }
+  nextTick(() => {
+    setModelType(modalType, gasUnitNum.value, monitorActive.value == 4 ? true : false)
+  })
 }
 
 function deviceChange(index) {
@@ -170,7 +172,7 @@ function changeModalType(currentData) {
     modalType = 'workFace4'
   }
   gasUnitNum.value = Math.ceil(Math.random() * 10)
-  setModelType(modalType, gasUnitNum.value)
+  setModelType(modalType, gasUnitNum.value, monitorActive.value == 4 ? true : false)
 }
 
 function changeMonitor(nav) {
@@ -185,6 +187,7 @@ function changeMonitor(nav) {
       }
     }
   })
+  showOrHideGasPlane(monitorActive.value == 4 ? true : false)
 }
 
 onBeforeMount(() => {
@@ -197,8 +200,10 @@ onMounted(async() => {
   loading.value = true;
   mountedThree().then(async () => {
     gasUnitNum.value = Math.ceil(Math.random() * 10)
-    setModelType(modalType, gasUnitNum.value)
     loading.value = false;
+    nextTick(() => {
+      setModelType(modalType, gasUnitNum.value, monitorActive.value == 4 ? true : false)
+    })
   });
 });
 

+ 15 - 3
src/views/vent/monitorManager/workFaceMonitor/wokeFace.threejs.ts

@@ -60,7 +60,7 @@ export const clearCss3D = () => {
 };
 
 // 切换风窗类型
-export const setModelType = (type, n = Math.ceil(Math.random() * 10)) => {
+export const setModelType = (type, n = Math.ceil(Math.random() * 10), isShowPlane) => {
   fiberType = type;
   return new Promise((resolve) => {
     if (workFaceObj) {
@@ -68,8 +68,10 @@ export const setModelType = (type, n = Math.ceil(Math.random() * 10)) => {
       group = workFaceObj.group;
 
       workFaceObj.setModalType(type);
-      // 判断模型类型
+      workFaceObj?.setPlanes(n);
+      showOrHideGasPlane(isShowPlane);
       if (type == 'workFace1') {
+        // 判断模型类型
         var oldControlsPosition = { x: 0.055, y: 0.062, z: 0.117 };
         var oldCameraPosition = { x: 0.055, y: 0.062, z: 0.117 };
         var newCameraPosition = { x: -0.17182200678070425, y: 1.7188311320712673, z: 1.787394450495768 };
@@ -99,13 +101,23 @@ export const setModelType = (type, n = Math.ceil(Math.random() * 10)) => {
         if (!model.scene.getObjectByName('workFace')) {
           model.scene.add(workFaceObj?.group);
         }
-        workFaceObj?.setPlanes(n);
+
         await animateCamera(oldCameraPosition, oldControlsPosition, newCameraPosition, newControlsPosition, model, 0.8);
       }, 600);
     }
   });
 };
 
+export const showOrHideGasPlane = (isShowPlane) => {
+  if (workFaceObj) {
+    if (isShowPlane) {
+      workFaceObj.planeGroup.visible = true;
+    } else {
+      workFaceObj.planeGroup.visible = false;
+    }
+  }
+};
+
 export const mountedThree = () => {
   return new Promise(async (resolve) => {
     model = new UseThree('#workFace3D', '#workFace3DCSS');

+ 20 - 11
src/views/vent/monitorManager/workFaceMonitor/workFace.threejs.base.ts

@@ -18,6 +18,7 @@ class WorkFace {
   model;
   modelName = 'workFace';
   group: THREE.Object3D = new THREE.Object3D();
+  planeGroup: THREE.Group = new THREE.Group();
   bloomComposer: EffectComposer | null = null;
   finalComposer: EffectComposer | null = null;
   outlinePass: OutlinePass | null = null;
@@ -92,22 +93,17 @@ class WorkFace {
       plane.rotation.x = -Math.PI / 2;
       plane.scale.set(lenScale - 0.001, 0.375, 1.0);
       plane.position.set(0.282 - lenScale * (i - 0.5), 0.015, 0.142);
-      this.group.add(plane);
-      const label = setTag3D(`抽采单元${i + 1}`, 'gas_unit_text');
-      label.scale.set(0.0018, 0.0018, 1); //根据相机渲染范围控制HTML 3D标签尺寸
-      label.position.set(0.282 - lenScale * (i + 0.5), 0.015, 0.142);
-      label.name = 'planeText' + i;
-      this.group.add(label);
+      this.planeGroup.add(plane);
     }
   };
 
   // 清除抽采单元绘制面
   clearPlanes = () => {
     for (let i = 0; i < this.planeNum; i++) {
-      const plane = this.group.getObjectByName(`unit${i}`);
-      const label = this.group.getObjectByName(`planeText${i}`);
-      if (plane) this.group.remove(plane);
-      if (label) this.group.remove(label);
+      const plane = this.planeGroup.getObjectByName(`unit${i}`);
+      const label = this.planeGroup.getObjectByName(`planeText${i}`);
+      if (plane) this.planeGroup.remove(plane);
+      if (label) this.planeGroup.remove(label);
     }
   };
   // 抽采单元内容显示
@@ -124,6 +120,14 @@ class WorkFace {
         this.group.add(gasUnitCSS3D);
       }
     }
+    for (let i = 0; i < this.planeNum; i++) {
+      const lenScale = 0.77 / this.planeNum;
+      const label = setTag3D(`抽采单元${i + 1}`, 'gas_unit_text');
+      label.scale.set(0.0018, 0.0018, 1); //根据相机渲染范围控制HTML 3D标签尺寸
+      label.position.set(0.282 - lenScale * (i + 0.5), 0.015, 0.142);
+      label.name = 'planeText' + i;
+      this.planeGroup.add(label);
+    }
   };
   // 显示或隐藏抽采单元显示内容
   changeCss3D = (isHide) => {
@@ -142,6 +146,10 @@ class WorkFace {
     if (element) {
       element.remove();
     }
+    for (let i = 0; i < this.planeNum; i++) {
+      const label = this.planeGroup.getObjectByName(`planeText${i}`);
+      if (label) this.planeGroup.remove(label);
+    }
   };
 
   setRenderPass = () => {
@@ -374,7 +382,8 @@ class WorkFace {
       this.model.orbitControls.update();
       this.model.setGLTFModel(['workFace-base', 'workFace-jin', 'workFace-hui'], this.group).then(async () => {
         this.group.name = this.modelName;
-        this.setPlanes(7);
+        this.group.add(this.planeGroup);
+        this.planeGroup.visible = false;
         // this.group.position.set(-0.06, 0.28, 0.07);
         this.group.scale.set(2.5, 2.5, 2.5);
         // this.resetMesh();