Procházet zdrojové kódy

1.新增大柳塔井的注氮监测功能

hongrunxia před 1 rokem
rodič
revize
35911a4a79

+ 1535 - 0
src/views/vent/monitorManager/compressor/components/nitrogenHome_bd.vue

@@ -0,0 +1,1535 @@
+<template>
+    <div>{{ Math.random() }}</div>
+    <div id="nitrogen3D" style="width: 100%; height: 100%; position: absolute; overflow: hidden"></div>
+    <div id="nitrogenCss3D" class="threejs-Object-CSS"
+        style="width: 100%; height: 100%; position: absolute; pointer-events: none; overflow: hidden; z-index: 2; top: 0px; left: 0px">
+        <a-spin :spinning="loading" />
+        <template>
+            <div v-for="groupNum in 1" :key="groupNum" class="modal-monitor">
+                <fourBorderBg :class="`kyj${groupNum}`" :id="`nitrogenMonitor${groupNum}`">
+                    <div class="title">{{ monitorData[0]['strname'] }} </div>
+                    <div class="monitor-item">
+                        <span class="monitor-title">实时流量:</span>
+                        <span class="monitor-val" v-if="!refresh"><span class="val">{{
+                            monitorData[0]['flow'] ? monitorData[0]['flow'] : '-' }}</span>
+                            <span class="unit">m³/min</span></span>
+                    </div>
+
+                    <div class="monitor-item">
+                        <span class="monitor-title">单次流量:</span>
+                        <span class="monitor-val" v-if="!refresh"><span class="val">{{
+                            monitorData[0]['single_flow'] ? monitorData[0]['single_flow'] : '-'
+                        }}</span>
+                            <span class="unit">m³</span></span>
+                    </div>
+
+                    <div class="monitor-item">
+                        <span class="monitor-title">总流量:</span>
+                        <span class="monitor-val" v-if="!refresh"><span class="val">{{
+                            monitorData[0]['total_flow'] ? monitorData[0]['total_flow'] : '-'
+                        }}</span>
+                            <span class="unit">m³</span></span>
+                    </div>
+
+                    <div class="monitor-item">
+                        <span class="monitor-title">氧浓度:</span>
+                        <span class="monitor-val" v-if="!refresh"><span class="val">{{
+                            monitorData[0]['oxygen_concentration'] ? monitorData[0]['oxygen_concentration'] : '-'
+                        }}</span>
+                            <span class="unit">%</span></span>
+                    </div>
+
+                </fourBorderBg>
+            </div>
+        </template>
+    </div>
+    <div class="nitrogen-home">
+        <div class="nitrogen-container">
+            <div class="top-box">
+                <!-- 中间区域控制按钮 -->
+                <div class="center-item-box">
+                    <div class="top-left">
+                        <div class="button-box" @click="handlerDevice(airCompressorState[0], '主机启动')">主机启动</div>
+                        <div class="button-box" @click="handlerDevice(airCompressorState[0], '主机停止')">主机停止</div>
+                        <div class="button-box" @click="handlerDevice(airCompressorState[0], '备机启动')">备机启动</div>
+                        <div class="button-box" @click="handlerDevice(airCompressorState[0], '备机停止')">备机停止</div>
+                    </div>
+                    <div class="top-center">
+                        <div class="top-c-label">通信状态:</div>
+                        <div class="top-c-val">{{ monitorData[0]['netStatus']==1 ? '连接' : monitorData[0]['netStatus']==0 ? '断开' : '未知'  }}</div>
+                    </div>
+                    <div class="top-right">
+                        <div class="control-type">
+                            <div class="control-title">运行状态:</div>
+                            <a-radio-group v-model:value="monitorData[0]['overhaul_run']">
+                                <a-radio :value="`1`" disabled>检修</a-radio>
+                                <a-radio :value="`0`" disabled>运行</a-radio>
+                            </a-radio-group>
+                        </div>
+                        <div class="control-type">
+                            <div class="control-title">控制模式:</div>
+                            <a-radio-group v-model:value="monitorData[0]['remote_local']">
+                                <a-radio :value="`1`" disabled>就地</a-radio>
+                                <a-radio :value="`0`" disabled>远程</a-radio>
+                            </a-radio-group>
+                        </div>
+
+                    </div>
+                </div>
+                <!-- 底部区域故障数据 -->
+                <div class="footer-item-box">
+                    <div class="device-detail">
+                        <div class="device-title">&nbsp</div>
+                        <div class="device-val">主机进气蝶阀</div>
+                        <div class="device-val">主机出气蝶阀</div>
+                        <div class="device-val">备机进气蝶阀</div>
+                        <div class="device-val">备机出气蝶阀</div>
+                        <!-- <div class="device-val">故障</div> -->
+                    </div>
+                    <div v-for="(device, key) in deviceMonitorList" class="device-detail" :key="key">
+                        <div class="device-title">{{ device.title }}</div>
+                        <div v-for="(detailItem, index) in device.dataList" :key="detailItem.code" class="device-val">
+                            <span :style="{ color: monitorData[0][detailItem.code] != '1' ? '#BFBFBF' : '#10BC79' }">{{
+                                monitorData[0][detailItem.code] == '0' ? '正常' : monitorData[0][detailItem.code] == '1' ?
+                                '故障' :
+                                '-'
+                            }}</span>
+                            <!-- <span v-if="index == 1"
+                                :style="{ color: monitorData[0][detailItem.code] != '1' ? '#BFBFBF' : '#10BC79' }">{{
+                                    monitorData[0][detailItem.code] == '0' ? '正常' : monitorData[0][detailItem.code] == '1' ? '故障' :
+                                    '-'
+                                }}</span> -->
+                        </div>
+                    </div>
+                </div>
+
+                <!-- 左边监测数据 -->
+                <div class="lr-box left-box">
+                    <div class="item item-l" v-for="(groupNum, ind) in monitorDataGroupNum" :key="groupNum">
+                        <ventBox1>
+                            <template #title>
+                                <!-- <div>{{ monitorData[groupNum - 1]['strname'] }}</div>   -->
+                                <div v-if="ind == 0">{{ `${monitorData[0]['strname']}-主` }}</div>
+                                <div v-else>{{ `${monitorData[0]['strname']}-备` }}</div>
+                            </template>
+                            <template #container>
+                                <div class="monitor-box">
+                                    <div class="parameter-title group-parameter-title">
+                                        <SvgIcon class="icon" size="38" name="device-group-paramer" /><span>进气蝶阀参数</span>
+                                    </div>
+
+                                    <div v-if="ind == 0">
+                                        <div class="state-item" v-for="(data, index) in groupParameterData" :key="index">
+                                            <div class="item-col">
+                                                <span class="state-title1">{{ Object.values(data)[0] }} :</span>
+                                                <span class="state-val1" v-if="index == 0">{{
+                                                    (monitorData.length > 0 && monitorData[0][Object.keys(data)[0]])
+                                                    >= 0
+                                                    ? monitorData[0][Object.keys(data)[0]] ?
+                                                        parseFloat(monitorData[0][Object.keys(data)[0]]).toFixed(2) : '-'
+                                                    : '-'
+                                                }}</span>
+
+                                                <span class="state-val" v-else>
+                                                    <span v-if="monitorData[0][Object.keys(data)[0]] == '0'"
+                                                        style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: blue;"></span>
+                                                    <span v-else-if="monitorData[0][Object.keys(data)[0]] == '1'"
+                                                        style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: greenyellow;"></span>
+                                                    <span v-else
+                                                        style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: #ccc;"></span>
+
+                                                </span>
+                                            </div>
+                                            <div class="item-col" v-if="Object.keys(data)[1]">
+                                                <span class="state-title1">{{ Object.values(data)[1] }} :</span>
+                                                <span class="state-val1">
+                                                    <span v-if="monitorData[0][Object.keys(data)[1]] == '0'"
+                                                        style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: blue;"></span>
+                                                    <span v-else-if="monitorData[0][Object.keys(data)[1]] == '1'"
+                                                        style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: greenyellow;"></span>
+                                                    <span v-else
+                                                        style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: #ccc;"></span>
+
+                                                </span>
+                                            </div>
+                                        </div>
+                                    </div>
+
+                                    <div v-else>
+                                        <div class="state-item" v-for="(data, index) in groupParameterData1" :key="index">
+                                            <div class="item-col">
+                                                <span class="state-title1">{{ Object.values(data)[0] }} :</span>
+                                                <span class="state-val1" v-if="index == 0">{{
+                                                    (monitorData.length > 0 && monitorData[0][Object.keys(data)[0]])
+                                                    >= 0
+                                                    ? monitorData[0][Object.keys(data)[0]] ?
+                                                        parseFloat(monitorData[0][Object.keys(data)[0]]).toFixed(2) : '-'
+                                                    : '-'
+                                                }}</span>
+
+                                                <span class="state-val" v-else>
+                                                    <span v-if="monitorData[0][Object.keys(data)[0]] == '0'"
+                                                        style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: blue;"></span>
+                                                    <span v-else-if="monitorData[0][Object.keys(data)[0]] == '1'"
+                                                        style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: greenyellow;"></span>
+                                                    <span v-else
+                                                        style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: #ccc;"></span>
+
+                                                </span>
+                                            </div>
+                                            <div class="item-col" v-if="Object.keys(data)[1]">
+                                                <span class="state-title1">{{ Object.values(data)[1] }} :</span>
+                                                <span class="state-val1">
+                                                    <span v-if="monitorData[0][Object.keys(data)[1]] == '0'"
+                                                        style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: blue;"></span>
+                                                    <span v-else-if="monitorData[0][Object.keys(data)[1]] == '1'"
+                                                        style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: greenyellow;"></span>
+                                                    <span v-else
+                                                        style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: #ccc;"></span>
+
+                                                </span>
+                                            </div>
+                                        </div>
+                                    </div>
+
+                                </div>
+                                <div class="monitor-box monitor-box1 ">
+                                    <div class="parameter-title device-parameter-title">
+                                        <SvgIcon class="icon" size="32" name="device-paramer" /><span>出气蝶阀参数</span>
+                                    </div>
+                                    <div class="state-box">
+                                        <div v-if="ind == 0">
+                                            <div class="state-item" v-for="(data, index) in deviceParameterData"
+                                                :key="index">
+                                                <div class="item-col">
+                                                    <span class="state-title1">{{ Object.values(data)[0] }} :</span>
+                                                    <span class="state-val1" v-if="index == 0">{{
+                                                        (monitorData.length > 0 && monitorData[0][Object.keys(data)[0]])
+                                                        >= 0
+                                                        ? monitorData[0][Object.keys(data)[0]] ?
+                                                            parseFloat(monitorData[0][Object.keys(data)[0]]).toFixed(2) : '-'
+                                                        : '-'
+                                                    }}</span>
+
+                                                    <span class="state-val" v-else>
+                                                        <span v-if="monitorData[0][Object.keys(data)[0]] == '0'"
+                                                            style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: blue;"></span>
+                                                        <span v-else-if="monitorData[0][Object.keys(data)[0]] == '1'"
+                                                            style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: greenyellow;"></span>
+                                                        <span v-else
+                                                            style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: #ccc;"></span>
+                                                    </span>
+                                                </div>
+                                                <div class="item-col" v-if="Object.keys(data)[1]">
+                                                    <span class="state-title1">{{ Object.values(data)[1] }} :</span>
+                                                    <span class="state-val1">
+                                                        <span v-if="monitorData[0][Object.keys(data)[1]] == '0'"
+                                                            style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: blue;"></span>
+                                                        <span v-else-if="monitorData[0][Object.keys(data)[1]] == '1'"
+                                                            style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: greenyellow;"></span>
+                                                        <span v-else
+                                                            style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: #ccc;"></span>
+                                                    </span>
+                                                </div>
+                                            </div>
+                                        </div>
+                                        <div v-else>
+                                            <div class="state-item" v-for="(data, index) in deviceParameterData1"
+                                                :key="index">
+                                                <div class="item-col">
+                                                    <span class="state-title1">{{ Object.values(data)[0] }} :</span>
+                                                    <span class="state-val1" v-if="index == 0">{{
+                                                        (monitorData.length > 0 && monitorData[0][Object.keys(data)[0]])
+                                                        >= 0
+                                                        ? monitorData[0][Object.keys(data)[0]] ?
+                                                            parseFloat(monitorData[0][Object.keys(data)[0]]).toFixed(2) : '-'
+                                                        : '-'
+                                                    }}</span>
+
+                                                    <span class="state-val" v-else>
+                                                        <span v-if="monitorData[0][Object.keys(data)[0]] == '0'"
+                                                            style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: blue;"></span>
+                                                        <span v-else-if="monitorData[0][Object.keys(data)[0]] == '1'"
+                                                            style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: greenyellow;"></span>
+                                                        <span v-else
+                                                            style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: #ccc;"></span>
+
+                                                    </span>
+                                                </div>
+                                                <div class="item-col" v-if="Object.keys(data)[1]">
+                                                    <span class="state-title1">{{ Object.values(data)[1] }} :</span>
+                                                    <span class="state-val1">
+                                                        <span v-if="monitorData[0][Object.keys(data)[1]] == '0'"
+                                                            style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: blue;"></span>
+                                                        <span v-else-if="monitorData[0][Object.keys(data)[1]] == '1'"
+                                                            style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: greenyellow;"></span>
+                                                        <span v-else
+                                                            style="display: inline-block; width: 10px;height: 10px;border-radius: 50%;background-color: #ccc;"></span>
+                                                    </span>
+                                                </div>
+                                            </div>
+                                        </div>
+
+                                    </div>
+
+                                </div>
+                            </template>
+                        </ventBox1>
+                    </div>
+
+                </div>
+                <!-- 右边控制状态 -->
+                <div class="lr-box right-box">
+
+                    <ventBox1 class="vent-margin-t-10">
+                        <template #title>
+                            <div>设备实时监测曲线</div>
+                        </template>
+                        <template #container>
+                            <BarAndLine v-if="chartsColumns.length > 0" xAxisPropType="readTime" :dataSource="echartData"
+                                height="340px" :chartsColumns="chartsColumns" chartsType="listMonitor"
+                                :option="echatsOption" />
+                            <!-- :option="zhudanOption" -->
+                        </template>
+                    </ventBox1>
+                </div>
+            </div>
+        </div>
+    </div>
+    <HandleModal :modal-is-show="modalIsShow" :modal-title="modalTitle" :modal-type="modalType" @handle-ok="handleOK"
+        @handle-cancel="handleCancel" />
+</template>
+<script lang="ts" setup name="nitrogenHome">
+import { onMounted, onUnmounted, ref, watch, reactive, defineProps, nextTick, inject, computed } from 'vue';
+import ventBox1 from '/@/components/vent/ventBox1.vue';
+import fourBorderBg from '../../../comment/components/fourBorderBg.vue';
+import { mountedThree, destroy, setModelType, addText } from '../nitrogen.threejs';
+import { getDevice } from '../nitrogen.api';
+import { SvgIcon } from '/@/components/Icon';
+import BarAndLine from '/@/components/chart/BarAndLine.vue';
+import HandleModal from './modal.vue';
+import { deviceControlApi } from '/@/api/vent/index';
+import { message } from 'ant-design-vue';
+import lodash from 'lodash';
+const globalConfig = inject('globalConfig');
+
+const props = defineProps({
+    deviceId: {
+        type: String,
+        require: true,
+    },
+    modalType: {
+        type: String,
+        require: true,
+    },
+});
+const refresh = ref(false)
+const modalTitle = ref(''); // 模态框标题显示内容,根据设备操作类型决定
+const modalType = ref(''); // 模态框内容显示类型,设备操作类型
+const modalIsShow = ref<boolean>(false); // 是否显示模态框
+const loading = ref(true);
+let kzParam = reactive<any>({
+    data: {},
+    isFw: '',
+});
+
+const flvURL1 = () => {
+    // return `https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv`;
+    return '';
+};
+const colors = ['#FDB146', '#EE6666', '#9BCB75', '#03C2EC', '#DA3914', '#9C83D9']
+const echatsOption = {
+    grid: {
+        top: '20%',
+        left: '0px',
+        right: '10px',
+        bottom: '3%',
+        containLabel: true
+    },
+    toolbox: {
+        feature: {}
+    }
+}
+const monitorDataGroupNum = ref(0);
+let airCompressorState = reactive<any[]>([]);
+
+//主机进气
+const groupParameterData = [
+    {
+        m_in_open: '开度',
+        m_bv_in_remote: '远控',
+    },
+    {
+        m_bv_in_open: '开到位',
+        m_bv_in_close: '关到位',
+    },
+
+];
+//备机进气
+const groupParameterData1 = [
+    {
+        b_in_open: '开度',
+        b_bv_in_remote: '远控',
+    },
+    {
+        b_bv_in_open: '开到位',
+        b_bv_in_close: '关到位',
+    },
+
+];
+//主机出气
+const deviceParameterData = [
+    {
+        m_out_open: '开度',
+        m_bv_out_remote: '远控',
+    },
+    {
+        m_bv_out_open: '开到位',
+        m_bv_out_close: '关到位',
+    },
+];
+//备机出气
+const deviceParameterData1 = [
+    {
+        b_out_open: '开度',
+        b_bv_out_remote: '远控',
+    },
+    {
+        b_bv_out_open: '开到位',
+        b_bv_out_close: '关到位',
+    },
+];
+
+
+const deviceMonitorList = reactive([
+    {
+        title: '负载短路故障',
+        dataList: [
+            {
+                title: '主机-进',
+                code: 'm_in_load_short',
+            },
+            {
+                title: '主机-出',
+                code: 'm_out_load_short',
+            },
+            {
+                title: '备机-进',
+                code: 'b_in_load_short',
+            },
+            {
+                title: '备机-出',
+                code: 'b_out_load_short',
+            },
+        ],
+    },
+
+    {
+        title: '电压过低故障',
+        dataList: [
+            {
+                title: '主机-进',
+                code: 'm_in_low_voltage',
+            },
+            {
+                title: '主机-出',
+                code: 'm_out_low_voltage',
+            },
+            {
+                title: '备机-进',
+                code: 'b_in_low_voltage',
+            },
+
+            {
+                title: '备机-出',
+                code: 'b_out_low_voltage',
+            },
+
+        ],
+    },
+
+    {
+        title: '电压过高故障',
+        dataList: [
+            {
+                title: '主机-进',
+                code: 'm_in_high_voltage',
+            },
+            {
+                title: '主机-出',
+                code: 'm_out_high_voltage',
+            },
+            {
+                title: '备机-进',
+                code: 'b_in_high_voltage',
+            },
+
+            {
+                title: '备机-出',
+                code: 'b_out_high_voltage',
+            },
+
+        ],
+    },
+
+    {
+        title: '电机漏电故障',
+        dataList: [
+            {
+                title: '主机-进',
+                code: 'm_in_motor_leakage',
+            },
+            {
+                title: '主机-出',
+                code: 'm_out_motor_leakage',
+            },
+            {
+                title: '备机-进',
+                code: 'b_in_motor_leakage',
+            },
+
+            {
+                title: '备机-出',
+                code: 'b_out_motor_leakage',
+            },
+
+        ],
+    },
+
+    {
+        title: '电源缺相故障',
+        dataList: [
+            {
+                title: '主机-进',
+                code: 'm_in_supply_phase',
+            },
+            {
+                title: '主机-出',
+                code: 'm_out_supply_phase',
+            },
+            {
+                title: '备机-进',
+                code: 'b_in_supply_phase',
+            },
+
+            {
+                title: '备机-出',
+                code: 'b_out_supply_phase',
+            },
+        ],
+    },
+
+    {
+        title: '关向过力矩故障',
+        dataList: [
+            {
+                title: '主机-进',
+                code: 'm_in_closing_overtorque',
+            },
+            {
+                title: '主机-出',
+                code: 'm_out_closing_overtorque',
+            },
+            {
+                title: '备机-进',
+                code: 'b_in_closing_overtorque',
+            },
+
+            {
+                title: '备机-出',
+                code: 'b_out_closing_overtorque',
+            },
+
+        ],
+    },
+
+    {
+        title: '开向过力矩故障',
+        dataList: [
+            {
+                title: '主机-进',
+                code: 'm_in_opening_overtorque',
+            },
+            {
+                title: '主机-出',
+                code: 'm_out_opening_overtorque',
+            },
+            {
+                title: '备机-进',
+                code: 'b_in_opening_overtorque',
+            },
+
+            {
+                title: '备机-出',
+                code: 'b_out_opening_overtorque',
+            },
+
+        ],
+    },
+
+    {
+        title: '关向过电流故障',
+        dataList: [
+            {
+                title: '主机-进',
+                code: 'm_in_closing_overcurrent',
+            },
+            {
+                title: '主机-出',
+                code: 'm_out_closing_overcurrent',
+            },
+            {
+                title: '备机-进',
+                code: 'b_in_closing_overcurrent',
+            },
+
+            {
+                title: '备机出',
+                code: 'b_out_closing_overcurrent',
+            },
+
+        ],
+    },
+
+    {
+        title: '开向过电流故障',
+        dataList: [
+            {
+                title: '主机-进',
+                code: 'm_in_opening_overcurrent',
+            },
+            {
+                title: '主机-出',
+                code: 'm_out_opening_overcurrent',
+            },
+            {
+                title: '备机-进',
+                code: 'b_in_opening_overcurrent',
+            },
+
+            {
+                title: '备机-出',
+                code: 'b_out_opening_overcurrent',
+            },
+
+        ],
+    },
+
+    {
+        title: '关向超时故障',
+        dataList: [
+            {
+                title: '主机-进',
+                code: 'm_in_closing_timeout',
+            },
+            {
+                title: '主机-出',
+                code: 'm_out_closing_timeout',
+            },
+            {
+                title: '备机-进',
+                code: 'b_in_closing_timeout',
+            },
+
+            {
+                title: '备机-出',
+                code: 'b_out_closing_timeout',
+            },
+
+        ],
+    },
+
+    {
+        title: '开向超时故障',
+        dataList: [
+            {
+                title: '主机-进',
+                code: 'm_in_opening_timeout',
+            },
+            {
+                title: '主机-出',
+                code: 'm_out_opening_timeout',
+            },
+            {
+                title: '备机-进',
+                code: 'b_in_opening_timeout',
+            },
+
+            {
+                title: '备机-出',
+                code: 'b_out_opening_timeout',
+            },
+
+        ],
+    },
+
+    {
+        title: '阀位故障',
+        dataList: [
+            {
+                title: '主机-进',
+                code: 'm_in_valve_position',
+            },
+            {
+                title: '主机-出',
+                code: 'm_out_valve_position',
+            },
+            {
+                title: '备机-进',
+                code: 'b_in_valve_position',
+            },
+
+            {
+                title: '备机-出',
+                code: 'b_out_valve_position',
+            },
+
+        ],
+    },
+
+    {
+        title: '热过载故障',
+        dataList: [
+            {
+                title: '主机-进',
+                code: 'm_in_thermal_overload',
+            },
+            {
+                title: '主机-出',
+                code: 'm_out_thermal_overload',
+            },
+            {
+                title: '备机-进',
+                code: 'b_in_thermal_overload',
+            },
+
+            {
+                title: '备机-出',
+                code: 'b_out_thermal_overload',
+            },
+
+        ],
+    },
+
+])
+
+
+const propTypeArr = ref([])
+const chartsColumns = ref([])
+watch(monitorDataGroupNum, () => {
+
+    const arr = <any[]>[]
+    const item = {
+        legend: '实时流量',
+        seriesName: '(m³/min)',
+        ymax: 100,
+        yname: 'm³/min',
+        linetype: 'line',
+        yaxispos: 'left',
+        color: '#FDB146',
+        sort: 1,
+        xRotate: 0,
+        dataIndex: 'flow',
+    }
+    const propTypeList = []
+    let echartLend=1
+    for (let i = 1; i <= echartLend; i++) {
+        const lineType = lodash.cloneDeep(item)
+        lineType.legend = '制氮机实时流量';
+        lineType.dataIndex = 'flow'
+        lineType.color = colors[i - 1]
+        arr.push(lineType)
+    }
+    chartsColumns.value = arr
+
+})
+
+
+
+const monitorData = ref(
+    new Array(3).fill({
+        // strName: '空压机',
+        // cumulativeFlow: '-',
+        // centerTemperature: '-',
+        // outletTemperature: '-',
+        // Ia: '-',
+        // Ib: '-',
+        // Ic: '-',
+        // Vab: '-',
+        // Vac: '-',
+        // Vbc: '-',
+        // compressGroupName: '',
+        // compressExhaustPressF1: '-',
+        // compressSeparatePressF1: '-',
+        // compressHostTempF1: '-',
+        // compressCrewTempF1: '-',
+        // compressRunTimeF1: '-',
+        // controlModel: 'LOC'
+    })
+);
+
+//图表数据
+let echartData = ref<any>([]);
+
+// https获取监测数据
+let timer: null | NodeJS.Timeout = null;
+async function getMonitor(flag?) {
+    if (Object.prototype.toString.call(timer) === '[object Null]') {
+        timer = await setTimeout(
+            async () => {
+                if (props.deviceId) {
+                    await getDataSource(props.deviceId);
+                }
+                if (timer) {
+                    timer = null;
+                }
+                await getMonitor();
+            },
+            flag ? 0 : 3000
+        );
+    }
+}
+
+async function getDataSource(systemID) {
+    const res = await getDevice({ devicetype: 'sys', systemID, type: 'all' });
+    if (res) {
+        const result = res;
+        if (!result || result.msgTxt.length < 1) return;
+        result.msgTxt.forEach((item) => {
+            if (item.type && item.type.startsWith('nitrogen')) {
+                airCompressorState.length = 0;
+                monitorData.value = item['datalist'].filter((data) => {
+                    const readData = data.readData;
+                    airCompressorState.push({
+                        id: data.deviceID,
+                        deviceType: data.deviceType,
+                        m_start: readData.m_start,
+                        m_stop: readData.m_stop,
+                        b_start: readData.b_start,
+                        b_stop: readData.b_stop,
+                    });
+                    return Object.assign(data, readData);
+                });
+                console.log(monitorData, 'monitorData.value---===')
+                const airCompressor = { readTime: monitorData.value[0]['readTime'].substring(11) }
+                const dataArr = lodash.cloneDeep(echartData.value)
+                //图表数据
+                if (dataArr.length <4) {
+                    monitorData.value.forEach((el, index) => {
+                        airCompressor['flow'] = el['flow'] || 0
+                    });
+                    dataArr.push(airCompressor)
+                } else {
+                    dataArr.shift()
+                    // dataArr.push(airCompressor)
+                    monitorData.value.forEach((el, index) => {
+                        airCompressor['flow'] = el['flow'] || 0
+                    });
+                    dataArr.push(airCompressor)
+                    console.log(dataArr,'dataArr---------')
+                }
+                echartData.value = dataArr
+
+            }
+        });
+        // monitorDataGroupNum.value = monitorData.value.length;
+        monitorDataGroupNum.value = 2;
+        refresh.value = true
+        nextTick(() => {
+            refresh.value = false
+        })
+    }
+}
+
+function handlerDevice(data, titles) {
+    kzParam.data = data;
+    kzParam.isFw = titles
+    switch (titles) {
+        case '主机启动':
+            modalTitle.value = titles;
+            modalType.value = '1';
+            modalIsShow.value = true;
+            kzParam.data.m_start = '1'
+            break;
+        case '备机启动':
+            modalTitle.value = titles;
+            modalType.value = '2';
+            modalIsShow.value = true;
+            kzParam.data.b_start = '1'
+            break;
+        case '主机停止':
+            modalTitle.value = titles;
+            modalType.value = '1';
+            modalIsShow.value = true;
+            kzParam.data.m_stop = '1'
+            break;
+        case '备机停止':
+            modalTitle.value = titles;
+            modalType.value = '2';
+            modalIsShow.value = true;
+            kzParam.data.b_stop = '1'
+            break;
+
+    }
+
+}
+function handleOK(passWord, handlerState) {
+    console.log(kzParam, 'kz----------');
+    // if (passWord !== '123456') {
+    //   message.warning('密码不正确,请重新输入');
+    //   return;
+    // }
+
+    let data = {};
+    switch (kzParam.isFw) {
+        case '主机启动':
+            data = {
+                deviceid: kzParam.data.id,
+                devicetype: kzParam.data.deviceType,
+                password: passWord,
+                m_start: kzParam.data.m_start,
+            };
+            break;
+        case '备机启动':
+            data = {
+                deviceid: kzParam.data.id,
+                devicetype: kzParam.data.deviceType,
+                password: passWord,
+                b_start: kzParam.data.b_start,
+            };
+            break;
+        case '主机停止':
+            data = {
+                deviceid: kzParam.data.id,
+                devicetype: kzParam.data.deviceType,
+                password: passWord,
+                m_stop: kzParam.data.m_stop,
+            };
+            break;
+        case '备机停止':
+            data = {
+                deviceid: kzParam.data.id,
+                devicetype: kzParam.data.deviceType,
+                password: passWord,
+                b_stop: kzParam.data.b_stop,
+            };
+            break;
+
+
+    }
+
+
+    deviceControlApi(data).then((res) => {
+        // 模拟时开启
+        if (res.success) {
+            modalIsShow.value = false;
+            getDataSource(props.deviceId);
+            if (globalConfig.History_Type == 'remote') {
+                message.success('指令已下发至生产管控平台成功!')
+            } else {
+                message.success('指令已下发成功!')
+            }
+        }
+    });
+}
+function handleCancel() {
+    modalIsShow.value = false;
+    modalTitle.value = '';
+    modalType.value = '';
+}
+
+watch([monitorDataGroupNum, loading], ([newMonitorDataGroupNum, newLoading]) => {
+    nextTick(() => {
+        if (newMonitorDataGroupNum && !newLoading) {
+            setModelType(props.modalType, newMonitorDataGroupNum);
+        }
+    });
+});
+
+
+onMounted(async () => {
+    await getMonitor(true);
+    await mountedThree().then(() => {
+        loading.value = false;
+    });
+});
+
+onUnmounted(() => {
+    destroy();
+    if (timer) {
+        clearTimeout(timer);
+        timer = undefined;
+    }
+});
+</script>
+  
+<style lang="less" scoped>
+@ventSpace: zxm;
+
+.nitrogen-box {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: center;
+}
+
+#nitrogenCss3D {
+    .modal-monitor {
+        width: 200px;
+        position: absolute;
+        left: 0px;
+        top: 0px;
+    }
+
+    &:deep(.win) {
+        margin: 0 !important;
+        background: #00000044;
+    }
+}
+
+.nitrogen-home {
+    width: 100%;
+    height: 100%;
+    position: fixed;
+    z-index: 9999;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    pointer-events: none;
+    top: 20px;
+
+    .nitrogen-container {
+        width: 100%;
+        height: calc(100% - 100px);
+        display: flex;
+        justify-content: space-between;
+        margin-bottom: 100px;
+
+        .top-box {
+            // margin-top: 40px; //lxh
+            position: relative;
+            width: 100%;
+            padding: 10px;
+            overflow: hidden;
+            display: flex;
+            justify-content: space-between;
+
+            .center-item-box {
+                position: absolute;
+                left: 50%;
+                top: 50px;
+                transform: translate(-48%, 0);
+                width: calc(100% - 760px);
+                height: 50px;
+                display: flex;
+                align-items: center;
+                pointer-events: auto;
+
+                .top-left {
+                    display: flex;
+                    flex: 2;
+                    color: #fff;
+
+                    .button-box {
+                        position: relative;
+                        width: auto;
+                        height: 32px;
+                        display: flex;
+                        align-items: center;
+                        justify-content: center;
+                        border-radius: 5px;
+                        color: #fff;
+                        padding: 10px 15px;
+                        margin: 0px 10px;
+                        box-sizing: border-box;
+                        cursor: pointer;
+                        background: linear-gradient(#1fa6cb, #127cb5);
+                    }
+                }
+                .top-center{
+                    display: flex;
+                    flex: 1;
+                    justify-content: center;
+                    align-items: center;
+                    font-size: 20px;
+                    color: #fff;
+                    .top-c-label{
+                        color: yellow;
+                    }
+                }
+
+                .top-right {
+                    display: flex;
+                    flex: 2;
+                    justify-content: right;
+                    align-items: center;
+                    color: #fff;
+
+                    .control-type {
+                        display: flex;
+                        color: #fff;
+
+                        .control-title {
+                            color: #73e8fe;
+                        }
+                    }
+                }
+
+            }
+
+            .footer-item-box {
+                width: calc(100% - 20px);
+                height: auto;
+                position: absolute;
+                left: 50%;
+                bottom: 30px;
+                transform: translate(-50%);
+                display: flex;
+                justify-content: center;
+                color: #fff;
+                // box-shadow: 0 0 30px rgb(0, 153, 184) inset;
+                pointer-events: auto;
+
+                .device-detail {
+                    text-align: center;
+
+                    &:first-child {
+                        background-color: #00bbff11;
+                    }
+
+                    &:last-child {
+
+                        .device-val,
+                        .device-title {
+                            border-right: 1px solid #00baffd4;
+                        }
+                    }
+
+                    .device-val {
+                        line-height: 36px;
+                        border-top: 1px solid #00baffd4;
+                        border-left: 1px solid #00baffd4;
+
+                        &:last-child {
+                            border-bottom: 1px solid #00baffd4;
+                        }
+                    }
+                }
+
+                .device-title {
+                    width: 110px;
+                    text-align: center;
+                    border-top: 1px solid #00baffd4;
+                    border-left: 1px solid #00baffd4;
+                    line-height: 46px;
+                    color: #00e5ff;
+                    background-color: #00bbff21;
+                }
+
+            }
+
+            .lr-box {
+                height: fit-content;
+                display: flex;
+                flex-direction: column;
+                position: relative;
+                overflow: hidden;
+                z-index: 9999;
+                pointer-events: auto;
+            }
+
+            .item {
+                width: 335px;
+                height: auto;
+                position: relative;
+                border-radius: 5px;
+                margin-top: 10px;
+                margin-bottom: 0px;
+                pointer-events: auto;
+                color: #fff;
+                overflow: hidden;
+
+                &:first-child {
+                    margin-top: 0px;
+                }
+
+                .base-title {
+                    color: #fff;
+                    margin-bottom: 8px;
+                    padding-left: 10px;
+                    position: relative;
+                    font-size: 16px;
+
+                    &::after {
+                        content: '';
+                        position: absolute;
+                        display: block;
+                        width: 4px;
+                        height: 12px;
+                        top: 7px;
+                        left: 0px;
+                        background: #45d3fd;
+                        border-radius: 4px;
+                    }
+                }
+
+                .state-item {
+                    display: flex;
+                    flex-direction: row;
+                    padding: 5px;
+
+                    .item-col {
+                        width: calc(50% - 5px);
+                        display: flex;
+                        justify-content: center;
+                        align-items: center;
+                        padding-right: 4px;
+                        background-image: linear-gradient(to right, #39a3ff00, #39a3ff10);
+
+                        &:first-child {
+                            margin-right: 10px;
+                        }
+
+
+                        .state-title {
+                            color: #ffffffcc;
+                            flex: 9;
+                            font-size: 14px;
+                        }
+
+                        .state-val {
+                            flex: 1;
+                            color: #00eefffe;
+                            margin-right: 5px;
+                            text-align: right;
+                            font-size: 14px;
+                        }
+
+                        .state-title1 {
+                            color: #ffffffcc;
+                            flex: 5;
+                            font-size: 14px;
+                        }
+
+                        .state-val1 {
+                            display: flex;
+                            flex: 1;
+                            justify-content: center;
+                            align-items: center;
+                        }
+                    }
+                }
+
+                .signal-box {
+                    margin: 5px 0;
+                    display: flex;
+                    align-items: center;
+
+                    .signal-title {
+                        color: #7af5ff;
+                        margin: 0 5px;
+                    }
+
+                    &:last-child {
+                        margin-right: 0px;
+                    }
+                }
+
+                .list-item {
+                    padding: 0 10px;
+                    display: flex;
+                    justify-content: space-between;
+                    align-items: center;
+
+                    .item-data-key {
+                        color: #ffffff99;
+                    }
+                }
+
+                .item-data-box {
+                    color: #fff;
+
+                    .state-icon {
+                        display: inline-block;
+                        width: 12px;
+                        height: 12px;
+                        border-radius: 12px;
+                    }
+
+                    .open {
+                        border: 5px solid #133a56;
+                        background: #4ecb73;
+                    }
+
+                    .close {
+                        border: 5px solid #192961;
+                        background: #6d7898;
+                    }
+                }
+            }
+
+            .item-l {
+                width: 100%;
+
+                .monitor-box {
+                    width: 100%;
+
+                    .parameter-title {
+                        position: relative;
+                        width: 100%;
+                        height: 14px;
+                        margin-top: 10px;
+
+                        .icon,
+                        span {
+                            position: absolute;
+                            top: -10px;
+                        }
+                    }
+
+                    .group-parameter-title {
+                        background-image: linear-gradient(to right, #39a3ff50, #39a3ff00);
+
+                        .icon {
+                            left: -12px;
+                            top: -17px;
+                        }
+
+                        span {
+                            left: 18px;
+                        }
+
+                        .item-col {
+                            background-image: linear-gradient(to right, #39a3ff00, #39a3ff10);
+                        }
+                    }
+
+                    .device-parameter-title {
+                        background-image: linear-gradient(to right, #3df6ff40, #3df6ff00);
+
+                        .icon {
+                            left: -10px;
+                            top: -14px;
+                        }
+
+                        span {
+                            left: 18px;
+                        }
+
+                        .item-col {
+                            background-image: linear-gradient(to right, #3df6ff10, #3df6ff00);
+                        }
+                    }
+                }
+
+                // .monitor-box1 {
+                //     height: 126px;
+                // }   
+
+                .state-box {
+                    height: calc(100% - 24px);
+                    overflow-y: auto;
+                }
+            }
+
+            .right-box {
+                width: 330px;
+                margin-top: 50px;
+
+                .control-group {
+                    display: flex;
+                    // justify-content: space-around;
+                    flex-wrap: wrap;
+                    height: 262px;
+                    overflow-y: auto;
+                    overflow-x: hidden;
+
+                    .control-item {
+                        width: 50%; //lxh
+                        display: flex;
+                        flex-direction: column;
+                        justify-content: center;
+                        align-items: center;
+                        padding: 0 4px;
+
+                        .control-item-title {
+                            color: #a6dce9;
+                            position: relative;
+                            top: 5px;
+                        }
+
+                        .control-item-state {
+                            // width: 94px;
+                            width: 162px;
+                            // height: 47px;
+                            height: 36px;
+                            background: url('/@/assets/images/vent/control-switch-bg.png');
+                            background-size: 100% 100%;
+                            display: flex;
+                            justify-content: center;
+                            align-items: center;
+                            color: #fff;
+                        }
+
+                        .button-box {
+                            position: relative;
+                            padding: 5px;
+                            border: 1px transparent solid;
+                            background-clip: border-box;
+                            border-radius: 5px;
+                            margin-left: 8px;
+                        }
+
+                        .a-button {
+                            pointer-events: auto;
+                        }
+
+                        &::v-deep .a-button--mini {
+                            padding: 6px 10px;
+                        }
+
+                        &::v-deep .a-button--mini.is-round {
+                            padding: 6px 10px;
+                        }
+                    }
+                }
+            }
+
+            .left-box {
+                width: 365px;
+                margin-top: 80px;
+            }
+        }
+
+        &:deep(.win) {
+            width: 100%;
+            margin: 0 !important;
+        }
+    }
+}
+
+&:deep(.main) {
+    .title {
+        height: 34px;
+        text-align: center;
+        font-weight: 600;
+        color: #7af5ff;
+        // background-image: url('../../../assets/img/yfj/light.png');
+        background-repeat: no-repeat;
+        background-position-x: center;
+        background-position-y: 100%;
+        background-size: 80%;
+        font-size: 16px;
+    }
+
+    .monitor-item {
+        width: 200px;
+        display: flex;
+        flex-direction: row;
+        width: auto;
+        margin-bottom: 3px;
+
+        .monitor-val {
+            color: #ffb700;
+            display: flex;
+            width: auto;
+
+            .val {
+                width: 80px;
+                // font-size: 14px;
+                font-size: 16px;
+            }
+
+            .unit {
+                color: #ffffffbb;
+                // font-size: 14px;
+                font-size: 16px;
+            }
+        }
+    }
+
+    .monitor-title {
+        width: 100px;
+        color: #7af5ff;
+        font-weight: 400;
+        // font-size: 14px;
+        font-size: 16px;
+    }
+
+
+
+    .signal-item {
+        display: flex;
+        justify-content: space-between;
+
+        // margin-bottom: 5px;
+        .signal-round {
+            display: inline-block;
+            width: 8px;
+            height: 8px;
+            border-radius: 50%;
+            margin: 0 10px;
+            position: relative;
+
+            &::after {
+                display: block;
+                content: '';
+                position: absolute;
+                width: 12px;
+                height: 12px;
+                top: -2px;
+                left: -2px;
+                border-radius: 50%;
+            }
+        }
+
+        .signal-round-gry {
+            background-color: #858585;
+
+            &::after {
+                background-color: #85858544;
+                box-shadow: 0 0 1px 1px #85858599;
+            }
+        }
+
+        .signal-round-run {
+            background-color: #67fc00;
+
+            &::after {
+                background-color: #67fc0044;
+                box-shadow: 0 0 1px 1px #c6ff77;
+            }
+        }
+
+        .signal-round-warning {
+            background-color: #e9170b;
+
+            &::after {
+                background-color: #e9170b44;
+                box-shadow: 0 0 1px 1px #e9170b;
+            }
+        }
+    }
+}
+
+:deep(.zxm-radio-wrapper) {
+    color: #fff !important;
+}
+
+:deep(.zxm-radio-group) {
+    color: #fff !important;
+}
+
+:deep(.zxm-radio-group .zxm-radio-wrapper) {
+    color: #fff !important;
+}
+:deep(.zxm-radio-disabled + span){
+    color: #fff;
+}
+
+:deep(.zxm-radio-disabled .zxm-radio-inner::after){
+    background-color:#0490a8;
+}
+</style>
+  

+ 865 - 0
src/views/vent/monitorManager/compressor/components/nitrogenHome_bet.vue

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

+ 960 - 0
src/views/vent/monitorManager/compressor/components/nitrogenHome_dltj.vue

@@ -0,0 +1,960 @@
+<template>
+  <div id="nitrogen3D" style="width: 100%; height: 100%; position: absolute; overflow: hidden"></div>
+  <div
+    id="nitrogenCss3D"
+    class="threejs-Object-CSS"
+    style="width: 100%; height: 100%; position: absolute; pointer-events: none; overflow: hidden; z-index: 2; top: 0px; left: 0px"
+  >
+    <a-spin :spinning="loading" />
+    <div v-for="groupNum in monitorDataGroupNum" :key="groupNum" class="modal-monitor">
+      <fourBorderBg :class="`kyj${groupNum}`" :id="`nitrogenMonitor${groupNum}`">
+        <div class="title">空压机{{ groupNum }} </div>
+        <template v-for="(preMonitor, preMonitorIndex) in preMonitorList" :key="preMonitorIndex">
+          <div v-if="preMonitor.code !== 'signal'" class="monitor-item">
+            <span class="monitor-title">{{ preMonitor.title }}:</span>
+            <span class="monitor-val"
+              ><span class="val">{{ monitorData[preMonitor.code + groupNum] ? formatNum(monitorData[preMonitor.code + groupNum]) : '-' }}</span
+              ><span class="unit">{{ preMonitor.unit }}</span></span
+            >
+          </div>
+          <div v-else class="signal-item">
+            <div class="signal" v-for="(signal, childIndex) in preMonitor.child" :key="childIndex">
+              <span class="monitor-title">{{ signal.title }}</span>
+              <span style="display: inline-block; width: 30px; text-align: center" v-if="signal.isFault == -2">{{
+                monitorData[signal.code + groupNum] == '0' ? '就地' : monitorData[signal.code + groupNum] == '1' ? '远程' : '-'
+              }}</span>
+              <span style="display: inline-block; width: 30px; text-align: center" v-else-if="signal.isFault == -1">{{
+                monitorData[signal.code + groupNum] == '1' ? '加载' : monitorData[signal.code + groupNum] == '0' ? '卸载' : '-'
+              }}</span>
+              <span
+                v-else
+                :class="{
+                  'signal-round': true,
+                  'signal-round-run': !signal.isFault && monitorData[signal.code + groupNum] == '1',
+                  'signal-round-warning': signal.isFault && monitorData[signal.code + groupNum] == '1',
+                  'signal-round-gry': monitorData[signal.code + groupNum] != '1',
+                }"
+              ></span>
+            </div>
+          </div>
+        </template>
+      </fourBorderBg>
+    </div>
+  </div>
+  <div class="nitrogen-home">
+    <div class="nitrogen-container">
+      <div class="top-box">
+        <!-- 中间区域控制按钮 -->
+        <div class="center-item-box">
+          <div class="top-left">
+            <div class="button-box" @click="handlerDevice(airCompressorState[0], '主机启动')">上位机启动</div>
+            <div class="button-box" @click="handlerDevice(airCompressorState[0], '主机停止')">上位机停止</div>
+            <div class="button-box" @click="handlerDevice(airCompressorState[0], '备机启动')">上位复位</div>
+          </div>
+          <div class="top-center">
+            <div class="top-c-label">通信状态:</div>
+            <div class="top-c-val">{{ monitorData['netStatus'] == 1 ? '连接' : monitorData['netStatus'] == 0 ? '断开' : '未知' }}</div>
+          </div>
+          <div class="top-right">
+            <div class="control-type">
+              <div class="control-title">空压机远近控切换:</div>
+              <a-radio-group v-model:value="monitorData['RemSelect']">
+                <a-radio :value="`1`">远程</a-radio>
+                <a-radio :value="`0`">就地</a-radio>
+              </a-radio-group>
+            </div>
+            <div class="control-type">
+              <div class="control-title">制氮机远近控切换:</div>
+              <a-radio-group v-model:value="monitorData['LocSelect']">
+                <a-radio :value="`1`">远程</a-radio>
+                <a-radio :value="`0`">就地</a-radio>
+              </a-radio-group>
+            </div>
+          </div>
+        </div>
+        <!-- 左边监测数据 -->
+        <div class="lr-box left-box">
+          <ventBox1>
+            <template #title>
+              <div>注氮机监测</div>
+            </template>
+            <template #container>
+              <div class="input-item" v-for="(preFan, index) in nitrogenMonitorData" :key="index">
+                <div class="title">{{ preFan.title }}</div>
+                <div v-if="preFan.unit !== 'signal'" class="value">{{
+                  monitorData[preFan.code] >= 0 ? formatNum(Number(monitorData[preFan.code])) : '-'
+                }}</div>
+                <div
+                  v-else
+                  :class="{
+                    'signal-round': true,
+                    'signal-round-warning': monitorData[preFan.code] == '1',
+                    'signal-round-gry': monitorData[preFan.code] != '1',
+                  }"
+                ></div>
+                <div class="unit">{{ preFan.unit !== 'signal' ? `(${preFan.unit})` : '' }}</div>
+              </div>
+            </template>
+          </ventBox1>
+          <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="monitor-item">
+                    <div class="state-item" v-for="(preFan, index) in preFanMonitorData" :key="index">
+                      <div class="state-title">{{ preFan.title + (preFan.unit !== 'signal' ? `(${preFan.unit})` : '') }}</div>
+                      <div v-if="preFan.unit !== 'signal'" class="state-val">{{
+                        monitorData[preFan.code + groupNum] >= 0 ? formatNum(Number(monitorData[preFan.code + groupNum])) : '-'
+                      }}</div>
+                      <div
+                        v-else
+                        :class="{
+                          'signal-round': true,
+                          'signal-round-warning': monitorData[preFan.code + groupNum] == '1',
+                          'signal-round-gry': monitorData[preFan.code + groupNum] != '1',
+                        }"
+                      ></div>
+                    </div>
+                  </div>
+                </div>
+              </template>
+            </ventBox1>
+          </div>
+        </div>
+        <!-- 右边控制状态 -->
+        <div class="lr-box right-box">
+          <ventBox1 class="vent-margin-t-10">
+            <template #title>
+              <div>设备实时监测曲线</div>
+            </template>
+            <template #container>
+              <BarAndLine
+                v-if="chartsColumns.length > 0"
+                xAxisPropType="readTime"
+                :dataSource="echartData"
+                height="340px"
+                :chartsColumns="chartsColumns"
+                chartsType="listMonitor"
+                :option="echatsOption"
+              />
+            </template>
+          </ventBox1>
+          <div ref="playerRef" style="height: auto; width: 100%; margin-top: 10px"></div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup name="nitrogenHome">
+  import { onMounted, onUnmounted, ref, watch, reactive, defineProps, nextTick, inject } from 'vue';
+  import ventBox1 from '/@/components/vent/ventBox1.vue';
+  import fourBorderBg from '../../../comment/components/fourBorderBg.vue';
+  import { mountedThree, destroy, setModelType } from '../nitrogen.threejs';
+  import { getDevice } from '../nitrogen.api';
+  import BarAndLine from '/@/components/chart/BarAndLine.vue';
+  import { deviceControlApi } from '/@/api/vent/index';
+  import { preMonitorList, preFanMonitorData, nitrogenMonitorData } from '../nitrogen.data.dltj';
+  import { formatNum } from '/@/utils/ventutil';
+  import { useCamera } from '/@/hooks/system/useCamera';
+  import { message } from 'ant-design-vue';
+  import lodash from 'lodash';
+  const globalConfig = inject('globalConfig');
+
+  const props = defineProps({
+    deviceId: {
+      type: String,
+      require: true,
+    },
+    modalType: {
+      type: String,
+      require: true,
+    },
+  });
+  const playerRef = ref();
+  const refresh = ref(false);
+  const modalTitle = ref(''); // 模态框标题显示内容,根据设备操作类型决定
+  const modalType = ref(''); // 模态框内容显示类型,设备操作类型
+  const modalIsShow = ref<boolean>(false); // 是否显示模态框
+  const loading = ref(true);
+  let kzParam = reactive<any>({
+    data: {},
+    isFw: null,
+  });
+
+  // const kyjs = ['1号空压机', '1号空压机', '1号空压机', '1号空压机'];
+  const flvURL1 = () => {
+    // return `https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv`;
+    return '';
+  };
+  const colors = ['#FDB146', '#EE6666', '#9BCB75', '#03C2EC', '#DA3914', '#9C83D9'];
+  const echatsOption = {
+    grid: {
+      top: '35%',
+      left: '15%',
+      right: '20px',
+      bottom: '8%',
+      // containLabel: true
+    },
+    toolbox: {
+      feature: {},
+    },
+  };
+
+  const monitorNetStatus = ref(0);
+  const monitorDataGroupNum = ref(2);
+
+  let airCompressorState = reactive<any[]>([]);
+
+  const chartsColumns = ref([
+    {
+      legend: '瞬时流量',
+      seriesName: '(m³/h)',
+      ymax: 2000,
+      yname: 'm³/h',
+      linetype: 'line',
+      yaxispos: 'left',
+      color: '#FDB146',
+      sort: 1,
+      xRotate: 0,
+      dataIndex: 'InputFlux',
+    },
+  ]);
+  const { getCamera, webRtcServer } = useCamera();
+
+  const monitorData = ref({});
+
+  //图表数据
+  let echartData = ref<any>([]);
+
+  // https获取监测数据
+  let timer: null | NodeJS.Timeout = null;
+  async function getMonitor(flag?) {
+    if (Object.prototype.toString.call(timer) === '[object Null]') {
+      timer = await setTimeout(
+        async () => {
+          if (props.deviceId) {
+            await getDataSource(props.deviceId);
+          }
+          if (timer) {
+            timer = null;
+          }
+          await getMonitor();
+        },
+        flag ? 0 : 3000
+      );
+    }
+  }
+
+  async function getDataSource(systemID) {
+    const res = await getDevice({ devicetype: 'sys', systemID, type: 'all' });
+    if (res) {
+      const result = res;
+      // const result = {
+      //   cmd: 'monitordata',
+      //   msgTxt: [
+      //     {
+      //       datalist: [
+      //         {
+      //           msgType: null,
+      //           deviceID: '1760842915239510017',
+      //           strname: '52603注氮机',
+      //           strinstallpos: '52603注氮机',
+      //           fsectarea: 'null',
+      //           stationname: '52603注氮机',
+      //           deviceType: 'nitrogen_52603',
+      //           typeName: '52603注氮机',
+      //           netStatus: 1,
+      //           warnFlag: 0,
+      //           warnLevel: 0,
+      //           warnLevel_str: '正常',
+      //           warnTime: null,
+      //           readTime: '2024-02-28 17:29:15',
+      //           warnDes: '',
+      //           frontGateOpenCtrl: null,
+      //           rearGateOpenCtrl: null,
+      //           readData: {
+      //             ExhaustTemp1: '15',
+      //             Status2: '0',
+      //             ExhaustTemp2: '26',
+      //             RunTime2: '2136',
+      //             RunTime1: '5127',
+      //             sign: '0',
+      //             NitrogenPurity: '206.4',
+      //             SysVoltage1: '640',
+      //             SysVoltage2: '653',
+      //             CtrlMode2: '0',
+      //             ExhaustPreHighFault2: '1',
+      //             ExhaustPreHighFault1: '1',
+      //             HMIReset: '0',
+      //             HMIStop: '0',
+      //             InputFlux: '0',
+      //             LocSelect: '0',
+      //             OilPressureLowFault1: '1',
+      //             OilPressureLowFault2: '0',
+      //             PhaseSequenceFault2: '0',
+      //             PhaseSequenceFault1: '0',
+      //             LoadorUnload2: '1',
+      //             LoadorUnload1: '1',
+      //             CtrlMode1: '0',
+      //             PreMembraneTemperature: '15.4',
+      //             HMIStart: '0',
+      //             ExhaustPre2: '7',
+      //             ExhaustPre1: '8',
+      //             LoadTime2: '2133',
+      //             RemSelect: '0',
+      //             Status1: '0',
+      //             LoadTime1: '5121',
+      //             isRun: '-2',
+      //             FluxTotal: '7242',
+      //             LeakageLock1: '0',
+      //             LeakageLock2: '0',
+      //           },
+      //           readDataDes: null,
+      //           summaryHour: [],
+      //           summaryDay: [],
+      //           history: [],
+      //           totalInfo: null,
+      //           sign: null,
+      //           cameras: [],
+      //           links: [],
+      //           other1: null,
+      //           other2: null,
+      //           other3: null,
+      //           remarkInfo: null,
+      //         },
+      //       ],
+      //       avginfo: {
+      //         warnFlag: {
+      //           value: 0,
+      //         },
+      //       },
+      //       typeName: '52603注氮机',
+      //       type: 'nitrogen_52603',
+      //     },
+      //     {
+      //       subtype: 'sys_nitrogen',
+      //       datalist: [
+      //         {
+      //           msgType: null,
+      //           deviceID: '1760932094094950402',
+      //           strname: '注氮系统',
+      //           strinstallpos: '注氮系统',
+      //           fsectarea: 'null',
+      //           stationname: null,
+      //           deviceType: 'sys_nitrogen',
+      //           typeName: '注氮',
+      //           netStatus: 0,
+      //           warnFlag: 0,
+      //           warnLevel: null,
+      //           warnLevel_str: null,
+      //           warnTime: null,
+      //           readTime: '2024-02-28 17:21:14',
+      //           warnDes: '',
+      //           frontGateOpenCtrl: null,
+      //           rearGateOpenCtrl: null,
+      //           readData: {
+      //             sign: '0',
+      //             isRun: '-2',
+      //           },
+      //           readDataDes: null,
+      //           summaryHour: [],
+      //           summaryDay: [],
+      //           history: [],
+      //           totalInfo: null,
+      //           sign: null,
+      //           cameras: [],
+      //           links: [],
+      //           other1: null,
+      //           other2: null,
+      //           other3: null,
+      //           remarkInfo: '设备断线',
+      //         },
+      //       ],
+      //       typeName: '综合监测系统',
+      //       type: 'sys',
+      //     },
+      //   ],
+      // };
+
+      if (!result || result.msgTxt.length < 1) return;
+      result.msgTxt.forEach((item) => {
+        if (item.type && item.type.startsWith('nitrogen')) {
+          airCompressorState.length = 0;
+          let netStatus = 0;
+          monitorData.value = Object.assign(item['datalist'][0], item['datalist'][0]['readData']);
+          if (monitorData.value['netStatus'] == 1) {
+            netStatus = 1;
+          }
+          airCompressorState.push({
+            id: monitorData.value['deviceID'],
+            deviceType: monitorData.value['deviceType'],
+            HMIStart: monitorData.value['HMIStart'],
+            HMIStop: monitorData.value['HMIStop'],
+          });
+          monitorNetStatus.value = netStatus;
+          const airCompressor = { readTime: monitorData.value['readTime'].substring(11) };
+          const dataArr = lodash.cloneDeep(echartData.value);
+          //图表数据
+          if (dataArr.length <= 5) {
+            airCompressor[`FluxTotal`] = monitorData.value['FluxTotal'] || 0;
+            dataArr.push(airCompressor);
+          } else {
+            dataArr.shift();
+            dataArr.push(airCompressor);
+          }
+          echartData.value = dataArr;
+        }
+      });
+      refresh.value = true;
+      nextTick(() => {
+        refresh.value = false;
+      });
+    }
+  }
+
+  function handlerDevice(data, bol) {
+    kzParam.data = data;
+    kzParam.isFw = bol;
+    if (bol) {
+      modalTitle.value = '一键复位';
+      modalType.value = '1';
+      modalIsShow.value = true;
+      kzParam.data.HMIReset = !data.HMIReset;
+    } else {
+      modalTitle.value = '一键启停';
+      modalType.value = '2';
+      modalIsShow.value = true;
+      kzParam.data.HMIStartStop = !data.HMIStartStop;
+    }
+  }
+  function handleOK(passWord, handlerState) {
+    console.log(kzParam, 'kz----------');
+    // if (passWord !== '123456') {
+    //   message.warning('密码不正确,请重新输入');
+    //   return;
+    // }
+
+    let data = {};
+    if (kzParam.isFw) {
+      data = {
+        deviceid: kzParam.data.id,
+        devicetype: kzParam.data.deviceType,
+        password: passWord,
+        HMIReset: kzParam.data.HMIReset,
+      };
+    } else {
+      data = {
+        deviceid: kzParam.data.id,
+        password: passWord,
+        devicetype: kzParam.data.deviceType,
+        HMIStartStop: kzParam.data.HMIStartStop,
+      };
+    }
+
+    deviceControlApi(data).then((res) => {
+      // 模拟时开启
+      if (res.success) {
+        modalIsShow.value = false;
+        getDataSource(props.deviceId);
+        if (globalConfig.History_Type == 'remote') {
+          message.success('指令已下发至生产管控平台成功!');
+        } else {
+          message.success('指令已下发成功!');
+        }
+      }
+    });
+  }
+  function handleCancel() {
+    modalIsShow.value = false;
+    modalTitle.value = '';
+    modalType.value = '';
+  }
+
+  watch([monitorDataGroupNum, loading], ([newMonitorDataGroupNum, newLoading]) => {
+    nextTick(() => {
+      if (newMonitorDataGroupNum && !newLoading) {
+        setModelType(props.modalType, newMonitorDataGroupNum);
+      }
+    });
+  });
+
+  onMounted(async () => {
+    await getMonitor(true);
+    await mountedThree().then(() => {
+      loading.value = false;
+    });
+    await getCamera(props.deviceId, playerRef.value);
+  });
+
+  onUnmounted(() => {
+    destroy();
+    if (webRtcServer.length > 0) {
+      webRtcServer.forEach((item) => {
+        item.disconnect();
+      });
+    }
+    if (timer) {
+      clearTimeout(timer);
+      timer = undefined;
+    }
+  });
+</script>
+
+<style lang="less" scoped>
+  @ventSpace: zxm;
+
+  .nitrogen-box {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: center;
+  }
+
+  #nitrogenCss3D {
+    .modal-monitor {
+      width: 200px;
+      position: absolute;
+      left: 0px;
+      top: 0px;
+    }
+
+    &:deep(.win) {
+      margin: 0 !important;
+      background: #00000044;
+    }
+  }
+
+  .nitrogen-home {
+    width: 100%;
+    height: 100%;
+    position: fixed;
+    z-index: 9999;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    pointer-events: none;
+    top: 20px;
+
+    .nitrogen-container {
+      width: 100%;
+      height: calc(100% - 100px);
+      display: flex;
+      justify-content: space-between;
+      margin-bottom: 100px;
+      .device-state {
+        width: 100%;
+        position: absolute;
+        top: 20px;
+        color: #e90000;
+        display: flex;
+        justify-content: center;
+        font-size: 20px;
+      }
+      .top-box {
+        width: 100%;
+        padding: 10px;
+        overflow: hidden;
+        display: flex;
+        justify-content: space-between;
+        // margin-top: 40px;
+
+        .center-item-box {
+          position: absolute;
+          left: 50%;
+          top: 50px;
+          transform: translate(-48%, 0);
+          width: calc(100% - 720px);
+          height: 50px;
+          display: flex;
+          align-items: center;
+          pointer-events: auto;
+
+          .top-left {
+            display: flex;
+            flex: 1.5;
+            color: #fff;
+
+            .button-box {
+              position: relative;
+              width: auto;
+              height: 32px;
+              display: flex;
+              align-items: center;
+              justify-content: center;
+              border-radius: 5px;
+              color: #fff;
+              padding: 10px 15px;
+              margin: 0px 10px;
+              box-sizing: border-box;
+              cursor: pointer;
+              background: linear-gradient(#1fa6cb, #127cb5);
+              &:hover {
+                background: linear-gradient(#1fa6cbcc, #127cb5cc);
+              }
+            }
+          }
+          .top-center {
+            display: flex;
+            flex: 1;
+            justify-content: center;
+            align-items: center;
+            font-size: 20px;
+            color: #fff;
+            .top-c-label {
+              color: yellow;
+            }
+          }
+
+          .top-right {
+            display: flex;
+            flex: 2;
+            justify-content: right;
+            align-items: center;
+            color: #fff;
+            .control-type {
+              display: flex;
+              color: #fff;
+              .control-title {
+                color: #73e8fe;
+              }
+            }
+          }
+        }
+        .lr-box {
+          height: 100%;
+          display: flex;
+          flex-direction: column;
+          position: relative;
+          // overflow: hidden;
+          z-index: 9999;
+          pointer-events: auto;
+          overflow-y: auto;
+          overflow-x: hidden;
+          height: calc(100% - 70px);
+        }
+
+        .item {
+          width: 305px;
+          height: auto;
+          position: relative;
+          border-radius: 5px;
+          margin-top: 10px;
+          margin-bottom: 0px;
+          pointer-events: auto;
+          color: #fff;
+          // overflow: hidden;
+
+          &:first-child {
+            margin-top: 0px;
+          }
+
+          .base-title {
+            color: #fff;
+            margin-bottom: 8px;
+            padding-left: 10px;
+            position: relative;
+            font-size: 16px;
+
+            &::after {
+              content: '';
+              position: absolute;
+              display: block;
+              width: 4px;
+              height: 12px;
+              top: 7px;
+              left: 0px;
+              background: #45d3fd;
+              border-radius: 4px;
+            }
+          }
+
+          .monitor-item {
+            width: 100%;
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            .state-item {
+              width: 50%;
+              padding: 5px;
+              display: flex;
+              align-items: center;
+              justify-content: space-between;
+              .state-title {
+                width: 100px;
+                color: #ffffffdd;
+                flex: 9;
+                font-size: 14px;
+                .unit {
+                  // color: #ffffffbb;
+                }
+              }
+              .state-val {
+                flex: 1;
+                color: #e4a300;
+                margin-right: 5px;
+                text-align: right;
+                font-size: 14px;
+              }
+            }
+          }
+
+          .signal-box {
+            margin: 5px 0;
+            display: flex;
+            align-items: center;
+
+            .signal-title {
+              color: #7af5ff;
+              margin: 0 5px;
+            }
+
+            &:last-child {
+              margin-right: 0px;
+            }
+          }
+
+          .list-item {
+            padding: 0 10px;
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+
+            .item-data-key {
+              color: #ffffff99;
+            }
+          }
+
+          .item-data-box {
+            color: #fff;
+
+            .state-icon {
+              display: inline-block;
+              width: 12px;
+              height: 12px;
+              border-radius: 12px;
+            }
+
+            .open {
+              border: 5px solid #133a56;
+              background: #4ecb73;
+            }
+
+            .close {
+              border: 5px solid #192961;
+              background: #6d7898;
+            }
+          }
+        }
+
+        .item-l {
+          width: 100%;
+
+          .monitor-box {
+            width: 100%;
+
+            .parameter-title {
+              position: relative;
+              width: 100%;
+              height: 14px;
+              margin-top: 10px;
+
+              .icon,
+              span {
+                position: absolute;
+                top: -10px;
+              }
+            }
+
+            .group-parameter-title {
+              background-image: linear-gradient(to right, #39a3ff50, #39a3ff00);
+
+              .icon {
+                left: -12px;
+                top: -17px;
+              }
+
+              span {
+                left: 18px;
+              }
+
+              .item-col {
+                background-image: linear-gradient(to right, #39a3ff00, #39a3ff10);
+              }
+            }
+
+            .device-parameter-title {
+              background-image: linear-gradient(to right, #3df6ff40, #3df6ff00);
+
+              .icon {
+                left: -10px;
+                top: -14px;
+              }
+
+              span {
+                left: 18px;
+              }
+
+              .item-col {
+                background-image: linear-gradient(to right, #3df6ff10, #3df6ff00);
+              }
+            }
+          }
+        }
+
+        .right-box {
+          width: 300px;
+          margin-top: 50px;
+        }
+
+        .left-box {
+          width: 335px;
+          margin-top: 80px;
+          .input-item {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            padding: 4px 8px;
+            margin: 6px 0;
+            background-image: linear-gradient(to right, #39deff15, #3977e500);
+
+            .title {
+              width: 200px;
+            }
+            .title-auto {
+              width: auto;
+            }
+
+            .input-value {
+              width: 80px;
+              height: 28px;
+              line-height: 28px !important;
+              background: transparent !important;
+              border-color: #228da2 !important;
+              color: #fff !important;
+            }
+            .value {
+              width: 100px;
+              color: #00d8ff;
+              padding-right: 20px;
+            }
+            .unit {
+              width: 80px;
+            }
+          }
+        }
+      }
+
+      &:deep(.win) {
+        width: 100%;
+        margin: 0 !important;
+      }
+    }
+  }
+
+  &:deep(.main) {
+    .title {
+      height: 34px;
+      text-align: center;
+      font-weight: 600;
+      color: #7af5ff;
+      // background-image: url('../../../assets/img/yfj/light.png');
+      background-repeat: no-repeat;
+      background-position-x: center;
+      background-position-y: 100%;
+      background-size: 80%;
+      font-size: 16px;
+    }
+
+    .monitor-item {
+      width: 200px;
+      display: flex;
+      flex-direction: row;
+      width: auto;
+      margin-bottom: 3px;
+
+      .monitor-val {
+        color: #ffb700;
+        display: flex;
+        width: auto;
+
+        .val {
+          width: 80px;
+          font-size: 14px;
+        }
+
+        .unit {
+          color: #ffffffbb;
+          font-size: 14px;
+        }
+      }
+    }
+
+    .monitor-title {
+      width: 100px;
+      color: #7af5ff;
+      font-weight: 400;
+      font-size: 14px;
+    }
+
+    .signal-item {
+      display: flex;
+      justify-content: space-between;
+
+      // margin-bottom: 5px;
+      .signal-round {
+        display: inline-block;
+        width: 8px;
+        height: 8px;
+        border-radius: 50%;
+        margin: 0 10px;
+        position: relative;
+
+        &::after {
+          display: block;
+          content: '';
+          position: absolute;
+          width: 12px;
+          height: 12px;
+          top: -2px;
+          left: -2px;
+          border-radius: 50%;
+        }
+      }
+
+      .signal-round-gry {
+        background-color: #858585;
+
+        &::after {
+          background-color: #85858544;
+          box-shadow: 0 0 1px 1px #85858599;
+        }
+      }
+
+      .signal-round-run {
+        background-color: #67fc00;
+
+        &::after {
+          background-color: #67fc0044;
+          box-shadow: 0 0 1px 1px #c6ff77;
+        }
+      }
+
+      .signal-round-warning {
+        background-color: #e9170b;
+
+        &::after {
+          background-color: #e9170b44;
+          box-shadow: 0 0 1px 1px #e9170b;
+        }
+      }
+    }
+  }
+
+  :deep(.zxm-radio-wrapper) {
+    color: #fff !important;
+  }
+</style>

+ 100 - 0
src/views/vent/monitorManager/compressor/nitrogen.data.dltj.ts

@@ -0,0 +1,100 @@
+export const preMonitorList = [
+  {
+    title: `排气压力`,
+    code: `ExhaustPre`,
+    unit: 'MPa',
+    child: [],
+  },
+  {
+    title: `排气温度`,
+    code: `ExhaustTemp`,
+    unit: '℃',
+    child: [],
+  },
+  {
+    title: `加载时间`,
+    code: `LoadTime`,
+    unit: 'h',
+    child: [],
+  },
+  {
+    title: `运行时间`,
+    code: `RunTime`,
+    unit: 'h',
+    child: [],
+  },
+  {
+    code: 'signal',
+    child: [
+      {
+        title: `加载/卸载:`,
+        code: `LoadorUnload`,
+        isFault: -1,
+      },
+      {
+        title: `控制方式:`,
+        code: `CtrlMode`,
+        isFault: -2,
+      },
+    ],
+  },
+  {
+    code: 'signal',
+    child: [
+      {
+        title: `运行信号:`,
+        code: `Status`,
+        isFault: false,
+      },
+      {
+        title: `排气压力过高:`,
+        code: `ExhaustPreHighFault`,
+        isFault: true,
+      },
+    ],
+  },
+];
+export const preFanMonitorData = [
+  {
+    title: '系统电压',
+    code: 'SysVoltage',
+    unit: 'V',
+  },
+  {
+    title: '漏电闭锁',
+    code: 'LeakageLock',
+    unit: 'signal',
+  },
+  {
+    title: '油压低故障',
+    code: 'OilPressureLowFault',
+    unit: 'signal',
+  },
+  {
+    title: '相序故障',
+    code: 'PhaseSequenceFault',
+    unit: 'signal',
+  },
+];
+export const nitrogenMonitorData = [
+  {
+    title: '总累计流量',
+    code: 'FluxTotal',
+    unit: 'm³',
+  },
+  {
+    title: '瞬时流量',
+    code: 'InputFlux',
+    unit: 'm³/min',
+  },
+  {
+    title: '氮气纯度',
+    code: 'NitrogenPurity',
+    unit: '%',
+  },
+  {
+    title: '膜前温度',
+    code: 'PreMembraneTemperature',
+    unit: '℃',
+  },
+];

+ 815 - 0
src/views/vent/monitorManager/nitrogen/components/nitrogenHome.vue

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

+ 154 - 0
src/views/vent/monitorManager/nitrogen/nitrogen.data.1.ts

@@ -0,0 +1,154 @@
+import { ref } from 'vue';
+import { useGlobSetting } from '/@/hooks/setting';
+import {
+  monitorDataGroupArr as monitorDataGroupArr_Jj,
+  preFanMonitorData as preFanMonitorData_Jj,
+  preMonitorList as preMonitorList_Jj,
+  cqgMonitorList as cqgMonitorList_Jj,
+  prefix as prefix_Jj,
+  getSysState as getSysState_Jj,
+  totalData as totalData_Ji,
+} from './nitrogen.dataJj'; // 锦界
+
+import {
+  monitorDataGroupArr as monitorDataGroupArr_Bet,
+  preFanMonitorData as preFanMonitorData_Bet,
+  preMonitorList as preMonitorList_Bet,
+  cqgMonitorList as cqgMonitorList_Bet,
+  prefix as prefix_Bet,
+  getSysState as getSysState_Bet,
+  totalData as totalData_Bet,
+} from './nitrogen.dataBet'; // 布尔台
+
+import {
+  monitorDataGroupArr as monitorDataGroupArr_Dlt,
+  preFanMonitorData as preFanMonitorData_Dlt,
+  preMonitorList as preMonitorList_Dlt,
+  cqgMonitorList as cqgMonitorList_Dlt,
+  prefix as prefix_Dlt,
+  getSysState as getSysState_Dlt,
+  totalData as totalData_Dlt,
+} from './nitrogen.dataDlt'; // 大柳塔
+
+import {
+  monitorDataGroupArr as monitorDataGroupArr_Hjt,
+  preFanMonitorData as preFanMonitorData_Hjt,
+  preMonitorList as preMonitorList_Hjt,
+  cqgMonitorList as cqgMonitorList_Hjt,
+  prefix as prefix_Hjt,
+  getSysState as getSysState_Hjt,
+  totalData as totalData_Hjt,
+} from './nitrogen.dataHjt'; // 活鸡兔
+
+import {
+  monitorDataGroupArr as monitorDataGroupArr_YJ,
+  preFanMonitorData as preFanMonitorData_YJ,
+  preMonitorList as preMonitorList_YJ,
+  cqgMonitorList as cqgMonitorList_YJ,
+  prefix as prefix_YJ,
+  getSysState as getSysState_YJ,
+  totalData as totalData_YJ,
+} from './nitrogen.dataYJ'; // 窑姐
+
+export type State = {
+  isRun: boolean;
+  fault: boolean;
+};
+export const bottomBtnList = ref([
+  {
+    text: '监控界面',
+    value: 'nitrogenMonitor',
+    isHover: false,
+  },
+  {
+    text: '关键节点监测',
+    value: 'nitrogenNode',
+    isHover: false,
+  },
+  {
+    text: '实时曲线',
+    value: 'nitrogenEcharts',
+    isHover: false,
+  },
+  {
+    text: '压风机历史记录',
+    value: 'nitrogenHistory',
+    isHover: false,
+  },
+  {
+    text: '操作历史记录',
+    value: 'nitrogenHandleHistory',
+    isHover: false,
+  },
+  {
+    text: '故障诊断历史记录',
+    value: 'nitrogenWarningHistory',
+    isHover: false,
+  },
+]);
+
+export function getMonitorData() {
+  const globSetting = useGlobSetting();
+  switch (globSetting.sysOrgCode) {
+    case 'yjmdsankuang': // 窑姐三矿
+      return {
+        monitorDataGroupArr: monitorDataGroupArr_YJ,
+        preFanMonitorData: preFanMonitorData_YJ,
+        preMonitorList: preMonitorList_YJ,
+        cqgMonitorList: cqgMonitorList_YJ,
+        prefix: prefix_YJ,
+        totalData: totalData_YJ,
+        getSysState: getSysState_YJ,
+      };
+    case 'sdmtjtdltmkhjtj': // 活鸡兔井
+      return {
+        monitorDataGroupArr: monitorDataGroupArr_Hjt,
+        preFanMonitorData: preFanMonitorData_Hjt,
+        preMonitorList: preMonitorList_Hjt,
+        cqgMonitorList: cqgMonitorList_Hjt,
+        prefix: prefix_Hjt,
+        getSysState: getSysState_Hjt,
+        totalData: totalData_Hjt,
+      };
+    case 'sdmtjtdltmk': // 大柳塔井
+      return {
+        monitorDataGroupArr: monitorDataGroupArr_Dlt,
+        preFanMonitorData: preFanMonitorData_Dlt,
+        preMonitorList: preMonitorList_Dlt,
+        cqgMonitorList: cqgMonitorList_Dlt,
+        prefix: prefix_Dlt,
+        getSysState: getSysState_Dlt,
+        totalData: totalData_Dlt,
+      };
+    case 'sdmtjtbetmk': // 布尔台
+      return {
+        monitorDataGroupArr: monitorDataGroupArr_Bet,
+        preFanMonitorData: preFanMonitorData_Bet,
+        preMonitorList: preMonitorList_Bet,
+        cqgMonitorList: cqgMonitorList_Bet,
+        prefix: prefix_Bet,
+        getSysState: getSysState_Bet,
+        totalData: totalData_Bet,
+      };
+    case 'sdmtjtjjmk': // 锦界
+      return {
+        monitorDataGroupArr: monitorDataGroupArr_Jj,
+        preFanMonitorData: preFanMonitorData_Jj,
+        preMonitorList: preMonitorList_Jj,
+        cqgMonitorList: cqgMonitorList_Jj,
+        prefix: prefix_Jj,
+        getSysState: getSysState_Jj,
+        totalData: totalData_Ji,
+      };
+    default: //默认锦界
+      return {
+        monitorDataGroupArr: monitorDataGroupArr_Bet,
+        preFanMonitorData: preFanMonitorData_Bet,
+        preMonitorList: preMonitorList_Bet,
+        cqgMonitorList: cqgMonitorList_Bet,
+        prefix: prefix_Bet,
+        getSysState: getSysState_Bet,
+        totalData: totalData_Bet,
+      };
+  }
+}