feat:告警模块优化
This commit is contained in:
@@ -131,7 +131,7 @@ function initPicture() {
|
|||||||
{
|
{
|
||||||
text: 'Top3',
|
text: 'Top3',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
top: '36%',
|
top: '48%',
|
||||||
textStyle: {
|
textStyle: {
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
@@ -144,19 +144,34 @@ function initPicture() {
|
|||||||
top: '5%',
|
top: '5%',
|
||||||
left: '20%',
|
left: '20%',
|
||||||
right: '10%',
|
right: '10%',
|
||||||
height: '35%'
|
height: '38%'
|
||||||
},
|
},
|
||||||
{ // Top3
|
{ // Top3
|
||||||
top: '50%',
|
top: '58%',
|
||||||
left: '20%',
|
left: '20%',
|
||||||
right: '10%',
|
right: '10%',
|
||||||
height: '30%'
|
height: '32%'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
axisPointer: { type: 'shadow' },
|
axisPointer: { type: 'shadow' },
|
||||||
formatter: '{b} : {c}',
|
formatter: function(params: any) {
|
||||||
|
if (Array.isArray(params) && params.length > 0) {
|
||||||
|
const param = params[0];
|
||||||
|
// 获取真实值而不是0.1的占位值
|
||||||
|
let realValue = 0;
|
||||||
|
if (param.seriesIndex === 0) {
|
||||||
|
// 第一个系列(告警类型)
|
||||||
|
realValue = alarmTypeType.value[param.dataIndex]?.value || 0;
|
||||||
|
} else if (param.seriesIndex === 1) {
|
||||||
|
// 第二个系列(Top3)
|
||||||
|
realValue = alarmTypeTypeTop.value[param.dataIndex]?.value || 0;
|
||||||
|
}
|
||||||
|
return `${param.name}: ${realValue}`;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
},
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
show: false
|
show: false
|
||||||
@@ -178,7 +193,12 @@ function initPicture() {
|
|||||||
type: 'category',
|
type: 'category',
|
||||||
gridIndex: 0,
|
gridIndex: 0,
|
||||||
data: alarmTypeType.value.map((item: any) => item.name),
|
data: alarmTypeType.value.map((item: any) => item.name),
|
||||||
axisLabel: { color: '#fff', fontSize: 14,fontWeight: 'bold' },
|
axisLabel: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
interval: 0 // 确保显示所有标签
|
||||||
|
},
|
||||||
axisLine: { show: false },
|
axisLine: { show: false },
|
||||||
axisTick: { show: false },
|
axisTick: { show: false },
|
||||||
inverse: true
|
inverse: true
|
||||||
@@ -187,7 +207,12 @@ function initPicture() {
|
|||||||
type: 'category',
|
type: 'category',
|
||||||
gridIndex: 1,
|
gridIndex: 1,
|
||||||
data: alarmTypeTypeTop.value.map((item: any) => item.name),
|
data: alarmTypeTypeTop.value.map((item: any) => item.name),
|
||||||
axisLabel: { color: '#fff', fontSize: 14,fontWeight: 'bold' },
|
axisLabel: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
interval: 0 // 确保显示所有标签
|
||||||
|
},
|
||||||
axisLine: { show: false },
|
axisLine: { show: false },
|
||||||
axisTick: { show: false },
|
axisTick: { show: false },
|
||||||
inverse: true
|
inverse: true
|
||||||
@@ -199,10 +224,15 @@ function initPicture() {
|
|||||||
type: 'bar',
|
type: 'bar',
|
||||||
xAxisIndex: 0,
|
xAxisIndex: 0,
|
||||||
yAxisIndex: 0,
|
yAxisIndex: 0,
|
||||||
barWidth: 18,
|
barWidth: 16,
|
||||||
|
barCategoryGap: '20%', // 添加柱状图间隙
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
borderRadius: [0, 8, 8, 0],
|
borderRadius: [0, 8, 8, 0],
|
||||||
color: function (params: any) {
|
color: function (params: any) {
|
||||||
|
// 如果值为0,显示透明背景但有边框效果
|
||||||
|
if (params.value === 0.1) {
|
||||||
|
return 'rgba(0,0,0,0.1)';
|
||||||
|
}
|
||||||
// 渐变色
|
// 渐变色
|
||||||
const colorArr = [
|
const colorArr = [
|
||||||
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
||||||
@@ -223,20 +253,23 @@ function initPicture() {
|
|||||||
])
|
])
|
||||||
];
|
];
|
||||||
return colorArr[params.dataIndex] || colorArr[3];
|
return colorArr[params.dataIndex] || colorArr[3];
|
||||||
}
|
},
|
||||||
|
borderColor: '#666',
|
||||||
|
borderWidth: 1
|
||||||
},
|
},
|
||||||
label: {
|
label: {
|
||||||
show: true,
|
show: true,
|
||||||
position: 'right',
|
position: 'right',
|
||||||
color: '#fff', //淡蓝色
|
color: '#fff',
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
fontSize: 16,
|
fontSize: 14,
|
||||||
formatter: (params: any) => {
|
formatter: (params: any) => {
|
||||||
if (!params.value) return '';
|
// 如果是最小值0.1,显示为0
|
||||||
return `${params.value}`;
|
const realValue = alarmTypeType.value[params.dataIndex]?.value || 0;
|
||||||
|
return `${realValue}`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: alarmTypeType.value.map((item: any) => item.value),
|
data: alarmTypeType.value.map((item: any) => Math.max(item.value || 0, 0.1)),
|
||||||
zlevel: 2
|
zlevel: 2
|
||||||
},
|
},
|
||||||
// Top3横向柱状图
|
// Top3横向柱状图
|
||||||
@@ -245,24 +278,37 @@ function initPicture() {
|
|||||||
type: 'bar',
|
type: 'bar',
|
||||||
xAxisIndex: 1,
|
xAxisIndex: 1,
|
||||||
yAxisIndex: 1,
|
yAxisIndex: 1,
|
||||||
barWidth: 18,
|
barWidth: 16,
|
||||||
|
barCategoryGap: '20%', // 添加柱状图间隙
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
borderRadius: [0, 20, 20, 0], // 圆角(左上、右上、右下、左下)
|
borderRadius: [0, 20, 20, 0],
|
||||||
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
color: function (params: any) {
|
||||||
{ offset: 0, color: '#f0f5ff' },
|
// 如果值为0,显示透明背景但有边框效果
|
||||||
{ offset: 0.5, color: '#adc6ff' },
|
if (params.value === 0 || params.value === 0.1) {
|
||||||
{ offset: 1, color: '#2f54eb' },
|
return 'rgba(0,0,0,0.1)';
|
||||||
]), // 渐变
|
}
|
||||||
|
return new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
||||||
|
{ offset: 0, color: '#f0f5ff' },
|
||||||
|
{ offset: 0.5, color: '#adc6ff' },
|
||||||
|
{ offset: 1, color: '#2f54eb' },
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
borderColor: '#666',
|
||||||
|
borderWidth: 1
|
||||||
},
|
},
|
||||||
label: {
|
label: {
|
||||||
show: true,
|
show: true,
|
||||||
position: 'right',
|
position: 'right',
|
||||||
color: '#fff', //淡蓝色
|
color: '#fff',
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
fontSize: 16,
|
fontSize: 14,
|
||||||
formatter: '{c}'
|
formatter: (params: any) => {
|
||||||
|
// 如果是最小值0.1,显示为0
|
||||||
|
const realValue = alarmTypeTypeTop.value[params.dataIndex]?.value || 0;
|
||||||
|
return `${realValue}`;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data: alarmTypeTypeTop.value.map((item: any) => item.value),
|
data: alarmTypeTypeTop.value.map((item: any) => Math.max(item.value || 0, 0.1)),
|
||||||
zlevel: 1
|
zlevel: 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
-webkit-background-size: cover;
|
-webkit-background-size: cover;
|
||||||
}
|
}
|
||||||
.column {
|
.column {
|
||||||
flex: 3;
|
flex: 2;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
display: none; /* 隐藏所有角框 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 左上角L形 - 相对于inner的实际边界 */
|
/* 左上角L形 - 相对于inner的实际边界 */
|
||||||
@@ -75,6 +76,7 @@
|
|||||||
border-right: 3px solid #4c9bfd;
|
border-right: 3px solid #4c9bfd;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
display: none; /* 隐藏所有角框 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 左下角L形 - 相对于inner的实际边界 */
|
/* 左下角L形 - 相对于inner的实际边界 */
|
||||||
@@ -89,6 +91,7 @@
|
|||||||
border-left: 3px solid #4c9bfd;
|
border-left: 3px solid #4c9bfd;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
display: none; /* 隐藏所有角框 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 为base模块调整角框显示 */
|
/* 为base模块调整角框显示 */
|
||||||
@@ -111,17 +114,23 @@
|
|||||||
right: -1.583rem;
|
right: -1.583rem;
|
||||||
bottom: -0.875rem;
|
bottom: -0.875rem;
|
||||||
left: -5.5rem;
|
left: -5.5rem;
|
||||||
padding: 1rem 1.5rem;
|
padding: 1rem 0.3rem;
|
||||||
}
|
}
|
||||||
.panel h3 {
|
.panel h3 {
|
||||||
font-size: 0.833rem;
|
font-size: 0.833rem;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
background: rgba(76, 155, 253, 0.1); /* 为所有模块标题添加淡蓝色背景 */
|
||||||
|
padding: 0.5rem 1.2rem;
|
||||||
|
border-radius: 0.7rem 0.7rem 0 0;
|
||||||
|
margin: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.leftright {
|
.leftright {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 2.5rem;
|
min-height: 2.5rem;
|
||||||
/*background: url(../images/title.png) no-repeat center center;*/
|
/*background: url(../images/title.png) no-repeat center center;*/
|
||||||
|
background: rgba(76, 155, 253, 0.1); /* 添加淡蓝色背景 */
|
||||||
background-size: 100%;
|
background-size: 100%;
|
||||||
color: #4c9bfd;
|
color: #4c9bfd;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -150,6 +159,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 2.5rem;
|
min-height: 2.5rem;
|
||||||
/*background: url(../images/title.png) no-repeat center center;*/
|
/*background: url(../images/title.png) no-repeat center center;*/
|
||||||
|
background: rgba(76, 155, 253, 0.1); /* 添加淡蓝色背景 */
|
||||||
background-size: 90%;
|
background-size: 90%;
|
||||||
color: #4c9bfd;
|
color: #4c9bfd;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -225,6 +235,11 @@
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
|
background: rgba(76, 155, 253, 0.1); /* 为网络拓扑模块标题添加淡蓝色背景 */
|
||||||
|
padding: 0.5rem 1.2rem;
|
||||||
|
border-radius: 0.7rem 0.7rem 0 0;
|
||||||
|
margin: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.topology .inner h3 .normal {
|
.topology .inner h3 .normal {
|
||||||
color: #52c41a;
|
color: #52c41a;
|
||||||
@@ -238,7 +253,7 @@
|
|||||||
.topology .inner .chart {
|
.topology .inner .chart {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin-top: 1rem;
|
margin-top: 0.1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 概览区域 */
|
/* 概览区域 */
|
||||||
@@ -318,6 +333,8 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
box-sizing: border-box;/*不知道为啥没生效*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 流量统计 */
|
/* 流量统计 */
|
||||||
@@ -328,6 +345,11 @@
|
|||||||
.upfFlowTotal1 .inner h3 {
|
.upfFlowTotal1 .inner h3 {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
background: rgba(76, 155, 253, 0.1); /* 为流量统计模块标题添加淡蓝色背景 */
|
||||||
|
padding: 0.5rem 1.2rem;
|
||||||
|
border-radius: 0.7rem 0.7rem 0 0;
|
||||||
|
margin: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.upfFlowTotal1 .inner h3 .filter {
|
.upfFlowTotal1 .inner h3 .filter {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -387,6 +409,11 @@
|
|||||||
.upfFlowTotal .inner h3 {
|
.upfFlowTotal .inner h3 {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
background: rgba(76, 155, 253, 0.1); /* 为流量统计模块标题添加淡蓝色背景 */
|
||||||
|
padding: 0.5rem 1.2rem;
|
||||||
|
border-radius: 0.7rem 0.7rem 0 0;
|
||||||
|
margin: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.upfFlowTotal .inner h3 .filter {
|
.upfFlowTotal .inner h3 .filter {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -445,7 +472,7 @@
|
|||||||
.resources .inner .chart {
|
.resources .inner .chart {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin-top: 1rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -459,6 +486,15 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 为base模块的第二个模块(4G部分)添加标题样式 */
|
||||||
|
.skim.panel.base:not(:first-of-type) h3 {
|
||||||
|
background: transparent; /* 移除背景,避免阴影问题 */
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
min-height: 0;
|
||||||
|
display: none; /* 完全隐藏空的h3元素 */
|
||||||
|
}
|
||||||
|
|
||||||
/* 跳转鼠标悬浮 */
|
/* 跳转鼠标悬浮 */
|
||||||
.toRouter:hover {
|
.toRouter:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|||||||
@@ -127,22 +127,15 @@ async function fnGetSkim() {
|
|||||||
let tempEnbSumNum = 0;
|
let tempEnbSumNum = 0;
|
||||||
|
|
||||||
const neHandlers = new Map([
|
const neHandlers = new Map([
|
||||||
// [
|
|
||||||
// 'UDM',
|
|
||||||
// {
|
|
||||||
// request: (neId: string) =>
|
|
||||||
// listUDMSub({ neId: neId, pageNum: 1, pageSize: 1 }),
|
|
||||||
// process: (res: any) =>
|
|
||||||
// res.code === RESULT_CODE_SUCCESS &&
|
|
||||||
// (skimState.udmSubNum += res.total),
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
[
|
[
|
||||||
'UDM',
|
'UDM',
|
||||||
{
|
{
|
||||||
request: (neId: string) => listUDMSub({ neId: neId, pageNum: 1, pageSize: 1 }),
|
request: (neId: string) => listUDMSub({ neId: neId, pageNum: 1, pageSize: 1 }),
|
||||||
process: (res: any) =>
|
process: (res: any) => {
|
||||||
res.code === RESULT_CODE_SUCCESS && (skimState.udmSubNum = res.data.total),
|
if (res.code === RESULT_CODE_SUCCESS && typeof res.data === 'number') {
|
||||||
|
skimState.udmSubNum += res.data;
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -340,15 +333,15 @@ async function fnSelectUDM(e: any) {
|
|||||||
udmNeId.value = e.key;
|
udmNeId.value = e.key;
|
||||||
try {
|
try {
|
||||||
const res = await listUDMSub({ neId: udmNeId.value, pageNum: 1, pageSize: 1 });
|
const res = await listUDMSub({ neId: udmNeId.value, pageNum: 1, pageSize: 1 });
|
||||||
// listUDMSub({ neId: udmNeId.value, pageNum: 1, pageSize: 1 }).then(res => {
|
// listUDMSub({ neId: udmNeId.value, pageNum: 1, pageSize: 1 }).then(res => {
|
||||||
if (res.code === RESULT_CODE_SUCCESS) {
|
if (res.code === RESULT_CODE_SUCCESS && typeof res.data === 'number') {
|
||||||
skimState.udmSubNum = res.data.total;
|
skimState.udmSubNum = res.data;
|
||||||
}else{
|
}else{
|
||||||
skimState.udmSubNum = 0;
|
skimState.udmSubNum = 0;
|
||||||
}
|
}
|
||||||
// }).catch(() => {
|
// }).catch(() => {
|
||||||
// skimState.udmSubNum = 0;
|
// skimState.udmSubNum = 0;
|
||||||
// });
|
// });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
skimState.udmSubNum = 0;
|
skimState.udmSubNum = 0;
|
||||||
}
|
}
|
||||||
@@ -478,7 +471,7 @@ onBeforeUnmount(() => {
|
|||||||
<div class="item toRouter" :title="t('views.dashboard.overview.toRouter')" v-if="neListStore.fnHasNe(['udm'])">
|
<div class="item toRouter" :title="t('views.dashboard.overview.toRouter')" v-if="neListStore.fnHasNe(['udm'])">
|
||||||
<div @click="fnToRouter('UdmSub_2001')">
|
<div @click="fnToRouter('UdmSub_2001')">
|
||||||
<UserOutlined style="color: #4096ff; margin-right: 8px; font-size: 1.1rem" />
|
<UserOutlined style="color: #4096ff; margin-right: 8px; font-size: 1.1rem" />
|
||||||
{{ skimState.udmSubNum }}
|
{{ skimState.udmSubNum || 0 }}
|
||||||
</div>
|
</div>
|
||||||
<span>
|
<span>
|
||||||
<a-dropdown :trigger="['click']" :get-Popup-Container="getPopupContainer">
|
<a-dropdown :trigger="['click']" :get-Popup-Container="getPopupContainer">
|
||||||
@@ -500,7 +493,7 @@ onBeforeUnmount(() => {
|
|||||||
style="margin: 0 12px" v-perms:has="['dashboard:overview:imsUeNum']" v-if="neListStore.fnHasNe(['ims'])">
|
style="margin: 0 12px" v-perms:has="['dashboard:overview:imsUeNum']" v-if="neListStore.fnHasNe(['ims'])">
|
||||||
<div>
|
<div>
|
||||||
<img :src="svgUserIMS" style="width: 18px; margin-right: 8px" />
|
<img :src="svgUserIMS" style="width: 18px; margin-right: 8px" />
|
||||||
{{ skimState.imsUeNum }}
|
{{ skimState.imsUeNum || 0 }}
|
||||||
</div>
|
</div>
|
||||||
<span>
|
<span>
|
||||||
{{ t('views.dashboard.overview.skim.imsUeNum') }}
|
{{ t('views.dashboard.overview.skim.imsUeNum') }}
|
||||||
@@ -510,7 +503,7 @@ onBeforeUnmount(() => {
|
|||||||
v-perms:has="['dashboard:overview:smfUeNum']" v-if="neListStore.fnHasNe(['smf'])">
|
v-perms:has="['dashboard:overview:smfUeNum']" v-if="neListStore.fnHasNe(['smf'])">
|
||||||
<div>
|
<div>
|
||||||
<img :src="svgUserSMF" style="width: 18px; margin-right: 8px" />
|
<img :src="svgUserSMF" style="width: 18px; margin-right: 8px" />
|
||||||
{{ skimState.smfUeNum }}
|
{{ skimState.smfUeNum || 0 }}
|
||||||
</div>
|
</div>
|
||||||
<span>
|
<span>
|
||||||
{{ t('views.dashboard.overview.skim.smfUeNum') }}
|
{{ t('views.dashboard.overview.skim.smfUeNum') }}
|
||||||
@@ -692,7 +685,7 @@ onBeforeUnmount(() => {
|
|||||||
<h3 class="resources leftright">
|
<h3 class="resources leftright">
|
||||||
<span class="title">
|
<span class="title">
|
||||||
<DashboardOutlined style="color: #68d8fe;font-size: 20px;" />
|
<DashboardOutlined style="color: #68d8fe;font-size: 20px;" />
|
||||||
<div style="margin-left: -3px"> {{ t('views.dashboard.overview.resources.title') }}:</div>
|
<div style="margin-left: -3px">{{ t('views.dashboard.overview.resources.title') }}:</div>
|
||||||
<a-dropdown :trigger="['click']" :get-Popup-Container="getPopupContainer">
|
<a-dropdown :trigger="['click']" :get-Popup-Container="getPopupContainer">
|
||||||
<div class="toDeep-text">
|
<div class="toDeep-text">
|
||||||
{{ graphNodeClickID }}
|
{{ graphNodeClickID }}
|
||||||
|
|||||||
Reference in New Issue
Block a user