完善首页以及告警界面
This commit is contained in:
@@ -290,12 +290,12 @@ export async function exportAll(query: Record<string, any>) {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 首页活动告警
|
* 展示页全部告警
|
||||||
* @param query 查询参数
|
* @param query 查询参数
|
||||||
* @returns bolb
|
* @returns bolb
|
||||||
*/
|
*/
|
||||||
export async function mainGet() {
|
export async function mainGet() {
|
||||||
let totalSQL = `select count(*) as value,alarm_type as name from alarm where alarm_status=1 group by alarm_type`;
|
let totalSQL = `select count(*) as value,orig_severity as name from alarm group by orig_severity`;
|
||||||
|
|
||||||
// 发起请求
|
// 发起请求
|
||||||
const result = await request({
|
const result = await request({
|
||||||
|
|||||||
@@ -61,3 +61,29 @@ export async function listUE(query: Record<string, any>) {
|
|||||||
// ];
|
// ];
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询SMF在线用户数
|
||||||
|
* @param query 查询参数
|
||||||
|
* @returns neId
|
||||||
|
*/
|
||||||
|
export async function listUENum(neId: String) {
|
||||||
|
const result = await request({
|
||||||
|
url: `/api/rest/ueManagement/v1/elementType/smf/objectType/ueNum?neId=${neId}`,
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
let data: DataList = {
|
||||||
|
total: 0,
|
||||||
|
rows: [],
|
||||||
|
code: result.code,
|
||||||
|
msg: result.msg,
|
||||||
|
};
|
||||||
|
// 解析数据
|
||||||
|
if (result.code === RESULT_CODE_SUCCESS && Array.isArray(result.data.data)) {
|
||||||
|
const rows = parseObjLineToHump(result.data.data);
|
||||||
|
data.total = rows.length;
|
||||||
|
data.rows = rows;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -115,3 +115,75 @@ export async function getGoldTitleByNE(neType: string) {
|
|||||||
// 解析数据
|
// 解析数据
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询UPF上下行速率数据
|
||||||
|
* @param query 查询参数
|
||||||
|
* @returns object
|
||||||
|
*/
|
||||||
|
export async function listUPFData(timeArr:any) {
|
||||||
|
return await Promise.allSettled([
|
||||||
|
// 获取参数规则
|
||||||
|
request({
|
||||||
|
url: `/api/rest/databaseManagement/v1/select/omc_db/gold_kpi`,
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
SQL: `SELECT gold_kpi.*,kpi_title.en_title FROM gold_kpi LEFT JOIN kpi_title on gold_kpi.kpi_id=kpi_title.kpi_id where 1=1 and gold_kpi.kpi_id ='UPF.06' and timestamp BETWEEN '${timeArr[0]}' AND '${timeArr[1]}' `,
|
||||||
|
},
|
||||||
|
timeout: 60_000,
|
||||||
|
}),
|
||||||
|
// 获取对应信息
|
||||||
|
request({
|
||||||
|
url: `/api/rest/databaseManagement/v1/select/omc_db/gold_kpi`,
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
SQL: `SELECT gold_kpi.*,kpi_title.en_title FROM gold_kpi LEFT JOIN kpi_title on gold_kpi.kpi_id=kpi_title.kpi_id where 1=1 and gold_kpi.kpi_id ='UPF.03' and timestamp BETWEEN '${timeArr[0]}' AND '${timeArr[1]}' `,
|
||||||
|
},
|
||||||
|
timeout: 60_000,
|
||||||
|
}),
|
||||||
|
]).then(resArr => {
|
||||||
|
let upData: any = [];
|
||||||
|
let downData: any = [];
|
||||||
|
|
||||||
|
// 规则数据
|
||||||
|
if (resArr[0].status === 'fulfilled') {
|
||||||
|
const itemV:any = resArr[0].value;
|
||||||
|
// 解析数据
|
||||||
|
if (
|
||||||
|
itemV.code === RESULT_CODE_SUCCESS &&
|
||||||
|
Array.isArray(itemV.data?.data)
|
||||||
|
) {
|
||||||
|
let itemData = itemV.data.data;
|
||||||
|
let data= itemData[0]['gold_kpi'];
|
||||||
|
if (Array.isArray(data)) {
|
||||||
|
try {
|
||||||
|
upData = data.map(v => parseObjLineToHump(v));
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resArr[1].status === 'fulfilled') {
|
||||||
|
const itemV = resArr[1].value;
|
||||||
|
// 解析数据
|
||||||
|
if (
|
||||||
|
itemV.code === RESULT_CODE_SUCCESS &&
|
||||||
|
Array.isArray(itemV.data?.data)
|
||||||
|
) {
|
||||||
|
let itemData = itemV.data.data;
|
||||||
|
const data = itemData[0]['gold_kpi'];
|
||||||
|
if (Array.isArray(data)) {
|
||||||
|
try {
|
||||||
|
downData = data.map(v => parseObjLineToHump(v));
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {upData,downData};
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -212,6 +212,11 @@ export default {
|
|||||||
systemStatus:'Status',
|
systemStatus:'Status',
|
||||||
realNeStatus:'Status',
|
realNeStatus:'Status',
|
||||||
reloadTime:'Refresh Time',
|
reloadTime:'Refresh Time',
|
||||||
|
Critical:'Critical',
|
||||||
|
Major:'Major',
|
||||||
|
Minor:'Minor',
|
||||||
|
Warning:'Warning',
|
||||||
|
Event:'Event'
|
||||||
},
|
},
|
||||||
error: {
|
error: {
|
||||||
err403: {
|
err403: {
|
||||||
@@ -483,6 +488,17 @@ export default {
|
|||||||
arrayMore: "Expand",
|
arrayMore: "Expand",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
dashboard: {
|
||||||
|
overview:{
|
||||||
|
UPFFlow:{
|
||||||
|
up:'Uplink Rate',
|
||||||
|
down:'Downlink Rate'
|
||||||
|
},
|
||||||
|
AlarmTypeBar:{
|
||||||
|
alarmTotal:'Total:'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
neUser: {
|
neUser: {
|
||||||
auth: {
|
auth: {
|
||||||
authInfo:'Authentication Info',
|
authInfo:'Authentication Info',
|
||||||
|
|||||||
@@ -212,6 +212,11 @@ export default {
|
|||||||
systemStatus:'系统状态',
|
systemStatus:'系统状态',
|
||||||
realNeStatus:'网元状态',
|
realNeStatus:'网元状态',
|
||||||
reloadTime:'刷新时间',
|
reloadTime:'刷新时间',
|
||||||
|
Critical:'严重告警',
|
||||||
|
Major:'主要告警',
|
||||||
|
Minor:'次要告警',
|
||||||
|
Warning:'警告告警',
|
||||||
|
Event:'事件告警'
|
||||||
},
|
},
|
||||||
error: {
|
error: {
|
||||||
err403: {
|
err403: {
|
||||||
@@ -483,6 +488,17 @@ export default {
|
|||||||
arrayMore: "展开",
|
arrayMore: "展开",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
dashboard: {
|
||||||
|
overview:{
|
||||||
|
UPFFlow:{
|
||||||
|
up:'上行',
|
||||||
|
down:'下行',
|
||||||
|
},
|
||||||
|
AlarmTypeBar:{
|
||||||
|
alarmTotal:'告警总数:'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
neUser: {
|
neUser: {
|
||||||
auth: {
|
auth: {
|
||||||
authInfo:'鉴权信息',
|
authInfo:'鉴权信息',
|
||||||
|
|||||||
@@ -118,3 +118,33 @@ export function parseSizeFromKBs(size: number): string {
|
|||||||
}
|
}
|
||||||
return (size / Math.pow(num, 3)).toFixed(2) + ' TB/s';
|
return (size / Math.pow(num, 3)).toFixed(2) + ' TB/s';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字节数转换速率
|
||||||
|
* @param sizeByte 数值大小
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function parseSizeFromKbs(sizeByte: number, timeInterval: number): any {
|
||||||
|
// let realBit:any=((sizeByte * 8) / timeInterval);
|
||||||
|
// if (realBit >= 0 && realBit < 1000) {
|
||||||
|
// return [realBit.toFixed(2),' bits/sec'];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (realBit >= 1000 && realBit < 1000*1000) {
|
||||||
|
// return [(realBit/1000).toFixed(2) ,' Kbits/sec'];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (realBit >= 1000*1000 && realBit < 1000*1000*1000) {
|
||||||
|
// return [((realBit/1000)/1000).toFixed(2) ,' Mbits/sec'];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (realBit >= 1000*1000*1000) {
|
||||||
|
// return [((realBit/1000*1000)/1000).toFixed(2) ,' Gbits/sec'];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return [((realBit/1000*1000*1000)/1000).toFixed(2) ,' TB/sec'];
|
||||||
|
|
||||||
|
let realBit: any = (sizeByte * 8) / timeInterval;
|
||||||
|
|
||||||
|
return [(realBit / 1000 / 1000).toFixed(2), ' Mbits/sec'];
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="alarmType" class="chart-container"></div>
|
<div ref="alarmTypeBar" class="chart-container"></div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted } from 'vue';
|
import { markRaw, onMounted, ref } from 'vue';
|
||||||
import { mainGet } from '@/api/faultManage/actAlarm';
|
import { mainGet } from '@/api/faultManage/actAlarm';
|
||||||
import * as echarts from 'echarts/core';
|
import * as echarts from 'echarts/core';
|
||||||
import {
|
import {
|
||||||
@@ -15,6 +15,12 @@ import { BarChart, PieChart } from 'echarts/charts';
|
|||||||
import { CanvasRenderer } from 'echarts/renderers';
|
import { CanvasRenderer } from 'echarts/renderers';
|
||||||
import { LabelLayout } from 'echarts/features';
|
import { LabelLayout } from 'echarts/features';
|
||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import {
|
||||||
|
GridComponentOption,
|
||||||
|
LegendComponentOption,
|
||||||
|
LineSeriesOption,
|
||||||
|
TooltipComponentOption,
|
||||||
|
} from 'echarts';
|
||||||
const { t, currentLocale } = useI18n();
|
const { t, currentLocale } = useI18n();
|
||||||
echarts.use([
|
echarts.use([
|
||||||
GridComponent,
|
GridComponent,
|
||||||
@@ -32,9 +38,15 @@ echarts.use([
|
|||||||
CanvasRenderer,
|
CanvasRenderer,
|
||||||
LabelLayout,
|
LabelLayout,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
/**图DOM节点实例对象 */
|
||||||
|
const alarmTypeBar = ref<HTMLElement | undefined>(undefined);
|
||||||
|
|
||||||
|
/**图实例对象 */
|
||||||
|
const alarmTypeBarChart = ref<any>(null);
|
||||||
|
|
||||||
// 将现有数据补全为期望的格式
|
// 将现有数据补全为期望的格式
|
||||||
function completeData(existingData: any, expectedData: any) {
|
function completeData(existingData: any, expectedData: any) {
|
||||||
let allType = { zh: { CommunicationAlarm: 'Communication Alarm' } };
|
|
||||||
const result = expectedData.map((item: any) => {
|
const result = expectedData.map((item: any) => {
|
||||||
const found = existingData.find(
|
const found = existingData.find(
|
||||||
(existingItem: any) => existingItem.name === item.name
|
(existingItem: any) => existingItem.name === item.name
|
||||||
@@ -44,161 +56,162 @@ function completeData(existingData: any, expectedData: any) {
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var lang = currentLocale.value.split('_')[0];
|
// result.forEach((item: any) => {
|
||||||
result.forEach((item: any) => {
|
// item.title = t('views.index.' + item.name);
|
||||||
item.name = t('views.index.' + item.name);
|
// });//
|
||||||
});
|
console.log(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function fnDesign() {
|
var wantArr = [
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
name: 'Critical',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
name: 'Major',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
name: 'Minor',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
name: 'Warning',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
name: 'Event',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function initPicture() {
|
||||||
mainGet().then((res: any) => {
|
mainGet().then((res: any) => {
|
||||||
const expectedData = [
|
const colorList = ['##ae273e', '#ffb854', '#ffc069', '#99ccff', '#49a9ee'];
|
||||||
{
|
|
||||||
name: 'CommunicationAlarm',
|
let yData: any[] = [];
|
||||||
value: 0,
|
let realData = completeData(res.data, wantArr).sort(function (
|
||||||
|
a: any,
|
||||||
|
b: any
|
||||||
|
) {
|
||||||
|
return a.value - b.value;
|
||||||
|
});
|
||||||
|
console.log(realData);
|
||||||
|
// realData.map((item: any) => {
|
||||||
|
// item.itemStyle={
|
||||||
|
// color:colorList[i]
|
||||||
|
// }
|
||||||
|
// item.name = t('views.index.' + item.name);
|
||||||
|
// });
|
||||||
|
for (let i = 0; i < realData.length; i++) {
|
||||||
|
realData[i].name= t('views.index.' + realData[i].name);
|
||||||
|
realData[i].itemStyle = {
|
||||||
|
color: colorList[i]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const optionData: any = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'EquipmentAlarm',
|
visualMap: {
|
||||||
value: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'ProcessingFailure',
|
|
||||||
value: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'EnvironmentalAlarm',
|
|
||||||
value: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'QualityOfServiceAlarm',
|
|
||||||
value: 0,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
var chartDom = document.getElementById('alarmType');
|
|
||||||
var myChart = echarts.init(chartDom);
|
|
||||||
var option: any;
|
|
||||||
var colorList = [
|
|
||||||
'#afa3f5',
|
|
||||||
'#00d488',
|
|
||||||
'#3feed4',
|
|
||||||
'#3bafff',
|
|
||||||
'#f1bb4c',
|
|
||||||
'#aff',
|
|
||||||
'rgba(250,250,250,0.5)',
|
|
||||||
];
|
|
||||||
option = {
|
|
||||||
grid: {
|
|
||||||
bottom: 120,
|
|
||||||
left: 0,
|
|
||||||
right: '10%',
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
show: false,
|
show: false,
|
||||||
orient: 'vertical',
|
min: 80,
|
||||||
top: 'middle',
|
max: 600,
|
||||||
right: '5%',
|
inRange: {
|
||||||
textStyle: {
|
colorLightness: [0, 1],
|
||||||
color: '#f2f2f2',
|
|
||||||
fontSize: 25,
|
|
||||||
},
|
},
|
||||||
icon: 'roundRect',
|
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
// 主要展示层的
|
|
||||||
{
|
{
|
||||||
radius: ['29%', '59%'],
|
name: 'Access From',
|
||||||
center: ['50%', '50%'],
|
|
||||||
type: 'pie',
|
type: 'pie',
|
||||||
itemStyle: {
|
radius: '75%',
|
||||||
normal: {
|
center: ['40%', '48%'],
|
||||||
color: function (params: any) {
|
data: realData,
|
||||||
return colorList[params.dataIndex];
|
roseType: 'radius',
|
||||||
},
|
// label: {
|
||||||
},
|
// formatter: '{c|{c}}\n{b|{b}}',
|
||||||
},
|
// rich: {
|
||||||
labelLine: {
|
// c: {
|
||||||
show: true,
|
// color: 'rgb(241,246,104)',
|
||||||
length: 10,
|
// fontSize: 20,
|
||||||
length2: 120,
|
// fontWeight: 'bold',
|
||||||
align: 'right',
|
// lineHeight: 5,
|
||||||
color: '#000',
|
// },
|
||||||
},
|
// b: {
|
||||||
|
// color: 'rgb(98,137,169)',
|
||||||
|
// fontSize: 15,
|
||||||
|
// height: 40,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// labelLine: {
|
||||||
|
// lineStyle: {
|
||||||
|
// color: 'rgb(98,137,169)',
|
||||||
|
// },
|
||||||
|
// smooth: 0.2,
|
||||||
|
// length: 10,
|
||||||
|
// length2: 20,
|
||||||
|
// },
|
||||||
label: {
|
label: {
|
||||||
show: true,
|
formatter: '{c|{c}}\n{b|{b}}',
|
||||||
formatter: '({d}%){b}:{c}',
|
distance: 80,
|
||||||
padding: [0, -120],
|
|
||||||
fontSize:15,
|
|
||||||
height: 35,
|
|
||||||
alignTo: 'labelLine',
|
|
||||||
color: 'auto',
|
|
||||||
rich: {
|
rich: {
|
||||||
name: {
|
c: {
|
||||||
color: '#ff0000', // 修改名称颜色
|
color: 'rgb(241,246,104)',
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
lineHeight: 5,
|
||||||
},
|
},
|
||||||
|
b: {
|
||||||
|
color: 'rgb(98,137,169)',
|
||||||
|
fontSize: 15,
|
||||||
|
height: 30,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: [
|
|
||||||
{ value: 1, name: '通信告警' },
|
|
||||||
{ value: 1, name: '设备告警' },
|
|
||||||
{ value: 1, name: '服务质量' },
|
|
||||||
{ value: 1, name: '环境告警' },
|
|
||||||
{ value: 1, name: '处理错误' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
// 边框的设置
|
|
||||||
{
|
|
||||||
radius: ['54%', '59%'],
|
|
||||||
center: ['50%', '50%'],
|
|
||||||
type: 'pie',
|
|
||||||
label: {
|
|
||||||
normal: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
emphasis: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
labelLine: {
|
labelLine: {
|
||||||
normal: {
|
lineStyle: {
|
||||||
show: false,
|
color: 'rgba(255, 255, 255, 0.3)',
|
||||||
},
|
},
|
||||||
emphasis: {
|
smooth: 0.2,
|
||||||
show: false,
|
length: 10,
|
||||||
},
|
length2: 80,
|
||||||
},
|
|
||||||
animation: false,
|
|
||||||
tooltip: {
|
|
||||||
show: false,
|
|
||||||
},
|
},
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
normal: {
|
shadowColor: 'rgba(0, 0, 0, 0.8)',
|
||||||
color: 'rgba(250,250,250,0.5)',
|
shadowBlur: 50,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
animationType: 'scale',
|
||||||
|
animationEasing: 'elasticOut',
|
||||||
|
animationDelay: function (idx: any) {
|
||||||
|
return Math.random() * 200;
|
||||||
},
|
},
|
||||||
data: [
|
|
||||||
{
|
|
||||||
value: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
option && myChart.setOption(option);
|
fnDesign(alarmTypeBar.value, optionData);
|
||||||
window.onresize = function () {
|
|
||||||
myChart.resize();
|
|
||||||
};
|
|
||||||
// 点击圆形饼状图
|
|
||||||
myChart.on('click', (params: any) => {
|
|
||||||
// 根据点击的数据params更新柱状图的数据
|
|
||||||
// const newData = generateNewData(params.name); // 根据点击的数据生成新的柱状图数据
|
|
||||||
// updateBarChart(newData); // 更新柱状图
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
function fnDesign(container: HTMLElement | undefined, option: any) {
|
||||||
|
if (!container) return;
|
||||||
|
const { clientHeight, clientWidth } = container;
|
||||||
|
|
||||||
|
alarmTypeBarChart.value = markRaw(
|
||||||
|
echarts.init(container, 'light', {
|
||||||
|
width: clientWidth,
|
||||||
|
height: clientHeight - 36,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
option && alarmTypeBarChart.value.setOption(option);
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fnDesign();
|
initPicture();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -209,3 +222,4 @@ onMounted(() => {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
<div ref="upfFlow" class="chart-container"></div>
|
<div ref="upfFlow" class="chart-container"></div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, onUnmounted, ref } from 'vue';
|
||||||
import { mainGet } from '@/api/faultManage/actAlarm';
|
import { listUPFData } from '@/api/perfManage/goldTarget';
|
||||||
|
import { parseSizeFromKbs } from '@/utils/parse-utils';
|
||||||
import * as echarts from 'echarts/core';
|
import * as echarts from 'echarts/core';
|
||||||
import {
|
import {
|
||||||
TooltipComponent,
|
TooltipComponent,
|
||||||
@@ -16,8 +17,11 @@ import {
|
|||||||
import { LineChart, LineSeriesOption } from 'echarts/charts';
|
import { LineChart, LineSeriesOption } from 'echarts/charts';
|
||||||
import { UniversalTransition } from 'echarts/features';
|
import { UniversalTransition } from 'echarts/features';
|
||||||
import { CanvasRenderer } from 'echarts/renderers';
|
import { CanvasRenderer } from 'echarts/renderers';
|
||||||
import { GaugeSeriesOption } from 'echarts';
|
|
||||||
import { markRaw } from 'vue';
|
import { markRaw } from 'vue';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { parseDateToStr } from '@/utils/date-utils';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
echarts.use([
|
echarts.use([
|
||||||
TooltipComponent,
|
TooltipComponent,
|
||||||
@@ -34,71 +38,86 @@ type EChartsOption = echarts.ComposeOption<
|
|||||||
| LegendComponentOption
|
| LegendComponentOption
|
||||||
| LineSeriesOption
|
| LineSeriesOption
|
||||||
>;
|
>;
|
||||||
|
/**设置定时器ID */
|
||||||
|
let timeoutDuration = 5 * 1000; // 设置5s进行刷新请求
|
||||||
|
let loadId: any = null;
|
||||||
|
|
||||||
|
// 超时锁屏
|
||||||
|
function resetTimeout() {
|
||||||
|
if (loadId) {
|
||||||
|
clearInterval(loadId);
|
||||||
|
}
|
||||||
|
loadId = setInterval(() => {
|
||||||
|
initPicture();
|
||||||
|
}, timeoutDuration);
|
||||||
|
}
|
||||||
|
|
||||||
/**图DOM节点实例对象 */
|
/**图DOM节点实例对象 */
|
||||||
const upfFlow = ref<HTMLElement | undefined>(undefined);
|
const upfFlow = ref<HTMLElement | undefined>(undefined);
|
||||||
|
|
||||||
/**图实例对象 */
|
/**图实例对象 */
|
||||||
const upfFlowChart = ref<any>(null);
|
const upfFlowChart = ref<any>(null);
|
||||||
|
|
||||||
// // 将现有数据补全为期望的格式
|
function fnDesign(container: HTMLElement | undefined, option: EChartsOption) {
|
||||||
// function completeData(existingData: any, expectedData: any) {
|
if (!container) {
|
||||||
// let allType = { zh: { CommunicationAlarm: 'Communication Alarm' } };
|
return;
|
||||||
// const result = expectedData.map((item: any) => {
|
}
|
||||||
// const found = existingData.find(
|
const { clientHeight, clientWidth } = container;
|
||||||
// (existingItem: any) => existingItem.name === item.name
|
if (!upfFlowChart.value) {
|
||||||
// );
|
upfFlowChart.value = markRaw(
|
||||||
// if (found) return found;
|
echarts.init(container, 'light', {
|
||||||
// else {
|
width: clientWidth,
|
||||||
// return item;
|
height: clientHeight - 36,
|
||||||
// }
|
})
|
||||||
// });
|
);
|
||||||
// var lang = currentLocale.value.split('_')[0];
|
}
|
||||||
// console.log(lang);
|
window.onresize = function () {
|
||||||
// result.forEach((item: any) => {
|
// echarts 窗口缩放自适应 随着div--echarts-records的大小来适应
|
||||||
// item.name = t('views.index.' + item.name);
|
upfFlowChart.value.resize();
|
||||||
// });
|
};
|
||||||
// return result;
|
option && upfFlowChart.value.setOption(option);
|
||||||
// }
|
|
||||||
var charts = {
|
|
||||||
unit: 'Kbps',
|
|
||||||
names: ['上行', '下行'],
|
|
||||||
lineX: [
|
|
||||||
'2018-11-11 17:01',
|
|
||||||
'2018-11-11 17:02',
|
|
||||||
'2018-11-11 17:03',
|
|
||||||
'2018-11-11 17:04',
|
|
||||||
'2018-11-11 17:05',
|
|
||||||
'2018-11-11 17:06',
|
|
||||||
'2018-11-11 17:07',
|
|
||||||
'2018-11-11 17:08',
|
|
||||||
'2018-11-11 17:09',
|
|
||||||
'2018-11-11 17:10',
|
|
||||||
'2018-11-11 17:11',
|
|
||||||
'2018-11-11 17:12',
|
|
||||||
'2018-11-11 17:13',
|
|
||||||
'2018-11-11 17:14',
|
|
||||||
'2018-11-11 17:15',
|
|
||||||
'2018-11-11 17:16',
|
|
||||||
'2018-11-11 17:17',
|
|
||||||
'2018-11-11 17:18',
|
|
||||||
'2018-11-11 17:19',
|
|
||||||
'2018-11-11 17:20',
|
|
||||||
],
|
|
||||||
value: [
|
|
||||||
[
|
|
||||||
451, 352, 303, 534, 95, 236, 217, 328, 159, 151, 231, 192, 453, 524, 165,
|
|
||||||
236, 527, 328, 129, 530,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
360, 545, 80, 192, 330, 580, 192, 80, 250, 453, 352, 28, 625, 345, 65,
|
|
||||||
325, 468, 108, 253, 98,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
};
|
|
||||||
var color = ['rgba(23, 255, 243', 'rgba(255,100,97'];
|
|
||||||
var lineY: any = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < charts.names.length; i++) {
|
}
|
||||||
|
|
||||||
|
//渲染速率图
|
||||||
|
function initPicture() {
|
||||||
|
let queryArr: any = [];
|
||||||
|
const initTime: Date = new Date();
|
||||||
|
console.log(initTime)
|
||||||
|
const startTime: Date = new Date(initTime);
|
||||||
|
startTime.setHours(0, 0, 0, 0); // 设置为今天的0点
|
||||||
|
const endTime: Date = new Date(initTime);
|
||||||
|
endTime.setHours(23, 59, 59, 59); // 设置为今天的12点
|
||||||
|
queryArr = [parseDateToStr(startTime), parseDateToStr(endTime)];
|
||||||
|
|
||||||
|
listUPFData(queryArr).then(res => {
|
||||||
|
let timeArr: any = [];
|
||||||
|
let upValue: any = [];
|
||||||
|
let downValue: any = [];
|
||||||
|
|
||||||
|
res.upData.map((item: any) => {
|
||||||
|
timeArr.push(item.timestamp);
|
||||||
|
upValue.push(parseSizeFromKbs(item.value, 60)[0]);
|
||||||
|
});
|
||||||
|
res.downData.map((item: any) => {
|
||||||
|
downValue.push(parseSizeFromKbs(item.value, 60)[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
var charts = {
|
||||||
|
unit: '(Kbps)',
|
||||||
|
names: [
|
||||||
|
t('views.dashboard.overview.UPFFlow.up'),
|
||||||
|
t('views.dashboard.overview.UPFFlow.down'),
|
||||||
|
],
|
||||||
|
|
||||||
|
lineX: timeArr,
|
||||||
|
value: [upValue, downValue],
|
||||||
|
};
|
||||||
|
|
||||||
|
var color = ['rgba(92, 123, 217', 'rgba(166, 215, 144'];
|
||||||
|
var lineY: any = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < charts.names.length; i++) {
|
||||||
var x = i;
|
var x = i;
|
||||||
if (x > color.length - 1) {
|
if (x > color.length - 1) {
|
||||||
x = color.length - 1;
|
x = color.length - 1;
|
||||||
@@ -118,11 +137,11 @@ for (var i = 0; i < charts.names.length; i++) {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
offset: 0,
|
offset: 0,
|
||||||
color: color[x] + ', 0.3)',
|
color: color[x] + ', 0.5)',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
offset: 0.8,
|
offset: 0.8,
|
||||||
color: color[x] + ', 0)',
|
color: color[x] + ', 0.5)',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
false
|
false
|
||||||
@@ -133,15 +152,34 @@ for (var i = 0; i < charts.names.length; i++) {
|
|||||||
},
|
},
|
||||||
symbol: 'circle',
|
symbol: 'circle',
|
||||||
symbolSize: 5,
|
symbolSize: 5,
|
||||||
|
formatter: '{b}',
|
||||||
data: charts.value[i],
|
data: charts.value[i],
|
||||||
|
yAxisIndex: i,
|
||||||
};
|
};
|
||||||
lineY.push(data);
|
lineY.push(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
const optionData: EChartsOption = {
|
const optionData: EChartsOption = {
|
||||||
tooltip: {
|
tooltip: {
|
||||||
show: true, //是否显示提示框组件
|
show: true, //是否显示提示框组件
|
||||||
trigger: 'axis',
|
trigger: 'axis',
|
||||||
|
//formatter:'{a0}:{c0}<br>{a1}:{c1}'
|
||||||
|
formatter: function (param: any) {
|
||||||
|
console.log(param);
|
||||||
|
var tip = '';
|
||||||
|
if (param !== null && param.length > 0) {
|
||||||
|
tip += param[0].name + '<br />';
|
||||||
|
for (var i = 0; i < param.length; i++) {
|
||||||
|
tip +=
|
||||||
|
param[i].marker +
|
||||||
|
param[i].seriesName +
|
||||||
|
': ' +
|
||||||
|
param[i].value +
|
||||||
|
'<br />';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tip;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
data: charts.names,
|
data: charts.names,
|
||||||
@@ -149,7 +187,7 @@ const optionData: EChartsOption = {
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: 'rgb(0,253,255,0.6)',
|
color: 'rgb(0,253,255,0.6)',
|
||||||
},
|
},
|
||||||
right: '4%',
|
right: '35%',
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
top: '14%',
|
top: '14%',
|
||||||
@@ -173,7 +211,8 @@ const optionData: EChartsOption = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: [
|
||||||
|
{
|
||||||
name: charts.unit,
|
name: charts.unit,
|
||||||
type: 'value',
|
type: 'value',
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
@@ -190,42 +229,40 @@ const optionData: EChartsOption = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: charts.unit,
|
||||||
|
type: 'value',
|
||||||
|
axisLabel: {
|
||||||
|
formatter: '{value}',
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: 'rgb(23,255,243,0.3)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: 'rgb(0,253,255,0.6)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
series: lineY,
|
series: lineY,
|
||||||
};
|
};
|
||||||
|
fnDesign(upfFlow.value, optionData);
|
||||||
function fnDesign(container: HTMLElement | undefined, option: EChartsOption) {
|
});
|
||||||
if (!container) return;
|
|
||||||
const { clientHeight, clientWidth } = container;
|
|
||||||
|
|
||||||
upfFlowChart.value = markRaw(
|
|
||||||
echarts.init(container, 'light', {
|
|
||||||
width: clientWidth,
|
|
||||||
height: clientHeight - 36,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
option && upfFlowChart.value.setOption(option);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fnDesign(upfFlow.value, optionData);
|
initPicture();
|
||||||
setInterval(() => {
|
resetTimeout();
|
||||||
upfFlowChart.value.setOption({
|
});
|
||||||
legend: {
|
|
||||||
selected: {
|
/**组件实例被卸载之后调用 */
|
||||||
上行: false,
|
onUnmounted(() => {
|
||||||
下行: false,
|
if (loadId) {
|
||||||
},
|
clearInterval(loadId);
|
||||||
},
|
}
|
||||||
});
|
|
||||||
upfFlowChart.value.setOption({
|
|
||||||
legend: {
|
|
||||||
selected: {
|
|
||||||
上行: true,
|
|
||||||
下行: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}, 10000);
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import useI18n from '@/hooks/useI18n';
|
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';
|
||||||
@@ -7,17 +7,59 @@ import CDR from './components/CDR/index.vue';
|
|||||||
import AlarnDayLine from './components/AlarnDayLine/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 { listUENum } from '@/api/neUser/ue';
|
||||||
|
|
||||||
import { graphNodeClickID } from './hooks/useTopology';
|
import { graphNodeClickID } from './hooks/useTopology';
|
||||||
import { useFullscreen } from '@vueuse/core';
|
import { useFullscreen } from '@vueuse/core';
|
||||||
import useAppStore from '@/store/modules/app';
|
import useAppStore from '@/store/modules/app';
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
// let subNum = ref<number>(0);
|
||||||
|
|
||||||
|
/**用户在线信息 */
|
||||||
|
let onlineInfo: {
|
||||||
|
/**签约用户数量 */
|
||||||
|
subNum: number;
|
||||||
|
/**告警清除类型 */
|
||||||
|
ueNum: any;
|
||||||
|
/**告警清除类型 */
|
||||||
|
activeAckState: DictType[];
|
||||||
|
/**原始严重程度 */
|
||||||
|
activeAlarmSeverity: DictType[];
|
||||||
|
} = reactive({
|
||||||
|
subNum: 0,
|
||||||
|
ueNum: 0,
|
||||||
|
activeAckState: [],
|
||||||
|
activeAlarmSeverity: [],
|
||||||
|
});
|
||||||
|
|
||||||
/**总览节点 */
|
/**总览节点 */
|
||||||
const viewportDom = ref<HTMLElement | null>(null);
|
const viewportDom = ref<HTMLElement | null>(null);
|
||||||
const { isFullscreen, toggle } = useFullscreen(viewportDom);
|
const { isFullscreen, toggle } = useFullscreen(viewportDom);
|
||||||
|
|
||||||
onMounted(() => {});
|
onMounted(() => {
|
||||||
|
Promise.allSettled([
|
||||||
|
listSub({
|
||||||
|
neid: '003',
|
||||||
|
sortField: 'imsi',
|
||||||
|
sortOrder: 'asc',
|
||||||
|
pageNum: '1',
|
||||||
|
pageSize: '20',
|
||||||
|
}),
|
||||||
|
// listUENum('001'),
|
||||||
|
]).then(resArr => {
|
||||||
|
console.log(resArr)
|
||||||
|
if (resArr[0].status === 'fulfilled') {
|
||||||
|
onlineInfo.subNum=resArr[0].value.total;
|
||||||
|
}
|
||||||
|
// if (resArr[1].status === 'fulfilled') {
|
||||||
|
// console.log(resArr[1].value)
|
||||||
|
// onlineInfo.ueNum=resArr[1].value.data?.ueNum;
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -36,14 +78,14 @@ onMounted(() => {});
|
|||||||
<div class="overview panel">
|
<div class="overview panel">
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<h4>2,190</h4>
|
<h4>{{onlineInfo.subNum}}</h4>
|
||||||
<span>
|
<span>
|
||||||
<UserOutlined style="color: #006cff" />
|
<UserOutlined style="color: #006cff" />
|
||||||
签约用户
|
签约用户
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<h4>190</h4>
|
<h4>1000</h4>
|
||||||
<span>
|
<span>
|
||||||
<UserSwitchOutlined style="color: #6acca3" />
|
<UserSwitchOutlined style="color: #6acca3" />
|
||||||
语音在线
|
语音在线
|
||||||
@@ -69,7 +111,7 @@ onMounted(() => {});
|
|||||||
<!--本月告警统计-->
|
<!--本月告警统计-->
|
||||||
<div class="alarmType panel">
|
<div class="alarmType panel">
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<h3>本月告警统计</h3>
|
<h3>告警统计</h3>
|
||||||
<div class="chart">
|
<div class="chart">
|
||||||
<AlarnTypeBar />
|
<AlarnTypeBar />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ let tableColumnsDnd = ref<ColumnsType>([]);
|
|||||||
/**记录开始结束时间 */
|
/**记录开始结束时间 */
|
||||||
let queryRangePicker = ref<[string, string]>(['', '']);
|
let queryRangePicker = ref<[string, string]>(['', '']);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**查询参数 */
|
/**查询参数 */
|
||||||
let queryParams = reactive({
|
let queryParams = reactive({
|
||||||
/**告警设备类型 */
|
/**告警设备类型 */
|
||||||
@@ -627,8 +629,18 @@ function fnExportAll() {
|
|||||||
const sortData = {
|
const sortData = {
|
||||||
header: sortArr,
|
header: sortArr,
|
||||||
};
|
};
|
||||||
|
|
||||||
exportAll(queryParams).then(res => {
|
exportAll(queryParams).then(res => {
|
||||||
if (res.code === RESULT_CODE_SUCCESS) {
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
res.data = res.data.map((objA: any) => {
|
||||||
|
let filteredObj: any = {};
|
||||||
|
sortArr.forEach((key: any) => {
|
||||||
|
if (objA.hasOwnProperty(key)) {
|
||||||
|
filteredObj[key] = objA[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return filteredObj;
|
||||||
|
});
|
||||||
message.success({
|
message.success({
|
||||||
content: t('common.msgSuccess', { msg: t('common.export') }),
|
content: t('common.msgSuccess', { msg: t('common.export') }),
|
||||||
key,
|
key,
|
||||||
@@ -875,7 +887,12 @@ onMounted(() => {
|
|||||||
{{ t('views.faultManage.activeAlarm.syncMyself') }}
|
{{ t('views.faultManage.activeAlarm.syncMyself') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|
||||||
<a-button type="primary" danger @click.prevent="fnClear()">
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
danger
|
||||||
|
@click.prevent="fnClear()"
|
||||||
|
:disabled="state.selectedRowKeys.length <= 0"
|
||||||
|
>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<DeleteOutlined />
|
<DeleteOutlined />
|
||||||
</template>
|
</template>
|
||||||
@@ -887,7 +904,11 @@ onMounted(() => {
|
|||||||
{{ t('views.faultManage.activeAlarm.disPlayFilfter') }}
|
{{ t('views.faultManage.activeAlarm.disPlayFilfter') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|
||||||
<a-button type="primary" @click.prevent="fnExportAll()">
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
@click.prevent="fnExportAll()"
|
||||||
|
:disabled="tableState.data.length <= 0"
|
||||||
|
>
|
||||||
<template #icon> <export-outlined /> </template>
|
<template #icon> <export-outlined /> </template>
|
||||||
{{ t('views.faultManage.activeAlarm.exportAll') }}
|
{{ t('views.faultManage.activeAlarm.exportAll') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
@@ -1240,12 +1261,6 @@ onMounted(() => {
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|
||||||
|
|||||||
@@ -651,7 +651,7 @@ onMounted(() => {
|
|||||||
<a-select
|
<a-select
|
||||||
v-model:value="queryParams.alarm_type"
|
v-model:value="queryParams.alarm_type"
|
||||||
:placeholder="t('common.selectPlease')"
|
:placeholder="t('common.selectPlease')"
|
||||||
:options="dict.activeAlarmSeverity"
|
:options="dict.activeAlarmType"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
|||||||
Reference in New Issue
Block a user