You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

635 lines
19 KiB
Vue

<template>
<div class="realtimeData">
<div class="realcontain">
<div class="realHead">
<h3>{{ msgTitle }}</h3>
<el-button
@click="handleTypeDraw"
type="primary"
style="margin-left: 16px"
>
选择设备类型
</el-button>
<el-button
@click="handleAreaDraw"
type="primary"
style="margin-left: 16px"
>
选择区域和主设备
</el-button>
<el-button
v-if="msgTitle == '设备类型实时数据'"
@click="exporTypeData"
type="primary"
style="margin-left: 16px"
>
按设备类型导出
</el-button>
<el-button
v-else
@click="exporZsbData"
type="primary"
style="margin-left: 16px"
>
按主设备导出
</el-button>
<el-drawer title="选择条件" :visible.sync="typedrawer" direction="ttb">
<div class="greyBox">
<div class="selectBox">
<h4>选择设备类型</h4>
<el-radio-group
v-model="deviceTypeVal"
size="mini"
@input="handletypeChange"
>
<el-radio
v-for="item in deviceTypeList"
:key="item.id"
:label="item.id"
border
>
{{ item.mc }}
</el-radio>
</el-radio-group>
</div>
</div>
</el-drawer>
<el-drawer title="选择条件" :visible.sync="areadrawer" direction="ttb">
<div class="greyBox">
<div class="selectBox">
<h4>选择区域</h4>
<el-radio-group
v-model="areaVal"
size="mini"
@input="handleAreaChange"
>
<el-radio
v-for="item in areaAllList"
:key="item.id"
:label="item.id"
border
>
{{ item.mc }}
</el-radio>
</el-radio-group>
</div>
<div class="selectBox">
<h4>选择主设备</h4>
<div class="zsbBox" v-if="zsbAllList.length !== 0">
<el-radio-group
v-model="zsbVal"
size="mini"
@input="handlezsbChange"
>
<el-radio
v-for="item in zsbAllList"
:key="item.id"
:label="item.id"
border
>
{{ item.mc }}
</el-radio>
</el-radio-group>
</div>
<div class="zsbBox" v-else>
<p class="empytBox">暂无数据</p>
</div>
</div>
</div>
</el-drawer>
</div>
<div class="loadingbox" v-loading="dataLoading">
<div class="cardBox" v-if="jksbAllList.length !== 0">
<el-card
class="box-card"
v-for="(item, index) in jksbAllList"
:key="index"
>
<div slot="header" class="clearfix">
<span class="headTitle" :title="item.name"
>{{ item.jgName }}/{{ item.zsbName }}/{{ item.name }}</span
>
<el-button
style="float: right; padding: 3px 0"
type="text"
@click="handlehistory(item)"
>历史数据</el-button
>
</div>
<el-tooltip placement="top-start">
<div slot="content">
<div class="textitem">
<h3 class="headTitle" :title="item.name">{{ item.name }}</h3>
<p>
采集时间
<span v-if="item.lastData" class="timeclass">
{{ item.lastData.acquisitionTime }}
</span>
<span v-else class="timeclass"> -- </span>
</p>
<!-- 遍历 typePoints 显示数据 -->
<div
class="dataclass"
v-for="fieldDesc in item.typePoints"
:key="fieldDesc.field"
>
<strong
>{{ fieldDesc.fieldDesc || fieldDesc.field }}:</strong
>
<span
v-if="item.lastData && fieldDesc.field in item.lastData"
>
{{ getDataByField(item, fieldDesc.field) }}
</span>
<span v-else> -- </span>
</div>
<!-- 显示 lastData 中有但 typePoints 中没有的字段 -->
<div
class="dataclass"
v-for="(value, key) in item.lastData"
:key="key"
v-if="
!item.typePoints.some((fd) => fd.field === key) &&
key !== 'acquisitionTime'
"
>
<strong>{{ key }}:</strong>
{{ value }}
</div>
</div>
</div>
<div class="textitem">
<p>
采集时间
<span v-if="item.lastData" class="timeclass">
{{ item.lastData.acquisitionTime }}
</span>
<span v-else class="timeclass"> -- </span>
</p>
<!-- 遍历 typePoints 显示数据 -->
<div
class="dataclass"
v-for="fieldDesc in item.typePoints"
:key="fieldDesc.field"
>
<strong>{{ fieldDesc.fieldDesc || fieldDesc.field }}:</strong>
<span
v-if="item.lastData && fieldDesc.field in item.lastData"
>
{{ getDataByField(item, fieldDesc.field) }}
</span>
<span v-else> -- </span>
</div>
<!-- 显示 lastData 中有但 typePoints 中没有的字段 -->
<div
class="dataclass"
v-for="(value, key) in item.lastData"
:key="key"
v-if="
!item.typePoints.some((fd) => fd.field === key) &&
key !== 'acquisitionTime'
"
>
<strong>{{ key }}:</strong>
{{ value }}
</div>
</div>
</el-tooltip>
</el-card>
</div>
<div class="emptyBox" v-else>
<el-empty description="暂无数据"></el-empty>
</div>
</div>
</div>
<historyDialog ref="historyDialogRef"></historyDialog>
</div>
</template>
<script>
import {
areaListAllApi,
zsbListAllApi,
monitoringListAllApi,
// getDetailApi,
modevtypeListAllApi,
} from "@/utils/api/index";
import historyDialog from "./components/historyDialog";
export default {
name: "realtimeData",
components: { historyDialog },
data() {
return {
msgTitle: "设备类型实时数据",
typedrawer: false,
areadrawer: false,
deviceTypeVal: null,
deviceTypeList: [], //设备类型
areaVal: null,
areaAllList: [], //区域
zsbVal: null,
zsbAllList: [], //主设备
jksbAllList: [], //监控设备
dataLoading: false,
intervalId: null, // 用于保存 setInterval 的 ID
intervalIdType: null,
};
},
computed: {},
watch: {},
created() {},
mounted() {
this.$nextTick(() => {
this.areaVal = JSON.parse(localStorage.getItem("areaVal"));
this.zsbVal = JSON.parse(localStorage.getItem("zsbVal"));
this.deviceTypeVal = JSON.parse(localStorage.getItem("deviceTypeVal"));
this.getdeviceTypeAll();
});
},
methods: {
//选择设备类型
handleTypeDraw() {
this.typedrawer = true;
this.msgTitle = "设备类型实时数据";
this.getdeviceTypeAll();
},
//选择区域和主设备
handleAreaDraw() {
this.areadrawer = true;
this.msgTitle = "主设备实时数据";
this.getAreaAllList();
},
//获取所有的设备类型
getdeviceTypeAll() {
modevtypeListAllApi()
.then((res) => {
console.log(res);
this.deviceTypeList = res.data;
// 尝试从 localStorage 获取 areaVal
const storeddeviceTypeVal = localStorage.getItem("deviceTypeVal");
if (storeddeviceTypeVal) {
// 如果 localStorage 中有 areaVal则将其解析为数字假设 id 是数字)并赋值给 this.areaVal
this.areaVal = JSON.parse(storeddeviceTypeVal);
} else {
// 否则,使用 res.data[0].id
this.deviceTypeVal = res.data[0]?.id; // 使用可选链操作符避免 res.data[0] 为 undefined 的情况
// 同时,将新获取的 areaVal 存储到 localStorage 中
localStorage.setItem(
"deviceTypeVal",
JSON.stringify(this.deviceTypeVal)
);
}
this.getTypeAllList();
this.startIntervalIfNeededType();
this.stopInterval();
})
.catch((err) => {
console.log(err); //代码错误、请求失败捕获
});
},
handletypeChange(value) {
this.deviceTypeVal = value;
localStorage.removeItem("deviceTypeVal");
localStorage.setItem("deviceTypeVal", JSON.stringify(value));
this.jksbAllList = [];
this.getTypeAllList();
this.startIntervalIfNeededType();
this.stopInterval();
},
//根据类型获取所有数据
getTypeAllList() {
monitoringListAllApi({ typeId: this.deviceTypeVal })
.then((res) => {
console.log(res);
this.jksbAllList = res.data;
this.dataLoading = false;
})
.catch((err) => {
console.log(err); //代码错误、请求失败捕获
});
},
startIntervalIfNeededType() {
// 如果定时器尚未启动,则启动它
if (this.intervalIdType === null) {
this.intervalIdType = setInterval(this.getTypeAllList, 10000);
}
},
stopIntervalType() {
// 停止定时器
if (this.intervalIdType !== null) {
clearInterval(this.intervalIdType);
this.intervalIdType = null;
}
},
//按照设备类型导出
exporTypeData() {
window.location.href =
"/cac-api/nsensor/exportLatest?typeId=" + this.deviceTypeVal;
},
//按照主设备导出
exporZsbData() {
window.location.href =
"/cac-api/nsensor/exportLatest?zsbid=" + this.zsbVal;
},
//获取所有区间间隔
getAreaAllList() {
areaListAllApi()
.then((res) => {
console.log(res);
this.areaAllList = res.data;
// 尝试从 localStorage 获取 areaVal
const storedAreaVal = localStorage.getItem("areaVal");
if (storedAreaVal) {
// 如果 localStorage 中有 areaVal则将其解析为数字假设 id 是数字)并赋值给 this.areaVal
this.areaVal = JSON.parse(storedAreaVal);
} else {
// 否则,使用 res.data[0].id
this.areaVal = res.data[0]?.id; // 使用可选链操作符避免 res.data[0] 为 undefined 的情况
// 同时,将新获取的 areaVal 存储到 localStorage 中
localStorage.setItem("areaVal", JSON.stringify(this.areaVal));
}
this.getzsbAllList();
})
.catch((err) => {
console.log(err); //代码错误、请求失败捕获
});
},
handleAreaChange(value) {
this.areaVal = value;
localStorage.setItem("areaVal", JSON.stringify(value));
localStorage.removeItem("zsbVal");
this.jksbAllList = [];
this.getzsbAllList();
},
//获取主设备
getzsbAllList() {
zsbListAllApi({ jgid: this.areaVal })
.then((res) => {
console.log(res);
this.zsbAllList = res.data;
// this.zsbVal = res.data[0].id;
// 尝试从 localStorage 获取 zsbVal
const storedzsbVal = localStorage.getItem("zsbVal");
if (storedzsbVal) {
this.zsbVal = JSON.parse(storedzsbVal);
} else {
// 否则,使用 res.data[0].id
this.zsbVal = res.data[0].id; // 使用可选链操作符避免 res.data[0] 为 undefined 的情况
localStorage.setItem("zsbVal", JSON.stringify(this.zsbVal));
}
// localStorage.setItem("zsbVal", JSON.stringify(res.data[0].id));
// 调用 getjcsbAllList 方法获取监测设备列表
this.getjcsbAllList();
// 启动定时器(如果尚未启动)
this.startIntervalIfNeeded();
this.stopIntervalType();
})
.catch((err) => {
console.log(err); //代码错误、请求失败捕获
});
},
handlezsbChange(value) {
this.zsbVal = value;
localStorage.setItem("zsbVal", JSON.stringify(value));
// 调用 getjcsbAllList 方法获取监测设备列表
this.getjcsbAllList();
// 启动定时器(如果尚未启动)
this.startIntervalIfNeeded();
this.stopIntervalType();
},
//获取所有监测设备
getjcsbAllList() {
//this.dataLoading = true;
monitoringListAllApi({ zsbid: this.zsbVal })
.then((res) => {
console.log(res);
this.jksbAllList = res.data;
this.dataLoading = false;
})
.catch((err) => {
console.log(err); //代码错误、请求失败捕获
});
},
startIntervalIfNeeded() {
// 如果定时器尚未启动,则启动它
if (this.intervalId === null) {
this.intervalId = setInterval(this.getjcsbAllList, 10000);
}
},
stopInterval() {
// 停止定时器
if (this.intervalId !== null) {
clearInterval(this.intervalId);
this.intervalId = null;
}
},
getDataByField(value, fieldName) {
return value.lastData[fieldName] || "--"; // 如果字段不存在,则返回'N/A'
},
//查看历史数据
handlehistory(item) {
console.log(item);
this.$refs.historyDialogRef.display(item);
},
},
beforeDestroy() {
// 在组件销毁前停止定时请求
this.stopInterval();
this.stopIntervalType();
},
};
</script>
<style lang="less">
.realtimeData {
display: flex;
height: 100%;
flex-direction: column;
.realHead {
// height: 200px;
// background: rgba(8, 9, 36, 0.28);
// box-shadow: inset 0 4px 44px 0 #106cde;
padding: 0px 12px;
margin: 10px 0px;
display: flex;
align-items: center;
.el-drawer__wrapper {
.el-drawer__header {
margin-bottom: 14px;
}
}
.el-drawer {
height: 50% !important;
}
.greyBox {
color: #000;
//margin-top: 12px;
margin-bottom: 12px;
padding: 8px 0px;
height: calc(100% - 40px);
.selectBox {
display: flex;
//align-items: center;
margin-bottom: 12px;
h4 {
color: #000;
margin-right: 12px;
font-weight: normal;
width: 100px;
height: 28px;
line-height: 28px;
margin-left: 12px;
}
.el-radio-group {
display: flex;
flex-wrap: wrap;
flex: 1;
color: #000;
.el-radio {
margin-bottom: 12px;
margin-right: 12px;
color: #000;
}
.el-radio.is-bordered.is-checked {
border-color: #337ab7;
}
.el-radio__input.is-checked + .el-radio__label {
color: #337ab7;
}
.el-radio__input.is-checked .el-radio__inner {
border-color: #337ab7;
background: #337ab7;
}
}
.zsbBox {
display: flex;
flex-wrap: wrap;
flex: 1;
.empytBox {
text-align: center;
line-height: 28px;
height: 28px;
color: #000;
width: 100%;
}
}
}
}
}
.realcontain {
height: calc(100% - 0px);
background: rgba(8, 9, 36, 0.28);
box-shadow: inset 0 4px 44px 0 #106cde;
padding: 0px 12px;
.loadingbox {
height: calc(100% - 64px);
overflow: auto;
}
.cardBox {
display: flex;
flex-wrap: wrap;
padding: 12px 0px;
.el-card {
margin-right: 24px;
margin-bottom: 24px;
background: rgba(8, 9, 36, 0.28);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
box-shadow: inset 0 4px 44px 0 #106cde;
color: #fff;
width: 346px;
border: 1px solid #66e6ff;
.el-card__header {
padding: 4px 8px;
border-bottom: 1px solid #66e6ff;
.headTitle {
font-weight: bold;
width: 250px;
font-size: 14px;
display: inline-block;
overflow: hidden; /*超出部分隐藏*/
text-overflow: ellipsis; /*超出部分省略号表示*/
white-space: nowrap; /*强制单行显示*/
}
.el-button--text {
color: #66e6ff;
}
}
.el-card__body {
padding: 8px;
height: 78px;
.textitem {
height: 100%;
overflow: hidden;
p {
font-size: 14px;
}
.timeclass {
font-size: 14px;
}
.dataclass {
strong {
font-weight: normal;
font-size: 14px;
}
}
}
}
}
}
.emptyBox {
height: 100%;
background: #eee;
.el-empty {
height: 100%;
}
}
// .el-table {
// margin-top: 12px;
// strong {
// font-weight: normal;
// }
// .timeclass {
// border-right: 1px solid #ebeef5;
// display: inline-block;
// padding-right: 12px;
// margin-right: 12px;
// }
// .dataclass {
// border-right: 1px solid #ebeef5;
// display: inline-block;
// padding-right: 12px;
// margin-right: 12px;
// }
// }
}
}
.el-tooltip__popper {
.textitem {
h3 {
margin-bottom: 12px;
}
strong {
font-weight: normal;
}
.dataclass {
margin-top: 8px;
}
}
}
</style>