<template>
|
<div class="main_contain">
|
<div class="ec_header">
|
<div class="ec_header_left">
|
<div class="ec_header_left_view">{{ pointName }}</div>
|
<div class="ec_header_left_view">
|
<span class="ec_header_val">{{
|
state.currentRecordParas.RecordValue
|
}}</span>
|
</div>
|
</div>
|
<div class="ec_header_right">
|
<div class="ec_header_right_view">
|
<div>状态:{{ state.currentRecordParas.RecordStatusName }}</div>
|
<div>警报:{{ state.currentRecordParas.AlarmNumber }}</div>
|
</div>
|
<div class="ec_header_right_view">
|
<div>{{ state.currentRecordParas.RecordTime }}</div>
|
<div>{{ lastRefreshTime }}s后刷新</div>
|
</div>
|
</div>
|
</div>
|
<div class="container">
|
<div id="chartMain" style="width: 100%; height: 418px"></div>
|
</div>
|
<!--先隐藏详情,目前接口返回值
|
<div class="ykt-detail-wraper">
|
<van-collapse v-model="state.activeNames">
|
<van-collapse-item name="1">
|
<template #title>
|
<div>详情</div>
|
</template>
|
<van-cell :value="state.MonitorPointID">
|
<template #title>
|
<div class="custom-title">测点编号</div>
|
</template>
|
</van-cell>
|
<van-cell value="瞬时压力">
|
<template #title>
|
<div class="custom-title">监控名称</div>
|
</template>
|
</van-cell>
|
<van-cell value="MPa">
|
<template #title>
|
<div class="custom-title">单位</div>
|
</template>
|
</van-cell>
|
<van-cell value="">
|
<template #title>
|
<div class="custom-title">上次报警</div>
|
</template>
|
</van-cell>
|
<van-cell>
|
<template #title>
|
<div class="custom-title">是否显示报警点</div>
|
</template>
|
<template #value>
|
<van-switch v-model="state.checked" size="24px" />
|
</template>
|
</van-cell>
|
<van-cell value="阈值">
|
<template #title>
|
<div class="custom-title">警报类型</div>
|
</template>
|
</van-cell>
|
</van-collapse-item>
|
</van-collapse>
|
</div> -->
|
<div class="ykt-detail-wrapers">
|
<div class="hykt_header" style="margin-bottom: 5px">
|
<div class="hykt_span">时间</div>
|
<div
|
class="hykt_span"
|
@click="changeMonitorStatus"
|
:style="state.isMonitorChange ? 'color:red;' : ''"
|
>
|
状态
|
</div>
|
<div class="hykt_span">监控值</div>
|
</div>
|
<div
|
class="hykt_li"
|
v-for="(monitor, index) in state.c_monitorList"
|
:key="index"
|
>
|
<div class="hykt_span">{{ monitor.RecordTime }}</div>
|
<div class="hykt_span">
|
{{
|
monitor.RecordStatusText.length > 0 &&
|
monitor.RecordStatusText[0] == "BJ"
|
? "中断"
|
: "正常"
|
}}
|
</div>
|
|
<div class="hykt_span">{{ monitor.RecordValue }}</div>
|
</div>
|
</div>
|
<!-- 刷新 -->
|
<div style="bottom: 140px" class="icon_view">
|
<van-icon name="revoke" size="20px" @click="onTapRefresh()" />
|
</div>
|
<!-- 间隔 -->
|
<div style="bottom: 200px" class="icon_view" @click="onTapInterval">
|
<van-icon
|
:name="state.isOnTapInterval ? 'exchange' : 'shrink'"
|
size="20px"
|
/>
|
</div>
|
</div>
|
</template>
|
|
<script setup>
|
import { reactive, onMounted, ref, shallowRef, onBeforeUnmount } from "vue";
|
import moment from "moment";
|
import * as echarts from "echarts"; //引入echarts
|
import axios from "axios";
|
import { useRouter } from "vue-router";
|
const router = useRouter();
|
const pointName = ref("");
|
const myChart = shallowRef(null);
|
const lastRefreshTime = ref(120);
|
let times = ref(null);
|
const now = new Date();
|
const minDate = new Date(
|
now.getFullYear(),
|
now.getMonth(),
|
now.getDate(),
|
0,
|
0,
|
0
|
);
|
const maxDate = new Date(
|
now.getFullYear(),
|
now.getMonth(),
|
now.getDate(),
|
23,
|
59,
|
59
|
);
|
let state = reactive({
|
currentRecordParas: {
|
RecordValue: "",
|
RecordStatusName: "",
|
AlarmNumber: 0,
|
RecordTime: "",
|
},
|
chartData: [],
|
x_yData: [],
|
activeNames: [""],
|
checked: false, //是否显示报警点
|
loading: false, //加载状态
|
isMonitorChange: false, //监测界面 --- 是否启用状态筛选
|
isOnTapInterval: false,
|
monitorList: [],
|
c_monitorList: [],
|
// PointID: "1620681990539972608",
|
PointID: "",
|
// token:
|
// "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySUQiOjEsIkxvZ2luTmFtZSI6Inl3YWRtaW4iLCJMb2dpblB3ZCI6ImFkbWluIiwiQ29ycElEIjoxLCJJc0FkbWluIjp0cnVlLCJpYXQiOjE2ODkyMTg3NzEsIm5iZiI6MTY4OTIxODc3MSwiZXhwIjoxNjg5MzA1MTcxLCJpc3MiOiJpc3RhdGlvbiIsImF1ZCI6ImlzdGF0aW9uIn0.cUxpJbn8krlTpaHkmd_nTgzc6YQzPxBn6pCJ0mFHAS8",
|
token: "",
|
});
|
onMounted(() => {
|
// console.log(router.currentRoute.value.query, 162);
|
state.PointID = router.currentRoute.value.query.PointID;
|
state.token = router.currentRoute.value.query.Token;
|
state.currentRecordParas.RecordTime = moment().format("YYYY-MM-DD");
|
initialRealTimeRecord();
|
getRecordDetail();
|
});
|
const countdown = () => {
|
if (lastRefreshTime.value === 0) {
|
onTapRefresh();
|
lastRefreshTime.value = 120;
|
return;
|
} else {
|
lastRefreshTime.value--;
|
}
|
};
|
onBeforeUnmount(() => {
|
console.log("mounted!", 307);
|
clearInterval(times.value);
|
times.value = null;
|
});
|
|
//刷新
|
const onTapRefresh = () => {
|
axios({
|
url: "http://47.101.141.88:9019/Run/MonitorRealRecord/Mobile/GetLastRecordByMonitorPointID@V1.0",
|
method: "GET",
|
headers: {
|
Authorization: `Bearer ${state.token}`,
|
},
|
params: {
|
CorpID: 14,
|
MonitorPointID: state.PointID,
|
},
|
})
|
.then((res) => {
|
if (res.data.Code != 0) {
|
return;
|
}
|
if (res.data.Data == null || res.data.Data == "") {
|
return;
|
}
|
var refreshData = res.data.Data;
|
var last_record = state.chartData[state.chartData.length - 1]; //获取最后一条数据
|
refreshData.forEach((item) => {
|
let getStatus = DataStatusTextEmun(item.DataStatus);
|
state.currentRecordParas.RecordStatusName = getStatus;
|
state.currentRecordParas.RecordValue = item.DataValue;
|
if (
|
item.DataValue != last_record.DataValue ||
|
item.DataTime != last_record.DataTime
|
) {
|
state.chartData.push(item);
|
}
|
});
|
|
setTimeout(() => {
|
drawBar();
|
}, 200);
|
})
|
.catch((error) => {
|
console.log(error);
|
});
|
};
|
//监控图标间隔
|
const onTapInterval = () => {
|
if (!state.isOnTapInterval) {
|
myChart.value.setOption({
|
yAxis: {
|
boundaryGap: ["0%", "0%"],
|
scale: true,
|
},
|
});
|
state.isOnTapInterval = true;
|
return;
|
}
|
if (state.isOnTapInterval) {
|
myChart.value.setOption({
|
yAxis: {
|
boundaryGap: ["15%", "15%"],
|
scale: false,
|
},
|
});
|
state.isOnTapInterval = false;
|
return;
|
}
|
};
|
//初始化获取数据
|
const initialRealTimeRecord = () => {
|
axios({
|
url: "http://47.101.141.88:9019/Run/MonitorRealRecord/Mobile/GetByMonitorPointIDOfDay@V1.0",
|
method: "GET",
|
headers: {
|
Authorization: `Bearer ${state.token}`,
|
},
|
params: {
|
CorpID: 14,
|
MonitorPointID: state.PointID,
|
Day: state.currentRecordParas.RecordTime,
|
},
|
})
|
.then((res) => {
|
if (res.data.Code != 0) {
|
return;
|
}
|
if (res.data.Data == null || res.data.Data == "") {
|
return;
|
}
|
var data = res.data.Data || [];
|
state.chartData = data;
|
var last_record = state.chartData[state.chartData.length - 1]; //获取最后一条数据
|
state.currentRecordParas.RecordStatusName = DataStatusTextEmun(
|
last_record.DataStatus
|
);
|
state.currentRecordParas.RecordValue = last_record.DataValue;
|
let m_MonitorList = data.map((item) => {
|
let totalState = DataStatusTextEmun(item.DataStatus);
|
return {
|
RecordTime: subTime(item.DataTime, 11, 16),
|
RecordStatusText: totalState,
|
RecordValue: item.DataValue,
|
};
|
});
|
let monitor_List = data.map((item) => {
|
let normalState = DataStatusTextEmun(item.DataStatus);
|
if (normalState == "正常") {
|
return {
|
RecordTime: subTime(item.DataTime, 11, 16),
|
RecordStatusText: normalState,
|
RecordValue: item.DataValue,
|
};
|
}
|
});
|
state.monitorList = m_MonitorList; //源数据
|
state.c_monitorList = monitor_List.reverse(); //切换数据
|
|
setTimeout(() => {
|
drawBar();
|
}, 200);
|
})
|
.catch((error) => {
|
console.log(error);
|
});
|
};
|
// 初始化echarts折线图
|
const drawBar = () => {
|
//先获取Dom上的实例
|
let chartDom = echarts.getInstanceByDom(document.getElementById("chartMain"));
|
//然后判断实例是否存在,如果不存在,就创建新实例
|
if (chartDom == null) {
|
chartDom = echarts.init(document.getElementById("chartMain"));
|
myChart.value = chartDom;
|
}
|
let x_yData = [];
|
state.chartData.forEach((item) => {
|
x_yData.push({ value: [item.DataTime, item.DataValue] });
|
});
|
state.x_yData = x_yData;
|
let series_arr = [];
|
series_arr.push({
|
type: "line",
|
showSymbol: false,
|
emphasis: { scale: false },
|
data: state.x_yData,
|
itemStyle: {
|
color: "#4169E1",
|
},
|
});
|
let option = {
|
tooltip: {
|
trigger: "axis",
|
},
|
legend: {
|
show: false,
|
fontSize: 12,
|
color: "#7e8390",
|
},
|
grid: {
|
left: "5%",
|
right: "5%",
|
bottom: "10%",
|
top: "12%",
|
containLabel: true,
|
},
|
xAxis: {
|
type: "time",
|
boundaryGap: false,
|
min: minDate,
|
max: maxDate,
|
axisLabel: {
|
showMaxLabel: true,
|
formatter: function (value) {
|
// 如果时间是 23:59:59 , 格式化为 24:00
|
if (
|
value ===
|
new Date(
|
moment().endOf("day").format("YYYY-MM-DD HH:mm:ss")
|
).getTime()
|
) {
|
return moment(value).format("24:00");
|
} else {
|
// 其他的时间返回格式化 00:00
|
return moment(value).format("HH:mm");
|
}
|
},
|
},
|
axisLine: { onZero: true, show: true },
|
minorTick: {
|
show: false,
|
splitNumber: 2,
|
},
|
splitLine: {
|
show: true, //是否显示分隔线
|
interval: "auto", //坐标轴分隔线的显示间隔
|
},
|
},
|
yAxis: {
|
boundaryGap: ["20%", "20%"],
|
|
type: "value",
|
axisLabel: {
|
formatter: "{value}",
|
},
|
// 整条y轴
|
axisLine: {
|
show: true,
|
},
|
},
|
dataZoom: [
|
{
|
type: "slider", //图表下方的伸缩条
|
show: true, //是否显示
|
realtime: true, //
|
start: 0, //伸缩条开始位置(1-100),可以随时更改
|
end: 100, //伸缩条结束位置(1-100),可以随时更改
|
left: 10,
|
right: 15,
|
bottom: 5, //底部的距离
|
fillerColor: "rgba(22,181,203,0.4)", //选中范围的填充颜色。
|
borderColor: "#ddd", //边框颜色。
|
backgroundColor: "rgba(167,183,204,0.4)", //组件的背景颜色
|
throttle: 100, //设置触发视图刷新的频率。单位为毫秒(ms)。
|
handleIcon:
|
"path://M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z",
|
handleSize: "80%", // 控制手柄的尺寸,可以是像素大小,也可以是相对于 dataZoom 组件宽度的百分比,默认跟 dataZoom 宽度相同。
|
handleStyle: {
|
color: "#16b5cb",
|
shadowBlur: 3, // shadowBlur图片阴影模糊值,shadowColor阴影的颜色
|
shadowColor: "#77CCD8",
|
shadowOffsetX: 1,
|
shadowOffsetY: 1,
|
opacity: 0.6,
|
},
|
},
|
],
|
series: series_arr,
|
};
|
myChart.value.clear();
|
myChart.value.setOption(option, true);
|
window.addEventListener("resize", selfAdaption);
|
times.value = setInterval(countdown, 1000);
|
};
|
// 自适应
|
const selfAdaption = () => {
|
if (!myChart.value) return;
|
myChart.value.resize();
|
setTimeout(() => {
|
drawBar();
|
}, 100);
|
};
|
//获取详情
|
const getRecordDetail = () => {
|
axios({
|
url: "http://47.101.141.88:9019/Monitor/MonitorPoint/GetByID@V1.0",
|
method: "GET",
|
headers: {
|
Authorization: `Bearer ${state.token}`,
|
},
|
params: {
|
CorpID: 14,
|
ID: state.PointID,
|
},
|
})
|
.then((res) => {
|
let getDetailData = res.data.Data || [];
|
if (res.data.Code != 0) {
|
return;
|
}
|
if (getDetailData == null || getDetailData == "") {
|
return;
|
}
|
pointName.value = getDetailData.Name;
|
})
|
.catch((error) => {
|
console.log(error);
|
});
|
};
|
//切换状态(正常/中断)
|
const changeMonitorStatus = () => {
|
if (!state.isMonitorChange) {
|
let arr = [];
|
state.monitorList.forEach((item) => {
|
if (item.RecordStatusText != "正常") {
|
arr.push({
|
RecordTime: item.RecordTime,
|
RecordStatusText: item.RecordStatusText,
|
RecordValue: item.RecordValue,
|
});
|
}
|
});
|
state.isMonitorChange = true;
|
state.c_monitorList = arr.reverse();
|
return;
|
} else {
|
let arr = [];
|
state.monitorList.forEach((item) => {
|
if (item.RecordStatusText == "正常") {
|
arr.push({
|
RecordTime: item.RecordTime,
|
RecordStatusText: item.RecordStatusText,
|
RecordValue: item.RecordValue,
|
});
|
}
|
});
|
state.isMonitorChange = false;
|
state.c_monitorList = arr.reverse();
|
return;
|
}
|
};
|
const DataStatusTextEmun = (value) => {
|
if (value.length == 0) return "正常";
|
let text = "";
|
if (value[0] == "GLSB") {
|
text = "过滤失败";
|
}
|
if (value[0] == "SZGSCW") {
|
text = "数据格式错误";
|
}
|
if (value[0] == "ZHSB") {
|
text = "转换失败";
|
}
|
if (value[0] == "BJ") {
|
text = "报警";
|
}
|
return text;
|
};
|
//切割数字
|
const subTime = (val, start, end) => {
|
var getVal = val.substring(start, end);
|
return getVal;
|
};
|
</script>
|
<style scoped lang="scss">
|
.main_contain {
|
background-color: #efeff4;
|
// overflow-y: unset;
|
.ec_header {
|
width: 100%;
|
font-size: 10px;
|
color: #fff;
|
display: flex;
|
|
.ec_header_left {
|
width: 55%;
|
height: 82px;
|
background: linear-gradient(to left, #97d8e0, #16b5cb);
|
border-radius: 5px;
|
.ec_header_left_view {
|
height: 40px;
|
font-size: 20px;
|
font-weight: 600;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
.ec_header_name {
|
font-size: 14px;
|
}
|
}
|
}
|
.ec_header_right {
|
width: 45%;
|
|
font-size: 10px;
|
.ec_header_right_view {
|
height: 40px;
|
display: flex;
|
justify-content: space-around;
|
align-items: center;
|
background: linear-gradient(45deg, #97d8e0, #16b5cb);
|
border-radius: 3px;
|
margin: 1px 1px;
|
}
|
}
|
}
|
.container {
|
/* position: relative; */
|
width: 100%;
|
height: 100%;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: space-between;
|
box-sizing: border-box;
|
background-color: #fff;
|
border-radius: 3px;
|
}
|
.ykt-detail-wraper {
|
width: 100%;
|
display: flex;
|
flex-direction: column;
|
margin: 10px auto;
|
background: #fff;
|
border-radius: 3px;
|
}
|
.ykt-detail-wrapers {
|
padding: 8px 0px 0px 0px;
|
// background: #fff;
|
width: 100%;
|
height: auto;
|
// height: calc(100vh - 60px);
|
// overflow-y: auto;
|
font-size: 12px;
|
justify-content: center;
|
}
|
.hykt_header {
|
width: 100%;
|
min-height: 25px;
|
background-color: #16b5cb;
|
color: #fff;
|
font-weight: 600;
|
border-radius: 50px;
|
display: flex;
|
align-items: center;
|
flex-wrap: wrap;
|
justify-content: space-between;
|
.hykt_span {
|
font-size: 12px;
|
height: 100%;
|
min-width: 100px;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
}
|
}
|
|
.hykt_li {
|
width: 100%;
|
min-height: 25px;
|
background-color: #fff;
|
color: #000;
|
font-weight: 500;
|
border-radius: 50px;
|
display: flex;
|
align-items: center;
|
flex-wrap: wrap;
|
justify-content: space-between;
|
margin-bottom: 5px;
|
.hykt_span {
|
font-size: 12px;
|
height: 100%;
|
min-width: 100px;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
}
|
}
|
.custom-title {
|
text-align: left;
|
}
|
.icon_view {
|
font-size: 30px;
|
color: #fff;
|
width: 40px;
|
height: 40px;
|
position: fixed;
|
right: 10px;
|
z-index: 200;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
background-color: #16b5cb;
|
border-radius: 5px;
|
box-shadow: 0 2px 6px 0 rgba(114, 124, 245, 0.5);
|
}
|
}
|
</style>
|