|
@@ -0,0 +1,553 @@
|
|
|
+<template>
|
|
|
+ <BasicModal v-bind="$attrs" @register="register" :title="`束管监测详情 ${currentTime}`" width="1200px" @ok="handleOk"
|
|
|
+ @cancel="handleCancel">
|
|
|
+ <div class="fiber-modal">
|
|
|
+ <div class="modal-left">
|
|
|
+ <div v-for="device in deviceList" class="link-item"
|
|
|
+ :class="{ 'active-device-title': device.deviceID === activeDeviceID }" :key="device.deviceID">
|
|
|
+ <span class="" @click="selectDevice(device.deviceID)">{{ device.strinstallpos }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="modal-right">
|
|
|
+ <!-- <span class="base-title">基本信息</span>
|
|
|
+ <div>
|
|
|
+ <div>
|
|
|
+ <span>监测区域范围:</span>
|
|
|
+ <span>{{ 0 }} - {{ 1 }}</span>
|
|
|
+ </div>
|
|
|
+ </div> -->
|
|
|
+ <span class="base-title">实时监测参数</span>
|
|
|
+ <div class="right-top">
|
|
|
+ <!-- 温度 -->
|
|
|
+ <div class="top-item">
|
|
|
+ <div class="icon">
|
|
|
+ <SvgIcon class="icon-style max-temperature" size="38" name="max-temperature" />
|
|
|
+ </div>
|
|
|
+ <div class="item-container">
|
|
|
+ <div class="title">最高温度</div>
|
|
|
+ <div class="value">{{ posMonitor.fmax }} <span>℃</span> </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="top-item">
|
|
|
+ <div class="icon">
|
|
|
+ <SvgIcon class="icon-style min-temperature" size="38" name="min-temperature" />
|
|
|
+ </div>
|
|
|
+ <div class="item-container">
|
|
|
+ <div class="title">最低温度</div>
|
|
|
+ <div class="value">{{ posMonitor.fmin }} <span>℃</span></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="top-item">
|
|
|
+ <div class="icon">
|
|
|
+ <SvgIcon class="icon-style aveg-temperature" size="38" name="aveg-temperature" />
|
|
|
+ </div>
|
|
|
+ <div class="item-container">
|
|
|
+ <div class="title">平均温度</div>
|
|
|
+ <div class="value">{{ posMonitor.favg }} <span>℃</span></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="top-item warning-box">
|
|
|
+ <div class="icon">
|
|
|
+ <SvgIcon class="icon-style" size="38" name="risk-level" />
|
|
|
+ </div>
|
|
|
+ <div class="item-container">
|
|
|
+ <div class="title">风险等级</div>
|
|
|
+ <div class="warning-value">低风险</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="top-item item-data">
|
|
|
+ <div class="icon">
|
|
|
+ <SvgIcon class="icon-style" name="coval" style="width: 62px; height: 38px; margin-top: 10px;" />
|
|
|
+ </div>
|
|
|
+ <div class="item-container">
|
|
|
+ <div class="title">温度</div>
|
|
|
+ <div class="value">{{ (posMonitor.coval !== undefined && posMonitor.coval !== null) ? posMonitor.coval : '-'
|
|
|
+ }} <span>ppm</span> </div>
|
|
|
+ <div>报警阈值:12</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="top-item item-data">
|
|
|
+ <div class="icon">
|
|
|
+ <SvgIcon class="icon-style" name="coval" style="width: 62px; height: 38px; margin-top: 10px;" />
|
|
|
+ </div>
|
|
|
+ <div class="item-container">
|
|
|
+ <div class="title">一氧化碳</div>
|
|
|
+ <div class="value">{{ (posMonitor.coval !== undefined && posMonitor.coval !== null) ? posMonitor.coval : '-'
|
|
|
+ }} <span>ppm</span> </div>
|
|
|
+ <div>报警阈值:12</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="top-item item-data">
|
|
|
+ <div class="icon">
|
|
|
+ <SvgIcon class="icon-style" name="co2val" style="width: 72px; height: 46px;" />
|
|
|
+ </div>
|
|
|
+ <div class="item-container">
|
|
|
+ <div class="title">二氧化碳</div>
|
|
|
+ <div class="value">{{ (posMonitor.co2val !== undefined && posMonitor.co2val !== null) ? posMonitor.co2val :
|
|
|
+ '-' }} <span>%</span></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="top-item item-data">
|
|
|
+ <div class="icon">
|
|
|
+ <SvgIcon class="icon-style" name="gasval" style="width: 72px; height: 46px;" />
|
|
|
+ </div>
|
|
|
+ <div class="item-container">
|
|
|
+ <div class="title">甲烷</div>
|
|
|
+ <div class="value">{{ (posMonitor.gasval !== undefined && posMonitor.gasval !== null) ? posMonitor.gasval :
|
|
|
+ '-' }} <span>%</span></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="top-item item-data">
|
|
|
+ <div class="icon">
|
|
|
+ <SvgIcon class="icon-style" name="ch2val" style="width: 76px; height: 42px;" />
|
|
|
+ </div>
|
|
|
+ <div class="item-container">
|
|
|
+ <div class="title">乙烯</div>
|
|
|
+ <div class="value">{{ (posMonitor.ch2val !== undefined && posMonitor.ch2val !== null) ? posMonitor.ch2val :
|
|
|
+ '-' }} <span>ppm</span></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="top-item">
|
|
|
+ <div class="icon">
|
|
|
+ <SvgIcon class="icon-style" name="chval" style="width: 76px; height: 42px;" />
|
|
|
+ </div>
|
|
|
+ <div class="item-container">
|
|
|
+ <div class="title">乙炔</div>
|
|
|
+ <div class="value">{{ (posMonitor.chval !== undefined && posMonitor.chval !== null) ? posMonitor.chval : '-'
|
|
|
+ }} <span>ppm</span></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="top-item">
|
|
|
+ <div class="icon">
|
|
|
+ <SvgIcon class="icon-style" name="o2val" style="width: 76px; height: 50px;" />
|
|
|
+ </div>
|
|
|
+ <div class="item-container">
|
|
|
+ <div class="title">氧气</div>
|
|
|
+ <div class="value">{{ (posMonitor.o2val !== undefined && posMonitor.o2val !== null) ? posMonitor.o2val : '-'
|
|
|
+ }} <span>%</span></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="top-item warning-box">
|
|
|
+ <div class="icon">
|
|
|
+ <SvgIcon class="icon-style" size="42" name="alarm-warning" style="margin-top: 5px;" />
|
|
|
+ </div>
|
|
|
+ <div class="item-container">
|
|
|
+ <div class="title">风险等级</div>
|
|
|
+ <div class="warning-value">{{ posMonitor['warnLevel_str'] ? posMonitor['warnLevel_str'] : '-' }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="top-item warning-box">
|
|
|
+ <div class="icon">
|
|
|
+ <SvgIcon class="icon-style" size="42" name="link" style="margin-top: 5px;" />
|
|
|
+ </div>
|
|
|
+ <div class="item-container">
|
|
|
+ <div class="title">连接状态</div>
|
|
|
+ <div class="warning-value">{{ posMonitor['netStatus'] == 1 ? '连接' : '未连接' }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="right-bottom">
|
|
|
+ <span class="base-title">设备监测曲线</span>
|
|
|
+ <div class="echarts-box">
|
|
|
+ <BarAndLine class="echarts-line" xAxisPropType="time" :dataSource="historyList" height="100%"
|
|
|
+ :chartsColumns="chartsColumns" :option="echatsOption" chartsType="listMonitor" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </BasicModal>
|
|
|
+</template>
|
|
|
+<script lang="ts">
|
|
|
+import { defineComponent, ref, watch, shallowRef } from 'vue';
|
|
|
+import { BasicModal, useModalInner } from '/@/components/Modal';
|
|
|
+import BarAndLine from '/@/components/chart/BarAndLine.vue';
|
|
|
+import { SvgIcon } from '/@/components/Icon';
|
|
|
+import { Decoration7 as DvDecoration7, ScrollBoard as DvScrollBoard } from '@kjgl77/datav-vue3';
|
|
|
+import dayjs from 'dayjs'
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ components: { BasicModal, BarAndLine, SvgIcon, DvScrollBoard, DvDecoration7 },
|
|
|
+ props: {
|
|
|
+ dataSource: { type: Array },
|
|
|
+ activeID: { type: String }
|
|
|
+ },
|
|
|
+ setup(props) {
|
|
|
+ const currentTime = ref(dayjs().format('YYYY-MM-DD HH:mm:ss'))
|
|
|
+ const modelRef = ref({});
|
|
|
+ const loading = ref(true);
|
|
|
+ const activeDeviceID = ref('');
|
|
|
+ const deviceList = ref<any[]>([])
|
|
|
+ const historyList = ref<any[]>([])
|
|
|
+ const posList = ref<any[]>([])
|
|
|
+ const posMonitor = shallowRef({})
|
|
|
+
|
|
|
+ const echatsOption = {
|
|
|
+ grid: {
|
|
|
+ top: '25%',
|
|
|
+ left: '30',
|
|
|
+ right: '45',
|
|
|
+ bottom: '3%',
|
|
|
+ containLabel: true
|
|
|
+ },
|
|
|
+ toolbox: {
|
|
|
+ feature: {}
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ const chartsColumns = [
|
|
|
+ {
|
|
|
+ legend: '一氧化碳',
|
|
|
+ seriesName: '(ppm)',
|
|
|
+ ymax: 10,
|
|
|
+ yname: 'ppm',
|
|
|
+ linetype: 'line',
|
|
|
+ yaxispos: 'left',
|
|
|
+ color: '#FDB146',
|
|
|
+ sort: 1,
|
|
|
+ xRotate: 0,
|
|
|
+ dataIndex: 'coval',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ legend: '乙炔',
|
|
|
+ seriesName: '',
|
|
|
+ ymax: 10,
|
|
|
+ yname: 'ppm',
|
|
|
+ linetype: 'line',
|
|
|
+ yaxispos: 'left',
|
|
|
+ color: '#00FFA8',
|
|
|
+ sort: 1,
|
|
|
+ xRotate: 0,
|
|
|
+ dataIndex: 'chval',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ legend: '乙烯',
|
|
|
+ seriesName: '',
|
|
|
+ ymax: 10,
|
|
|
+ yname: 'ppm',
|
|
|
+ linetype: 'line',
|
|
|
+ yaxispos: 'left',
|
|
|
+ color: '#AE19FF',
|
|
|
+ sort: 1,
|
|
|
+ xRotate: 0,
|
|
|
+ dataIndex: 'ch2val',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ legend: '二氧化碳',
|
|
|
+ seriesName: '(%)',
|
|
|
+ ymax: 20,
|
|
|
+ yname: '1%',
|
|
|
+ linetype: 'line',
|
|
|
+ yaxispos: 'right',
|
|
|
+ color: '#9C83D9',
|
|
|
+ sort: 2,
|
|
|
+ xRotate: 0,
|
|
|
+ dataIndex: 'co2val',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ legend: '甲烷',
|
|
|
+ seriesName: '',
|
|
|
+ ymax: 20,
|
|
|
+ yname: '1%',
|
|
|
+ linetype: 'line',
|
|
|
+ yaxispos: 'right',
|
|
|
+ color: '#DA3914',
|
|
|
+ sort: 2,
|
|
|
+ xRotate: 0,
|
|
|
+ dataIndex: 'gasval',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ legend: '氧气',
|
|
|
+ seriesName: '(氧气%)',
|
|
|
+ ymax: 30,
|
|
|
+ yname: '2%',
|
|
|
+ linetype: 'line',
|
|
|
+ yaxispos: 'right',
|
|
|
+ color: '#03C2EC',
|
|
|
+ sort: 3,
|
|
|
+ xRotate: 0,
|
|
|
+ dataIndex: 'o2val',
|
|
|
+ },
|
|
|
+
|
|
|
+ ]
|
|
|
+ const [register, { setModalProps, closeModal }] = useModalInner();
|
|
|
+
|
|
|
+ function handleVisibleChange(visible) {
|
|
|
+ if (visible) {
|
|
|
+ loading.value = true;
|
|
|
+ setModalProps({ loading: true, confirmLoading: true });
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ loading.value = false;
|
|
|
+ setModalProps({ loading: false, confirmLoading: false });
|
|
|
+ }, 1000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 选择监测
|
|
|
+ function selectDevice(id) {
|
|
|
+ loading.value = true;
|
|
|
+ setModalProps({ loading: true, confirmLoading: true });
|
|
|
+ setTimeout(() => {
|
|
|
+ loading.value = false;
|
|
|
+ activeDeviceID.value = id
|
|
|
+ setModalProps({ loading: false, confirmLoading: false });
|
|
|
+ }, 300);
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleOk(e) {
|
|
|
+ e.preventDefault()
|
|
|
+ closeModal()
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleCancel(e) {
|
|
|
+ e.preventDefault()
|
|
|
+ closeModal()
|
|
|
+ }
|
|
|
+
|
|
|
+ watch([() => props.dataSource, () => props.activeID], ([newDataSource, newActiveID], [oldDataSource, oldActiveID]) => {
|
|
|
+ if (newActiveID != oldActiveID) {
|
|
|
+ activeDeviceID.value = newActiveID as string
|
|
|
+ }
|
|
|
+ deviceList.value = newDataSource?.filter((item: any, index) => {
|
|
|
+ if ((!activeDeviceID.value && index == 0) || item.deviceID === activeDeviceID.value) {
|
|
|
+ activeDeviceID.value = item.deviceID
|
|
|
+ posMonitor.value = Object.assign(item, item.readData)
|
|
|
+ historyList.value = item['history']
|
|
|
+ }
|
|
|
+ item.readTime = item.readTime?.substring(11)
|
|
|
+ return item
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ return { register, model: modelRef, currentTime, handleVisibleChange, selectDevice, handleOk, handleCancel, deviceList, historyList, activeDeviceID, posMonitor, echatsOption, posList, chartsColumns };
|
|
|
+ },
|
|
|
+
|
|
|
+});
|
|
|
+</script>
|
|
|
+<style lang="less" scoped>
|
|
|
+.fiber-modal {
|
|
|
+ width: 100%;
|
|
|
+ height: 650px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
+
|
|
|
+ .modal-left {
|
|
|
+ width: 200px;
|
|
|
+ height: 100%;
|
|
|
+ overflow-y: auto;
|
|
|
+ background: #ffffff11;
|
|
|
+ padding: 5px;
|
|
|
+ border-radius: 5px;
|
|
|
+
|
|
|
+ .active-device-title {
|
|
|
+ color: aqua;
|
|
|
+ }
|
|
|
+
|
|
|
+ .link-item {
|
|
|
+ position: relative;
|
|
|
+ cursor: pointer;
|
|
|
+ line-height: 30px;
|
|
|
+ padding-left: 30px;
|
|
|
+
|
|
|
+ span:hover {
|
|
|
+ color: #89ffff;
|
|
|
+ }
|
|
|
+
|
|
|
+ &::after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ display: block;
|
|
|
+ width: 8px;
|
|
|
+ height: 8px;
|
|
|
+ top: 12px;
|
|
|
+ left: 10px;
|
|
|
+ transform: rotateZ(45deg) skew(10deg, 10deg);
|
|
|
+ background: #45d3fd;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .modal-right {
|
|
|
+ width: calc(100% - 220px);
|
|
|
+
|
|
|
+ .base-title {
|
|
|
+ line-height: 32px;
|
|
|
+ position: relative;
|
|
|
+ padding-left: 20px;
|
|
|
+
|
|
|
+ &::after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ display: block;
|
|
|
+ width: 4px;
|
|
|
+ height: 12px;
|
|
|
+ top: 4px;
|
|
|
+ left: 10px;
|
|
|
+ background: #45d3fd;
|
|
|
+ border-radius: 4px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .right-top {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ margin-bottom: 10px;
|
|
|
+
|
|
|
+ .top-item {
|
|
|
+ width: 220px;
|
|
|
+ height: 100px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: center;
|
|
|
+ border: 1px solid rgba(25, 237, 255, .4);
|
|
|
+ box-shadow: inset 0 0 10px rgba(0, 197, 255, .6);
|
|
|
+ background: rgba(0, 0, 0, .06666666666666667);
|
|
|
+ padding-top: 20px;
|
|
|
+ margin: 10px 0;
|
|
|
+
|
|
|
+ .icon {
|
|
|
+ margin-right: 10px;
|
|
|
+ margin-top: 5px;
|
|
|
+ color: #FDB146;
|
|
|
+ }
|
|
|
+
|
|
|
+ .item-container {
|
|
|
+ width: 100px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+
|
|
|
+ div {
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-size: 18px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .value {
|
|
|
+ text-shadow: 0 0 25px #00fbfe;
|
|
|
+ background: linear-gradient(0deg, #45d3fd, #45d3fd, #61ddb1, #61ddb1);
|
|
|
+ font-style: normal;
|
|
|
+ background-size: cover;
|
|
|
+ font-family: electronicFont;
|
|
|
+ font-size: 30px;
|
|
|
+ -webkit-background-clip: text;
|
|
|
+ background-clip: text;
|
|
|
+ -webkit-text-fill-color: transparent;
|
|
|
+ position: relative;
|
|
|
+ top: -8px;
|
|
|
+
|
|
|
+ span {
|
|
|
+ font-family: Arial, Helvetica, sans-serif;
|
|
|
+ font-size: 18px;
|
|
|
+ color: aliceblue;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .item-data{
|
|
|
+ height: 130px;
|
|
|
+ padding-top: 0;
|
|
|
+ .icon{
|
|
|
+ margin-right: 30px;
|
|
|
+ margin-top: 25px;
|
|
|
+ }
|
|
|
+ .item-container{
|
|
|
+ .value{
|
|
|
+ top: 0px;
|
|
|
+ }
|
|
|
+ .rang{
|
|
|
+ color: #ff8663;;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .warning-box {
|
|
|
+ padding-top: 0px;
|
|
|
+
|
|
|
+ .icon {
|
|
|
+ margin-top: 20px;
|
|
|
+
|
|
|
+ :deep(.icon-style) {
|
|
|
+ width: auto;
|
|
|
+ color: #FDB146;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .warning-value {
|
|
|
+ font-size: 18px;
|
|
|
+ color: #61ddb1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .right-center {
|
|
|
+ margin-top: 20px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
+
|
|
|
+ .table-box {
|
|
|
+ position: relative;
|
|
|
+ width: 500px;
|
|
|
+ height: 250px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .warning-box {
|
|
|
+ width: calc(100% - 520px);
|
|
|
+
|
|
|
+ .warning-container {
|
|
|
+ width: 100%;
|
|
|
+ height: convert;
|
|
|
+ background: #009acd00;
|
|
|
+
|
|
|
+ :deep(.dv-scroll-board) {
|
|
|
+ .row-item {
|
|
|
+ height: 40px !important;
|
|
|
+ line-height: 40px !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .header-item {
|
|
|
+ border-top: 1px solid #91e9fe !important;
|
|
|
+ border-bottom: 1px solid #91e9fe !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .right-bottom {
|
|
|
+ margin-top: 20px;
|
|
|
+
|
|
|
+ .echarts-box {
|
|
|
+ width: 100%;
|
|
|
+ height: 320px;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .echarts-line {
|
|
|
+ width: calc(100% + 80px);
|
|
|
+ position: absolute
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.zxm-table-body) {
|
|
|
+ border: 1px solid rgba(57, 232, 255, 0.2) !important;
|
|
|
+
|
|
|
+ .zxm-table-tbody>tr>td {
|
|
|
+ border: none !important;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.zxm-table-cell) {
|
|
|
+ border-right: none !important;
|
|
|
+}</style>
|