feat: 看板左右高度百分比适配
This commit is contained in:
@@ -1,71 +1,31 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref, onMounted } from 'vue';
|
import { reactive, ref, onMounted } from 'vue';
|
||||||
|
import {
|
||||||
|
cdrEventData,
|
||||||
|
cdrEventTotal,
|
||||||
|
cdrEventId,
|
||||||
|
} from '../../hooks/useCDREvent';
|
||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const newNumber = ref(1);
|
|
||||||
const dataArr = ref([
|
|
||||||
{
|
|
||||||
recordType: 'CALL',
|
|
||||||
seqNumber: 1,
|
|
||||||
callReference: 'X1gcbQ8zT@10.10.91.252',
|
|
||||||
callerParty: '12307551241',
|
|
||||||
calledParty: '12307550064',
|
|
||||||
serviceResult: 'ok',
|
|
||||||
seizureTime: 1705542348,
|
|
||||||
answerTime: 1705542356,
|
|
||||||
releaseTime: 1705542378,
|
|
||||||
callDuration: 22,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
setInterval(function () {
|
|
||||||
const random = Math.ceil(Math.random() * 1000);
|
|
||||||
const time = Math.ceil(Date.now() / 1000);
|
|
||||||
newNumber.value = time;
|
|
||||||
dataArr.value.unshift({
|
|
||||||
recordType: 'CALL',
|
|
||||||
seqNumber: time,
|
|
||||||
callReference: `X${random}Q8zT@10${random}.252`,
|
|
||||||
callerParty: `1230755${random}`,
|
|
||||||
calledParty: `${random}075064`,
|
|
||||||
serviceResult: random > 500 ? 'ok' : 'fail',
|
|
||||||
seizureTime: time,
|
|
||||||
answerTime: time,
|
|
||||||
releaseTime: time - random,
|
|
||||||
callDuration: 22,
|
|
||||||
});
|
|
||||||
if (dataArr.value.length > 50) {
|
|
||||||
dataArr.value.splice(50);
|
|
||||||
}
|
|
||||||
}, 2000);
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="cdr" style="display: block">
|
<div class="cdr" style="display: block">
|
||||||
<div class="cdr-head">
|
<div class="cdr-head">
|
||||||
<span class="col">号码</span>
|
<span class="col">call</span>
|
||||||
<span class="col">行为</span>
|
<span class="col">行为</span>
|
||||||
<span class="col-w">描述</span>
|
<span class="col-w">信息</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="cdr-marquee-view">
|
<div class="cdr-marquee-view">
|
||||||
<div
|
<div
|
||||||
class="row"
|
class="row"
|
||||||
:class="{ 'row-new': item.seqNumber === newNumber }"
|
:class="{ 'row-new': item.id === cdrEventId }"
|
||||||
v-for="item in dataArr"
|
v-for="item in cdrEventData"
|
||||||
:key="item.seqNumber"
|
:key="item.id"
|
||||||
>
|
>
|
||||||
<span class="col">{{ item.callReference }}</span>
|
<span class="col" :title="item.call">{{ item.call }}</span>
|
||||||
<span class="col">{{ item.recordType }}</span>
|
<span class="col" :title="item.type">{{ item.type }}</span>
|
||||||
<span class="col-w"
|
<span class="col-w" :title="item.msg">{{ item.msg }}</span>
|
||||||
>[{{ item.serviceResult }}]
|
|
||||||
{{ item.callerParty }}
|
|
||||||
->
|
|
||||||
{{ item.calledParty }}
|
|
||||||
# {{ item.callDuration }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -73,21 +33,26 @@ onMounted(() => {
|
|||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.cdr {
|
.cdr {
|
||||||
|
height: 88%;
|
||||||
|
|
||||||
&-head {
|
&-head {
|
||||||
background: rgba(255, 255, 255, 0.1);
|
background: rgba(255, 255, 255, 0.1);
|
||||||
font-size: 0.583rem;
|
font-size: 0.583rem;
|
||||||
padding: 0.5rem 1.5rem;
|
padding: 0.5rem 1.5rem;
|
||||||
color: #68d8fe;
|
color: #68d8fe;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: flex-start;
|
||||||
line-height: 1.05;
|
line-height: 1.05;
|
||||||
& .col {
|
& .col {
|
||||||
width: 3.2rem;
|
min-width: 3.2rem;
|
||||||
|
width: 30%;
|
||||||
|
margin-right: 1rem;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
&-w {
|
&-w {
|
||||||
width: 8.4rem;
|
min-width: 8.4rem;
|
||||||
|
width: 60%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,7 +60,7 @@ onMounted(() => {
|
|||||||
&-marquee-view {
|
&-marquee-view {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
height: 70%;
|
height: 92%;
|
||||||
|
|
||||||
/* 修改滚动条的样式 */
|
/* 修改滚动条的样式 */
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
@@ -115,16 +80,18 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
& .row {
|
& .row {
|
||||||
line-height: 1.05;
|
line-height: 1.5;
|
||||||
padding: 0.5rem 1.5rem;
|
padding: 0 1.5rem;
|
||||||
color: #61a8ff;
|
color: #61a8ff;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
cursor: context-menu;
|
||||||
&-new {
|
&-new {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
animation: backInRight 0.3s alternate;
|
animation: backInRight 0.3s alternate;
|
||||||
|
font-size: 0.95rem;
|
||||||
}
|
}
|
||||||
@keyframes backInRight {
|
@keyframes backInRight {
|
||||||
0% {
|
0% {
|
||||||
@@ -146,12 +113,18 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
& .col {
|
& .col {
|
||||||
width: 3.2rem;
|
min-width: 3.2rem;
|
||||||
|
width: 30%;
|
||||||
|
margin-right: 1rem;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
&-w {
|
&-w {
|
||||||
width: 8.4rem;
|
min-width: 8.4rem;
|
||||||
|
width: 60%;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,24 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref, onBeforeUnmount, nextTick } from 'vue';
|
import { onMounted, ref, onBeforeUnmount, nextTick, watch } from 'vue';
|
||||||
import * as echarts from 'echarts/core';
|
import * as echarts from 'echarts/core';
|
||||||
import { TooltipComponent } from 'echarts/components';
|
import { GridComponent, GridComponentOption } from 'echarts/components';
|
||||||
import { GaugeChart } from 'echarts/charts';
|
import {
|
||||||
|
BarChart,
|
||||||
|
BarSeriesOption,
|
||||||
|
PictorialBarChart,
|
||||||
|
PictorialBarSeriesOption,
|
||||||
|
} from 'echarts/charts';
|
||||||
import { CanvasRenderer } from 'echarts/renderers';
|
import { CanvasRenderer } from 'echarts/renderers';
|
||||||
import { graphNodeClickID, graphNodeState } from '../../hooks/useTopology';
|
import { graphNodeClickID, graphNodeState } from '../../hooks/useTopology';
|
||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
import { GaugeSeriesOption } from 'echarts/types/dist/echarts';
|
import { markRaw } from 'vue';
|
||||||
import { watch } from 'vue';
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
echarts.use([TooltipComponent, GaugeChart, CanvasRenderer]);
|
echarts.use([GridComponent, BarChart, PictorialBarChart, CanvasRenderer]);
|
||||||
|
|
||||||
type EChartsOption = echarts.ComposeOption<GaugeSeriesOption>;
|
type EChartsOption = echarts.ComposeOption<
|
||||||
|
GridComponentOption | BarSeriesOption | PictorialBarSeriesOption
|
||||||
|
>;
|
||||||
|
|
||||||
/**图DOM节点实例对象 */
|
/**图DOM节点实例对象 */
|
||||||
const neResourcesDom = ref<HTMLElement | undefined>(undefined);
|
const neResourcesDom = ref<HTMLElement | undefined>(undefined);
|
||||||
@@ -20,199 +26,188 @@ const neResourcesDom = ref<HTMLElement | undefined>(undefined);
|
|||||||
/**图实例对象 */
|
/**图实例对象 */
|
||||||
const neResourcesChart = ref<any>(null);
|
const neResourcesChart = ref<any>(null);
|
||||||
|
|
||||||
const optionData: EChartsOption = {
|
// 类别
|
||||||
tooltip: {
|
const category = ref<any>([
|
||||||
formatter: '{a} <br> {b} : {c}%',
|
{
|
||||||
|
name: '系统内存',
|
||||||
|
value: 1,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: '系统CPU',
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '网元CPU',
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 数据总数
|
||||||
|
const total = 100;
|
||||||
|
|
||||||
|
/**图数据 */
|
||||||
|
const optionData: EChartsOption = {
|
||||||
|
xAxis: {
|
||||||
|
max: total,
|
||||||
|
splitLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: '1%', // 设置条形图的边距
|
||||||
|
bottom: '12%',
|
||||||
|
left: '25%',
|
||||||
|
right: '25%',
|
||||||
|
},
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
inverse: false,
|
||||||
|
data: category.value,
|
||||||
|
axisLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name: '系统内存',
|
// 内
|
||||||
type: 'gauge',
|
type: 'bar',
|
||||||
center: ['15%', '45%'],
|
barWidth: 10,
|
||||||
radius: '65%',
|
legendHoverLink: false,
|
||||||
startAngle: 90,
|
silent: true,
|
||||||
endAngle: -270,
|
|
||||||
min: 1,
|
|
||||||
max: 100,
|
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
color: '#1890ff',
|
color: function (params) {
|
||||||
},
|
// 红色
|
||||||
progress: {
|
if (+params.value >= 70) {
|
||||||
show: true,
|
return new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
||||||
width: 20,
|
{ offset: 0, color: '#fff1f0' },
|
||||||
overlap: true,
|
{ offset: 0.5, color: '#ffa39e' },
|
||||||
roundCap: true,
|
{ offset: 1, color: '#f5222d' },
|
||||||
clip: false,
|
]);
|
||||||
},
|
}
|
||||||
pointer: {
|
// 蓝色
|
||||||
show: false,
|
if (+params.value >= 30) {
|
||||||
},
|
return new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
||||||
axisLine: {
|
{ offset: 0, color: '#f0f5ff' },
|
||||||
lineStyle: {
|
{ offset: 0.5, color: '#adc6ff' },
|
||||||
width: 20,
|
{ offset: 1, color: '#2f54eb' },
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
// 绿色
|
||||||
|
return new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
||||||
|
{ offset: 0, color: '#f6ffed' },
|
||||||
|
{ offset: 0.5, color: '#b7eb8f' },
|
||||||
|
{ offset: 1, color: '#52c41a' },
|
||||||
|
]);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
axisTick: {
|
label: {
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
splitLine: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
anchor: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
show: true,
|
show: true,
|
||||||
offsetCenter: [0, '-10%'],
|
position: 'left',
|
||||||
|
formatter: '{b}: ',
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
color: '#fafafa',
|
color: '#fff',
|
||||||
},
|
},
|
||||||
detail: {
|
data: category.value,
|
||||||
valueAnimation: true,
|
z: 1,
|
||||||
width: '60%',
|
animationEasing: 'elasticOut',
|
||||||
lineHeight: 40,
|
|
||||||
borderRadius: 8,
|
|
||||||
offsetCenter: [0, '30%'],
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: 'bolder',
|
|
||||||
formatter: '{value}%',
|
|
||||||
color: 'inherit',
|
|
||||||
},
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
name: '系统内存',
|
|
||||||
value: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '系统CPU',
|
// 分隔
|
||||||
type: 'gauge',
|
type: 'pictorialBar',
|
||||||
center: ['50%', '45%'],
|
|
||||||
radius: '65%',
|
|
||||||
startAngle: 90,
|
|
||||||
endAngle: -270,
|
|
||||||
min: 1,
|
|
||||||
max: 100,
|
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
color: '#1890ff',
|
color: '#0a3ca0',
|
||||||
},
|
},
|
||||||
progress: {
|
symbolRepeat: 'fixed',
|
||||||
show: true,
|
symbolMargin: 6,
|
||||||
width: 20,
|
symbol: 'rect',
|
||||||
overlap: true,
|
symbolClip: true,
|
||||||
roundCap: true,
|
symbolSize: [1, 12],
|
||||||
clip: false,
|
symbolPosition: 'start',
|
||||||
},
|
symbolOffset: [0, -1],
|
||||||
pointer: {
|
symbolBoundingData: total,
|
||||||
show: false,
|
data: category.value,
|
||||||
},
|
z: 2,
|
||||||
axisLine: {
|
animationEasing: 'elasticOut',
|
||||||
lineStyle: {
|
|
||||||
width: 20,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
axisTick: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
splitLine: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
anchor: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
show: true,
|
|
||||||
offsetCenter: [0, '-10%'],
|
|
||||||
fontSize: 15,
|
|
||||||
color: '#fafafa',
|
|
||||||
},
|
|
||||||
detail: {
|
|
||||||
valueAnimation: true,
|
|
||||||
width: '60%',
|
|
||||||
lineHeight: 40,
|
|
||||||
borderRadius: 8,
|
|
||||||
offsetCenter: [0, '30%'],
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: 'bolder',
|
|
||||||
formatter: '{value}%',
|
|
||||||
color: 'inherit',
|
|
||||||
},
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
name: '系统内存',
|
|
||||||
value: 20,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '网元内存',
|
// 外边框
|
||||||
type: 'gauge',
|
type: 'pictorialBar',
|
||||||
center: ['85%', '45%'],
|
symbol: 'rect',
|
||||||
radius: '65%',
|
symbolBoundingData: total,
|
||||||
startAngle: 90,
|
|
||||||
endAngle: -270,
|
|
||||||
min: 1,
|
|
||||||
max: 100,
|
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
color: '#1890ff',
|
color: 'transparent',
|
||||||
},
|
},
|
||||||
progress: {
|
label: {
|
||||||
show: true,
|
formatter: params => {
|
||||||
width: 20,
|
var text = `{a| ${params.value}%} `;
|
||||||
overlap: true,
|
if (+params.value >= 70) {
|
||||||
roundCap: true,
|
text = `{c| ${params.value}%} `;
|
||||||
clip: false,
|
} else if (+params.value >= 30) {
|
||||||
},
|
text = `{b| ${params.value}%} `;
|
||||||
pointer: {
|
}
|
||||||
show: false,
|
return text;
|
||||||
},
|
|
||||||
axisLine: {
|
|
||||||
lineStyle: {
|
|
||||||
width: 20,
|
|
||||||
},
|
},
|
||||||
},
|
rich: {
|
||||||
axisTick: {
|
a: {
|
||||||
show: false,
|
color: '#52c41a', // 绿
|
||||||
},
|
fontSize: 16,
|
||||||
splitLine: {
|
},
|
||||||
show: false,
|
b: {
|
||||||
},
|
color: '#2f54eb', // 蓝
|
||||||
axisLabel: {
|
fontSize: 16,
|
||||||
show: false,
|
},
|
||||||
},
|
c: {
|
||||||
anchor: {
|
color: '#f5222d', // 红
|
||||||
show: false,
|
fontSize: 16,
|
||||||
},
|
},
|
||||||
title: {
|
f: {
|
||||||
show: true,
|
color: '#ffffff', // 默认
|
||||||
offsetCenter: [0, '-10%'],
|
fontSize: 16,
|
||||||
fontSize: 15,
|
},
|
||||||
color: '#fafafa',
|
|
||||||
},
|
|
||||||
detail: {
|
|
||||||
valueAnimation: true,
|
|
||||||
width: '60%',
|
|
||||||
lineHeight: 40,
|
|
||||||
borderRadius: 8,
|
|
||||||
offsetCenter: [0, '30%'],
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: 'bolder',
|
|
||||||
formatter: '{value}%',
|
|
||||||
color: 'inherit',
|
|
||||||
},
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
name: '系统内存',
|
|
||||||
value: 20,
|
|
||||||
},
|
},
|
||||||
],
|
position: 'right',
|
||||||
|
distance: 0, // 向右偏移位置
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
data: category.value,
|
||||||
|
z: 0,
|
||||||
|
animationEasing: 'elasticOut',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '外框',
|
||||||
|
type: 'bar',
|
||||||
|
barGap: '-120%', // 设置外框粗细
|
||||||
|
data: [total, total, total],
|
||||||
|
barWidth: 14,
|
||||||
|
itemStyle: {
|
||||||
|
color: 'transparent', // 填充色
|
||||||
|
borderColor: '#0a3ca0', // 边框色
|
||||||
|
borderWidth: 1, // 边框宽度
|
||||||
|
borderRadius: 1, //圆角半径
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
// 标签显示位置
|
||||||
|
show: false,
|
||||||
|
position: 'top', // insideTop 或者横向的 insideLeft
|
||||||
|
},
|
||||||
|
z: 0,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@@ -223,12 +218,14 @@ function handleRanderChart(
|
|||||||
option: EChartsOption
|
option: EChartsOption
|
||||||
) {
|
) {
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
neResourcesChart.value = echarts.init(container, 'light');
|
neResourcesChart.value = markRaw(echarts.init(container, 'light'));
|
||||||
option && neResourcesChart.value.setOption(option);
|
option && neResourcesChart.value.setOption(option);
|
||||||
|
|
||||||
// 创建 ResizeObserver 实例
|
// 创建 ResizeObserver 实例
|
||||||
var observer = new ResizeObserver(function (entries) {
|
var observer = new ResizeObserver(entries => {
|
||||||
neResourcesChart.value.resize();
|
if (neResourcesChart.value) {
|
||||||
|
neResourcesChart.value.resize();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// 监听元素大小变化
|
// 监听元素大小变化
|
||||||
observer.observe(container);
|
observer.observe(container);
|
||||||
@@ -240,75 +237,45 @@ function fnChangeData(data: any[], itemID: string) {
|
|||||||
info = data.find((item: any) => item.id === 'OMC');
|
info = data.find((item: any) => item.id === 'OMC');
|
||||||
graphNodeClickID.value = 'OMC';
|
graphNodeClickID.value = 'OMC';
|
||||||
}
|
}
|
||||||
let sysMemUsage = 0;
|
// console.log(info.id);
|
||||||
|
// console.log(info.neState.cpu.nfCpuUsage);
|
||||||
|
// console.log(info.neState.cpu.sysCpuUsage);
|
||||||
|
// console.log(info.neState.mem.sysMemUsage);
|
||||||
let sysCpuUsage = 0;
|
let sysCpuUsage = 0;
|
||||||
let nfCpuUsage = 0;
|
let nfCpuUsage = 0;
|
||||||
if (info.neState.cpu) {
|
if (info.neState.cpu) {
|
||||||
nfCpuUsage = info.neState.cpu.nfCpuUsage;
|
nfCpuUsage = info.neState.cpu.nfCpuUsage;
|
||||||
if (nfCpuUsage > 1000) {
|
if (nfCpuUsage > 100) {
|
||||||
nfCpuUsage = +(info.neState.cpu.nfCpuUsage / 100).toFixed(2);
|
nfCpuUsage = +(info.neState.cpu.nfCpuUsage / 100).toFixed(2);
|
||||||
}
|
}
|
||||||
sysCpuUsage = info.neState.cpu.sysCpuUsage;
|
sysCpuUsage = info.neState.cpu.sysCpuUsage;
|
||||||
if (nfCpuUsage > 1000) {
|
if (sysCpuUsage > 100) {
|
||||||
sysCpuUsage = +(info.neState.cpu.sysCpuUsage / 100).toFixed(2);
|
sysCpuUsage = +(info.neState.cpu.sysCpuUsage / 100).toFixed(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let sysMemUsage = 0;
|
||||||
if (info.neState.mem) {
|
if (info.neState.mem) {
|
||||||
let men = info.neState.mem.sysMemUsage;
|
let men = info.neState.mem.sysMemUsage;
|
||||||
if (men > 1000) {
|
if (men > 100) {
|
||||||
men = +(men / 100).toFixed(2);
|
men = +(men / 100).toFixed(2);
|
||||||
}
|
}
|
||||||
sysMemUsage = men;
|
sysMemUsage = men;
|
||||||
}
|
}
|
||||||
|
|
||||||
function colorStyle(v: number): string {
|
category.value[0].value = sysMemUsage;
|
||||||
let color = '#1890ff';
|
category.value[1].value = sysCpuUsage;
|
||||||
if (v < 30) {
|
category.value[2].value = nfCpuUsage;
|
||||||
color = '#73d13d';
|
|
||||||
}
|
|
||||||
if (v > 60) {
|
|
||||||
color = '#ff4d4f';
|
|
||||||
}
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
neResourcesChart.value.setOption({
|
neResourcesChart.value.setOption({
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
data: [
|
data: category.value,
|
||||||
{
|
|
||||||
name: '系统内存',
|
|
||||||
value: sysMemUsage,
|
|
||||||
itemStyle: {
|
|
||||||
color: colorStyle(sysMemUsage),
|
|
||||||
shadowColor: colorStyle(sysMemUsage),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
data: [
|
data: category.value,
|
||||||
{
|
|
||||||
name: '系统CPU',
|
|
||||||
value: sysCpuUsage,
|
|
||||||
itemStyle: {
|
|
||||||
color: colorStyle(sysCpuUsage),
|
|
||||||
shadowColor: colorStyle(sysCpuUsage),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
data: [
|
data: category.value,
|
||||||
{
|
|
||||||
name: '网元CPU',
|
|
||||||
value: nfCpuUsage,
|
|
||||||
itemStyle: {
|
|
||||||
color: colorStyle(nfCpuUsage),
|
|
||||||
shadowColor: colorStyle(nfCpuUsage),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@@ -330,43 +297,30 @@ watch(graphNodeClickID, v => {
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// setInterval(function () {
|
// setInterval(function () {
|
||||||
|
// var ndata = [
|
||||||
|
// {
|
||||||
|
// name: '系统内存',
|
||||||
|
// value: Math.round(Math.random() * 100),
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: '系统CPU',
|
||||||
|
// value: Math.round(Math.random() * 100),
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: '网元CPU',
|
||||||
|
// value: Math.round(Math.random() * 100),
|
||||||
|
// },
|
||||||
|
// ];
|
||||||
// neResourcesChart.value.setOption({
|
// neResourcesChart.value.setOption({
|
||||||
// series: [
|
// series: [
|
||||||
// {
|
// {
|
||||||
// data: [
|
// data: ndata,
|
||||||
// {
|
|
||||||
// name: '系统内存',
|
|
||||||
// value: sysMemUsage,
|
|
||||||
// itemStyle: {
|
|
||||||
// color: colorStyle(sysMemUsage),
|
|
||||||
// shadowColor: colorStyle(sysMemUsage),
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// },
|
// },
|
||||||
// {
|
// {
|
||||||
// data: [
|
// data: ndata,
|
||||||
// {
|
|
||||||
// name: '系统CPU',
|
|
||||||
// value: sysCpuUsage,
|
|
||||||
// itemStyle: {
|
|
||||||
// color: colorStyle(sysCpuUsage),
|
|
||||||
// shadowColor: colorStyle(sysCpuUsage),
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// },
|
// },
|
||||||
// {
|
// {
|
||||||
// data: [
|
// data: ndata,
|
||||||
// {
|
|
||||||
// name: '网元CPU',
|
|
||||||
// value: nfCpuUsage,
|
|
||||||
// itemStyle: {
|
|
||||||
// color: colorStyle(nfCpuUsage),
|
|
||||||
// shadowColor: colorStyle(nfCpuUsage),
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// },
|
// },
|
||||||
// ],
|
// ],
|
||||||
// });
|
// });
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ onMounted(() => {});
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="cdr" style="display: block">
|
<div class="ue" style="display: block">
|
||||||
<div class="cdr-head">
|
<div class="ue-head">
|
||||||
<span class="col">IMSI</span>
|
<span class="col">IMSI</span>
|
||||||
<span class="col">行为</span>
|
<span class="col">行为</span>
|
||||||
<span class="col-w">信息</span>
|
<span class="col-w">信息</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="cdr-marquee-view">
|
<div class="ue-marquee-view">
|
||||||
<div
|
<div
|
||||||
class="row"
|
class="row"
|
||||||
:class="{ 'row-new': item.id === ueEventId }"
|
:class="{ 'row-new': item.id === ueEventId }"
|
||||||
@@ -30,22 +30,27 @@ onMounted(() => {});
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.cdr {
|
.ue {
|
||||||
|
height: 88%;
|
||||||
|
|
||||||
&-head {
|
&-head {
|
||||||
background: rgba(255, 255, 255, 0.1);
|
background: rgba(255, 255, 255, 0.1);
|
||||||
font-size: 0.583rem;
|
font-size: 0.583rem;
|
||||||
padding: 0.5rem 1.5rem;
|
padding: 0.5rem 1.5rem;
|
||||||
color: #68d8fe;
|
color: #68d8fe;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: flex-start;
|
||||||
line-height: 1.05;
|
line-height: 1.05;
|
||||||
& .col {
|
& .col {
|
||||||
width: 3.2rem;
|
min-width: 3.2rem;
|
||||||
|
width: 30%;
|
||||||
|
margin-right: 1rem;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
&-w {
|
&-w {
|
||||||
width: 8.4rem;
|
min-width: 8.4rem;
|
||||||
|
width: 60%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,7 +58,7 @@ onMounted(() => {});
|
|||||||
&-marquee-view {
|
&-marquee-view {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
height: 70%;
|
height: 92%;
|
||||||
|
|
||||||
/* 修改滚动条的样式 */
|
/* 修改滚动条的样式 */
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
@@ -73,16 +78,18 @@ onMounted(() => {});
|
|||||||
}
|
}
|
||||||
|
|
||||||
& .row {
|
& .row {
|
||||||
line-height: 1.05;
|
line-height: 1.5;
|
||||||
padding: 0.5rem 1.5rem;
|
padding: 0 1.5rem;
|
||||||
color: #61a8ff;
|
color: #61a8ff;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
cursor: context-menu;
|
||||||
&-new {
|
&-new {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
animation: backInRight 0.3s alternate;
|
animation: backInRight 0.3s alternate;
|
||||||
|
font-size: 0.95rem;
|
||||||
}
|
}
|
||||||
@keyframes backInRight {
|
@keyframes backInRight {
|
||||||
0% {
|
0% {
|
||||||
@@ -104,12 +111,18 @@ onMounted(() => {});
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
& .col {
|
& .col {
|
||||||
width: 3.2rem;
|
min-width: 3.2rem;
|
||||||
|
width: 30%;
|
||||||
|
margin-right: 1rem;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
&-w {
|
&-w {
|
||||||
width: 8.4rem;
|
min-width: 8.4rem;
|
||||||
|
width: 60%;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
padding: 5rem 0.833rem 0;
|
padding: 5rem 0.833rem 0;
|
||||||
line-height: 1.15;
|
line-height: 1.15;
|
||||||
background-color: #101129;
|
background-color: #101129;
|
||||||
|
height: 100vh;
|
||||||
|
margin-bottom: -20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.column {
|
.column {
|
||||||
@@ -113,8 +115,8 @@
|
|||||||
|
|
||||||
/* 本月告警统计 */
|
/* 本月告警统计 */
|
||||||
.alarmType {
|
.alarmType {
|
||||||
height: 16rem;
|
min-height: 13rem;
|
||||||
display: flex;
|
height: 25%;
|
||||||
}
|
}
|
||||||
.alarmType .chart {
|
.alarmType .chart {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -122,13 +124,12 @@
|
|||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* cdr会话监控 */
|
||||||
/* 告警趋势 */
|
.cdrEvent {
|
||||||
.alarmDay {
|
min-height: 22rem;
|
||||||
height: 22rem;
|
height: 60%;
|
||||||
display: flex;
|
|
||||||
}
|
}
|
||||||
.alarmDay .inner .chart {
|
.cdrEvent .inner .chart {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
@@ -136,7 +137,8 @@
|
|||||||
|
|
||||||
/* 总流量 */
|
/* 总流量 */
|
||||||
.totalFlow {
|
.totalFlow {
|
||||||
height: 6.167rem;
|
min-height: 6.167rem;
|
||||||
|
height: 12%;
|
||||||
}
|
}
|
||||||
.totalFlow .inner .filter {
|
.totalFlow .inner .filter {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -179,8 +181,8 @@
|
|||||||
|
|
||||||
/* 资源情况 */
|
/* 资源情况 */
|
||||||
.resources {
|
.resources {
|
||||||
height: 16rem;
|
min-height: 13rem;
|
||||||
display: flex;
|
height: 25%;
|
||||||
}
|
}
|
||||||
.resources .inner .chart {
|
.resources .inner .chart {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -188,12 +190,12 @@
|
|||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 会话监控 */
|
/* ue会话监控 */
|
||||||
.cdr {
|
.ueEvent {
|
||||||
height: 22rem;
|
min-height: 22rem;
|
||||||
display: flex;
|
height: 60%;
|
||||||
}
|
}
|
||||||
.cdr .inner .chart {
|
.ueEvent .inner .chart {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
|
|||||||
10
src/views/dashboard/overview/hooks/useCDREvent.ts
Normal file
10
src/views/dashboard/overview/hooks/useCDREvent.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
/**事件数据 */
|
||||||
|
export const cdrEventData = ref<Record<string, any>[]>([]);
|
||||||
|
|
||||||
|
/**事件总量 */
|
||||||
|
export const cdrEventTotal = ref<number>(0);
|
||||||
|
|
||||||
|
/**事件推送id */
|
||||||
|
export const cdrEventId = ref<string>('');
|
||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
import { OptionsType, WS } from '@/plugins/ws-websocket';
|
import { OptionsType, WS } from '@/plugins/ws-websocket';
|
||||||
import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue';
|
import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue';
|
||||||
import { ueEventData, ueEventId, ueEventTotal } from './useUEEvent';
|
import { ueEventData, ueEventId, ueEventTotal } from './useUEEvent';
|
||||||
|
import { cdrEventData, cdrEventTotal, cdrEventId } from './useCDREvent';
|
||||||
|
|
||||||
/**websocket连接 */
|
/**websocket连接 */
|
||||||
export default function useWS() {
|
export default function useWS() {
|
||||||
@@ -15,6 +16,36 @@ export default function useWS() {
|
|||||||
ws.send(data);
|
ws.send(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function wsInitData() {
|
||||||
|
// cdrEvent CDR会话事件
|
||||||
|
ws.send({
|
||||||
|
requestId: '1005',
|
||||||
|
type: 'cdr',
|
||||||
|
data: {
|
||||||
|
neType: 'IMS',
|
||||||
|
neId: '001',
|
||||||
|
sortField: 'timestamp',
|
||||||
|
sortOrder: 'desc',
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 50,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// ueEvent UE会话事件
|
||||||
|
ws.send({
|
||||||
|
requestId: '1010',
|
||||||
|
type: 'ue',
|
||||||
|
data: {
|
||||||
|
neType: 'AMF',
|
||||||
|
neId: '001',
|
||||||
|
sortField: 'timestamp',
|
||||||
|
sortOrder: 'desc',
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 50,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**接收数据后回调 */
|
/**接收数据后回调 */
|
||||||
function wsMessage(res: Record<string, any>) {
|
function wsMessage(res: Record<string, any>) {
|
||||||
console.log(res);
|
console.log(res);
|
||||||
@@ -42,6 +73,23 @@ export default function useWS() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
//cdrEvent CDR会话事件
|
||||||
|
case '1005':
|
||||||
|
if (Array.isArray(data.rows)) {
|
||||||
|
cdrEventTotal.value = data.total;
|
||||||
|
const evDataArr: Record<string, any>[] = [];
|
||||||
|
for (const item of data.rows) {
|
||||||
|
const v = cdrEventParse(item);
|
||||||
|
if (v) {
|
||||||
|
evDataArr.push(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cdrEventData.value = evDataArr;
|
||||||
|
if (evDataArr.length > 0) {
|
||||||
|
cdrEventId.value = evDataArr[0].id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data?.groupId) {
|
if (!data?.groupId) {
|
||||||
@@ -59,30 +107,25 @@ export default function useWS() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
// cdrEvent CDR会话事件
|
||||||
|
case '1005':
|
||||||
|
if (data.data) {
|
||||||
|
const v = cdrEventParse(data.data);
|
||||||
|
if (v) {
|
||||||
|
cdrEventData.value.unshift(v);
|
||||||
|
cdrEventId.value = v.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function wsInitData() {
|
|
||||||
ws.send({
|
|
||||||
requestId: '1010',
|
|
||||||
type: 'ue',
|
|
||||||
data: {
|
|
||||||
neType: 'AMF',
|
|
||||||
neId: '001',
|
|
||||||
sortField: 'timestamp',
|
|
||||||
sortOrder: 'desc',
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 50,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**ueEvent UE会话事件 数据解析 */
|
/**ueEvent UE会话事件 数据解析 */
|
||||||
function ueEventParse(item: Record<string, any>) {
|
function ueEventParse(item: Record<string, any>) {
|
||||||
let evData: Record<string, any> = item.eventJSON;
|
let evData: Record<string, any> = item.eventJSON;
|
||||||
if (typeof evData === 'string') {
|
if (typeof evData === 'string') {
|
||||||
try {
|
try {
|
||||||
evData = JSON.parse(item.eventJSON);
|
evData = JSON.parse(evData);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return false;
|
return false;
|
||||||
@@ -120,6 +163,29 @@ export default function useWS() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**cdrEvent CDR会话事件 数据解析 */
|
||||||
|
function cdrEventParse(item: Record<string, any>) {
|
||||||
|
let evData: Record<string, any> = item.cdrJSON || item.CDR;
|
||||||
|
if (typeof evData === 'string') {
|
||||||
|
try {
|
||||||
|
evData = JSON.parse(evData);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (evData.recordType === 'CALL') {
|
||||||
|
return {
|
||||||
|
id: item.id || item.timestamp,
|
||||||
|
type: evData.recordType,
|
||||||
|
time: evData.callDuration,
|
||||||
|
call: evData.callReference,
|
||||||
|
msg: `${evData.calledParty} -> ${evData.callerParty}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**接收数据后回调 */
|
/**接收数据后回调 */
|
||||||
function wsError(ev: any) {
|
function wsError(ev: any) {
|
||||||
// 接收数据后回调
|
// 接收数据后回调
|
||||||
@@ -133,8 +199,9 @@ export default function useWS() {
|
|||||||
/**订阅通道组
|
/**订阅通道组
|
||||||
*
|
*
|
||||||
* UE会话事件-AMF (GroupID:1010)
|
* UE会话事件-AMF (GroupID:1010)
|
||||||
|
* CDR会话事件-IMS (GroupID:1005)
|
||||||
*/
|
*/
|
||||||
subGroupID: '1010',
|
subGroupID: '1010,1005',
|
||||||
},
|
},
|
||||||
onmessage: wsMessage,
|
onmessage: wsMessage,
|
||||||
onerror: wsError,
|
onerror: wsError,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ 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 UEEvent from './components/UEEvent/index.vue';
|
import UEEvent from './components/UEEvent/index.vue';
|
||||||
|
import CDREvent from './components/CDREvent/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';
|
||||||
@@ -136,7 +137,7 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--本月告警统计-->
|
<!--告警统计-->
|
||||||
<div class="alarmType panel">
|
<div class="alarmType panel">
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<h3>告警统计</h3>
|
<h3>告警统计</h3>
|
||||||
@@ -146,12 +147,14 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 告警趋势 -->
|
<!-- CDR会话 -->
|
||||||
<div class="alarmDay panel">
|
<div class="cdrEvent panel">
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<h3>告警趋势</h3>
|
<h3>
|
||||||
|
<WhatsAppOutlined style="color: #68d8fe" /> CDR会话
|
||||||
|
</h3>
|
||||||
<div class="chart">
|
<div class="chart">
|
||||||
<AlarnDayLine />
|
<CDREvent />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -219,11 +222,11 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 会话监控 -->
|
<!-- UE会话 -->
|
||||||
<div class="cdr panel">
|
<div class="ueEvent panel">
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<h3>
|
<h3>
|
||||||
<WhatsAppOutlined style="color: #d93f36" /> 会话监控
|
<WhatsAppOutlined style="color: #68d8fe" /> UE会话
|
||||||
</h3>
|
</h3>
|
||||||
<div class="chart">
|
<div class="chart">
|
||||||
<UEEvent />
|
<UEEvent />
|
||||||
|
|||||||
Reference in New Issue
Block a user