添加告警板块

This commit is contained in:
lai
2024-01-30 18:05:53 +08:00
parent 335afc5f76
commit ef30d2b742
8 changed files with 260 additions and 319 deletions

View File

@@ -288,14 +288,13 @@ export async function exportAll(query: Record<string, any>) {
return result; return result;
} }
/** /**
* 展示页全部告警 * 展示页全部告警
* @param query 查询参数 * @param query 查询参数
* @returns bolb * @returns bolb
*/ */
export async function mainGet() { export async function origGet() {
let totalSQL = `select count(*) as value,orig_severity as name from alarm group by orig_severity`; let totalSQL = `select count(*) as value,orig_severity as name from alarm group by orig_severity`;
// 发起请求 // 发起请求
const result = await request({ const result = await request({
@@ -305,6 +304,43 @@ export async function mainGet() {
SQL: totalSQL, SQL: totalSQL,
}, },
}); });
////
// 解析数据
if (result.code === RESULT_CODE_SUCCESS) {
const itemData = result.data.data;
if (Array.isArray(itemData)) {
const v = itemData[0]['alarm'];
if (Array.isArray(v)) {
result.data = v;
}
if (v === null) {
result.data = [];
}
}
}
return result;
}
/**
* 查询前三的网元
* @param filterFlag 查询参数
* @returns object
*/
export async function top3Sel(filterFlag?: string) {
let filter = ` WHERE orig_severity='${filterFlag}'`;
if (!filterFlag) filter = '';
let top3SQL = `select count(*) as value,ne_type as name from alarm ${filter} group by ne_type ORDER BY value desc limit 0,3 `;
// 发起请求
const result = await request({
url: `/api/rest/databaseManagement/v1/select/omc_db/alarm`,
method: 'get',
params: {
SQL: top3SQL,
},
});
// 解析数据 // 解析数据
if (result.code === RESULT_CODE_SUCCESS) { if (result.code === RESULT_CODE_SUCCESS) {
@@ -314,6 +350,9 @@ export async function mainGet() {
if (Array.isArray(v)) { if (Array.isArray(v)) {
result.data = v; result.data = v;
} }
if (v === null) {
result.data = [];
}
} }
} }
return result; return result;

View File

@@ -509,6 +509,10 @@ export default {
alarmType: { alarmType: {
title: "Alarm Statistics", title: "Alarm Statistics",
}, },
alarmTypeBar:{
alarmSum:'Alarm Statistics',
topTitle:"Alarm-TOP 3 ",
},
resources: { resources: {
title: "Resource Summary", title: "Resource Summary",
sysMem: "Memory", sysMem: "Memory",

View File

@@ -509,6 +509,10 @@ export default {
alarmType: { alarmType: {
title: "告警统计", title: "告警统计",
}, },
alarmTypeBar:{
alarmSum:'告警统计',
topTitle:"告警总数TOP3",
},
resources: { resources: {
title: "资源情况", title: "资源情况",
sysMem: "系统内存", sysMem: "系统内存",

View File

@@ -3,7 +3,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { markRaw, onMounted, ref } from 'vue'; import { markRaw, onMounted, ref } from 'vue';
import { mainGet } from '@/api/faultManage/actAlarm'; import { origGet } from '@/api/faultManage/actAlarm';
import * as echarts from 'echarts/core'; import * as echarts from 'echarts/core';
import { import {
TitleComponent, TitleComponent,

View File

@@ -3,13 +3,15 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { markRaw, onMounted, ref } from 'vue'; import { markRaw, onMounted, ref } from 'vue';
import { mainGet } from '@/api/faultManage/actAlarm'; import { origGet, top3Sel } from '@/api/faultManage/actAlarm';
import * as echarts from 'echarts/core'; import * as echarts from 'echarts/core';
import { import {
DatasetComponent,
GridComponent, GridComponent,
TransformComponent,
TitleComponent, TitleComponent,
TooltipComponent, TooltipComponent,
LegendComponent, // LegendComponent,
} from 'echarts/components'; } from 'echarts/components';
import { BarChart, PieChart } from 'echarts/charts'; import { BarChart, PieChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers'; import { CanvasRenderer } from 'echarts/renderers';
@@ -17,21 +19,26 @@ import { LabelLayout } from 'echarts/features';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
const { t } = useI18n(); const { t } = useI18n();
echarts.use([ echarts.use([
GridComponent,
BarChart,
CanvasRenderer,
TitleComponent, TitleComponent,
TooltipComponent, TooltipComponent,
GridComponent,
LegendComponent,
BarChart,
CanvasRenderer,
TooltipComponent,
LegendComponent, LegendComponent,
PieChart, PieChart,
CanvasRenderer, CanvasRenderer,
LabelLayout, LabelLayout,
DatasetComponent,
GridComponent,
TransformComponent,
BarChart,
CanvasRenderer,
GridComponent,
BarChart,
CanvasRenderer,
GridComponent,
BarChart,
CanvasRenderer,
CanvasRenderer,
]); ]);
/**图DOM节点实例对象 */ /**图DOM节点实例对象 */
@@ -40,269 +47,171 @@ const alarmTypeBar = ref<HTMLElement | undefined>(undefined);
/**图实例对象 */ /**图实例对象 */
const alarmTypeBarChart = ref<any>(null); const alarmTypeBarChart = ref<any>(null);
// 将现有数据补全为期望的格式 //
function completeData(existingData: any, expectedData: any) {
const result = expectedData.map((item: any) => {
const found = existingData.find(
(existingItem: any) => existingItem.name === item.name
);
if (found) return found;
else {
return item;
}
});
// result.forEach((item: any) => {
// item.title = t('views.index.' + item.name);
// });//
console.log(result);
return result;
}
var wantArr = [
{
value: 0,
name: 'Critical',
},
{
value: 0,
name: 'Major',
},
{
value: 0,
name: 'Minor',
},
{
value: 0,
name: 'Warning',
},
{
value: 0,
name: 'Event',
},
];
function initPicture() { function initPicture() {
mainGet().then((res: any) => { Promise.allSettled([origGet(), top3Sel()]).then(resArr => {
const colorList = ['##ae273e', '#ffb854', '#ffc069', '#99ccff', '#49a9ee']; let barArr: any = [
{ name: 'AMF', value: 0 },
{ name: 'UDM', value: 0 },
{ name: 'SMF', value: 0 },
];
let pieArr: any = [];
let yData: any[] = []; if (resArr[0].status === 'fulfilled') {
let realData = completeData(res.data, wantArr).sort(function ( resArr[0].value.data.map((item: any) => {
a: any, item.name = item.name + ':' + item.value;
b: any pieArr.push(item);
) { });
return a.value - b.value;
});
for (let i = 0; i < realData.length; i++) {
yData.push(realData[i].name);
realData[i].name = t('views.index.' + realData[i].name);
// realData[i].itemStyle = {
// color: colorList[i],
// };
} }
// const optionData: any = { if (resArr[1].status === 'fulfilled') {
// tooltip: { if (resArr[1].value.data.length) barArr = [];
// trigger: 'item', resArr[1].value.data.map((item: any) => {
// }, barArr.push(item);
});
// visualMap: { }
// show: false, console.log(pieArr);
// min: 80,
// max: 600,
// inRange: {
// colorLightness: [0, 1],
// },
// },
// series: [
// {
// name: 'Access From',
// type: 'pie',
// radius: '75%',
// center: ['50%', '48%'],
// data: realData,
// roseType: 'radius',
// label: {
// formatter: '{c|{c}}\n{b|{b}}',
// distance: 80,
// rich: {
// c: {
// color: 'rgb(241,246,104)',
// fontSize: 18,
// fontWeight: 'bold',
// lineHeight: 5,
// },
// b: {
// color: 'rgb(98,137,169)',
// fontSize: 15,
// height: 30,
// },
// },
// },
// labelLine: {
// lineStyle: {
// color: 'rgba(255, 255, 255, 0.3)',
// },
// smooth: 0.2,
// length: 10,
// length2: 80,
// },
// itemStyle: {
// shadowColor: 'rgba(0, 0, 0, 0.8)',
// shadowBlur: 50,
// },
// animationType: 'scale',
// animationEasing: 'elasticOut',
// animationDelay: function (idx: any) {
// return Math.random() * 200;
// },
// },
// ],
// };
const optionData: any = { const optionData: any = {
color: ['#EAEA26', '#906BF9', '#FE5656', '#01E17E', '#3DD1F9'], title: [
{
text: '',
},
{
text: t('views.dashboard.overview.alarmTypeBar.topTitle'),
textStyle: {
color: '#63C0FA',
fontSize: '14',
fontFamily: 'PingFang',
fontWeight: '400',
},
top: '210',
left: '4%',
},
],
grid: { grid: [
left: -100, {
top: 50, top: '55%',
bottom: 10, left: '15%',
right: 10, right: '25%',
containLabel: true, bottom: '3%',
}, },
tooltip: { ],
trigger: 'item',
formatter: '{b} : {c} ({d}%)',
},
legend: { legend: {
type: 'scroll', orient: 'vertical',
orient: 'vartical', left: '65%',
// x: "right", right: 'right',
top: 'center', top: '10%',
right: '15', data: pieArr.map((item: any) => item.name), //label数组
// bottom: "0%",
itemWidth: 16,
itemHeight: 8,
itemGap: 16,
textStyle: { textStyle: {
color: '#A3E2F4', color: '#A7D6F4', // 设置图例文字颜色
fontSize: 12,
fontWeight: 0,
},
data: yData,
},
polar: {},
angleAxis: {
interval: 1,
type: 'category',
data: [],
z: 10,
axisLine: {
show: false,
lineStyle: {
color: '#0B4A6B',
width: 1,
type: 'solid',
},
},
axisLabel: {
interval: 0,
show: true,
color: '#0B4A6B',
margin: 8,
fontSize: 16,
}, },
}, },
radiusAxis: { // 饼图设置
min: 40, color: ['#FFAE57', '#FF7853', '#EA5151', '#CC3F57', '#9A2555'],
max: 120, // color: ['#FFAE57', '#FFA500', '#FFAE57', '#1E90FF', '#1E90FF'], //红橙黄蓝绿 为告警级别配色 以严重性依次往下!
interval: 20,
axisLine: {
show: false,
lineStyle: {
color: '#0B3E5E',
width: 1,
type: 'solid',
},
},
axisLabel: {
formatter: '{value} %',
show: false,
padding: [0, 0, 20, 0],
color: '#0B3E5E',
fontSize: 16,
},
splitLine: {
lineStyle: {
color: '#0B3E5E',
width: 2,
type: 'solid',
},
},
},
calculable: true,
series: [ series: [
//饼图:
{ {
type: 'pie', type: 'pie',
radius: ['5%', '10%'], radius: '35%',
label: {
show: false,
},
labelLine: { labelLine: {
show: false, show: false,
length: 30,
length2: 55,
}, },
data: [ center: ['40%', '25%'],
{ data: pieArr.sort((a: any, b: any) => {
name: '', return a.value - b.value;
value: 0, }),
itemStyle: { lineStyle: 'none', // 设置线条样式为无,即可去掉线条
color: '#0B4A6B', zlevel: 2, // 设置zlevel为1使得柱状图在下层显示
}, itemStyle: {
}, shadowBlur: 10,
], shadowOffsetX: 0,
}, shadowColor: 'rgba(0, 0, 0, 0.5)',
{ // color: function (params: any) {
type: 'pie', // console.log(params);
radius: ['90%', '95%'], // // 设置每个数据项的颜色
labelLine: { // var colorList = {
show: false, // '#FFAE57',
length: 30, // '#FF7853',
length2: 55, // '#EA5151',
// '#CC3F57',
// '#9A2555',
// }
// ;
// return colorList[params.dataIndex];
// },
}, },
name: '',
data: [
{
name: '',
value: 0,
itemStyle: {
color: '#0B4A6B',
},
},
],
}, },
//柱状
{ {
type: 'pie', type: 'bar',
radius: ['20%', '80%'], barWidth: 12, // 柱子宽度
roseType: 'area', barCategoryGap: '30%', // 控制同一系列的柱间距离
zlevel: 10,
label: { label: {
show: true, show: true,
formatter: '{c|{c}}', position: 'right', // 位置
rich: { color: '#A7D6F4', //淡蓝色
c: { fontSize: 14,
color: 'rgb(241,246,104)', distance: 14, // label与柱子距离
fontSize: 16, formatter: '{c}',
fontWeight: 'bold', }, // 柱子上方的数值
lineHeight: 5, itemStyle: {
}, borderRadius: [0, 20, 20, 0], // 圆角(左上、右上、右下、左下)
}, color: new echarts.graphic.LinearGradient(
position: 'outside', 1,
0,
0,
0,
[
{
offset: 0,
color: '#51C5FD',
},
{
offset: 1,
color: '#005BB1',
},
],
false
), // 渐变
}, },
labelLine: { data: barArr.map((item: any) => item.value),
show: true, },
length: 20, ],
length2: 55, // 柱状图设置
xAxis: [
{
splitLine: {
show: false,
},
type: 'value',
show: false,
},
],
yAxis: [
{
splitLine: {
show: false,
},
axisLine: {
//y轴
show: false,
},
type: 'category',
axisTick: {
show: false,
},
inverse: true,
data: barArr.map((item: any) => item.name),
axisLabel: {
color: '#A7D6F4',
fontSize: 14,
}, },
data: realData,
}, },
], ],
}; };
@@ -313,13 +222,13 @@ function fnDesign(container: HTMLElement | undefined, option: any) {
if (!container) return; if (!container) return;
const { clientHeight, clientWidth } = container; const { clientHeight, clientWidth } = container;
alarmTypeBarChart.value = markRaw( alarmTypeBarChart.value = markRaw(echarts.init(container, 'light'));
echarts.init(container, 'light', {
width: clientWidth,
height: clientHeight - 36,
})
);
option && alarmTypeBarChart.value.setOption(option); option && alarmTypeBarChart.value.setOption(option);
window.onresize = function () {
// echarts 窗口缩放自适应 随着div--echarts-records的大小来适应
alarmTypeBarChart.value.resize();
};
} }
onMounted(() => { onMounted(() => {

View File

@@ -62,20 +62,15 @@ function fnDesign(container: HTMLElement | undefined, option: EChartsOption) {
if (!container) { if (!container) {
return; return;
} }
const { clientHeight, clientWidth } = container;
if (!upfFlowChart.value) { if (!upfFlowChart.value) {
upfFlowChart.value = markRaw( upfFlowChart.value = markRaw(echarts.init(container, 'light'));
echarts.init(container, 'light', {
width: clientWidth,
height: clientHeight - 36,
})
);
} }
option && upfFlowChart.value.setOption(option);
window.onresize = function () { window.onresize = function () {
// echarts 窗口缩放自适应 随着div--echarts-records的大小来适应 // echarts 窗口缩放自适应 随着div--echarts-records的大小来适应
upfFlowChart.value.resize(); upfFlowChart.value.resize();
}; };
option && upfFlowChart.value.setOption(option);
} }
//渲染速率图 //渲染速率图
@@ -126,27 +121,25 @@ function initPicture() {
color: color[x] + ')', color: color[x] + ')',
smooth: true, smooth: true,
areaStyle: { areaStyle: {
normal: { color: new echarts.graphic.LinearGradient(
color: new echarts.graphic.LinearGradient( 0,
0, 0,
0, 0,
0, 1,
1, [
[ {
{ offset: 0,
offset: 0, color: color[x] + ', 0.5)',
color: color[x] + ', 0.5)', },
}, {
{ offset: 0.8,
offset: 0.8, color: color[x] + ', 0.5)',
color: color[x] + ', 0.5)', },
}, ],
], false
false ),
), shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowColor: 'rgba(0, 0, 0, 0.1)', shadowBlur: 10,
shadowBlur: 10,
},
}, },
symbol: 'circle', symbol: 'circle',
symbolSize: 5, symbolSize: 5,
@@ -201,7 +194,7 @@ function initPicture() {
formatter: function (params: any) { formatter: function (params: any) {
return params.split(' ')[0] + '\n' + params.split(' ')[1]; return params.split(' ')[0] + '\n' + params.split(' ')[1];
}, },
fontSize:12 fontSize: 14,
}, },
axisLine: { axisLine: {
lineStyle: { lineStyle: {
@@ -213,9 +206,9 @@ function initPicture() {
{ {
name: charts.unit, name: charts.unit,
type: 'value', type: 'value',
// splitNumber: 4, // splitNumber: 4,
min:0, min: 0,
max:300, max: 300,
axisLabel: { axisLabel: {
formatter: '{value}', formatter: '{value}',
}, },
@@ -230,11 +223,9 @@ function initPicture() {
}, },
}, },
}, },
], ],
series: lineY, series: lineY,
}; };
console.log(optionData)
fnDesign(upfFlow.value, optionData); fnDesign(upfFlow.value, optionData);
}); });
} }

View File

@@ -135,16 +135,7 @@
color: #4c9bfd; color: #4c9bfd;
} }
/* 本月告警统计 */
.alarmType {
min-height: 13rem;
height: 25%;
}
.alarmType .chart {
width: 100%;
height: 100%;
margin-top: 1rem;
}
/* 用户行为 */ /* 用户行为 */
.userActivity { .userActivity {
@@ -213,6 +204,17 @@
margin-top: 1rem; margin-top: 1rem;
} }
/* 告警统计 */
.alarmType {
min-height: 22rem;
height: 60%;
}
.alarmType .inner .chart {
width: 100%;
height: 100%;
margin-top: 1rem;
}
/* 监控 */ /* 监控 */
.monitor { .monitor {
height: 20rem; height: 20rem;

View File

@@ -4,7 +4,6 @@ import useI18n from '@/hooks/useI18n';
import Topology from './components/Topology/index.vue'; import Topology from './components/Topology/index.vue';
import NeResources from './components/NeResources/index.vue'; import NeResources from './components/NeResources/index.vue';
import UserActivity from './components/UserActivity/index.vue'; import UserActivity from './components/UserActivity/index.vue';
import AlarnDayLine from './components/AlarnDayLine/index.vue';
import AlarnTypeBar from './components/AlarnTypeBar/index.vue'; import AlarnTypeBar from './components/AlarnTypeBar/index.vue';
import UPFFlow from './components/UPFFlow/index.vue'; import UPFFlow from './components/UPFFlow/index.vue';
import { listSub } from '@/api/neUser/sub'; import { listSub } from '@/api/neUser/sub';
@@ -295,24 +294,17 @@ onBeforeUnmount(() => {
</div> </div>
</div> </div>
</div> </div>
<!--告警统计--> <!-- 告警统计 -->
<div class="alarmType panel"> <div class="alarmType panel">
<div class="inner"> <div class="inner">
<h3>{{ t('views.dashboard.overview.alarmType.title') }}</h3> <h3>
<WhatsAppOutlined style="color: #68d8fe" />&nbsp;&nbsp; {{ t('views.dashboard.overview.alarmTypeBar.alarmSum') }}
</h3>
<div class="chart"> <div class="chart">
<AlarnTypeBar /> <AlarnTypeBar />
</div> </div>
</div> </div>
</div> </div>
<!--告警Top-->
<div class="alarmType panel">
<div class="inner">
<h3>{{ t('views.dashboard.overview.alarmType.title') }}</h3>
<div class="chart">
<AlarnDayLine />
</div>
</div>
</div>
</div> </div>
</div> </div>
</template> </template>