Pārlūkot izejas kodu

Merge branch 'master' of http://47.94.222.6:3003/lizuo/VentSystem_2.0_front

lxh 1 gadu atpakaļ
vecāks
revīzija
adc7a5388d

+ 1 - 1
src/components/chart/BarAndLineCustom.vue

@@ -86,7 +86,7 @@
         //轴数据
         let xAxisData = Array.from(new Set(props.chartData.map((item) => item[props.xAxisPropType])));
         [...props.propTypeArr].forEach((filed:string, index) => {
-          option.series[index]['data'] = props.chartData.map((item:any) => item[filed]);
+          option.series[index]['data'] = props.chartData.map(item => item[filed]);
         });
         option.xAxis.data = xAxisData;
         setOptions(option, false);

+ 3 - 0
src/design/vent/comment.less

@@ -29,4 +29,7 @@
 }
 .vent-margin-t-20 {
   margin-top: 20px;
+}
+.vent-margin-t-10 {
+  margin-top: 10px;
 }

+ 1 - 1
src/views/vent/comment/components/customHeader.vue

@@ -4,7 +4,7 @@
       <Decoration5 class="header-icon" :dur="2" :color="['#21437F', '#2CF7FE']" style="width:500px;height:40px;" />
       <div class="header-text"><slot></slot></div>
     </div>
-    <div class = "container-title">
+    <div class = "container-title" v-if="fieldNames">
       <a-select
         class="title-select"
         ref="select"

+ 9 - 8
src/views/vent/monitorManager/chamberMonitor/chamber.data.ts

@@ -2,15 +2,16 @@ import { reactive } from 'vue';
 import { BasicColumn } from '/@/components/Table';
 
 export const warningConfig = reactive({
+  header: ['设备名称', '预警信息', '时间'],
   data: [
-    ['火焰6', '318℃', '严重报警', '03-05'],
-    ['测点43', '142℃', '一般预警', '03-05'],
-    ['CO23', '167℃', '一版预警', '03-05'],
-    ['测点6', '198℃', '超高预警', '03-05'],
-    ['测点65', '197℃', '超高预警', '03-05'],
-    ['温度4', '154℃', '一般预警', '03-05'],
-    ['测点61', '104℃', '一般预警', '03-05'],
-    ['测点87', '150℃', '一般信息', '03-05'],
+    ['火焰6', '严重报警', '03-05'],
+    ['测点43', '一般预警', '03-05'],
+    ['CO23', '一版预警', '03-05'],
+    ['测点6', '超高预警', '03-05'],
+    ['测点65', '超高预警', '03-05'],
+    ['温度4', '一般预警', '03-05'],
+    ['测点61', '一般预警', '03-05'],
+    ['测点87', '一般信息', '03-05'],
   ],
   index: false,
   // columnWidth: [150, 80, 150, 150],

+ 274 - 160
src/views/vent/monitorManager/chamberMonitor/components/chamberHome.vue

@@ -2,133 +2,160 @@
   <div class="monitor-container">
     <div class="lr left-box">
       <div class="monitor-info item-box">
-        <FourBorderBg>
-          <div>
-            <div class="box-title" style="margin-bottom: 10px;">光纤测温实时监测</div>
+        <ventBox1>
+          <template #title>
+            <div>光纤测温实时监测</div>
+          </template>
+          <template #container>
             <div class="temperature-group">
-              <div class="temperature-item">
-                <SvgIcon class="icon" size="40" name="aveg-temperature" />
-                <div class="temperature">
-                  <span>平均温度</span>
-                  <span class="value">56.99</span>
+              <div class="light-group">
+                <div class="light-bg"></div>
+                <div class="temperature-item">
+                  <SvgIcon class="icon" size="25" name="aveg-temperature" />
+                  <div class="temperature">
+                    <div class="temperature-icon"></div>
+                    <div class="temperature-title">平均温度</div>
+                    <div class="temperature-val-box">
+                      <div class="temperature-val-icon"></div>
+                      <div class="temperature-val">56.99</div>
+                    </div>
+                  </div>
                 </div>
-              </div>
-              <div class="temperature-item">
-                <SvgIcon class="icon" size="40" name="max-temperature" />
-                <div class="temperature">
-                  <span>最高温度</span>
-                  <span class="value">56.99</span>
+                <div class="temperature-item">
+                  <SvgIcon class="icon" size="25" name="max-temperature" />
+                  <div class="temperature">
+                    <div class="temperature-icon"></div>
+                    <div class="temperature-title">最高温度</div>
+                    <div class="temperature-val-box">
+                      <div class="temperature-val-icon"></div>
+                      <div class="temperature-val">56.99</div>
+                    </div>
+                  </div>
                 </div>
-              </div>
-              <div class="temperature-item">
-                <SvgIcon class="icon" size="40" name="min-temperature" />
-                <div class="temperature">
-                  <span>最低温度</span>
-                  <span class="value">56.99</span>
+                <div class="temperature-item">
+                  <SvgIcon class="icon" size="25" name="min-temperature" />
+                  <div class="temperature">
+                    <div class="temperature-icon"></div>
+                    <div class="temperature-title">最低温度</div>
+                    <div class="temperature-val-box">
+                      <div class="temperature-val-icon"></div>
+                      <div class="temperature-val">56.99</div>
+                    </div>
+                  </div>
                 </div>
               </div>
+              
             </div>
-          </div>
-          <div class="warning-group">
-            <div class="box-title" style="margin-bottom: 10px;">近一月报警情况</div>
-            <div class="warning-item">
-              <div>
-                <SvgIcon class="icon" size="28" name="alarm-fire" />
-                <span class="title">火焰传感器报警</span>
-                <span class="value">无</span>
-              </div>
-              <div>
-                <SvgIcon class="icon" size="28" name="warning-fire" />
-                <span class="title">火焰传感器预警</span>
-                <span class="value">无</span>
-              </div>
-            </div>
-            <div class="warning-item">
-              <div>
-                <SvgIcon class="icon" size="28" name="alarm-smoke" />
-                <span class="title">烟雾传感器报警</span>
-                <span class="value" style="color: #FF3823; font-weight: 600;">15</span>
-              </div>
-              <div>
-                <SvgIcon class="icon" size="28" name="warning-smoke" />
-                <span class="title">烟雾传感器预警</span>
-                <span class="value">无</span>
-              </div>
-            </div>
-            <div class="warning-item">
-              <div>
-                <SvgIcon class="icon" size="28" name="alarm-CO" />
-                <span class="title">CO传感器报警</span>
-                <span class="value">无</span>
-              </div>
-              <div>
-                <SvgIcon class="icon" size="28" name="warning-CO" />
-                <span class="title">CO传感器预警</span>
-                <span class="value">无</span>
+          </template>
+        </ventBox1>
+      </div>
+      <div class="warning-group">
+        <ventBox1>
+          <template #title>
+            <div>近一月报警情况</div>
+          </template>
+          <template #container>
+            <div class="monitor-box">
+              <div class="parameter-title group-parameter-title"><SvgIcon class="icon" size="42" name="alarm-icon"/><span>报警信息</span></div>
+              <div class="item-group">
+                <div class="item-col">
+                  <SvgIcon class="icon" size="24" name="alarm-fire" />
+                  <span class="title">火焰传感器</span>
+                  <span class="value">无</span>
+                </div>
+                <div class="item-col">
+                  <SvgIcon class="icon" size="24" name="alarm-smoke" />
+                  <span class="title">烟雾传感器</span>
+                  <span class="value" style="color: #FF3823; font-weight: 600;">15</span>
+                </div>
+                <div class="item-col">
+                  <SvgIcon class="icon" size="24" name="alarm-CO" />
+                  <span class="title">CO传感器</span>
+                  <span class="value">无</span>
+                </div>
+                <div class="item-col">
+                  <SvgIcon class="icon" size="24" name="alarm-temperature" />
+                  <span class="title">温度传感器</span>
+                  <span class="value">无</span>
+                </div>
               </div>
             </div>
-            <div class="warning-item">
-              <div>
-                <SvgIcon class="icon" size="28" name="alarm-temperature" />
-                <span class="title">温度传感器报警</span>
-                <span class="value">无</span>
+            <div class="monitor-box">
+              <div class="parameter-title group-parameter-title"><SvgIcon class="icon" size="42" name="warning-icon"/><span>预警信息</span></div>
+              <div class="item-group">
+                <div class="item-col">
+                  <SvgIcon class="icon" size="22" name="warning-fire" />
+                  <span class="title">火焰传感器</span>
+                  <span class="value">无</span>
+                </div>
+                <div class="item-col">
+                  <SvgIcon class="icon" size="22" name="warning-smoke" />
+                  <span class="title">烟雾传感器</span>
+                  <span class="value" style="color: #FF9B17; font-weight: 600;">15</span>
+                </div>
+                <div class="item-col">
+                  <SvgIcon class="icon" size="22" name="warning-CO" />
+                  <span class="title">CO传感器</span>
+                  <span class="value">无</span>
+                </div>
+                <div class="item-col">
+                  <SvgIcon class="icon" size="22" name="warning-temperature" />
+                  <span class="title">温度传感器</span>
+                  <span class="value">无</span>
+                </div>
               </div>
-              <div>
-                <SvgIcon class="icon" size="28" name="warning-temperature" />
-                <span class="title">温度传感器预警</span>
-                <span class="value" style="color: #FF9B17; font-weight: 600;">10</span>
+              <div class="alarm-box">
+                <dv-scroll-board ref="scrollBoard" :config="warningConfig"
+                  style="width: 100%; height: 240px; overflow-y: auto; " />
               </div>
             </div>
-            <div class="alarm-box">
               
-              <dv-scroll-board ref="scrollBoard" :config="warningConfig"
-                style="width: 100%; height: 240px; overflow-y: auto; " />
-            </div>
-            
-          </div>
-          <!-- <div class="base-info">
-            <div class="box-title" style="margin-bottom: 10px;">基本情况</div>
-            <div>
-              <div>
-                <div>火焰传感器</div>
-              </div>
-            </div>
-          </div> -->
-        </FourBorderBg>
+          
+          </template>
+        </ventBox1>
       </div>
     </div>
     <div class="lr right-box">
       <div class="item-box sensor-container">
-        <div class="box-title">烟雾传感器实时监测</div>
-        <a-table :columns="sensorColumns" :data-source="smokeDataSource" :pagination="false" size="small" maxWidth="340"
-          :scroll="{ x: 'max-content', y: 240 }">
-          <template #bodyCell="{ column, record }">
-            <template v-if="column.dataIndex === 'warnFlag'">
-              <span v-if="record['warnFlag'] == 0" style="color: #00ff00;">正常</span>
-              <span v-else style="color: #ff0000;"> {{ record.warnDes }}</span>
-            </template>
+        <ventBox1>
+          <template #title>
+            <div>烟雾传感器实时监测</div>
           </template>
-        </a-table>
-      </div>
-      <div class="item-box">
-        <div class="box-title">喷粉监控</div>
-        <a-table :columns="dustColumns" :data-source="dustDataSource" :pagination="false" size="small" maxWidth="340"
-          :scroll="{ x: 'max-content', y: 240 }">
-          <template #bodyCell="{ column, record }">
-            <template v-if="column.dataIndex === 'warnFlag'">
-              <span v-if="record['warnFlag'] == 0" style="color: #00ff00;">链接</span>
-              <span v-else style="color: #ff0000;"> {{ record.warnDes }}</span>
-            </template>
-            <template v-if="column.dataIndex === 'action'">
-              <a-switch v-model:checked="openDust" @change="handleDust" />
-            </template>
+          <template #container>
+            <a-table :columns="sensorColumns" :data-source="smokeDataSource" :pagination="false" size="small" maxWidth="340"
+              :scroll="{ x: 'max-content', y: 240 }">
+              <template #bodyCell="{ column, record }">
+                <template v-if="column.dataIndex === 'warnFlag'">
+                  <span v-if="record['warnFlag'] == 0" style="color: #00ff00;">正常</span>
+                  <span v-else style="color: #ff0000;"> {{ record.warnDes }}</span>
+                </template>
+              </template>
+            </a-table>
           </template>
-        </a-table>
+        </ventBox1>
+        <ventBox1 class="vent-margin-t-10">
+          <template #title>
+            <div>{{ groupNum }}喷粉监控</div>
+          </template>
+          <template #container>
+            <a-table :columns="dustColumns" :data-source="dustDataSource" :pagination="false" size="small" maxWidth="340"
+              :scroll="{ x: 'max-content', y: 240 }">
+              <template #bodyCell="{ column, record }">
+                <template v-if="column.dataIndex === 'warnFlag'">
+                  <span v-if="record['warnFlag'] == 0" style="color: #00ff00;">链接</span>
+                  <span v-else style="color: #ff0000;"> {{ record.warnDes }}</span>
+                </template>
+                <template v-if="column.dataIndex === 'action'">
+                  <a-switch v-model:checked="openDust" @change="handleDust" />
+                </template>
+              </template>
+            </a-table>
+          </template>
+        </ventBox1>        
       </div>
       <div class="item-box" >
         <LivePlayer id="fm-player1" style="height: 250px;" ref="player1" :videoUrl="flvURL1()" muted live loading controls />
       </div>
-      
     </div>
   </div>
 </template>
@@ -138,6 +165,7 @@
 import { onBeforeMount, ref, onMounted, onUnmounted, reactive, toRaw, shallowReactive, defineProps, watch } from 'vue';
 // import MonitorTable from '../comment/MonitorTable.vue';
 import { ScrollBoard as DvScrollBoard } from '@kjgl77/datav-vue3';
+import ventBox1 from '/@/components/vent/ventBox1.vue'
 import { mountedThree, destroy, addChamberText, setModelType } from '../chamber.threejs';
 import { SvgIcon } from '/@/components/Icon';
 import FourBorderBg from '/@/components/vent/fourBorderBg.vue';
@@ -281,7 +309,7 @@ onUnmounted(() => {
   justify-content: space-between;
 
   .lr {
-    width: 380px;
+    width: 350px;
     height: 100%;
     display: flex;
     flex-direction: column;
@@ -298,80 +326,166 @@ onUnmounted(() => {
     margin-top: 30px;
 
     .monitor-info {
-      padding: 0 10px;
       .temperature-group {
         width: 100%;
-        display: flex;
-        flex-direction: row;
-        justify-content: space-between;
         margin-top: 10px;
-        
-
-        .temperature-item {
+        .light-group{
           display: flex;
-          justify-content: center;
-          align-items: center;
-
-          .icon {
+          flex-direction: row;
+          justify-content: space-between;
+          position: relative;
+          .light-bg{
+            width: 331px;
+            height: 42px;
+            background: url('/@/assets/images/vent/plane-bg.png') no-repeat;
+            background-size: contain;
+            position: absolute;
+            z-index: -1;
+            top: 44px;
+          }
+          .temperature-item {
+            width: 120px;
             display: flex;
+            flex-direction: column;
             justify-content: center;
             align-items: center;
-            border-radius: 25px;
-            background: #00d4f944;
-            padding: 8px;
-            margin-right: 5px;
-          }
-
-          .temperature {
-            color: #fff;
-
-            span {
+            position: reactive;
+            .icon {
               display: block;
-
+              position: absolute;
+              top: -5px;
             }
-          }
 
-          .value {
-            font-family: 'douyuFont';
-            color: #20dbfd;
-            text-shadow: 0 0 25px #00d8ff;
-            font-size: 13px;
+            .temperature {
+              display: flex;
+              flex-direction: column;
+              justify-content: center;
+              align-items: center;
+              .temperature-icon{
+                width: 90px;
+                height: 58px;
+                background: url('/@/assets/images/vent/ligth-q.png');
+              }
+              .temperature-title{
+                position: relative;
+                top: -15px;
+              }
+              
+              .temperature-val-box{
+                display: flex;
+                flex-direction: column;
+                justify-content: center;
+                align-items: center;
+                position: relative;
+                top: -10px;
+                .temperature-val-icon{
+                  width: 2px;
+                  height: 18px;
+                  background: #00d8ff;
+                  position: relative;
+                  &::after{
+                    content: '';
+                    display: block;
+                    position: absolute;
+                    width: 6px;
+                    height: 6px;
+                    border-radius: 3px;
+                    background: #00d8ff;
+                    bottom: -2px;
+                    left: -2px;
+                  }
+
+                }
+                .temperature-val{
+                  position: relative;
+                  font-family: 'douyuFont';
+                  color: #20dbfd;
+                  text-shadow: 0 0 25px #00d8ff;
+                  font-size: 13px;
+                  border: 1px solid #40B7F3;
+                  padding: 5px 8px 2px 8px;
+                  top: 2px;
+                  &::after{
+                    width: calc(100% - 4px);
+                    height: calc(100% - 4px);
+                    content: '';
+                    position: absolute;
+                    top: 2px;
+                    left: 2px;
+                    display: block;
+                    border: 1px solid #006EA6;
+                  }
+                }
+              }
+              
+            }
           }
         }
+
+        
       }
 
-      .warning-group {
-        padding: 10px 0;
+    }
+    .warning-group {
+      padding: 10px 0;
+    }
+    .monitor-box {
+      width: 100%;
+      margin-bottom: 20px;
+      .parameter-title{
+        position: relative;
+        width: 100%;
+        height: 16px;
         margin-top: 10px;
-
-        .warning-item {
-          display: flex;
-          justify-content: space-between;
-          height: 40px;
-
-          span {
-            display: inline-block;
-          }
-
-          .value {
-            width: 20px;
-          }
+        margin-bottom: 5px;
+        .icon, span{
+          position: absolute;
+          top: -10px;
         }
-        .alarm-box{
-          margin-top: 10px;
-          
+      }
+      .group-parameter-title{
+        background-image: linear-gradient(to right, #39a3ff50, #39a3ff00);
+        
+        .icon{
+          left: -12px;
+          top: -20px;
         }
-        .title {
-          width: 110px;
-          margin-left: 8px;
+        span{
+          left: 20px;
         }
+        
       }
-
+      .item-group{
+        display: flex;
+        flex-wrap: wrap;
+        .item-col{
+          width: calc(50% - 5px);
+          background-image: linear-gradient(to right, #39A3FF00, #39A3FF10);
+          position: relative;
+          // display: flex;
+          // align-items: center;
+          &:nth-child(even){
+            margin-left: 10px;
+          }
+          padding: 2px 0;
+          margin: 3px 0;
+          .title{
+            margin-left: 5px;
+          }
+          .value{
+            position: absolute;
+            right: 10px;
+            top: 5px;
+          }
+        }
+      }
+      
+      
+      
+    }
+    .alarm-box{
+      margin-top: 10px;
     }
-  }
-
-  .item-box{
-    margin-bottom: 15px;
   }
   .box-title{
     color: #fff;

+ 121 - 100
src/views/vent/monitorManager/compressor/components/nitrogenHome.vue

@@ -1,112 +1,75 @@
 <template>
-    <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">{{ groupNum }}号制氮机 </div>
-          <div class="monitor-item">
-            <span class="monitor-title">注氮压力:</span>
-            <span class="monitor-val"><span class="val">{{ monitorData[groupNum - 1]['nitrogenPressure'] ?
-              monitorData[groupNum - 1]['nitrogenPressure'] : '-' }}</span><span class="unit">Mpa</span></span>
-          </div>
-          <div class="monitor-item">
-            <span class="monitor-title">氮气实时流量:</span>
-            <span class="monitor-val"><span class="val">{{ monitorData[groupNum - 1]['instantaneousFlow'] ?
-              monitorData[groupNum - 1]['instantaneousFlow'] : '-' }}</span><span class="unit">m³/h</span></span>
-          </div>
-          <div class="monitor-item">
-            <span class="monitor-title">氮气浓度:</span>
-            <span class="monitor-val"><span class="val">{{ monitorData[groupNum - 1]['nitrogenContent'] ?
-              monitorData[groupNum - 1]['nitrogenContent'] : '-' }}</span><span class="unit">%</span></span>
+  <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">{{ groupNum }}号制氮机 </div>
+        <div class="monitor-item">
+          <span class="monitor-title">注氮压力:</span>
+          <span class="monitor-val"><span class="val">{{ monitorData[groupNum - 1]['nitrogenPressure'] ?
+            monitorData[groupNum - 1]['nitrogenPressure'] : '-' }}</span><span class="unit">Mpa</span></span>
+        </div>
+        <div class="monitor-item">
+          <span class="monitor-title">氮气实时流量:</span>
+          <span class="monitor-val"><span class="val">{{ monitorData[groupNum - 1]['instantaneousFlow'] ?
+            monitorData[groupNum - 1]['instantaneousFlow'] : '-' }}</span><span class="unit">m³/h</span></span>
+        </div>
+        <div class="monitor-item">
+          <span class="monitor-title">氮气浓度:</span>
+          <span class="monitor-val"><span class="val">{{ monitorData[groupNum - 1]['nitrogenContent'] ?
+            monitorData[groupNum - 1]['nitrogenContent'] : '-' }}</span><span class="unit">%</span></span>
+        </div>
+        <div class="signal-item">
+          <div class="signal"><span class="monitor-title">运行信号</span><span
+              :class="{ 'signal-round': true, 'signal-round-run': monitorData[groupNum - 1]['compressRunSigF1'], 'signal-round-gry': !monitorData[groupNum - 1]['compressRunSigF1'] }"></span>
           </div>
-          <div class="signal-item">
-            <div class="signal"><span class="monitor-title">运行信号</span><span
-                :class="{ 'signal-round': true, 'signal-round-run': monitorData[groupNum - 1]['compressRunSigF1'], 'signal-round-gry': !monitorData[groupNum - 1]['compressRunSigF1'] }"></span>
-            </div>
-            <div class="signal"><span class="monitor-title">加载信号</span><span
-                :class="{ 'signal-round': true, 'signal-round-run': monitorData[groupNum - 1]['compressLoadSigF1'], 'signal-round-gry': !monitorData[groupNum - 1]['compressLoadSigF1'] }"></span>
-            </div>
+          <div class="signal"><span class="monitor-title">加载信号</span><span
+              :class="{ 'signal-round': true, 'signal-round-run': monitorData[groupNum - 1]['compressLoadSigF1'], 'signal-round-gry': !monitorData[groupNum - 1]['compressLoadSigF1'] }"></span>
           </div>
-        </fourBorderBg>
-      </div>
+        </div>
+      </fourBorderBg>
     </div>
-    <div id="nitrogen3D" style="width: 100%; height: 100%; position: absolute; overflow: hidden"></div>
-    <div class="nitrogen-home">
-      <div class="nitrogen-container">
-        <div class="top-box">
-          <!-- 左边监测数据 -->
-          <div class="lr-box left-box">
-            <div class="item item-l" v-for="groupNum in monitorDataGroupNum" :key="groupNum">
-              <ventBox1>
-                <template #title>
-                  <div>{{ groupNum }}号制氮机组</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="state-item" v-for="(data, index) in groupParameterData" :key="index">
-                      <div class="item-col">
-                        <span class="state-title">{{ Object.values(data)[0] }} :</span>
-                        <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[0]])
-                          >= 0 ? monitorData[groupNum - 1][Object.keys(data)[0]] : '-' }}</span>
-                      </div>
-                      <div class="item-col">
-                        <span class="state-title">{{ Object.values(data)[1] }} :</span>
-                        <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[1]])
-                          >= 0 ? monitorData[groupNum - 1][Object.keys(data)[1]] : '-' }}</span>
-                      </div>
-                    </div>
-                  </div>
-                  <div class="monitor-box">
-                    <div class="parameter-title device-parameter-title"><SvgIcon class="icon" size="32" name="device-paramer"/><span>电机数据</span></div>
-                    <div class="state-item" v-for="(data, index) in deviceParameterData" :key="index">
-                      <div class="item-col">
-                        <span class="state-title">{{ Object.values(data)[0] }} :</span>
-                        <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[0]])
-                          >= 0 ? monitorData[groupNum - 1][Object.keys(data)[0]] : '-' }}</span>
-                      </div>
-                      <div class="item-col">
-                        <span class="state-title">{{ Object.values(data)[1] }} :</span>
-                        <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[1]])
-                          >= 0 ? monitorData[groupNum - 1][Object.keys(data)[1]] : '-' }}</span>
-                      </div>
-                    </div>
-                  </div>
-                </template>
-              </ventBox1>
-            </div>
-          </div>
-          <!-- 右边控制状态 -->
-          <div class="lr-box right-box">
+  </div>
+  <div id="nitrogen3D" style="width: 100%; height: 100%; position: absolute; overflow: hidden"></div>
+  <div class="nitrogen-home">
+    <div class="nitrogen-container">
+      <div class="top-box">
+        <!-- 左边监测数据 -->
+        <div class="lr-box left-box">
+          <div class="item item-l" v-for="groupNum in monitorDataGroupNum" :key="groupNum">
             <ventBox1>
               <template #title>
-                <div>远程控制</div>
+                <div>{{ groupNum }}号制氮机组</div>
               </template>
               <template #container>
-                <div class="control-group">
-                  <div class="control-item" v-for="groupNum in monitorDataGroupNum" :key="groupNum">
-                    <div class="control-item-title">{{ zdjs[groupNum - 1] }}</div>
-                    <div class="control-item-state">
-                      <a-switch v-model="airCompressorState[groupNum - 1][`compressRunSigF1`]" size="small"  checked-children="开启"
-                        un-checked-children="关闭" :disabled="airCompressorState[groupNum - 1][`controlModel`]"
-                        @change="handlerDevice(airCompressorState[groupNum - 1])">
-                      </a-switch>
+                <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="state-item" v-for="(data, index) in groupParameterData" :key="index">
+                    <div class="item-col">
+                      <span class="state-title">{{ Object.values(data)[0] }} :</span>
+                      <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[0]])
+                        >= 0 ? monitorData[groupNum - 1][Object.keys(data)[0]] : '-' }}</span>
                     </div>
-                  </div>
-                  <div class="control-item" v-for="groupNum in monitorDataGroupNum" :key="groupNum">
-                    <div class="control-item-title">{{ kyjs[groupNum - 1] }}</div>
-                    <div class="control-item-state">
-                      <a-switch v-model="airCompressorState[groupNum - 1][`compressRunSigF1`]" size="small"  checked-children="开启"
-                        un-checked-children="关闭" :disabled="airCompressorState[groupNum - 1][`controlModel`]"
-                        @change="handlerDevice(airCompressorState[groupNum - 1])">
-                      </a-switch>
+                    <div class="item-col">
+                      <span class="state-title">{{ Object.values(data)[1] }} :</span>
+                      <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[1]])
+                        >= 0 ? monitorData[groupNum - 1][Object.keys(data)[1]] : '-' }}</span>
                     </div>
                   </div>
-                  <div class="control-item">
-                    <div class="control-item-title">是否开启联动</div>
-                    <div class="control-item-state">
-                      <a-radio v-model:checked="isLink">开启</a-radio>
+                </div>
+                <div class="monitor-box">
+                  <div class="parameter-title device-parameter-title"><SvgIcon class="icon" size="32" name="device-paramer"/><span>电机数据</span></div>
+                  <div class="state-item" v-for="(data, index) in deviceParameterData" :key="index">
+                    <div class="item-col">
+                      <span class="state-title">{{ Object.values(data)[0] }} :</span>
+                      <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[0]])
+                        >= 0 ? monitorData[groupNum - 1][Object.keys(data)[0]] : '-' }}</span>
+                    </div>
+                    <div class="item-col">
+                      <span class="state-title">{{ Object.values(data)[1] }} :</span>
+                      <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[1]])
+                        >= 0 ? monitorData[groupNum - 1][Object.keys(data)[1]] : '-' }}</span>
                     </div>
                   </div>
                 </div>
@@ -114,8 +77,57 @@
             </ventBox1>
           </div>
         </div>
+        <!-- 右边控制状态 -->
+        <div class="lr-box right-box">
+          <ventBox1>
+            <template #title>
+              <div>远程控制</div>
+            </template>
+            <template #container>
+              <div class="control-group">
+                <div class="control-item" v-for="groupNum in monitorDataGroupNum" :key="groupNum">
+                  <div class="control-item-title">{{ zdjs[groupNum - 1] }}</div>
+                  <div class="control-item-state">
+                    <a-switch v-model="airCompressorState[groupNum - 1][`compressRunSigF1`]" size="small"  checked-children="开启"
+                      un-checked-children="关闭" :disabled="airCompressorState[groupNum - 1][`controlModel`]"
+                      @change="handlerDevice(airCompressorState[groupNum - 1])">
+                    </a-switch>
+                  </div>
+                </div>
+                <div class="control-item" v-for="groupNum in monitorDataGroupNum" :key="groupNum">
+                  <div class="control-item-title">{{ kyjs[groupNum - 1] }}</div>
+                  <div class="control-item-state">
+                    <a-switch v-model="airCompressorState[groupNum - 1][`compressRunSigF1`]" size="small"  checked-children="开启"
+                      un-checked-children="关闭" :disabled="airCompressorState[groupNum - 1][`controlModel`]"
+                      @change="handlerDevice(airCompressorState[groupNum - 1])">
+                    </a-switch>
+                  </div>
+                </div>
+                <div class="control-item">
+                  <div class="control-item-title">是否开启联动</div>
+                  <div class="control-item-state">
+                    <a-radio v-model:checked="isLink">开启</a-radio>
+                  </div>
+                </div>
+              </div>
+            </template>
+          </ventBox1>
+          <ventBox1 class="vent-margin-t-10">
+            <template #title>
+              <div>设备实时监测曲线</div>
+            </template>
+            <template #container >
+              <BarAndLineCustom xAxisPropType="readTime" :chartData="monitorData" height="240px" :propTypeArr="['flowRate']" :option="zhudanOption" />
+            </template>
+          </ventBox1>
+          <div class="vent-margin-t-10">
+            <LivePlayer id="fm-player1" style="height: 250px;" ref="player1" :videoUrl="flvURL1()" muted live loading controls />
+          </div>
+        </div>
       </div>
     </div>
+  </div>
+  
 </template>
 <script lang="ts" setup name="nitrogenHome">
 import { onMounted, onUnmounted, ref, watch } from 'vue'
@@ -124,6 +136,9 @@ import fourBorderBg from '../../../comment/components/fourBorderBg.vue'
 import { mountedThree, destroy } from '../nitrogen.threejs'
 import { list } from '../nitrogen.api'
 import { SvgIcon } from '/@/components/Icon'
+import LivePlayer from '@liveqing/liveplayer-v3';
+import BarAndLineCustom from '/@/components/chart/BarAndLineCustom.vue';
+import { zhudanOption } from '../nitrogen.data.ts'
 
 const loading = ref(true)
 const isLink = ref(true)
@@ -131,6 +146,11 @@ const isLink = ref(true)
 const zdjs = ['1号制氮机', '2号制氮机', '3号制氮机', '4号制氮机'];
 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 monitorDataGroupNum = ref(0);
 
 const airCompressorState = ref([
@@ -206,7 +226,7 @@ async function getMonitor() {
 };
 
 async function getDataSource() {
-  const res = await list({ devicetype: 'nitrogen_auto', pagetype: 'normal' });
+  const res = await list({ devicetype: 'nitrogen', pagetype: 'normal' });
   const dataSource = res.msgTxt[0].datalist || [];
   monitorData.value = dataSource.filter((data) => {
     const item = data.readData;
@@ -471,6 +491,7 @@ onUnmounted(() => {
       }
 
       .right-box {
+        width: 330px;
         .control-group{
           display: flex;
           // justify-content: space-around;
@@ -481,7 +502,7 @@ onUnmounted(() => {
             flex-direction: column;
             justify-content: center;
             align-items: center;
-            padding: 0 13px;
+            padding: 0 4px;
             .control-item-title{
               color: #A6DCE9;
               position: relative;

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

@@ -1,4 +1,5 @@
 <template>
+ 
   <div class="nitrogen-box">
     <div class="nitrogen-home-header">
       <Decoration5 class="header-icon" :dur="2" :color="['#21437F', '#2CF7FE']" style="width:500px;height:40px;" />
@@ -22,7 +23,7 @@ import nitrogenHandleHistory from './components/nitrogenHandleHistory.vue'
 import nitrogenAlarmHistory from './components/nitrogenAlarmHistory.vue'
 import { Decoration5 } from '@kjgl77/datav-vue3'
 import BottomMenu from '/@/views/vent/comment/components/bottomMenu.vue';
-
+const loading = ref(true)
 const btnActive = ref('nitrogen_page')
 const navList = ref([
   {

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

@@ -1,4 +1,6 @@
-import { ref } from 'vue';
+import { ref, reactive } from 'vue';
+import echarts from '/@/utils/lib/echarts';
+
 export const bottomBtnList = ref([
   {
     text: '监控界面',
@@ -32,6 +34,119 @@ export const bottomBtnList = ref([
   },
 ]);
 
+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: 50, y: 60, x2: 12, y2: 60 },
+  xAxis: {
+    type: 'category',
+    boundaryGap: false,
+    axisLine: { lineStyle: { color: '#57617B' } },
+    axisLabel: { textStyle: { color: '#ffffffcc' } },
+    splitLine: { show: true, lineStyle: { color: '#57617B22', type: 'dashed' } },
+    data: [],
+  },
+  yAxis: [
+    {
+      type: 'value',
+      name: 'MPa',
+      max: 10,
+      axisTick: {
+        show: false,
+      },
+      position: 'left',
+      axisLine: { lineStyle: { show: true, color: '#57617B' } },
+      axisLabel: { margin: 10, textStyle: { fontSize: 12, color: '#ffffffcc' } },
+      splitLine: { show: true, lineStyle: { color: '#57617B22', type: 'dashed' } },
+    },
+    {
+      type: 'value',
+      name: 'm³/h',
+      max: 10,
+      axisTick: {
+        show: false,
+      },
+      position: 'right',
+      axisLine: { lineStyle: { show: true, color: '#57617B' } },
+      axisLabel: { margin: 10, textStyle: { fontSize: 12, color: '#ffffffcc' } },
+      splitLine: { show: true, lineStyle: { color: '#57617B22', type: 'dashed' } },
+    },
+  ],
+  series: [
+    {
+      name: '注氮压力',
+      type: 'line',
+
+      smooth: true,
+      lineStyle: { normal: { width: 2 } },
+      yAxisIndex: 0,
+      areaStyle: {
+        normal: {
+          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: { normal: { color: '#B996F8' } },
+      data: [],
+    },
+    {
+      name: '氮气流量',
+      type: 'line',
+
+      smooth: true,
+      lineStyle: { normal: { width: 2 } },
+      yAxisIndex: 0,
+      areaStyle: {
+        normal: {
+          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: { normal: { color: '#03C2EC' } },
+      data: [],
+    },
+  ],
+});
 
       // dataInfo: {
       //   controlModel: false

+ 589 - 539
src/views/vent/monitorManager/deviceMonitor/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="scene-box" v-if="routerParam !== 'home'">
-  <!-- <div class="scene-box"> -->
+    <!-- <div class="scene-box"> -->
     <div class="device-header">智能通风管控系统</div>
     <div class="select-node" :class="{ 'node-select-show': !treeShow, 'node-select-hide': treeShow, }">
       <SvgIcon class="is-expansion-icon put-away-icon" size="38" name="expansion" @click="showTree(true)" />
@@ -9,646 +9,696 @@
     <div class="device-select" :class="{ 'device-select-show': treeShow, 'device-select-hide': !treeShow, }">
       <SvgIcon class="is-expansion-icon expansion-icon" size="28" name="put-away" @click="showTree(false)" />
       <div class="device-select-box">
-        <a-tree
-          :show-line="true"
-          :tree-data="treeData"
-          v-model:selectedKeys="selectedKeys"
-          v-model:expandedKeys="expandedKeys"
-          @select="onSelect"
-        >
+        <a-tree :show-line="true" :tree-data="treeData" v-model:selectedKeys="selectedKeys"
+          v-model:expandedKeys="expandedKeys" @select="onSelect">
         </a-tree>
-      </div>  
+      </div>
     </div>
     <div class="bottom-tabs-box" @mousedown="setDivHeight" id="monitorBox">
       <div class="to-small" @click="toHome"></div>
       <div class="device-button-group" v-if="deviceList.length > 0">
-        <div class="device-button" :class="{ 'device-active': deviceActive == device.deviceType }" v-for="(device, index) in deviceList" :key="index" @click="monitorChange(index)">{{ device.deviceName }}</div>
+        <div class="device-button" :class="{ 'device-active': deviceActive == device.deviceType }"
+          v-for="(device, index) in deviceList" :key="index" @click="monitorChange(index)">{{ device.deviceName }}</div>
         <div class="enter-detail" @click="goDetail()">
           <send-outlined />
           {{ treeNodeTitle }}详情
         </div>
       </div>
-      <a-tabs class="tabs-box" v-model:activeKey="activeKey" @change="tabChange" >
+      <a-tabs class="tabs-box" v-model:activeKey="activeKey" @change="tabChange">
         <a-tab-pane key="1" tab="实时监测">
           <template v-if="deviceType == 'fan' && activeKey == '1'">
             <GroupMonitorTable :dataSource="dataSource" :columnsType="`${deviceType}_monitor`" />
           </template>
-          <template v-else-if = "activeKey == '1'">
-            <MonitorTable
-              ref="monitorTable"
-              :columnsType="`${deviceType}_monitor`"
-              :dataSource="dataSource"
-              design-scope="device_monitor"
-              :isShowPagination = "false"
-              :isShowActionColumn="true"
-              title="设备监测"
-            >
-            <template #action="{ record }">
-              <TableAction
-                :actions="[
-                    {
-                      label: '详情',
-                      onClick: goDetail.bind(null, record),
-                    },
-                    {
-                      label: '定位',
-                      onClick: goLocation.bind(null, record),
-                    },
-                  ]"
-              />
-            </template>
+          <template v-else-if="activeKey == '1'">
+            <MonitorTable ref="monitorTable" :columnsType="`${deviceType}_monitor`" :dataSource="dataSource"
+              design-scope="device_monitor" :isShowPagination="false" :isShowActionColumn="true" title="设备监测">
+              <template #action="{ record }">
+                <TableAction :actions="[
+                  {
+                    label: '详情',
+                    onClick: goDetail.bind(null, record),
+                  },
+                  {
+                    label: '定位',
+                    onClick: goLocation.bind(null, record),
+                  },
+                ]" />
+              </template>
             </MonitorTable>
-          </template> 
+          </template>
         </a-tab-pane>
         <a-tab-pane key="2" tab="历史数据">
           <div class="tab-item">
-            <HistoryTable ref="historyTable" v-if="activeKey == '2'" :sysId="systemID" :columns-type="`${deviceType}`" :device-type="deviceType" :device-list-api="getDeviceList.bind(null, { strtype : deviceType, sysId: systemID })" designScope="device-history" />
+            <HistoryTable ref="historyTable" v-if="activeKey == '2'" :sysId="systemID" :columns-type="`${deviceType}`"
+              :device-type="deviceType"
+              :device-list-api="getDeviceList.bind(null, { strtype: deviceType, sysId: systemID })"
+              designScope="device-history" />
           </div>
         </a-tab-pane>
         <a-tab-pane key="3" tab="报警历史">
           <div class="tab-item">
-            <AlarmHistoryTable ref="alarmHistoryTable" v-if="activeKey == '3'" :sysId="systemID" columns-type="alarm" :device-type="deviceType" :device-list-api="getDeviceList.bind(null, { strtype: deviceType, sysId: systemID })" designScope="alarm-history" />
+            <AlarmHistoryTable ref="alarmHistoryTable" v-if="activeKey == '3'" :sysId="systemID" columns-type="alarm"
+              :device-type="deviceType"
+              :device-list-api="getDeviceList.bind(null, { strtype: deviceType, sysId: systemID })"
+              designScope="alarm-history" />
           </div>
         </a-tab-pane>
         <a-tab-pane key="4" tab="操作历史">
           <div class="tab-item">
-            <HandlerHistoryTable ref="handlerHistoryTable" v-if="activeKey == '4'" :sysId="systemID" columns-type="operatorhistory" :device-type="deviceType"  :device-list-api="getDeviceList.bind(null, { strtype: deviceType, sysId: systemID  })" designScope="operator-history" />
-          </div> 
+            <HandlerHistoryTable ref="handlerHistoryTable" v-if="activeKey == '4'" :sysId="systemID"
+              columns-type="operatorhistory" :device-type="deviceType"
+              :device-list-api="getDeviceList.bind(null, { strtype: deviceType, sysId: systemID })"
+              designScope="operator-history" />
+          </div>
         </a-tab-pane>
       </a-tabs>
     </div>
-    <component v-if="modalVisible" :is="currentModal" v-model:visible="modalVisible" :dataSource="dataSource" :activeID="activeID" />
+    <component v-if="modalVisible" :is="currentModal" v-model:visible="modalVisible" :dataSource="dataSource"
+      :activeID="activeID" />
   </div>
 </template>
 <script setup lang="ts">
-  import {ref, onMounted, onUnmounted, ComponentOptions, shallowRef } from 'vue'
-  import { SendOutlined } from '@ant-design/icons-vue';
-  import { list, getDeviceList, getDeviceTypeList } from './device.api'
-  import AlarmHistoryTable from '../comment/AlarmHistoryTable.vue';
-  import HistoryTable from '../comment/HistoryTable.vue';
-  import HandlerHistoryTable from '../comment/HandlerHistoryTable.vue';
-  import MonitorTable from '../comment/MonitorTable.vue';
-  import GroupMonitorTable from '../comment/GroupMonitorTable.vue';
-  import { TreeProps, message } from 'ant-design-vue';
-  import { TableAction } from '/@/components/Table';
-  import FiberModal from './modal/fiber.modal.vue';
-  import DustModal from './modal/dust.modal.vue'
-  import { SvgIcon } from '/@/components/Icon';
-  import { getActions } from '/@/qiankun/state';
-  import { useRouter } from 'vue-router';
-  
+import { ref, onMounted, onUnmounted, ComponentOptions, shallowRef, nextTick } from 'vue'
+import { SendOutlined } from '@ant-design/icons-vue';
+import { list, getDeviceList, getDeviceTypeList } from './device.api'
+import AlarmHistoryTable from '../comment/AlarmHistoryTable.vue';
+import HistoryTable from '../comment/HistoryTable.vue';
+import HandlerHistoryTable from '../comment/HandlerHistoryTable.vue';
+import MonitorTable from '../comment/MonitorTable.vue';
+import GroupMonitorTable from '../comment/GroupMonitorTable.vue';
+import { TreeProps, message } from 'ant-design-vue';
+import { TableAction } from '/@/components/Table';
+import FiberModal from './modal/fiber.modal.vue';
+import DustModal from './modal/dust.modal.vue'
+import { SvgIcon } from '/@/components/Icon';
+import { getActions } from '/@/qiankun/state';
+import { useRouter } from 'vue-router';
 
-  type DeviceType = { deviceType: string, deviceName: string, datalist: any[] };
 
-  const router = useRouter()
+type DeviceType = { deviceType: string, deviceName: string, datalist: any[] };
 
-  const actions = getActions();
-  actions.setGlobalState({ pageObj: { pageType: 'home' } });
+const router = useRouter()
 
-  const monitorTable = ref()
-  const historyTable = ref()
-  const alarmHistoryTable = ref()
-  const handlerHistoryTable = ref()
-
-  const routerParam = ref('home') // 默认进来时首页
-  // 模态框
-  const currentModal = shallowRef<Nullable<ComponentOptions>>(null); //模态框
-  const modalVisible = ref<Boolean>(false); // 模态框是否可见
-
-  //
-  const drawerHeight = ref(240) // 监测框最小高度
-  const treeShow = ref(true) //是否显示树形菜单
-  const treeNodeTitle = ref('') // 选中的树形标题
-
-  const deviceList = ref<DeviceType[]>([])
-  const deviceActive = ref('')
-  const activeKey = ref('1'); // tab key
-  const dataSource = shallowRef([]) // 实时监测数据
-  const activeID = ref('') // 打开详情modal时监测的设备id
-  const deviceType = ref('') // 监测设备类型
-  const systemType = ref('')
-  const systemID = ref('') // 系统监测时,系统id
-  const selectedKeys = ref<string[]>([]);
-  const expandedKeys = ref<string[]>([]);
-  const scroll = ref({
-    y: drawerHeight.value - 100
-  })
-  const treeData = ref<TreeProps['treeData']>([]);
-
-  //树形菜单选择事件
-  const onSelect: TreeProps['onSelect'] = async(keys, e) => {
-    deviceType.value = ''
-    systemID.value = ''
-    deviceList.value = []
-    if(e.node.parent && (e.node.parent.node.type.toString()).startsWith('sys')){
-      systemType.value = e.node.parent.node.type
-      deviceType.value = e.node.parent.node.type
-      systemID.value = e.node.type
-      // 传递工作面id信息,用于定位
-      actions.setGlobalState({ locationObj: { pageType: deviceType.value ,deviceid: systemID.value }, pageObj: null });
-    }else{
-      systemType.value = e.node.type
-      deviceType.value = e.node.type
-    }
-    selectedKeys.values = keys
-    treeNodeTitle.value = e.node.title
+const actions = getActions();
+actions.setGlobalState({ pageObj: { pageType: 'home' } });
 
-    if (timer) clearInterval(timer);
-    await getDataSource()
-    getMonitor() 
-  };
-  
-  function tabChange(activeKeyVal) {
-    activeKey.value = activeKeyVal;
-  };
+const monitorTable = ref()
+const historyTable = ref()
+const alarmHistoryTable = ref()
+const handlerHistoryTable = ref()
+
+const routerParam = ref('home') // 默认进来时首页
+// 模态框
+const currentModal = shallowRef<Nullable<ComponentOptions>>(null); //模态框
+const modalVisible = ref<Boolean>(false); // 模态框是否可见
+
+//
+const drawerHeight = ref(240) // 监测框最小高度
+const treeShow = ref(true) //是否显示树形菜单
+const treeNodeTitle = ref('') // 选中的树形标题
+
+const deviceList = ref<DeviceType[]>([])
+const deviceActive = ref('')
+const activeKey = ref('1'); // tab key
+const dataSource = shallowRef([]) // 实时监测数据
+const activeID = ref('') // 打开详情modal时监测的设备id
+const deviceType = ref('') // 监测设备类型
+const systemType = ref('')
+const systemID = ref('') // 系统监测时,系统id
+const selectedKeys = ref<string[]>([]);
+const expandedKeys = ref<string[]>([]);
+const scroll = ref({
+  y: drawerHeight.value - 100
+})
+const treeData = ref<TreeProps['treeData']>([]);
 
-  function showTree(flag) {
-    treeShow.value = flag
+//树形菜单选择事件
+const onSelect: TreeProps['onSelect'] = (keys, e) => {
+  deviceType.value = ''
+  systemID.value = ''
+  deviceList.value = []
+  if (e.node.parent && (e.node.parent.node.type.toString()).startsWith('sys')) {
+    systemType.value = e.node.parent.node.type
+    deviceType.value = e.node.parent.node.type
+    systemID.value = e.node.type
+    // 传递工作面id信息,用于定位
+    actions.setGlobalState({ locationObj: { pageType: deviceType.value, deviceid: systemID.value }, pageObj: null });
+  } else {
+    systemType.value = e.node.type
+    deviceType.value = e.node.type
   }
+  selectedKeys.values = keys
+  treeNodeTitle.value = e.node.title
+  debugger
+  if(timer) clearTimeout(timer)
+  timer = undefined
+  if (monitorTable.value) monitorTable.value.setLoading(true)
+  nextTick(() => {
+    timer = null
+    getMonitor()
+  })
   
-  async function getDeviceType () {
-    const result = await getDeviceTypeList({})
-    if (result.length > 0) {
-      const dataSource = <TreeProps['treeData']>[]
-      let key = '0'
-      const getData = (resultList, dataSourceList, keyVal) => {
-        resultList.forEach((item, index) => {
-          if (item.children && item.children.length > 0) {
-            const children = getData(item.children, [], `${keyVal}-${index}`)
-            dataSourceList.push({
-              children: children,
-              title: item.itemText,
-              key: `${keyVal}-${index}`,
-              type: item.itemValue,
-            });
-            
-          } else {
-            dataSourceList.push({
-              children: [],
-              title: item.itemText,
-              key: `${keyVal}-${index}`,
-              type: item.itemValue,
-            });
-          }
-        });
-        return dataSourceList
-      }
-      console.log('树形菜单-------------->', treeData.value)
-      treeData.value = getData(result, dataSource, key)
-      
+};
+
+function tabChange(activeKeyVal) {
+  activeKey.value = activeKeyVal;
+};
+
+function showTree(flag) {
+  treeShow.value = flag
+}
+
+async function getDeviceType() {
+  const result = await getDeviceTypeList({})
+  if (result.length > 0) {
+    const dataSource = <TreeProps['treeData']>[]
+    let key = '0'
+    const getData = (resultList, dataSourceList, keyVal) => {
+      resultList.forEach((item, index) => {
+        if (item.children && item.children.length > 0) {
+          const children = getData(item.children, [], `${keyVal}-${index}`)
+          dataSourceList.push({
+            children: children,
+            title: item.itemText,
+            key: `${keyVal}-${index}`,
+            type: item.itemValue,
+          });
+
+        } else {
+          dataSourceList.push({
+            children: [],
+            title: item.itemText,
+            key: `${keyVal}-${index}`,
+            type: item.itemValue,
+          });
+        }
+      });
+      return dataSourceList
     }
+    console.log('树形菜单-------------->', treeData.value)
+    treeData.value = getData(result, dataSource, key)
+
   }
+}
 
-  // https获取监测数据
-  let timer: null | NodeJS.Timeout = null;
-  function getMonitor() {
-    timer = setInterval(async () => {
+// https获取监测数据
+let timer: null | NodeJS.Timeout = undefined;
+function getMonitor() {
+  if (timer) timer = null
+  if (Object.prototype.toString.call(timer) === '[object Null]' && deviceType.value) {
+    timer = setTimeout(async () => {
       await getDataSource()
+      if (timer) {
+        getMonitor();
+      }
     }, 1000);
-  };
-
-  async function getDataSource() {
-    if (deviceType.value.startsWith('sys') && systemID.value) {
-      const res = await list({ devicetype: 'sys', systemID: systemID.value });
-      const result = res.msgTxt;
-      const deviceArr = <DeviceType[]>[]
-      result.forEach(item => {
-        const data = item['datalist'].filter((data: any) => {
-          const readData = data.readData;
-          return Object.assign(data, readData);
-        })
-        if (item.type != 'sys') {
-          deviceArr.unshift({ deviceType: item.type, deviceName: item['typeName'] ? item['typeName'] : item['datalist'][0]['typeName'], datalist: data })
-        }
+  }
+};
+
+async function getDataSource() {
+  if (deviceType.value.startsWith('sys') && systemID.value) {
+    const res = await list({ devicetype: 'sys', systemID: systemID.value });
+    const result = res.msgTxt;
+    const deviceArr = <DeviceType[]>[]
+    result.forEach(item => {
+      const data = item['datalist'].filter((data: any) => {
+        const readData = data.readData;
+        return Object.assign(data, readData);
       })
-      console.log('关联设备列表', deviceArr)
-      deviceList.value = deviceArr
-      deviceActive.value = deviceArr[1].deviceType
-      monitorChange(1)
-    } else {
-      const res = await list({ devicetype: deviceType.value, pagetype: 'normal' })
-      if (res.msgTxt[0]) {
-        dataSource.value = res.msgTxt[0].datalist || [];
-        dataSource.value.filter((data: any) => {
-          const readData = data.readData;
-          return Object.assign(data, readData);
-        });
+      if (item.type != 'sys') {
+        deviceArr.unshift({ deviceType: item.type, deviceName: item['typeName'] ? item['typeName'] : item['datalist'][0]['typeName'], datalist: data })
       }
+    })
+    console.log('关联设备列表', deviceArr)
+    deviceList.value = deviceArr
+    deviceActive.value = deviceArr[1].deviceType
+    monitorChange(1)
+  } else {
+    const res = await list({ devicetype: deviceType.value, pagetype: 'normal' })
+    if (res.msgTxt[0]) {
+      dataSource.value = res.msgTxt[0].datalist || [];
+      dataSource.value.filter((data: any) => {
+        const readData = data.readData;
+        return Object.assign(data, readData);
+      });
     }
   }
+}
 
-  function setDivHeight(e: MouseEvent) {
-    const divObject = document.getElementById('monitorBox') as HTMLElement
-    const divHeight = divObject.offsetHeight
-    drawerHeight.value = divHeight
-    const startY = e.clientY
-    document.onmousemove = function(res){
-      res.preventDefault()
-      const distY = Math.abs(res.clientY - startY)
-      if(res.clientY > startY){
-        if(divHeight - distY >= 240){
-          drawerHeight.value = divHeight - distY
-        }else{
-          drawerHeight.value = 240
-        }
-      }
-      if(res.clientY < startY){
-        drawerHeight.value = divHeight + distY
+function setDivHeight(e: MouseEvent) {
+  const divObject = document.getElementById('monitorBox') as HTMLElement
+  const divHeight = divObject.offsetHeight
+  drawerHeight.value = divHeight
+  const startY = e.clientY
+  document.onmousemove = function (res) {
+    res.preventDefault()
+    const distY = Math.abs(res.clientY - startY)
+    if (res.clientY > startY) {
+      if (divHeight - distY >= 240) {
+        drawerHeight.value = divHeight - distY
+      } else {
+        drawerHeight.value = 240
       }
-      divObject.style.height = drawerHeight.value+'px'
     }
-    document.onmouseup = function() {
-      document.onmousemove = null
-      if(scroll.value.y != drawerHeight.value - 100) {
-        scroll.value = {y: drawerHeight.value - 100 }
-
-        // const tableBody =  document.getElementsByClassName('zxm-table-container')[0].children[1] as HTMLElement
-        // debugger
-        // tableBody.style.height = `${drawerHeight.value - 350}px`
-      }
+    if (res.clientY < startY) {
+      drawerHeight.value = divHeight + distY
     }
+    divObject.style.height = drawerHeight.value + 'px'
   }
-  // 定位
-  function goLocation(record) {
-    actions.setGlobalState({ locationId: record.deviceID, locationObj: null, pageObj: null });
-  }
-  // 详情
-  function goDetail(record?){
-
-    if(record){
-      if (deviceType.value.startsWith('fiber')) {
-        activeID.value = record.deviceID
-        currentModal.value = FiberModal
-        modalVisible.value = true;
-      } else if (deviceType.value.startsWith('dusting')) {
-        activeID.value = record.deviceID
-        currentModal.value = DustModal
-        modalVisible.value = true;
-      } else if (deviceType.value.indexOf("gate") != -1) {
-        const newPage = router.resolve({path: '/monitorChannel/monitor-gate'})
-        window.open(newPage.href, '_blank')
-      } else if (deviceType.value.indexOf("window") != -1) {
-        const newPage = router.resolve({ path: '/monitorChannel/monitor-window' })
-        window.open(newPage.href, '_blank')
-      } else if (deviceType.value.indexOf("windrect") != -1) {
-        const newPage = router.resolve({ path: '/monitorChannel/monitor-windrect' })
-        window.open(newPage.href, '_blank')
-      } else if (deviceType.value.indexOf("fanmain") != -1) {
-        const newPage = router.resolve({ path: '/monitorChannel/monitor-fan-main' })
-        window.open(newPage.href, '_blank')
-      } else if (deviceType.value.indexOf("fanlocal") != -1) {
-        const newPage = router.resolve({ path: '/monitorChannel/monitor-fan-local' })
-        window.open(newPage.href, '_blank')
-      } else {
-        message.info('待开发。。。')
-      }
-    }else{
-      if (systemType.value.indexOf("sys_dongshi") != -1) {
-        const newPage = router.resolve({ path: '/chamber-home', query: {id: systemID.value }})
-        window.open(newPage.href, '_blank')
-      }else{
-        message.info('待开发。。。')
-      }
+  document.onmouseup = function () {
+    document.onmousemove = null
+    if (scroll.value.y != drawerHeight.value - 100) {
+      scroll.value = { y: drawerHeight.value - 100 }
+
+      // const tableBody =  document.getElementsByClassName('zxm-table-container')[0].children[1] as HTMLElement
+      // debugger
+      // tableBody.style.height = `${drawerHeight.value - 350}px`
     }
-    
   }
-  
-  function toHome() {
-    deviceList.value = []
-    actions.setGlobalState({ pageObj: { pageType: 'home'} });
+}
+
+function goLocation(record) {
+  actions.setGlobalState({ locationId: record.deviceID, locationObj: null, pageObj: null });
+}
+function goDetail(record?) {
+
+  if (record) {
+    if (deviceType.value.startsWith('fiber')) {
+      activeID.value = record.deviceID
+      currentModal.value = FiberModal
+      modalVisible.value = true;
+    } else if (deviceType.value.startsWith('dusting')) {
+      activeID.value = record.deviceID
+      currentModal.value = DustModal
+      modalVisible.value = true;
+    } else if (deviceType.value.indexOf("gate") != -1) {
+      const newPage = router.resolve({ path: '/monitorChannel/monitor-gate' })
+      window.open(newPage.href, '_blank')
+    } else if (deviceType.value.indexOf("window") != -1) {
+      const newPage = router.resolve({ path: '/monitorChannel/monitor-window' })
+      window.open(newPage.href, '_blank')
+    } else if (deviceType.value.indexOf("windrect") != -1) {
+      const newPage = router.resolve({ path: '/monitorChannel/monitor-windrect' })
+      window.open(newPage.href, '_blank')
+    } else if (deviceType.value.indexOf("fanmain") != -1) {
+      const newPage = router.resolve({ path: '/monitorChannel/monitor-fan-main' })
+      window.open(newPage.href, '_blank')
+    } else if (deviceType.value.indexOf("fanlocal") != -1) {
+      const newPage = router.resolve({ path: '/monitorChannel/monitor-fan-local' })
+      window.open(newPage.href, '_blank')
+    } else {
+      message.info('待开发。。。')
+    }
+  } else {
+    if (systemType.value.indexOf("sys_dongshi") != -1) {
+      const newPage = router.resolve({ path: '/chamber-home', query: { id: systemID.value } })
+      window.open(newPage.href, '_blank')
+    } else {
+      message.info('待开发。。。')
+    }
   }
-  // 遍历树形菜单
-  async function findTreeDataValue(data:[], obj) {
-    const findDeviceType = (data: [], obj) => {
-      let type = ''
-      if (obj.deviceid) {
-        type = obj.deviceid
-      } else {
-        type = obj.deviceType
-      }
-      data.find((item: any) => {
-        if (item.children.length > 0) {
-          findDeviceType(item.children, obj)
-        }
-        if (item.type == type) {
-          deviceType.value = obj.deviceid ? 'sys' : item.type
-          if (obj.deviceid) systemID.value = obj.deviceid
-          selectedKeys.value = [item.key]
-          expandedKeys.value = [item.key]
-          treeNodeTitle.value = item.title
-        }
-      })
+
+}
+
+function toHome() {
+  deviceList.value = []
+  if(timer) clearTimeout(timer)
+  timer = undefined
+  actions.setGlobalState({ pageObj: { pageType: 'home' } });
+}
+
+async function findTreeDataValue(data: [], obj) {
+  const findDeviceType = (data: [], obj) => {
+    let type = ''
+    if (obj.deviceid) {
+      type = obj.deviceid
+    } else {
+      type = obj.deviceType
     }
-    findDeviceType(data, obj)
-    if (timer) clearInterval(timer);
+    data.find((item: any) => {
+      if (item.children.length > 0) {
+        findDeviceType(item.children, obj)
+      }
+      if (item.type == type) {
+        deviceType.value = obj.deviceid ? 'sys' : item.type
+        if (obj.deviceid) systemID.value = obj.deviceid
+        selectedKeys.value = [item.key]
+        expandedKeys.value = [item.key]
+        treeNodeTitle.value = item.title
+      }
+    })
+  }
+  findDeviceType(data, obj)
+  debugger
+  if (timer === undefined) {
+    timer = null
     await getDataSource()
     getMonitor()
   }
+}
 
-  function monitorChange(index) {
-    dataSource.value = []
-    deviceActive.value = deviceType.value = deviceList.value[index].deviceType
+function monitorChange(index) {
+  dataSource.value = []
+  deviceActive.value = deviceType.value = deviceList.value[index].deviceType
 
-    if (activeKey.value == '1' && monitorTable.value) {
-      monitorTable.value.setLoading(true)
-      dataSource.value = deviceList.value[index].datalist
-    }
-    if(activeKey.value == '2' && historyTable.value){
-      historyTable.value.setLoading(true)
-    }
-    if (activeKey.value == '3' && alarmHistoryTable.value) {
-      alarmHistoryTable.value.setLoading(true)
-    }
-    if (activeKey.value == '4' && handlerHistoryTable.value) {
-      handlerHistoryTable.value.setLoading(true)
-    }
+  if (activeKey.value == '1' && monitorTable.value) {
+    monitorTable.value.setLoading(true)
+    dataSource.value = deviceList.value[index].datalist
   }
-  
-  onMounted(async() => {
-    actions.onGlobalStateChange(async(newState, prev) => {
-      for (const key in newState) {
-        if (key === 'pageObj') {
-          const pageObj = newState[key]
-          if (pageObj) {
-            routerParam.value = pageObj.pageType
+  if (activeKey.value == '2' && historyTable.value) {
+    historyTable.value.setLoading(true)
+  }
+  if (activeKey.value == '3' && alarmHistoryTable.value) {
+    alarmHistoryTable.value.setLoading(true)
+  }
+  if (activeKey.value == '4' && handlerHistoryTable.value) {
+    handlerHistoryTable.value.setLoading(true)
+  }
+}
+
+
+onMounted(async () => {
+  actions.onGlobalStateChange((newState, prev) => {
+    for (const key in newState) {
+      if (key === 'pageObj') {
+        const pageObj = newState[key]
+        if (pageObj) {
+          routerParam.value = pageObj.pageType
+          if(routerParam.value !== 'home'){
             if (pageObj.deviceid) {
-              await findTreeDataValue(treeData.value, { deviceid: pageObj.deviceid })
+              findTreeDataValue(treeData.value, { deviceid: pageObj.deviceid })
             } else {
-              await findTreeDataValue(treeData.value, { deviceType: pageObj.pageType })
+              findTreeDataValue(treeData.value, { deviceType: pageObj.pageType })
             }
           }
         }
       }
-    })
-    await getDeviceType()
-    // await getDataSource()
-    // getMonitor()
-  })
-  
-  onUnmounted(() => {
-    if (timer) {
-      clearInterval(timer);
     }
   })
+  await getDeviceType()
+  // getMonitor()
+})
+onUnmounted(() => {
+  if (timer) {
+    clearTimeout(timer);
+  }
+  timer = undefined;
+})
 
 </script>
 <style lang="less" scoped >
-  @import '/@/design/vent/modal.less';
-  @ventSpace: zxm;  
-  .device-header{
-    position: fixed;
-    width: 100%;
-    height: 56px;
-    background: url('/@/assets/images/vent/home/modal-top.png');
-    text-align: center;
-    line-height: 56px;
-    font-size: 28px;
-    color: #ffffffdd;
-    font-weight: 600;
-    z-index: -1;
+@import '/@/design/vent/modal.less';
+@ventSpace: zxm;
+
+.device-header {
+  position: fixed;
+  width: 100%;
+  height: 56px;
+  background: url('/@/assets/images/vent/home/modal-top.png');
+  text-align: center;
+  line-height: 56px;
+  font-size: 28px;
+  color: #ffffffdd;
+  font-weight: 600;
+  z-index: -1;
+}
+
+.select-node {
+  position: fixed;
+  top: 60px;
+  left: 10px;
+  color: #fff;
+  display: flex;
+  justify-content: center;
+  font-size: 24px;
+
+  .title {
+    margin-left: 10px;
   }
-  .select-node{
-    position: fixed;
-    top: 60px;
-    left: 10px;
-    color: #fff;
-    display: flex;
-    justify-content: center;
-    font-size: 24px;
-    .title{
-      margin-left: 10px;
-    }
+}
+
+.device-select {
+  width: 250px;
+  height: 500px;
+  background: url('/@/assets/images/vent/home/tree-bg.png') no-repeat;
+  position: fixed;
+  top: 60px;
+  left: 10px;
+  background-size: contain;
+  pointer-events: auto;
+  padding: 20px 10px 30px 10px;
+
+  .expansion-icon {
+    position: absolute;
+    left: 190px;
+    top: 25px;
   }
-  .device-select{
-    width: 250px;
-    height: 500px;
-    background: url('/@/assets/images/vent/home/tree-bg.png') no-repeat;
-    position: fixed;
-    top: 60px;
-    left: 10px;
+}
+
+.is-expansion-icon {
+  background: url('/@/assets/images/vent/home/tree-icon-bg.png') no-repeat;
+  background-size: contain;
+  padding: 5px;
+  pointer-events: auto;
+  z-index: 999;
+
+  &:hover {
+    background: url('/@/assets/images/vent/home/tree-icon-hover-bg.png') no-repeat;
     background-size: contain;
-    pointer-events: auto;
-    padding: 20px 10px 30px 10px;
-    .expansion-icon{
-      position: absolute;
-      left: 190px;
-      top: 25px;
-    }
   }
-  .is-expansion-icon{
-    background: url('/@/assets/images/vent/home/tree-icon-bg.png') no-repeat;
-    background-size: contain;
-    padding: 5px;
-    pointer-events: auto;
-    z-index: 999;
-    &:hover{
-      background: url('/@/assets/images/vent/home/tree-icon-hover-bg.png') no-repeat;
-      background-size: contain;
-    }
-  }
-  .put-away-icon{
-    display: inline-block;
-  }
-  .device-select-show{
-    left: 10px;
-    animation-name: treeShow;
-    /* 持续时间 */
-    animation-duration: 1s;
-    transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) .5s;
-  }
-  .device-select-hide{
-    left: -250px;
-    animation-name: treeHide;
-    /* 持续时间 */
-    animation-duration: 1s;
-    transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) .5s;
-  }
-  .node-select-show{
-    left: 10px;
-    animation-name: treeShow;
-    /* 持续时间 */
-    animation-duration: 1s;
-    transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) .5s;
-  }
-  .node-select-hide{
-    left: -400px;
-    animation-name: treeHide;
-    /* 持续时间 */
-    animation-duration: 1s;
-    transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) .5s;
-  }
-  .device-select-box{
-    width: 208px;
-    height: 450px;
-    overflow-y: auto;    
-    color: #fff;    
-    :deep(.zxm-tree){
+}
+
+.put-away-icon {
+  display: inline-block;
+}
+
+.device-select-show {
+  left: 10px;
+  animation-name: treeShow;
+  /* 持续时间 */
+  animation-duration: 1s;
+  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) .5s;
+}
+
+.device-select-hide {
+  left: -250px;
+  animation-name: treeHide;
+  /* 持续时间 */
+  animation-duration: 1s;
+  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) .5s;
+}
+
+.node-select-show {
+  left: 10px;
+  animation-name: treeShow;
+  /* 持续时间 */
+  animation-duration: 1s;
+  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) .5s;
+}
+
+.node-select-hide {
+  left: -400px;
+  animation-name: treeHide;
+  /* 持续时间 */
+  animation-duration: 1s;
+  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) .5s;
+}
+
+.device-select-box {
+  width: 208px;
+  height: 450px;
+  overflow-y: auto;
+  color: #fff;
+
+  :deep(.zxm-tree) {
+    background: transparent !important;
+    color: #fff !important;
+
+    .zxm-tree-switcher {
       background: transparent !important;
-      color: #fff !important;
-      .zxm-tree-switcher{
-        background: transparent !important;
-      }
-      .zxm-tree-node-content-wrapper.zxm-tree-node-selected{
-        background-color: #00b1c8;
-      }
-      .zxm-tree-node-content-wrapper:hover{
-        background-color: #00b1c855;
-      }
-      input{
-        height: 0px !important;
-      }
     }
-    &::-webkit-scrollbar-track {
-      -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
-      border-radius: 10px;
-      background: #ededed22;
-      height: 100px;
+
+    .zxm-tree-node-content-wrapper.zxm-tree-node-selected {
+      background-color: #00b1c8;
     }
-    &::-webkit-scrollbar-thumb {
-      -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
-      background: #4288A444;
+
+    .zxm-tree-node-content-wrapper:hover {
+      background-color: #00b1c855;
     }
-  }
-  .bottom-tabs-box{
-    
-    position: relative;
-    .to-small{
-      width: 60px;
-      height: 60px;
-      background: url('/@/assets/images/vent/home/tosmall.png') no-repeat center;
-      background-size: auto;
-      position: absolute;
-      top: -65px;
-      right: 30px;
-      border-radius: 10px;
-      padding: 8px;
-      backdrop-filter: blur(10px);
-      background-color: rgba(0, 58, 128, 0.418);
-      &:hover{
-        background-color: rgba(42, 85, 138, 0.418);
-      }
+
+    input {
+      height: 0px !important;
     }
-    .device-button-group{
-      position: absolute;
-      top: -30px;
-      left: 30px;
-      display: flex;
-      width: 100%;
-      
-      .device-button{
-        padding: 4px 15px;
-        position: relative;
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        font-size: 14px;
-        
-        color: #fff;
-        cursor: pointer;
-        margin: 0 3px;
-
-        &::before{
-          content: '';
-          position: absolute;
-          top: 0;
-          right: 0;
-          bottom: 0;
-          left: 0;
-          border: 1px solid #6176AF;
-          transform: skewX(-38deg);
-          background-color: rgba(0, 77, 103,85%);
-          z-index: -1;
-        }
-      }
-      .device-active{
-        // color: #0efcff;
-        &::before{
-          border-color: #0efcff;
-          box-shadow: 1px 1px 3px 1px #0efcff inset;
-        }
-      }
+  }
+
+  &::-webkit-scrollbar-track {
+    -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
+    border-radius: 10px;
+    background: #ededed22;
+    height: 100px;
+  }
+
+  &::-webkit-scrollbar-thumb {
+    -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
+    background: #4288A444;
+  }
+}
+
+.bottom-tabs-box {
+
+  position: relative;
+
+  .to-small {
+    width: 60px;
+    height: 60px;
+    background: url('/@/assets/images/vent/home/tosmall.png') no-repeat center;
+    background-size: auto;
+    position: absolute;
+    top: -65px;
+    right: 30px;
+    border-radius: 10px;
+    padding: 8px;
+    backdrop-filter: blur(10px);
+    background-color: rgba(0, 58, 128, 0.418);
+
+    &:hover {
+      background-color: rgba(42, 85, 138, 0.418);
     }
-    .enter-detail{
-      color: #fff;
-      cursor: pointer;
-      position: absolute;
-      right: 150px;
-      top: -10px;
-      padding: 5px;
-      // border: 1px transparent solid;
-      border-radius: 5px;
-      margin-left: 8px;
-      margin-right: 8px;
-      width: auto;
-      // height: 40px;
-      // border: 1px solid #65dbea;
-      height: 33px !important;
+  }
+
+  .device-button-group {
+    position: absolute;
+    top: -30px;
+    left: 30px;
+    display: flex;
+    width: 100%;
+
+    .device-button {
+      padding: 4px 15px;
+      position: relative;
       display: flex;
-      align-items: center;
       justify-content: center;
+      align-items: center;
+      font-size: 14px;
+
       color: #fff;
-      padding: 5px 15px 5px 15px;
       cursor: pointer;
-      &:hover {
-        background: linear-gradient(#2cd1ff55, #1eb0ff55);
-      }
+      margin: 0 3px;
+
       &::before {
-        width: calc(100% - 6px);
-        height: 27px;
         content: '';
         position: absolute;
-        top: 3px;
+        top: 0;
         right: 0;
-        left: 3px;
         bottom: 0;
+        left: 0;
+        border: 1px solid #6176AF;
+        transform: skewX(-38deg);
+        background-color: rgba(0, 77, 103, 85%);
         z-index: -1;
-        border-radius: inherit; /*important*/
-        background: linear-gradient(#1fa6cb, #127cb5);
       }
-      &::after {
-        width: calc(100% + 32px);
-        height: 10px;
-        content: '';
-        position: absolute;
-        top: 35px;
-        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;
+    }
+
+    .device-active {
+
+      // color: #0efcff;
+      &::before {
+        border-color: #0efcff;
+        box-shadow: 1px 1px 3px 1px #0efcff inset;
       }
     }
   }
-  @keyframes treeShow {
-    0% {
-      left: -400px;
-      opacity: 0;
-    }
-    100% {
-      left: 10px;
-      opacity: 1;
+
+  .enter-detail {
+    color: #fff;
+    cursor: pointer;
+    position: absolute;
+    right: 120px;
+    top: -10px;
+    padding: 5px;
+    // border: 1px transparent solid;
+    border-radius: 5px;
+    margin-left: 8px;
+    margin-right: 8px;
+    width: auto;
+    // height: 40px;
+    // border: 1px solid #65dbea;
+    height: 33px !important;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: #fff;
+    padding: 5px 15px 5px 15px;
+    cursor: pointer;
+
+    &:hover {
+      background: linear-gradient(#2cd1ff55, #1eb0ff55);
     }
-  }
-  @keyframes treeHide {
-    0% {
-      left: 10px;
-      opacity: 1;
+
+    &::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);
     }
-    100% {
-      left: -400px;
-      opacity: 0;
+
+    &::after {
+      width: calc(100% + 32px);
+      height: 10px;
+      content: '';
+      position: absolute;
+      top: 35px;
+      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;
     }
   }
-  
-  :deep(.@{ventSpace}-tabs-tabpane-active) {
-    overflow: auto;
-    // height: 100%;
+}
+
+@keyframes treeShow {
+  0% {
+    left: -400px;
+    opacity: 0;
+  }
+
+  100% {
+    left: 10px;
+    opacity: 1;
   }
-  :deep(.zxm-select-dropdown){
-    left: 0 !important;
+}
+
+@keyframes treeHide {
+  0% {
+    left: 10px;
+    opacity: 1;
   }
-</style>
+
+  100% {
+    left: -400px;
+    opacity: 0;
+  }
+}
+
+:deep(.@{ventSpace}-tabs-tabpane-active) {
+  overflow: auto;
+  // height: 100%;
+}
+
+:deep(.zxm-select-dropdown) {
+  left: 0 !important;
+}</style>

+ 6 - 13
src/views/vent/monitorManager/groutMonitor/components/groutAlarmHistory.vue

@@ -1,25 +1,18 @@
 <template>
   <div class="alarm-history">
-    <AlarmHistoryTable columns-type="alarm" device-type="pressurefan"
-      :device-list-api="getTableList.bind(null, { strtype: 'pressurefan' })" designScope="alarm-history" />
+    <AlarmHistoryTable columns-type="alarm" device-type="pulping"
+      :device-list-api="getTableList.bind(null, { devicekind: 'pulping' })" designScope="alarm-history" />
   </div>
 </template>
 <script setup lang="ts">
 import AlarmHistoryTable from '../../comment/AlarmHistoryTable.vue';
 import { getTableList } from '../grout.api'
-const props = defineProps({
-  deviceType: {
-    type: String,
-    required: true,
-  },
-  deviceId: {
-    type: String,
-    required: true,
-  }
-})
+
 </script>
 <style lang="less" scoped>
 .alarm-history {
-  pointer-events: auto;
+  width: 100%;
+  position: fixed;
+  top: 80px;
 }
 </style>

+ 6 - 13
src/views/vent/monitorManager/groutMonitor/components/groutHandleHistory.vue

@@ -1,25 +1,18 @@
 <template>
   <div class="handle-history">
-    <HandlerHistoryTable columns-type="operatorhistory" device-type="pressurefan"
-      :device-list-api="getTableList.bind(null, { strtype: 'pressurefan' })" designScope="pressurefan_history" />
+    <HandlerHistoryTable columns-type="operatorhistory" device-type="pulping"
+      :device-list-api="getTableList.bind(null, { devicekind: 'pulping' })" designScope="pulping_history" />
   </div>
 </template>
 <script setup lang="ts">
 import HandlerHistoryTable from '../../comment/HandlerHistoryTable.vue';
 import { getTableList } from '../grout.api'
-  const props = defineProps({
-    deviceType: {
-      type: String,
-      required: true,
-    },
-    deviceId: {
-      type: String,
-      required: true,
-    }
-  })
+
 </script>
 <style lang="less" scoped>
 .handle-history {
-  pointer-events: auto;
+  position: fixed;
+  top: 80px;
+  z-index: 99;
 }
 </style>

+ 6 - 17
src/views/vent/monitorManager/groutMonitor/components/groutHistory.vue

@@ -1,28 +1,17 @@
 <template>
-  <div class="history-box">
-    <HistoryTable :columns-type="`${deviceType}`" :device-type="deviceType" :sysId="deviceId"
-      :device-list-api="getTableList.bind(null, { strtype: deviceType, sysId: deviceId })" designScope="pressurefan_history" />
+  <div class="grout-history">
+    <HistoryTable columns-type="pulping" device-type="pulping"
+      :device-list-api="getTableList.bind(null, { devicekind: 'pulping' })" designScope="pulping_auto_history" />
   </div>
 </template>
 <script setup lang="ts">
-import { ref, defineProps } from 'vue'
 import HistoryTable from '../../comment/HistoryTable.vue';
 import { getTableList } from '../grout.api'
 
-const props = defineProps({
-  deviceType: {
-    type: String,
-    required: true,
-  },
-  deviceId: {
-    type: String,
-    required: true,
-  }
-})
-
 </script>
 <style lang="less" scoped>
-.history-box {
-  pointer-events: auto;
+.grout-history {
+  position: fixed;
+  top: 80px;
 }
 </style>

+ 88 - 10
src/views/vent/monitorManager/groutMonitor/components/groutHome.vue

@@ -74,10 +74,42 @@
             </div>
           </template>
         </ventBox1>
+        
       </div>
-      <div class="item-box" >
-        <LivePlayer id="fm-player1" style="height: 250px;" ref="player1" :videoUrl="flvURL1()" muted live loading controls />
+      <div class="control-container item-box echarts-box">
+        <ventBox1>
+          <template #title>
+            <div>设备实时监测曲线</div>
+          </template>
+          <template #container >
+            <div class="btn-group">
+              <span class="active">注浆流量</span>
+              <span>注浆压力</span>
+              <span>水舱液位</span>
+              <span>注浆筒液位</span>
+            </div>
+            <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" />
+                </div>
+                <div class="echarts-item">
+                  <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" />
+                </div>
+                <div class="echarts-item">
+                  <BarAndLineCustom xAxisPropType="readTime" :chartData="dataSource" height="240px" :propTypeArr="['flowRate']" :option="zhujiangOption" />
+                </div>
+              </div>
+            </div>
+          </template>
+        </ventBox1>
       </div>
+      <!-- <div class="item-box" >
+        <LivePlayer id="fm-player1" style="height: 250px;" ref="player1" :videoUrl="flvURL1()" muted live loading controls />
+      </div> -->
     </div>
   </div>
   <component v-if="modalVisible" :is="currentModal" v-model:visible="modalVisible" />
@@ -85,16 +117,17 @@
 
 <script setup lang="ts">
 
-import { onBeforeMount, ref, onMounted, onUnmounted, shallowRef, defineProps, ComponentOptions } from '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 { SvgIcon } from '/@/components/Icon';
 import ventBox1 from '/@/components/vent/ventBox1.vue';
 import RunParameterModal from './runParameter.modal.vue'
 import WarningParameterModal from './warningParameter.modal.vue'
-import { warningConfig} from '../grout.data'
+import { warningConfig, zhujiangOption, yaliOption } from '../grout.data'
 import { list } from '../grout.api';
 import LivePlayer from '@liveqing/liveplayer-v3';
+import BarAndLineCustom from '/@/components/chart/BarAndLineCustom.vue';
 
 
 const props = defineProps({
@@ -103,7 +136,7 @@ const props = defineProps({
     require: true
   }
 })
-
+const left: string = "0px";
 const currentModal = shallowRef<Nullable<ComponentOptions>>(null); //模态框
 const modalVisible = ref<Boolean>(false); // 模态框是否可见
 const loading = ref(false);
@@ -116,7 +149,8 @@ const dataSource = ref([
     density: '-',
     pressure: '-',
     liquidLevel: '-',
-    flowRate: '-'
+    flowRate: '-',
+    readTime: '',
   },
   {
     waterSupply: '-',
@@ -124,9 +158,11 @@ const dataSource = ref([
     density: '-',
     pressure: '-',
     liquidLevel: '-',
-    flowRate: '-'
+    flowRate: '-',
+    readTime: '',
   }
 ]); //dusting
+
 const deviceMonitorData = {
   '1#_waterSupply': { text: '1#制浆机供水流量', unit: 'm³/h' },
   '1#_beltVla': { text: '1#皮带秤数值', unit: 'T' },
@@ -147,7 +183,6 @@ const deviceControlData = {
   'liquidLevelProtect ':'液位保护'
 }
 
-
 const flvURL1 = () => {
   return `https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv`;
   // return ''
@@ -354,11 +389,11 @@ onUnmounted(() => {
         }
         .remote-icon-box{
           transform: rotate(30deg);
-          animation: iconRotate 1s linear infinite;
+          animation: iconRotate 1s linear;
         }
         .remote-icon-box1{
           transform: rotate(-30deg);
-          animation: iconRotate1 1s linear infinite;
+          animation: iconRotate1 1s linear;
         }
 
         @keyframes iconRotate{
@@ -392,6 +427,49 @@ onUnmounted(() => {
       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;
+        }
+      }
+      .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 {

+ 132 - 36
src/views/vent/monitorManager/groutMonitor/grout.data.ts

@@ -1,4 +1,5 @@
 import { reactive } from 'vue';
+import echarts from '/@/utils/lib/echarts';
 import { BasicColumn } from '/@/components/Table';
 
 export const warningConfig = reactive({
@@ -21,43 +22,138 @@ export const warningConfig = reactive({
   align: ['center', 'center', 'center'],
 });
 
-export const sensorColumns: BasicColumn[] = [
-  {
-    title: '名称',
-    dataIndex: 'strname',
-    width: 100,
-    align: 'center',
+export const zhujiangOption = reactive({
+  tooltip: { trigger: 'axis', axisPointer: { lineStyle: { color: '#fff' } } },
+  legend: {
+    top: '10',
+    icon: 'rect',
+    data: ['注浆压力'],
+    right: '10px',
+    textStyle: { fontSize: 12, color: '#fff' },
   },
-  {
-    title: '实时值',
-    dataIndex: 'smokeval',
-    width: 80,
-    align: 'center',
+  grid: { x: 50, y: 50, x2: 12, y2: 40 },
+  xAxis: {
+    type: 'category',
+    boundaryGap: false,
+    axisLine: { lineStyle: { color: '#57617B' } },
+    axisLabel: { textStyle: { color: '#ffffffcc' } },
+    splitLine: { show: true, lineStyle: { color: '#57617B22', type: 'dashed' } },
+    data: [],
   },
-  {
-    title: '报警',
-    dataIndex: 'warnFlag',
-    width: 100,
-    align: 'center',
-  },
-];
-export const dustColumns: BasicColumn[] = [
-  {
-    title: '名称',
-    dataIndex: 'strname',
-    width: 100,
-    align: 'center',
-  },
-  {
-    title: '链接状态',
-    dataIndex: 'netStatus',
-    width: 80,
-    align: 'center',
+  yAxis: [
+    {
+      type: 'value',
+      name: 'm³/h',
+      max: 10,
+      axisTick: {
+        show: false,
+      },
+      axisLine: { lineStyle: { show: true, color: '#57617B' } },
+      axisLabel: { margin: 10, textStyle: { fontSize: 12, color: '#ffffffcc' } },
+      splitLine: { show: true, lineStyle: { color: '#57617B22', type: 'dashed' } },
+    },
+  ],
+  series: [
+    {
+      name: '注浆流量',
+      type: 'line',
+
+      smooth: true,
+      lineStyle: { normal: { width: 2 } },
+      yAxisIndex: 0,
+      areaStyle: {
+        normal: {
+          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: { normal: { color: '#B996F8' } },
+      data: [],
+    },
+  ],
+});
+
+export const yaliOption = reactive({
+  tooltip: { trigger: 'axis', axisPointer: { lineStyle: { color: '#fff' } } },
+  legend: {
+    top: '10',
+    icon: 'rect',
+    data: ['注浆压力'],
+    right: '10px',
+    textStyle: { fontSize: 12, color: '#fff' },
   },
-  {
-    title: '操作',
-    dataIndex: 'action',
-    width: 100,
-    align: 'center',
+  grid: { x: 50, y: 50, x2: 12, y2: 40 },
+  xAxis: {
+    type: 'category',
+    boundaryGap: false,
+    axisLine: { lineStyle: { color: '#57617B' } },
+    axisLabel: { textStyle: { color: '#ffffffcc' } },
+    splitLine: { show: true, lineStyle: { color: '#57617B22', type: 'dashed' } },
+    data: [],
   },
-];
+  yAxis: [
+    {
+      type: 'value',
+      name: 'm³/h',
+      max: 10,
+      axisTick: {
+        show: false,
+      },
+      axisLine: { lineStyle: { show: true, color: '#57617B' } },
+      axisLabel: { margin: 10, textStyle: { fontSize: 12, color: '#ffffffcc' } },
+      splitLine: { show: true, lineStyle: { color: '#57617B22', type: 'dashed' } },
+    },
+  ],
+  series: [
+    {
+      name: '注浆压力',
+      type: 'line',
+
+      smooth: true,
+      lineStyle: { normal: { width: 2 } },
+      yAxisIndex: 0,
+      areaStyle: {
+        normal: {
+          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: { normal: { color: '#03C2EC' } },
+      data: [],
+    },
+  ],
+});

+ 6 - 67
src/views/vent/monitorManager/groutMonitor/index.vue

@@ -17,17 +17,14 @@
     </div> -->
   </div>
   <div class="scene-box">
-    <customHeader :fieldNames="{ label: 'strinstallpos', value: 'deviceID', options: 'children' }" :options = 'options' @change="getSelectRow" :optionValue="optionValue">智能注浆系统</customHeader>
+    <customHeader >智能注浆系统</customHeader>
     <div class="center-container">
       <groutHome v-if="activeKey == 'monitor'" :deviceId = 'optionValue' />
       <div v-else class="history-group">
-        <div class="device-button-group" v-if="deviceList.length > 0">
-          <div class="device-button" :class="{ 'device-active': deviceActive == device.deviceType }" v-for="(device, index) in deviceList" :key="index" @click="deviceChange(index)">{{ device.deviceName }}</div>
-        </div>
         <div class="history-container">
-          <groutHistory v-if="activeKey == 'monitor_history'" ref="historyTable" class="vent-margin-t-20" :deviceId = 'optionValue' :device-type="deviceType"/>
-          <groutHandleHistoryVue v-if="activeKey == 'handler_history'" ref="alarmHistoryTable" class="vent-margin-t-20" :deviceId = 'optionValue' :device-type="deviceType" />
-          <groutAlarmHistory v-if="activeKey == 'faultRecord'" ref="handlerHistoryTable" class="vent-margin-t-20" :deviceId = 'optionValue' :device-type="deviceType"/>
+          <groutHistory v-if="activeKey == 'monitor_history'" ref="historyTable" class="vent-margin-t-20"/>
+          <groutHandleHistoryVue v-if="activeKey == 'handler_history'" ref="alarmHistoryTable" class="vent-margin-t-20"  />
+          <groutAlarmHistory v-if="activeKey == 'faultRecord'" ref="handlerHistoryTable" class="vent-margin-t-20"/>
         </div> 
       </div>      
     </div>
@@ -55,12 +52,6 @@ const historyTable = ref()
 const alarmHistoryTable = ref()
 const handlerHistoryTable = ref()
 
-
-//关联设备
-const deviceList = ref<DeviceType[]>([])
-const deviceActive = ref('')
-const deviceType = ref('')
-
 const options = ref()
 // 默认初始是第一行
 const selectRowIndex = ref(0);
@@ -75,65 +66,12 @@ function changeActive(activeValue) {
   activeKey.value = activeValue
 }
 
-function deviceChange(index) {
-  deviceActive.value = deviceType.value = deviceList.value[index].deviceType
-}
-
-// 查询关联设备列表
-async function getDeviceList() {
-  const res = await list({ devicetype: 'sys', systemID: optionValue.value });
-  const result = res.msgTxt;
-  const deviceArr = <DeviceType[]>[]
-  result.forEach(item => {
-    const data = item['datalist'].filter((data: any) => {
-      const readData = data.readData;
-      return Object.assign(data, readData);
-    })
-    if (item.type != 'sys') {
-      deviceArr.unshift({ deviceType: item.type, deviceName: item['typeName'] ? item['typeName'] : item['datalist'][0]['typeName'], datalist: data })
-    }
-  })
-  deviceList.value = deviceArr
-  deviceActive.value = deviceArr[0].deviceType
-  deviceChange(0)
-};
-
-async function getSysDataSource () {
-  const res = await list({ devicetype: 'sys_dongshi', pagetype: 'normal' });
-  dataSource.value = res.msgTxt[0].datalist || [];
-  dataSource.value.forEach((data: any) => {
-    const readData = data.readData;
-    data = Object.assign(data, readData);
-  });
-  
-  if(!options.value) {
-    // 初始时选择第一条数据
-    options.value = dataSource.value
-    optionValue.value = dataSource.value[0]['deviceID']
-    Object.assign(selectData,  dataSource.value[0])
-  }
-  const data: any = toRaw(dataSource.value[selectRowIndex.value]); //maxarea
-  return data;
-};
-
-// 切换检测数据
-function getSelectRow(deviceID){
-  const currentData = dataSource.value.find((item: any) => {
-    return item.deviceID == deviceID
-  })
-  if(currentData){
-    optionValue.value = currentData['deviceID']
-    Object.assign(selectData, currentData)
-  }
-}
-
 onBeforeMount(() => {
 
 });
 
 onMounted(async() => {
-  await getSysDataSource()
-  await getDeviceList()
+
 });
 onUnmounted(() => {
  
@@ -154,6 +92,7 @@ onUnmounted(() => {
       left: -10px;
       border: 1px solid #ffffff22;
       padding: 10px 0;
+      pointer-events: auto;
     }
   }
   .device-button-group{

+ 247 - 68
src/views/vent/monitorManager/nitrogen/components/nitrogenHome.vue

@@ -55,72 +55,94 @@
         <div class="top-box">
           <!-- 左边监测数据 -->
           <div class="lr-box left-box">
-            <div class="item item-l" v-for="groupNum in monitorDataGroupNum" :key="groupNum">
-              <div class="monitor-box">
-                <!-- <div class="device-title">{{ monitorData[groupNum - 1]['strName'] }}</div>-->
-                <dv-decoration7 style="height:30px;">
-                  <div class="base-title">{{ groupNum }}号空压机组</div>
-                </dv-decoration7>
-                <div class="state-item" v-for="(data, index) in showMonitorData" :key="index">
-                  <div class="item-col">
-                    <span class="state-title">{{ Object.values(data)[0] }} :</span>
-                    <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[0]])
-                      >= 0 ? monitorData[groupNum - 1][Object.keys(data)[0]] : '-' }}</span>
-                  </div>
-                  <div class="item-col">
-                    <span class="state-title">{{ Object.values(data)[1] }} :</span>
-                    <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[1]])
-                      >= 0 ? monitorData[groupNum - 1][Object.keys(data)[1]] : '-' }}</span>
-                  </div>
+            <div class="left-container">
+              <div class="item item-l" v-for="groupNum in monitorDataGroupNum" :key="groupNum">
+                <div class="monitor-box">
+                  <ventBox1>
+                    <template #title>
+                      <div>{{ groupNum }}号空压机组</div>
+                    </template>
+                    <template #container>
+                      <div class="state-item" v-for="(data, index) in showMonitorData" :key="index">
+                        <div class="item-col">
+                          <span class="state-title">{{ Object.values(data)[0] }} :</span>
+                          <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[0]])
+                            >= 0 ? monitorData[groupNum - 1][Object.keys(data)[0]] : '-' }}</span>
+                        </div>
+                        <div class="item-col">
+                          <span class="state-title">{{ Object.values(data)[1] }} :</span>
+                          <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[1]])
+                            >= 0 ? monitorData[groupNum - 1][Object.keys(data)[1]] : '-' }}</span>
+                        </div>
+                      </div>
+                    </template>
+                  </ventBox1>                
                 </div>
               </div>
             </div>
           </div>
           <!-- 右边控制状态 -->
           <div class="lr-box right-box">
-            <div class="item">
-              <div class="control-item">
-                <div class="control-item-l">
-                  <!-- <img src="@/assets/img/yccz.png" alt="" width="36px" height="36px" style="margin-right: 10px;"> -->
-                  <span style="font-size: 18px;">远程控制</span>
-                </div>
-              </div>
-              <div class="control-item" v-for="groupNum in monitorDataGroupNum" :key="groupNum">
-                <div class="control-item-l">
-                  <span class="round"></span>
-                  <span>{{ kyjs[groupNum - 1] }}</span>
-                </div>
-                <div class="control-item-r" style="display: flex; align-items: center;">
-                  <a-switch v-model="airCompressorState[groupNum - 1][`compressRunSigF1`]" checked-children="开启"
-                    un-checked-children="关闭" :disabled="airCompressorState[groupNum - 1][`controlModel`]"
-                    @change="handlerDevice(airCompressorState[groupNum - 1])">
-                  </a-switch>
-                </div>
-              </div>
-              <div class="control-item">
-                <div class="control-item-l">
-                  <span class="round"></span>
-                  <span>控制模式</span>
-                </div>
-                <div>
-                  <a-switch v-model="airCompressorState[0][`controlModel`]" checked-children="就地" un-checked-children="远程"
-                    @change="handlerControlModel(airCompressorState[0])">
-                  </a-switch>
-                </div>
-              </div>
-              <div class="control-item">
-                <div class="control-item-l">
-                  <span class="round"></span>
-                  <span>是否开启联动</span>
-                </div>
-                <div class="item-data-box" style="display: flex">
-                  <div
-                    :class="{ 'state-icon': true, 'open': monitorData[0].linkState, 'close': !monitorData[0].linkState }">
+            <ventBox1>
+              <template #title>
+                <div>远程控制</div>
+              </template>
+              <template #container>
+                <div class="control-group">
+                  <div class="control-item" v-for="groupNum in monitorDataGroupNum" :key="groupNum">
+                    <div class="control-item-title">{{ kyjs[groupNum - 1] }}</div>
+                    <div class="control-item-state">
+                      <a-switch v-model="airCompressorState[groupNum - 1][`compressRunSigF1`]" size="small"  checked-children="开启"
+                        un-checked-children="关闭" :disabled="airCompressorState[groupNum - 1][`controlModel`]"
+                        @change="handlerDevice(airCompressorState[groupNum - 1])">
+                      </a-switch>
+                    </div>
+                  </div>
+                  <div class="control-item" v-for="groupNum in monitorDataGroupNum" :key="groupNum">
+                    <div class="control-item-title">{{ cqgs[groupNum - 1] }}</div>
+                    <div class="control-item-state">
+                      <a-switch v-model="airCompressorState[groupNum - 1][`compressRunSigF1`]" size="small"  checked-children="开启"
+                        un-checked-children="关闭" :disabled="airCompressorState[groupNum - 1][`controlModel`]"
+                        @change="handlerDevice(airCompressorState[groupNum - 1])">
+                      </a-switch>
+                    </div>
+                  </div>
+                  
+                  <a-divider style="height: 1px; background-color: #d7d7d755" />
+                  <div class="control-btn-group">
+                    <div class="control-left-box">
+                      <div class="btn-box">
+                        <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"></div>
+                      </div>
+                    </div>
+                    <div class="control-right-box">
+                      <div class="control-item-title">是否开启联动</div>
+                      <div class="item-data-box" >
+                        <div :class="{ 'state-icon': true, 'open': monitorData[0].linkState, 'close': !monitorData[0].linkState }">
+                        </div>
+                        <div >{{ !monitorData[0].linkState ? '不联动' : '联动' }}</div>
+                      </div>
+                    </div>
                   </div>
-                  <div style="margin-left: 10px;">{{ !monitorData[0].linkState ? '不联动' : '联动' }}</div>
                 </div>
+              </template>
+            </ventBox1>
+            
+            <!-- <div class="control-item">
+              <div class="control-item-l">
+                <span class="round"></span>
+                <span>控制模式</span>
               </div>
-            </div>
+              <div>
+                <a-switch v-model="airCompressorState[0][`controlModel`]" checked-children="就地" un-checked-children="远程"
+                  @change="handlerControlModel(airCompressorState[0])">
+                </a-switch>
+              </div>
+            </div> -->
           </div>
         </div>
       </div>
@@ -128,10 +150,10 @@
 </template>
 <script lang="ts" setup name="nitrogenHome">
 import { onMounted, onUnmounted, ref, watch } from 'vue'
-import { Decoration7 as DvDecoration7 } from '@kjgl77/datav-vue3'
 import fourBorderBg from '../../../comment/components/fourBorderBg.vue'
 import { mountedThree, destroy } from '../nitrogen.threejs'
 import { list } from '../nitrogen.api'
+import ventBox1 from '/@/components/vent/ventBox1.vue'
 
 const loading = ref(true)
 
@@ -409,11 +431,10 @@ onUnmounted(() => {
       justify-content: space-between;
 
       .lr-box {
-        height: fit-content;
         display: flex;
         flex-direction: column;
         position: relative;
-        overflow: hidden;
+
         z-index: 9999;
       }
 
@@ -584,23 +605,181 @@ onUnmounted(() => {
         width: 335px;
 
         .monitor-box {
-          width: 335px;
+          // width: 335px;
           background-color: #ffffff05;
-          margin-left: 2px;
-          border-radius: 5px;
-          backdrop-filter: blur(10px);
+          // margin-left: 2px;
+          // border-radius: 5px;
+          // backdrop-filter: blur(10px);
         }
       }
 
       .right-box {
-        .item {
-          height: auto;
+         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-box {
-        width: 365px;
-
+        height: calc(100% );
+        overflow-x: hidden;
+        overflow-y: auto;
+        pointer-events: auto;
+        direction: rtl;
+        .left-container{
+          direction: ltr;
+        }
         .control-item {
           height: 36px;
         }

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

@@ -66,7 +66,7 @@ export const setModelType = (type) => {
       group = nitrogenObj.group;
       // setModalCenter(group);
       const oldCameraPosition = { x: -1000, y: 100, z: 500 };
-      const oldControlsPosition = { x: -10, y: 10, z: 10 };
+      const oldControlsPosition = { x: 0, y: 0, z: 0 };
       model.scene.add(nitrogenObj.group);
       setTimeout(async () => {
         resolve(null);