gangkou/ruoyi-ui/src/views/dataAnalysis/bound/index.vue

382 lines
11 KiB
Vue
Raw Normal View History

2024-09-03 22:09:21 +08:00
<template>
<div class="app-container">
<el-row :gutter="10">
<el-col :span="6">
<dept-tree @deptChange="handleDeptChange" :showQuickGroup="true" />
</el-col>
<el-col :span="6">
<el-date-picker
v-model="dateList"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
:picker-options="pickerOptions"
@change="dateChange"
>
</el-date-picker>
</el-col>
<el-col :span="6">
<device-select
v-model="queryDeviceSn"
:deptId="dept ? dept.deptId : ''"
placeholder="请选择设备"
@change="handleDeviceSelectChange"
/>
</el-col>
</el-row>
<div style="display: flex; height: 700px; margin-top: 10px;">
<div style="width: 50%; background: #e0e1e2; padding: 10px">
2024-09-03 22:09:21 +08:00
<div class="title">厂界在线监测设备报警情况分析</div>
<div style="width: 100%; height: 650px" ref="qdCityMap1"></div>
</div>
<div style="width: 50%; background: #e0e1e2; padding: 10px">
结合{{days}}天的数据分析报警最多的监测设备列表如下请在未来加强管控
<el-table v-loading="loading" :data="alarmCountDesc" max-height="650">
<el-table-column label="企业名称" align="center" prop="p" />
<el-table-column label="设备编号" align="center" prop="sn" />
<el-table-column label="放置区域" align="center" prop="address" />
<el-table-column label="报警次数" align="center" prop="count">
<template slot-scope="scope">
<el-tag type="danger" class="count-tag" @click="clickAlarmTag(scope.row)">{{ scope.row.count }}</el-tag>
</template>
2024-09-03 22:09:21 +08:00
</el-table-column>
<el-table-column
v-if="checkRole(['admin', 'notice'])"
label="操作"
align="center"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>下发通知</el-button
>
</template>
</el-table-column>
</el-table>
</div>
2024-09-03 22:09:21 +08:00
</div>
<el-dialog title="报警管理" :visible.sync="dialogAlarmVisible">
<alarm-monitor :queryParamsName="queryParamsName" :queryParamsDate="queryParamsDate"/>
</el-dialog>
<!--发送通知-->
<send-msg
:deviceInfo="deviceInfo"
v-if="isOpenMsg"
:isOpenMsg="isOpenMsg"
@closeMsg="closeMsg"
></send-msg>
</div>
</template>
<script>
import { queryAlarmChart } from "@/api/demostrate/monitor";
import { queryMonitorPrediction } from "@/api/demostrate/monitor";
import sendMsg from "@/views/demostrate/alarm/sendMsg.vue";
import DeviceSelect from '@/components/DeviceSelect/index.vue';
const echarts = require("echarts");
import { factoryBoundaryOnline } from "@/api/analysis"
import to from '@/utils/await-to.js';
import moment from 'moment';
import { debounce } from '@/utils';
import { checkRole } from "@/utils/permission";
import AlarmMonitor from '@/views/alarmMonitor/bound/index.vue';
export default {
name: "alarm",
components: { sendMsg, DeviceSelect, AlarmMonitor },
dicts: [],
data() {
return {
dept: null,
queryDebounce: null,
alarmCount: [],
alarmCountDesc: [],
days: 0,
loading: false,
pickerOptions: {
// disabledDate(time) {
// // 计算选择的时间跨度
// const diff = Math.abs(time.getTime() - new Date().getTime()) / (1000 * 60 * 60 * 24);
// // 如果时间跨度超过30天则禁用该日期
// return diff > 30;
// },
shortcuts: [
{
text: "最近30天",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setDate(start.getDate() - 29); // 30天前
picker.$emit("pick", [start, end]);
},
},
],
},
dateList: [], //日期
total: 0,
isOpenMsg: false,
deviceInfo: {},
queryDeviceSn: "",
// 查询参数
queryParams: {
deptId: null,
beginDate: null,
endDate: null,
deviceSn: null,
},
dialogAlarmVisible: false,
queryParamsName: null,
queryParamsDate: null,
};
},
mounted() {
this.queryDebounce = debounce(this.query, 100);
setTimeout(() => {
let dsiab_com = this.$refs.qdCityMap1;
dsiab_com.removeAttribute("_echarts_instance_");
this.getDefaultDateRange();
});
},
watch: {
dateList: {
handler: function () {
// 计算选择的时间天数
const diff = Math.abs(
new Date(this.dateList[1]).getTime() -
new Date(this.dateList[0]).getTime()
);
this.days = diff / (1000 * 60 * 60 * 24);
},
deep: true,
},
},
methods: {
checkRole,
clickAlarmTag(row) {
this.dialogAlarmVisible = true;
this.queryParamsName = row.name;
// 日期加上00:00:00
this.queryParamsDate = [
moment(this.dateList[0]).format("YYYY-MM-DD 00:00:00"),
moment(this.dateList[1]).format("YYYY-MM-DD 23:59:59"),
];
},
dateChange() {
this.queryDebounce();
2024-09-03 22:09:21 +08:00
},
handleDeptChange(dept) {
this.dept = dept;
this.queryDeviceSn = "";
this.queryDebounce();
2024-09-03 22:09:21 +08:00
},
async query() {
if (this.dept && this.dateList.length > 0) {
this.queryParams.deptId = this.dept.deptId;
this.queryParams.beginDate = this.dateList[0];
this.queryParams.endDate = this.dateList[1];
this.queryParams.deviceSn = this.queryDeviceSn || '';
const [err, res] = await to(factoryBoundaryOnline(this.queryParams));
if (err) {
console.error(err);
this.$message.error("查询失败");
return;
}
if (res.code !== 200) {
this.$message.error(res.msg);
return;
}
this.alarmCount = res.data.alarmCount;
this.alarmCountDesc = res.data.alarmCountDesc;
this.queryChart();
}
2024-09-03 22:09:21 +08:00
},
//发送通知
2024-09-03 22:09:21 +08:00
handleUpdate(row) {
this.deviceInfo = row;
this.isOpenMsg = true;
2024-09-03 22:09:21 +08:00
},
queryChart() {
const xData = [];
const yData1 = [];
const yData2 = [];
const yData3 = [];
this.alarmCount.forEach((item) => {
xData.push(item.day);
yData1.push(item.alarmCount);
yData3.push(((item.alarmCount / item.count) * 100).toFixed(2));
});
this.init(xData, yData1, yData2, yData3);
},
getDefaultDateRange() {
const endDate = new Date(); // 当前时间
const startDate = new Date();
startDate.setDate(startDate.getDate() - 7); // 当前时间之前的7天
// 格式化为YYYY-MM-DD
this.dateList = [
moment(startDate).format("YYYY-MM-DD"),
moment(endDate).format("YYYY-MM-DD"),
];
this.queryChart();
},
init(xData, yData1, yData2, yData3) {
const yData2GradientColor = [
{
offset: 0,
color: "#0058e1",
},
{
offset: 1,
color: "#3BA1E3",
},
];
const yData3GradientColor = [
{
offset: 0,
color: "#32E8D4",
},
{
offset: 1,
color: "#4BA1E3",
},
];
const option = {
tooltip: {
trigger: "axis", // x轴触发
formatter: function (params) {
let list = [];
let listItem = "";
params.forEach((item) => {
// 柱状图加单位 局,折线图加单位 %
let unitValue =
item.seriesType == "bar" ? item.value + "个" : item.value + "%";
list.push(item.marker + "" + item.seriesName + ": " + unitValue);
});
listItem = list.join("<br/>");
return "<div>" + listItem + "</div>";
2024-09-03 22:09:21 +08:00
},
},
legend: {
orient: "horizontal", // 水平排列
x: "center", //可设定图例在左、右、居中
y: "top", //可设定图例在上、下、居中
padding: 6, //位置也可为数组 [距上方距离,距右方距离,距下方距离,距左方距离]
},
xAxis: {
type: "category",
data: xData,
},
yAxis: [
2024-09-03 22:09:21 +08:00
{
type: "value",
name: "报警数",
yAxisIndex: 0,
axisLabel: {
//y轴每个刻度都加单位
formatter: "{value}个",
},
2024-09-03 22:09:21 +08:00
},
{
type: "value",
name: "报警率(%)",
min: 0, // 最小为0
max: 100, // 最大为100
interval: 25, // 间隔25
axisLabel: {
//y轴每个刻度都加单位
formatter: "{value}%",
2024-09-03 22:09:21 +08:00
},
},
],
series: [
{
type: "bar",
stack: "x",
name: "报警数",
data: yData1,
label: {
show: true,
color: "#eee",
2024-09-03 22:09:21 +08:00
},
barGap: "-100%", // 平移自身一个身位,使之与前一个柱状图重叠
// stack:'重叠',
itemStyle: {
// borderRadius: [20, 20, 6, 6],
color: "#15C1AF",
2024-09-03 22:09:21 +08:00
},
},
// {
// type: 'bar',
// stack: 'x',
// name: "二级报警数",
// data: yData2,
// label: {
// show: true,
// color: '#eee'
// },
// barGap: "-100%", // 平移自身一个身位,使之与前一个柱状图重叠
// // stack:'重叠',
// itemStyle: {
// // borderRadius: [20, 20, 6, 6],
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, yData3GradientColor),
// }
// },
{
type: "line",
name: "报警率(%)",
data: yData3,
yAxisIndex: 1, // 1表示以右侧Y轴为基准 0表示以左侧Y轴为基准
symbolSize: 10, // 圆点大小
2024-09-03 22:09:21 +08:00
// itemStyle: {
// color: '#74DER1', // 折线图小圆点颜色
// },
lineStyle: {
color: "#DE390F",
},
label: {
show: true,
color: "#ddd",
formatter: "{c}%", // {c}数据值
},
},
],
};
this.myChart = echarts.init(this.$refs.qdCityMap1);
this.myChart.setOption(option);
},
handleDeviceSelectChange() {
this.queryDebounce();
},
},
};
</script>
<style>
.title {
padding-left: 10px;
color: #212121;
font-size: 20px;
margin-bottom: 10px;
margin-top: 10px;
background-position-y: 7px;
}
.count-tag {
cursor: pointer;
}
</style>