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.

656 lines
19 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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
class="rightbtn"
v-if="msgTitle == '设备类型实时数据'"
@click="exporTypeData"
type="primary"
style="margin-left: 16px"
>
导出
</el-button>
<el-button
v-else
class="rightbtn"
@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="bottom-start">
<div slot="content">
<div class="textitem">
<h3 class="headTitle" :title="item.name">
{{ item.jgName }}/{{ item.zsbName }}/{{ 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,
getlistAllCountApi,
} from "@/utils/api/index";
import historyDialog from "./components/historyDialog";
export default {
name: "realtimeData",
components: { historyDialog },
data() {
return {
msgTitle: "设备类型实时数据",
deviceTitle: "",
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() {
getlistAllCountApi()
.then((res) => {
console.log(res);
this.deviceTypeList = res.data.filter(
(item) => item.sensorCount !== 0
);
// 尝试从 localStorage 获取 areaVal
const storeddeviceTypeVal = localStorage.getItem("deviceTypeVal");
const deviceInfoVal = localStorage.getItem("deviceTitle");
if (storeddeviceTypeVal) {
// 如果 localStorage 中有 areaVal则将其解析为数字假设 id 是数字)并赋值给 this.areaVal
this.areaVal = JSON.parse(storeddeviceTypeVal);
this.deviceTitle = JSON.parse(deviceInfoVal);
} else {
// 否则,使用 res.data[0].id
this.deviceTypeVal = res.data[0]?.id; // 使用可选链操作符避免 res.data[0] 为 undefined 的情况
this.deviceTitle = res.data[0].mc;
// 同时,将新获取的 areaVal 存储到 localStorage 中
localStorage.setItem(
"deviceTypeVal",
JSON.stringify(this.deviceTypeVal)
);
localStorage.setItem(
"deviceTitle",
JSON.stringify(this.deviceTitle)
);
}
this.getTypeAllList();
this.startIntervalIfNeededType();
this.stopInterval();
})
.catch((err) => {
console.log(err); //代码错误、请求失败捕获
});
},
handletypeChange(value) {
this.deviceTypeVal = value;
const typeArr = this.deviceTypeList.find((item) => item.id === value);
console.log(typeArr.mc);
this.deviceTitle = typeArr.mc;
localStorage.removeItem("deviceTypeVal");
localStorage.setItem("deviceTypeVal", JSON.stringify(value));
localStorage.setItem("deviceTitle", JSON.stringify(typeArr.mc));
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;
.rightbtn {
margin-left: auto !important;
}
.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>