2024-09-03 22:09:21 +08:00
|
|
|
|
<template>
|
2024-10-11 21:16:39 +08:00
|
|
|
|
<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>
|
2024-12-15 17:21:58 +08:00
|
|
|
|
<el-col :span="6">
|
|
|
|
|
<device-select
|
|
|
|
|
v-model="queryDeviceSn"
|
|
|
|
|
:deptId="dept ? dept.deptId : ''"
|
|
|
|
|
placeholder="请选择设备"
|
|
|
|
|
@change="handleDeviceSelectChange"
|
|
|
|
|
/>
|
|
|
|
|
</el-col>
|
2024-10-11 21:16:39 +08:00
|
|
|
|
</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>
|
2024-10-11 21:16:39 +08:00
|
|
|
|
<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">
|
|
|
|
|
<span :style="{ color: 'red' }">{{ scope.row.count }}</span>
|
|
|
|
|
</template>
|
2024-09-03 22:09:21 +08:00
|
|
|
|
</el-table-column>
|
2024-10-11 21:16:39 +08:00
|
|
|
|
<el-table-column
|
2024-12-15 17:21:58 +08:00
|
|
|
|
v-if="checkRole(['admin', 'notice'])"
|
2024-10-11 21:16:39 +08:00
|
|
|
|
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>
|
|
|
|
|
|
2024-10-11 21:16:39 +08:00
|
|
|
|
<!--发送通知-->
|
|
|
|
|
<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";
|
2024-12-15 17:21:58 +08:00
|
|
|
|
import DeviceSelect from '@/components/DeviceSelect/index.vue';
|
2024-10-11 21:16:39 +08:00
|
|
|
|
const echarts = require("echarts");
|
|
|
|
|
import { factoryBoundaryOnline } from "@/api/analysis"
|
|
|
|
|
import to from '@/utils/await-to.js';
|
|
|
|
|
import moment from 'moment';
|
|
|
|
|
import { debounce } from '@/utils';
|
2024-12-15 17:21:58 +08:00
|
|
|
|
import { checkRole } from "@/utils/permission";
|
2024-10-11 21:16:39 +08:00
|
|
|
|
export default {
|
|
|
|
|
name: "alarm",
|
2024-12-15 17:21:58 +08:00
|
|
|
|
components: { sendMsg, DeviceSelect },
|
2024-10-11 21:16:39 +08:00
|
|
|
|
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: {},
|
2024-12-15 17:21:58 +08:00
|
|
|
|
queryDeviceSn: "",
|
2024-10-11 21:16:39 +08:00
|
|
|
|
// 查询参数
|
|
|
|
|
queryParams: {
|
|
|
|
|
deptId: null,
|
|
|
|
|
beginDate: null,
|
|
|
|
|
endDate: null,
|
2024-12-15 17:21:58 +08:00
|
|
|
|
deviceSn: null,
|
2024-10-11 21:16:39 +08:00
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
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: {
|
2024-12-15 17:21:58 +08:00
|
|
|
|
checkRole,
|
2024-10-11 21:16:39 +08:00
|
|
|
|
dateChange() {
|
|
|
|
|
this.queryDebounce();
|
2024-09-03 22:09:21 +08:00
|
|
|
|
},
|
2024-10-11 21:16:39 +08:00
|
|
|
|
handleDeptChange(dept) {
|
|
|
|
|
this.dept = dept;
|
2024-12-15 17:21:58 +08:00
|
|
|
|
this.queryDeviceSn = "";
|
2024-10-11 21:16:39 +08:00
|
|
|
|
this.queryDebounce();
|
2024-09-03 22:09:21 +08:00
|
|
|
|
},
|
2024-10-11 21:16:39 +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];
|
2024-12-15 17:21:58 +08:00
|
|
|
|
this.queryParams.deviceSn = this.queryDeviceSn || '';
|
2024-10-11 21:16:39 +08:00
|
|
|
|
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-10-11 21:16:39 +08:00
|
|
|
|
//发送通知
|
2024-09-03 22:09:21 +08:00
|
|
|
|
handleUpdate(row) {
|
2024-10-11 21:16:39 +08:00
|
|
|
|
this.deviceInfo = row;
|
|
|
|
|
this.isOpenMsg = true;
|
2024-09-03 22:09:21 +08:00
|
|
|
|
},
|
2024-10-11 21:16:39 +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
|
|
|
|
},
|
2024-10-11 21:16:39 +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
|
|
|
|
{
|
2024-10-11 21:16:39 +08:00
|
|
|
|
type: "value",
|
|
|
|
|
name: "报警数",
|
|
|
|
|
yAxisIndex: 0,
|
|
|
|
|
axisLabel: {
|
|
|
|
|
//y轴每个刻度都加单位
|
|
|
|
|
formatter: "{value}个",
|
|
|
|
|
},
|
2024-09-03 22:09:21 +08:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-10-11 21:16:39 +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
|
|
|
|
},
|
2024-10-11 21:16:39 +08:00
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
type: "bar",
|
|
|
|
|
stack: "x",
|
|
|
|
|
name: "报警数",
|
|
|
|
|
data: yData1,
|
|
|
|
|
label: {
|
|
|
|
|
show: true,
|
|
|
|
|
color: "#eee",
|
2024-09-03 22:09:21 +08:00
|
|
|
|
},
|
2024-10-11 21:16:39 +08:00
|
|
|
|
barGap: "-100%", // 平移自身一个身位,使之与前一个柱状图重叠
|
|
|
|
|
// stack:'重叠',
|
|
|
|
|
itemStyle: {
|
|
|
|
|
// borderRadius: [20, 20, 6, 6],
|
|
|
|
|
color: "#15C1AF",
|
2024-09-03 22:09:21 +08:00
|
|
|
|
},
|
2024-10-11 21:16:39 +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', // 折线图小圆点颜色
|
|
|
|
|
// },
|
2024-10-11 21:16:39 +08:00
|
|
|
|
lineStyle: {
|
|
|
|
|
color: "#DE390F",
|
|
|
|
|
},
|
|
|
|
|
label: {
|
|
|
|
|
show: true,
|
|
|
|
|
color: "#ddd",
|
|
|
|
|
formatter: "{c}%", // {c}数据值
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.myChart = echarts.init(this.$refs.qdCityMap1);
|
|
|
|
|
this.myChart.setOption(option);
|
|
|
|
|
},
|
2024-12-15 17:21:58 +08:00
|
|
|
|
handleDeviceSelectChange() {
|
|
|
|
|
this.queryDebounce();
|
|
|
|
|
},
|
2024-10-11 21:16:39 +08:00
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
<style>
|
|
|
|
|
.title {
|
|
|
|
|
padding-left: 10px;
|
|
|
|
|
color: #212121;
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
|
|
|
|
|
background-position-y: 7px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|