Browse Source

add:对接告警总览

temp
zhaohy 4 months ago
parent
commit
7e50064857
  1. 8
      hx-ai-intelligent/src/api/alarmManagement/alarmOverview.ts
  2. BIN
      hx-ai-intelligent/src/view/alarmManagement/alarmOverview/img/decline.png
  3. BIN
      hx-ai-intelligent/src/view/alarmManagement/alarmOverview/img/energyAlarm.png
  4. BIN
      hx-ai-intelligent/src/view/alarmManagement/alarmOverview/img/equipmentAlarm.png
  5. BIN
      hx-ai-intelligent/src/view/alarmManagement/alarmOverview/img/gatewayAlarm.png
  6. BIN
      hx-ai-intelligent/src/view/alarmManagement/alarmOverview/img/icon.png
  7. BIN
      hx-ai-intelligent/src/view/alarmManagement/alarmOverview/img/priority.png
  8. BIN
      hx-ai-intelligent/src/view/alarmManagement/alarmOverview/img/rise.png
  9. 427
      hx-ai-intelligent/src/view/alarmManagement/alarmOverview/index.vue
  10. 2
      hx-ai-intelligent/src/view/alarmManagement/energyAlarm/index.vue
  11. 2
      hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/index.vue

8
hx-ai-intelligent/src/api/alarmManagement/alarmOverview.ts

@ -0,0 +1,8 @@
export enum alarmOverviewApi {
getAlarmEquipment = '/carbon-smart/api/AlarmOverview/alarmEquipment', //设备告警 数量
getAlarmEnergyConsumption = '/carbon-smart/api/AlarmOverview/alarmEnergyConsumption', //能碳告警 数量
getAlarmGateway = '/carbon-smart/api/AlarmOverview/alarmGateway', //网关告警 数量
getPriority = '/carbon-smart/api/AlarmOverview/priority', //优先级 数量
getProcessProgress = '/carbon-smart/api/AlarmOverview/processProgress', //进度 数量
getAlarmTrend = '/carbon-smart/api/AlarmOverview/alarmTrend', //30天告警 数量
}

BIN
hx-ai-intelligent/src/view/alarmManagement/alarmOverview/img/decline.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

BIN
hx-ai-intelligent/src/view/alarmManagement/alarmOverview/img/energyAlarm.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
hx-ai-intelligent/src/view/alarmManagement/alarmOverview/img/equipmentAlarm.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
hx-ai-intelligent/src/view/alarmManagement/alarmOverview/img/gatewayAlarm.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
hx-ai-intelligent/src/view/alarmManagement/alarmOverview/img/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
hx-ai-intelligent/src/view/alarmManagement/alarmOverview/img/priority.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
hx-ai-intelligent/src/view/alarmManagement/alarmOverview/img/rise.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

427
hx-ai-intelligent/src/view/alarmManagement/alarmOverview/index.vue

@ -1,60 +1,141 @@
<template>
<div class="box">
<div class="box-top">
<div v-for="index in 3" :key="index" class="box-top-item">
<div class="item-box">
<div v-for="(item, index) in infoObject" :key="index" class="box-top-item">
<div
class="item-box"
:style="{
'background-image': 'url(' + item.url + ')',
'background-position': 'center right',
'background-repeat': 'no-repeat',
'background-clip': 'content-box',
'background-origin': 'content-box',
}">
<div class="item-box-icon">
<img style="width: 34px; height: 34px" src="./img/icon.png" />
</div>
<div class="item-box-left">
<div class="item-box-left-title">设备告警 (今日处理 / 总数) </div>
<div class="iem-box-left-number">
10 / 13
{{ item.todayProcessing }} / {{ item.total }}
<span
style="
color: #04d919;
font-size: 14px;
margin-left: 5px;
font-weight: 700;
font-style: normal;
"
>+10%</span
v-if="item.liftRatio"
style="font-size: 12px; margin-left: 5px; font-weight: 700; font-style: normal"
:style="{
color: item.liftRatio > 0 ? 'rgba(243, 97, 99, 1)' : 'rgba(0, 170, 124, 1)',
}"
><span v-if="item.liftRatio > 0">+</span>{{ item.liftRatio }}%</span
>
<img
v-if="item.liftRatio"
style="width: 12px; margin-top: 6px"
:src="item.liftRatio > 0 ? rise : decline" />
<span
v-if="item.liftRatio === 0"
style="font-size: 12px; margin-left: 5px; font-weight: 700; font-style: normal">
-
</span>
</div>
<div class="item-box-left-title"
><span style="color: rgba(0, 0, 0, 1); font-size: 16px; font-weight: 700">{{
item.title
}}</span>
<span style="margin-left: 6px; font-size: 13px"> 今日处理 / 总数</span>
</div>
<div class="item-box-right">
<img width="48px" height="48px" src="../../../../src/icon/gaojingtonglan.svg" />
</div>
</div>
</div>
</div>
<div style="flex: 4; width: 100%; display: flex; gap: 5px">
<div class="box-center">
<div class="box-center-item">
<div class="box-center-item-top">
<img style="display: flex; position: absolute; top: 5px" :src="priority" />
<div class="box-center-item-top-title">
<span style="font-size: 18px">优先级</span>
</div>
<div
style="
width: auto;
height: 40px;
display: flex;
position: absolute;
left: 128px;
top: 13px;
color: rgba(102, 102, 102, 1);
font-size: 12px;
">
( 近30天 )
</div>
</div>
<div ref="echartPieOne" style="width: 100%; height: calc(100% - 40px)"></div>
</div>
<div class="box-center-item">
<div class="box-center-item-top">
<img style="display: flex; position: absolute; top: 5px" :src="priority" />
<div class="box-center-item-top-title">
<span style="font-size: 18px">处理进度</span>
</div>
<div
style="flex: 1; height: 100%; background-color: white; border-radius: 4px; padding: 12px">
<div ref="echartPieOne" style="width: 100%; height: 100%"></div>
style="
width: auto;
height: 40px;
display: flex;
position: absolute;
left: 148px;
top: 13px;
color: rgba(102, 102, 102, 1);
font-size: 12px;
">
( 近30天 )
</div>
</div>
<div style="flex: 1; height: 100%; background-color: white; border-radius: 4px">
<div ref="echartPieTow" style="width: 100%; height: 100%"></div>
<div ref="echartPieTow" style="width: 100%; height: calc(100% - 40px)"></div>
</div>
</div>
<!-- 告警矩形 echarts -->
<div style="flex: 4; width: 100%; background-color: white; border-radius: 4px; padding: 12px">
<div ref="graphChart" style="width: 100%; height: 100%"></div>
<div class="box-bottom">
<div class="box-bottom-top">
<img style="display: flex; position: absolute; top: 5px" :src="priority" />
<div class="box-bottom-top-title">
<span style="font-size: 18px">处理进度</span>
</div>
<div class="box-bottom-top-unit"> ( 近30天 ) </div>
</div>
<div ref="graphChart" style="width: 100%; height: calc(100% - 40px)"></div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue'; // Vue refonMounted watchEffect
import * as echarts from 'echarts';
import gatewayAlarm from './img/gatewayAlarm.png';
import equipmentAlarm from './img/equipmentAlarm.png';
import energyAlarm from './img/energyAlarm.png';
import rise from './img/rise.png';
import decline from './img/decline.png';
import priority from './img/priority.png';
import { alarmOverviewApi } from '/@/api/alarmManagement/alarmOverview.ts';
import { http } from '/nerv-lib/util';
defineOptions({
name: 'alarmOverviewIndex', // name
});
//
const orgId = ref('');
const result = JSON.parse(sessionStorage.getItem('ORGID')!);
orgId.value = result;
const infoObject = ref([
{ title: '设备告警', url: gatewayAlarm, liftRatio: 0, todayProcessing: 0, total: 0 },
{ title: '网关告警', url: equipmentAlarm, liftRatio: 0, todayProcessing: 0, total: 0 },
{ title: '能源告警', url: energyAlarm, liftRatio: 0, todayProcessing: 0, total: 0 },
]);
let chartInstance: echarts.ECharts | null = null;
let chartInstanceOne: echarts.ECharts | null = null;
let chartInstanceTow: echarts.ECharts | null = null;
const graphChart = ref(null);
const echartPieOne = ref(null);
const echartPieTow = ref(null);
const getGraphChart = () => {
const getGraphChart = async () => {
let dayData = [];
//
let energyAlarm = [];
@ -63,21 +144,28 @@
//
let equipmentAlarm = [];
let total = [];
// Extend data for 30 days
for (let i = 1; i < 30; i++) {
dayData.push(`3/${i}`);
energyAlarm.push(Math.floor(Math.random() * 11)); // Assuming the same value for simplicity
wgAlarm.push(Math.floor(Math.random() * 11)); // Assuming the same value for simplicity
equipmentAlarm.push(Math.floor(Math.random() * 11)); // Assuming the same value for simplicity
total.push(0); // Assuming the same value for simplicity
await http
.post(alarmOverviewApi.getAlarmTrend, {
orgId: orgId.value,
})
.then((res) => {
if (res.msg === 'success') {
res.data.forEach((item: any, index) => {
energyAlarm.push(item.alarmEnergyConsumptionNum);
wgAlarm.push(item.alarmGatewayNum);
equipmentAlarm.push(item.alarmEquipmentNum);
total.push(0);
dayData.push(item.createTime);
});
}
});
if (chartInstance) {
chartInstance.dispose();
}
chartInstance = echarts.init(graphChart.value);
const option = {
title: {
show: false,
text: '告警趋势/ 近30天',
textStyle: {
fontSize: 16,
@ -126,7 +214,7 @@
legend: [
{
top: 5,
left: 'center', //
left: 'right', //
textStyle: {
color: 'rgb(89, 89, 89)',
fontSize: '14',
@ -136,13 +224,6 @@
itemGap: 30, //
},
],
// toolbox: {
// show: true,
// feature: {
// restore: {},
// saveAsImage: {},
// },
// },
calculable: true,
xAxis: [
{
@ -194,12 +275,12 @@
name: '能源告警',
type: 'bar',
stack: '能源告警',
barMaxWidth: 40,
barMaxWidth: 20,
barGap: '10%',
itemStyle: {
normal: {
barBorderRadius: 0,
color: 'rgb(246, 189, 22)',
color: 'rgba(85, 125, 255, 1)',
},
},
data: energyAlarm,
@ -208,12 +289,12 @@
name: '网关告警',
type: 'bar',
stack: '能源告警',
barMaxWidth: 40,
barMaxWidth: 20,
barGap: '10%',
itemStyle: {
normal: {
barBorderRadius: 0,
color: 'rgb(91, 143, 249)',
color: 'rgba(255, 232, 139, 1)',
},
},
data: wgAlarm,
@ -222,12 +303,12 @@
name: '设备告警',
type: 'bar',
stack: '能源告警',
barMaxWidth: 40,
barMaxWidth: 20,
barGap: '10%',
itemStyle: {
normal: {
barBorderRadius: 0,
color: 'rgb(48, 191, 120)',
color: 'rgba(47, 213, 135, 1)',
},
},
data: equipmentAlarm,
@ -236,7 +317,7 @@
name: '总数',
type: 'bar',
stack: '能源告警',
barMaxWidth: 40,
barMaxWidth: 20,
barHight: 0,
itemStyle: {
normal: {
@ -264,38 +345,42 @@
chartInstance = echarts.init(graphChart.value);
chartInstance.setOption(option);
};
const getEchartPieOne = () => {
const getEchartPieOne = async () => {
if (chartInstanceOne) {
chartInstanceOne.dispose();
}
chartInstanceOne = echarts.init(echartPieOne.value);
//
var m2R2Data = [
{ value: 335, name: '紧急', itemStyle: { color: '#F56E53' } },
{ value: 310, name: '重要', itemStyle: { color: '#F7C122' } },
{ value: 234, name: '一般', itemStyle: { color: '#3BC27F' } },
{ value: 0, name: '紧急', itemStyle: { color: 'rgba(243, 97, 99, 1)' } },
{ value: 0, name: '重要', itemStyle: { color: 'rgba(255, 116, 44, 1)' } },
{ value: 0, name: '一般', itemStyle: { color: 'rgba(255, 224, 158, 1)' } },
];
var total = 0;
await http
.post(alarmOverviewApi.getPriority, {
orgId: orgId.value,
})
.then((res) => {
if (res.msg === 'success') {
m2R2Data[0].value = res.data.emergent;
m2R2Data[1].value = res.data.important;
m2R2Data[2].value = res.data.general;
total = res.data.prioritySum;
}
});
chartInstanceOne = echarts.init(echartPieOne.value);
const option = {
title: [
{
text: '优先级 / 近30天',
text: total,
subtext: '优先级',
textStyle: {
fontSize: 16,
fontWeight: 'normal',
color: '#aaaaaa',
},
left: '2%',
top: '2%',
},
{
text: '优先级',
subtext: 12312 + '个',
textStyle: {
fontSize: 24,
fontSize: 22,
color: 'black',
},
subtextStyle: {
fontSize: 24,
fontWeight: '700',
fontSize: 18,
color: 'black',
},
textAlign: 'center',
@ -305,8 +390,8 @@
],
tooltip: {
trigger: 'item',
formatter: function (parms) {
var str = parms.marker + ' :' + parms.data.value;
formatter: function (parms: any) {
var str = parms.marker + ' ' + parms.data.name + ' : ' + parms.data.value;
return str;
},
},
@ -316,9 +401,9 @@
top: 'center',
orient: 'vertical',
//
icon: 'circle',
itemWidth: 12,
itemHeight: 12,
// icon: 'circle',
itemWidth: 16,
itemHeight: 16,
itemGap: 16,
textStyle: {
fontSize: 14,
@ -345,12 +430,25 @@
return '[ ' + parms.data.name + ' ] : ' + parms.data.value;
},
},
// emphasis: {
// show: true, //
// position: 'outside', //
// textStyle: {
// fontSize: 14,
// },
// formatter: function (params) {
// return '[ ' + params.data.name + ' ] : ' + params.data.value;
// },
// },
},
labelLine: {
show: true, // 线
length: 10, // 线
length2: 0, // 线
// lineStyle
show: true, // 线
length: 15, // 线
length2: 10, // 线
lineStyle: {
width: 2, // 线
type: 'solid', // 线
},
},
data: m2R2Data,
},
@ -359,38 +457,44 @@
chartInstanceOne = echarts.init(echartPieOne.value);
chartInstanceOne.setOption(option);
};
const getEchartPieTow = () => {
const getEchartPieTow = async () => {
if (chartInstanceTow) {
chartInstanceTow.dispose();
}
chartInstanceTow = echarts.init(echartPieTow.value);
var m2R2Data = [
{ value: 335, name: '紧急', itemStyle: { color: '#F56E53' } },
{ value: 310, name: '重要', itemStyle: { color: '#F7C122' } },
{ value: 234, name: '一般', itemStyle: { color: '#3BC27F' } },
{ value: 0, name: '待处理', itemStyle: { color: '#f36163' } },
{ value: 310, name: '处理中', itemStyle: { color: '#2778ff' } },
{ value: 234, name: '已完成', itemStyle: { color: '#62daab' } },
{ value: 234, name: '超时', itemStyle: { color: '#ffbc46' } },
{ value: 234, name: '关闭', itemStyle: { color: '#5e87d2' } },
];
var total = 0;
await http
.post(alarmOverviewApi.getProcessProgress, {
orgId: orgId.value,
})
.then((res) => {
if (res.msg === 'success') {
m2R2Data[0].value = res.data.pendingProcessing;
m2R2Data[1].value = res.data.processing;
m2R2Data[2].value = res.data.completed;
m2R2Data[3].value = res.data.timeout;
m2R2Data[4].value = res.data.close;
total = res.data.processSum;
}
});
const option = {
title: [
{
text: '优先级 / 近30天',
textStyle: {
fontSize: 16,
fontWeight: 'normal',
color: '#aaaaaa',
},
left: '2%',
top: '2%',
},
{
text: '优先级',
subtext: 12312 + '个',
text: total,
subtext: '进度',
textStyle: {
fontSize: 24,
fontSize: 22,
color: 'black',
},
subtextStyle: {
fontSize: 24,
fontWeight: '700',
fontSize: 18,
color: 'black',
},
textAlign: 'center',
@ -400,8 +504,8 @@
],
tooltip: {
trigger: 'item',
formatter: function (parms) {
var str = parms.marker + ' :' + parms.data.value;
formatter: function (parms: any) {
var str = parms.marker + ' ' + parms.data.name + ' : ' + parms.data.value;
return str;
},
},
@ -410,10 +514,8 @@
right: 50,
top: 'center',
orient: 'vertical',
//
icon: 'circle',
itemWidth: 12,
itemHeight: 12,
itemWidth: 16,
itemHeight: 16,
itemGap: 16,
textStyle: {
fontSize: 14,
@ -444,7 +546,7 @@
labelLine: {
show: true, // 线
length: 10, // 线
length2: 0, // 线
length2: 10, // 线
// lineStyle
},
data: m2R2Data,
@ -454,7 +556,47 @@
chartInstanceTow = echarts.init(echartPieTow.value);
chartInstanceTow.setOption(option);
};
const getTotal = () => {
//
http
.post(alarmOverviewApi.getAlarmEquipment, {
orgId: orgId.value,
})
.then((res) => {
if (res.msg === 'success') {
infoObject.value[0].total = res.data.total;
infoObject.value[0].liftRatio = res.data.liftRatio;
infoObject.value[0].todayProcessing = res.data.todayProcessing;
}
});
//
http
.post(alarmOverviewApi.getAlarmGateway, {
orgId: orgId.value,
})
.then((res) => {
if (res.msg === 'success') {
infoObject.value[1].total = res.data.total;
infoObject.value[1].liftRatio = res.data.liftRatio;
infoObject.value[1].todayProcessing = res.data.todayProcessing;
}
});
//
http
.post(alarmOverviewApi.getAlarmEnergyConsumption, {
orgId: orgId.value,
})
.then((res) => {
if (res.msg === 'success') {
infoObject.value[2].total = res.data.total;
infoObject.value[2].liftRatio = res.data.liftRatio;
infoObject.value[2].todayProcessing = res.data.todayProcessing;
}
});
};
onMounted(() => {
//
getTotal();
//
getGraphChart();
//
@ -469,36 +611,41 @@
// border: 1px solid red;
display: flex;
flex-direction: column;
gap: 5px;
gap: 12px;
background-color: #f0f1f4;
box-sizing: border-box;
.box-top {
flex: 1;
flex: 1.5;
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
gap: 5px;
gap: 12px;
.box-top-item {
height: 100%;
flex: 1;
gap: 5px;
gap: 12px;
background-color: white;
border-radius: 4px;
padding: 20px;
.item-box {
width: 100%;
height: 100%;
display: flex;
.item-box-icon {
flex: 1.5;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.item-box-left {
flex: 9;
flex: 8.5;
height: 100%;
padding: 0px !important;
padding: 20px 4px;
.item-box-left-title {
color: rgba(0, 0, 0, 0.45);
font-weight: 400;
font-style: normal;
font-size: 14px;
color: #aaaaaa;
font-kerning: normal;
font-family: '微软雅黑', sans-serif;
@ -512,13 +659,71 @@
}
}
.item-box-right {
flex: 5;
height: 100%;
}
}
}
}
.box-center {
flex: 4;
width: 100%;
display: flex;
gap: 12px;
.box-center-item {
flex: 1;
height: 100%;
display: grid;
place-items: center;
background-color: white;
border-radius: 4px;
padding: 12px;
.box-center-item-top {
width: 100%;
height: 40px;
padding: 0px 12px;
display: flex;
position: relative;
.box-center-item-top-title {
width: auto;
height: 40px;
display: flex;
position: absolute;
left: 62px;
top: 5px;
}
}
}
}
.box-bottom {
flex: 3.5;
width: 100%;
background-color: white;
border-radius: 4px;
padding: 12px;
.box-bottom-top {
width: 100%;
height: 40px;
padding: 0px 12px;
display: flex;
position: relative;
.box-bottom-top-title {
width: auto;
height: 40px;
display: flex;
position: absolute;
left: 62px;
top: 5px;
}
.box-bottom-top-unit {
width: auto;
height: 40px;
display: flex;
position: absolute;
left: 148px;
top: 13px;
color: rgba(102, 102, 102, 1);
font-size: 12px;
}
}
}
}
</style>

2
hx-ai-intelligent/src/view/alarmManagement/energyAlarm/index.vue

@ -2,7 +2,7 @@
<ns-view-list-table v-bind="config" ref="mainRef">
<template #bodyCell="{ record, column }">
<template v-if="column.dataIndex === 'alarmTitle'">
<div style="color: #2778ff">{{ record.alarmTitle }}</div>
<div style="color: rgba(255, 118, 54, 1)">{{ record.alarmTitle }}</div>
{{ record.abnormalDescription }}
</template>
<template v-if="column.dataIndex === 'priority'">

2
hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/index.vue

@ -2,7 +2,7 @@
<ns-view-list-table v-bind="config" ref="mainRef">
<template #bodyCell="{ record, column }">
<template v-if="column.dataIndex === 'alarmTitle'">
<div style="color: #2778ff">{{ record.alarmTitle }}</div>
<div style="color: rgba(255, 118, 54, 1)">{{ record.alarmTitle }}</div>
{{ record.abnormalDescription }}
</template>
<template v-if="column.dataIndex === 'priority'">

Loading…
Cancel
Save