feat(dashboard): add overview2 component with images and functionality
- Introduced new images for the dashboard overview (rect.png, title.png). - Created index.vue for the overview2 component, implementing various features including: - User activity tracking and statistics. - Network element state retrieval and display. - Integration of multiple sub-components (Topology, NeResources, UserActivity, IMSActivity, AlarnTypeBar, UPFFlow). - Added dropdowns for selecting UDM and NE resources. - Implemented periodic data fetching for network statistics. - Enhanced user interface with responsive design and improved styling.
This commit is contained in:
@@ -7,7 +7,6 @@ import useI18n from '@/hooks/useI18n';
|
||||
import Topology from './components/Topology/index.vue';
|
||||
import NeResources from './components/NeResources/index.vue';
|
||||
import UserActivity from './components/UserActivity/index.vue';
|
||||
import IMSActivity from './components/IMSActivity/index.vue';
|
||||
import AlarnTypeBar from './components/AlarnTypeBar/index.vue';
|
||||
import UPFFlow from './components/UPFFlow/index.vue';
|
||||
import { listUDMSub } from '@/api/neData/udm_sub';
|
||||
@@ -30,11 +29,6 @@ import { useRouter } from 'vue-router';
|
||||
import useNeInfoStore from '@/store/modules/neinfo';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { upfWhoId } from './hooks/useWS';
|
||||
import {
|
||||
listAMFNbStatelist,
|
||||
} from '@/api/neData/amf';
|
||||
import { listMMENbStatelist } from '@/api/neData/mme';
|
||||
|
||||
|
||||
const neInfoStore = useNeInfoStore();
|
||||
const router = useRouter();
|
||||
@@ -58,11 +52,8 @@ type SkimStateType = {
|
||||
enbNum: number;
|
||||
/**4G在线用户数量 */
|
||||
enbUeNum: number;
|
||||
/**5G用户总数量 */
|
||||
gNbSumNum: number;
|
||||
/**4G用户总数量 */
|
||||
eNbSumNum: number;
|
||||
};
|
||||
|
||||
/**概览状态信息 */
|
||||
let skimState: SkimStateType = reactive({
|
||||
udmSubNum: 0,
|
||||
@@ -72,9 +63,6 @@ let skimState: SkimStateType = reactive({
|
||||
gnbUeNum: 0,
|
||||
enbNum: 0,
|
||||
enbUeNum: 0,
|
||||
gNbSumNum: 0,
|
||||
eNbSumNum: 0,
|
||||
|
||||
});
|
||||
|
||||
/**网元参数 */
|
||||
@@ -96,34 +84,25 @@ function fnGetNeState() {
|
||||
// 获取节点状态
|
||||
for (const node of graphState.data.nodes) {
|
||||
if (notNeNodes.includes(node.id)) continue;
|
||||
const { neType, neId } = node.neInfo;
|
||||
if (!neType || !neId) continue;
|
||||
// 请求标记检查避免重复发送
|
||||
if (neStateRequestMap.value.get(neType)) continue;
|
||||
neStateRequestMap.value.set(neType, true);
|
||||
|
||||
|
||||
const neInfoList = node.neInfoList || [];
|
||||
if (neInfoList.length === 0) continue;
|
||||
|
||||
|
||||
for (const neInfo of neInfoList) {
|
||||
|
||||
if (!neInfo.neType || !neInfo.neId) continue;
|
||||
|
||||
wsSend({
|
||||
requestId: `neState_${neInfo.neType}_${neInfo.neId}`,
|
||||
type: 'ne_state',
|
||||
data: {
|
||||
neType: neInfo.neType,
|
||||
neId: neInfo.neId,
|
||||
},
|
||||
});
|
||||
}
|
||||
wsSend({
|
||||
requestId: `neState_${neType}_${neId}`,
|
||||
type: 'ne_state',
|
||||
data: {
|
||||
neType: neType,
|
||||
neId: neId,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**获取概览信息 */
|
||||
async function fnGetSkim() {
|
||||
|
||||
let tempGnbSumNum = 0;
|
||||
let tempEnbSumNum = 0;
|
||||
|
||||
const neHandlers = new Map([
|
||||
// [
|
||||
// 'UDM',
|
||||
@@ -155,19 +134,13 @@ async function fnGetSkim() {
|
||||
'AMF',
|
||||
{
|
||||
request: (neId: string) => listBase5G({ neType: 'AMF', neId }),
|
||||
process: async (res: any, neId: any) => {
|
||||
process: (res: any) => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
skimState.gnbNum += res.total;
|
||||
skimState.gnbUeNum += res.rows.reduce(
|
||||
(sum: number, item: any) => sum + item.ueNum,
|
||||
0
|
||||
);
|
||||
const amfNbRes = await listAMFNbStatelist({ neId });
|
||||
if (amfNbRes.code === RESULT_CODE_SUCCESS && Array.isArray(amfNbRes.data)) {
|
||||
// skimState.gNbSumNum += amfNbRes.data.length;
|
||||
tempGnbSumNum += amfNbRes.data.length;
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -176,20 +149,13 @@ async function fnGetSkim() {
|
||||
'MME',
|
||||
{
|
||||
request: (neId: string) => listBase5G({ neType: 'MME', neId }),
|
||||
process: async (res: any, neId: any) => {
|
||||
process: (res: any) => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
skimState.enbNum += res.total;
|
||||
skimState.enbUeNum += res.rows.reduce(
|
||||
(sum: number, item: any) => sum + item.ueNum,
|
||||
0
|
||||
);
|
||||
|
||||
const mmeNbRes = await listMMENbStatelist({ neId });
|
||||
if (mmeNbRes.code === RESULT_CODE_SUCCESS && Array.isArray(mmeNbRes.data)) {
|
||||
// skimState.eNbSumNum += mmeNbRes.data.length;
|
||||
tempEnbSumNum += mmeNbRes.data.length;
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -203,10 +169,9 @@ async function fnGetSkim() {
|
||||
const handler = neHandlers.get(child.neType);
|
||||
return handler
|
||||
? {
|
||||
promise: handler.request(child.neId),
|
||||
process: handler.process,
|
||||
neId: child.neId, // 这里加上neId
|
||||
}
|
||||
promise: handler.request(child.neId),
|
||||
process: handler.process,
|
||||
}
|
||||
: null;
|
||||
})
|
||||
.filter(Boolean) || []
|
||||
@@ -224,21 +189,14 @@ async function fnGetSkim() {
|
||||
enbNum: 0,
|
||||
enbUeNum: 0,
|
||||
});
|
||||
const processPromises = results.map((result, index) => {
|
||||
const req = requests[index];
|
||||
results.forEach((result, index) => {
|
||||
if (result.status === 'fulfilled') {
|
||||
return req.process(result.value, req.neId);
|
||||
requests[index].process(result.value);
|
||||
} else {
|
||||
return req.process(0, req.neId);
|
||||
requests[index].process(0);
|
||||
}
|
||||
});
|
||||
|
||||
// 等待所有 process 执行完再赋值gNbSumNum等
|
||||
await Promise.all(processPromises);
|
||||
|
||||
skimState.gNbSumNum = tempGnbSumNum;
|
||||
skimState.eNbSumNum = tempEnbSumNum;
|
||||
|
||||
// UDM
|
||||
listUDMSub({ neId: udmNeId.value, pageNum: 1, pageSize: 1 }).then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
@@ -247,8 +205,6 @@ async function fnGetSkim() {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**初始数据函数 */
|
||||
function loadData() {
|
||||
fnGetNeState(); // 获取网元状态
|
||||
@@ -277,7 +233,7 @@ function loadData() {
|
||||
if (!interval5s.value || !initFlag) return;
|
||||
fnGetSkim(); // 获取概览信息
|
||||
fnGetNeState(); // 获取网元状态
|
||||
}, 10_000);
|
||||
}, 5_000);
|
||||
}
|
||||
|
||||
/**栏目信息跳转 */
|
||||
@@ -304,8 +260,6 @@ function fnSelectNe(value: any, option: any) {
|
||||
|
||||
let udmNeId = ref<string>('001');
|
||||
let udmOtions = ref<Record<string, any>[]>([]);
|
||||
let onlineOtions = ref<Record<string, any>[]>([]);
|
||||
|
||||
/**用户数量-选择UDM */
|
||||
function fnSelectUDM(e: any) {
|
||||
udmNeId.value = e.key;
|
||||
@@ -315,11 +269,7 @@ function fnSelectUDM(e: any) {
|
||||
}
|
||||
});
|
||||
}
|
||||
/**资源控制-选择NE */
|
||||
function fnSelectNeRe(e: any) {
|
||||
graphNodeClickID.value = e.key;
|
||||
}
|
||||
//
|
||||
|
||||
// 定义一个方法返回 views 容器
|
||||
const getPopupContainer = () => {
|
||||
// 使用 ref 或其他方式来引用你的 views 容器
|
||||
@@ -346,29 +296,19 @@ onMounted(() => {
|
||||
//queryParams.neRealId = arr[0].value;
|
||||
fnSelectNe(arr[0].value, arr[0]);
|
||||
}
|
||||
//online Ne
|
||||
let onlineArr: Record<string, any>[] = [];
|
||||
|
||||
// UDM
|
||||
let arr1: Record<string, any>[] = [];
|
||||
res.data.forEach((v: any) => {
|
||||
if (v.status && ['UDM', 'UPF', 'AUSF', 'PCF', 'SMF', 'AMF', 'OMC', 'SMSC', 'IMS', 'MME'].includes(v.neType)) {
|
||||
onlineArr.push({ value: v.neType + '_' + v.neId, label: v.neName, rmUid: v.rmUid });
|
||||
}
|
||||
if (v.neType === 'UDM') {
|
||||
arr1.push({ value: v.neId, label: v.neName, rmUid: v.rmUid });
|
||||
}
|
||||
});
|
||||
udmOtions.value = arr1;
|
||||
onlineOtions.value = onlineArr;
|
||||
if (arr1.length > 0) {
|
||||
fnSelectUDM({ key: arr1[0].value });
|
||||
}
|
||||
|
||||
if (onlineArr.length > 0) {
|
||||
fnSelectNeRe({ key: onlineArr[0].value });
|
||||
}
|
||||
|
||||
// 过滤不可用的网元
|
||||
neCascaderOptions.value = neInfoStore.getNeCascaderOptions.filter(
|
||||
(item: any) => {
|
||||
@@ -410,7 +350,11 @@ onBeforeUnmount(() => {
|
||||
<template>
|
||||
<div class="viewport" ref="viewportDom">
|
||||
<div class="brand">
|
||||
<div class="brand-title" @click="toggle" :title="t('views.dashboard.overview.fullscreen')">
|
||||
<div
|
||||
class="brand-title"
|
||||
@click="toggle"
|
||||
:title="t('views.dashboard.overview.fullscreen')"
|
||||
>
|
||||
{{ t('views.dashboard.overview.title') }}
|
||||
<FullscreenExitOutlined v-if="isFullscreen" />
|
||||
<FullscreenOutlined v-else />
|
||||
@@ -419,30 +363,37 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
|
||||
<!--概览-->
|
||||
<div class="skim panel">
|
||||
<div class="inner">
|
||||
<h3 class="leftright">
|
||||
<span class="title">
|
||||
<IdcardOutlined style="color: #68d8fe" />
|
||||
{{ t('views.dashboard.overview.skim.userTitle') }}
|
||||
</span>
|
||||
<h3>
|
||||
<IdcardOutlined style="color: #68d8fe" />
|
||||
{{ t('views.dashboard.overview.skim.userTitle') }}
|
||||
</h3>
|
||||
<div class="data">
|
||||
<div class="item toRouter" :title="t('views.dashboard.overview.toRouter')">
|
||||
<div
|
||||
class="item toRouter"
|
||||
:title="t('views.dashboard.overview.toRouter')"
|
||||
>
|
||||
<div @click="fnToRouter('Sub_2010')">
|
||||
<UserOutlined style="color: #4096ff; margin-right: 8px; font-size: 1.1rem" />
|
||||
<UserOutlined
|
||||
style="color: #4096ff; margin-right: 8px; font-size: 1.1rem"
|
||||
/>
|
||||
{{ skimState.udmSubNum }}
|
||||
</div>
|
||||
<span>
|
||||
<a-dropdown :trigger="['click']" :get-Popup-Container="getPopupContainer">
|
||||
<a-dropdown :trigger="['click']">
|
||||
<div class="toDeep-text">
|
||||
{{ t('views.dashboard.overview.skim.users') }}
|
||||
<DownOutlined style="margin-left: 12px; font-size: 12px" />
|
||||
</div>
|
||||
<template #overlay>
|
||||
<a-menu @click="fnSelectUDM">
|
||||
<a-menu-item v-for="v in udmOtions" :key="v.value" :disabled="udmNeId === v.value">
|
||||
<a-menu-item
|
||||
v-for="v in udmOtions"
|
||||
:key="v.value"
|
||||
:disabled="udmNeId === v.value"
|
||||
>
|
||||
{{ v.label }}
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
@@ -450,8 +401,13 @@ onBeforeUnmount(() => {
|
||||
</a-dropdown>
|
||||
</span>
|
||||
</div>
|
||||
<div class="item toRouter" @click="fnToRouter('Ims_2080')" :title="t('views.dashboard.overview.toRouter')"
|
||||
style="margin: 0 12px" v-perms:has="['dashboard:overview:imsUeNum']">
|
||||
<div
|
||||
class="item toRouter"
|
||||
@click="fnToRouter('Ims_2080')"
|
||||
:title="t('views.dashboard.overview.toRouter')"
|
||||
style="margin: 0 12px"
|
||||
v-perms:has="['dashboard:overview:imsUeNum']"
|
||||
>
|
||||
<div>
|
||||
<img :src="svgUserIMS" style="width: 18px; margin-right: 8px" />
|
||||
{{ skimState.imsUeNum }}
|
||||
@@ -460,8 +416,12 @@ onBeforeUnmount(() => {
|
||||
{{ t('views.dashboard.overview.skim.imsUeNum') }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="item toRouter" @click="fnToRouter('Ue_2081')" :title="t('views.dashboard.overview.toRouter')"
|
||||
v-perms:has="['dashboard:overview:smfUeNum']">
|
||||
<div
|
||||
class="item toRouter"
|
||||
@click="fnToRouter('Ue_2081')"
|
||||
:title="t('views.dashboard.overview.toRouter')"
|
||||
v-perms:has="['dashboard:overview:smfUeNum']"
|
||||
>
|
||||
<div>
|
||||
<img :src="svgUserSMF" style="width: 18px; margin-right: 8px" />
|
||||
{{ skimState.smfUeNum }}
|
||||
@@ -473,115 +433,36 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!--告警统计-->
|
||||
<div class="alarmType panel">
|
||||
<div class="inner">
|
||||
<h3 class="toRouter leftright" :title="t('views.dashboard.overview.toRouter')">
|
||||
<span class="title" @click="fnToRouter('HistoryAlarm_2097')">
|
||||
<PieChartOutlined style="color: #68d8fe" />
|
||||
{{ t('views.dashboard.overview.alarmTypeBar.alarmSum') }}
|
||||
</span>
|
||||
</h3>
|
||||
<div class="chart">
|
||||
<AlarnTypeBar />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 用户行为 -->
|
||||
<div class="userActivity panel">
|
||||
<div class="inner">
|
||||
<h3 class="leftright">
|
||||
<span class="title">
|
||||
<WhatsAppOutlined style="color: #68d8fe" />
|
||||
{{ t('views.dashboard.overview.userActivity.title') }}
|
||||
</span>
|
||||
</h3>
|
||||
<div class="chart">
|
||||
<UserActivity />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column" style="flex: 4; margin: 1.333rem 0.833rem 0">
|
||||
|
||||
<!-- 实时流量 -->
|
||||
<div class="upfFlow panel">
|
||||
<div class="inner">
|
||||
<h3 class="toRouter centerStyle" :title="t('views.dashboard.overview.toRouter')">
|
||||
<span class="title">
|
||||
<div @click="fnToRouter('GoldTarget_2104')">
|
||||
<AreaChartOutlined style="color: #68d8fe" />
|
||||
{{
|
||||
t('views.dashboard.overview.upfFlow.title')
|
||||
}}
|
||||
</div>
|
||||
<a-select v-model:value="upfWhoId" :options="neOtions" :get-Popup-Container="getPopupContainer"
|
||||
class="toDeep" style="color: #fff;" @change="fnSelectNe" />
|
||||
|
||||
</span>
|
||||
|
||||
|
||||
|
||||
</h3>
|
||||
|
||||
<div class="chart">
|
||||
<UPFFlow />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 网络拓扑 -->
|
||||
<div class="topology panel">
|
||||
<div class="inner">
|
||||
<h3 class="toRouter centerStyle" @click="fnToRouter('TopologyArchitecture_2128')"
|
||||
:title="t('views.dashboard.overview.toRouter')">
|
||||
<span class="title">
|
||||
<ApartmentOutlined style="color: #68d8fe" />
|
||||
{{ t('views.dashboard.overview.topology.title') }}
|
||||
</span>
|
||||
</h3>
|
||||
<div class="chart">
|
||||
<Topology />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<!-- 基站信息 -->
|
||||
<div class="skim panel base" v-perms:has="['dashboard:overview:gnbBase']">
|
||||
<div class="inner">
|
||||
<h3 class="leftright">
|
||||
<span class="title">
|
||||
<GlobalOutlined style="color: #68d8fe" />
|
||||
{{t('views.dashboard.overview.skim.nodeBInfo')}}
|
||||
</span>
|
||||
<h3>
|
||||
<GlobalOutlined style="color: #68d8fe" /> 5G
|
||||
{{ t('views.dashboard.overview.skim.baseTitle') }}
|
||||
</h3>
|
||||
<div class="data" style="margin-top: 20px;">
|
||||
<div class="item toRouter" @click="fnToRouter('BaseStation_2096', { neType: 'AMF' })"
|
||||
:title="t('views.dashboard.overview.toRouter')">
|
||||
<div class="data">
|
||||
<div
|
||||
class="item toRouter"
|
||||
@click="fnToRouter('BaseStation_2096', { neType: 'AMF' })"
|
||||
:title="t('views.dashboard.overview.toRouter')"
|
||||
>
|
||||
<div style="align-items: flex-start">
|
||||
<img :src="svgBase" style="width: 18px; margin-right: 8px; height: 2rem" />
|
||||
{{ skimState.gNbSumNum }}
|
||||
</div>
|
||||
<span>{{ t('views.dashboard.overview.skim.gnbSumBase') }}</span>
|
||||
</div>
|
||||
<div class="item toRouter" @click="fnToRouter('BaseStation_2096', { neType: 'AMF' })"
|
||||
:title="t('views.dashboard.overview.toRouter')">
|
||||
<div style="align-items: flex-start">
|
||||
<img :src="svgBase" style="width: 18px; margin-right: 8px; height: 2rem" />
|
||||
<img
|
||||
:src="svgBase"
|
||||
style="width: 18px; margin-right: 8px; height: 2rem"
|
||||
/>
|
||||
{{ skimState.gnbNum }}
|
||||
</div>
|
||||
<span>{{ t('views.dashboard.overview.skim.gnbBase') }}</span>
|
||||
</div>
|
||||
<div class="item toRouter" @click="fnToRouter('BaseStation_2096', { neType: 'AMF' })"
|
||||
:title="t('views.dashboard.overview.toRouter')">
|
||||
<div
|
||||
class="item toRouter"
|
||||
@click="fnToRouter('BaseStation_2096', { neType: 'AMF' })"
|
||||
:title="t('views.dashboard.overview.toRouter')"
|
||||
>
|
||||
<div style="align-items: flex-start">
|
||||
<UserOutlined style="color: #4096ff; margin-right: 8px; font-size: 1.1rem" />
|
||||
<UserOutlined
|
||||
style="color: #4096ff; margin-right: 8px; font-size: 1.1rem"
|
||||
/>
|
||||
{{ skimState.gnbUeNum }}
|
||||
</div>
|
||||
<span>{{ t('views.dashboard.overview.skim.gnbUeNum') }}</span>
|
||||
@@ -589,32 +470,36 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="skim panel base" v-perms:has="['dashboard:overview:enbBase']">
|
||||
<div class="inner">
|
||||
<h3>
|
||||
<GlobalOutlined style="color: #68d8fe" /> 4G
|
||||
{{ t('views.dashboard.overview.skim.baseTitle') }}
|
||||
</h3>
|
||||
<div class="data" style="margin-top: 40px;">
|
||||
<div class="item toRouter" @click="fnToRouter('BaseStation_2096', { neType: 'MME' })"
|
||||
:title="t('views.dashboard.overview.toRouter')">
|
||||
<div class="data">
|
||||
<div
|
||||
class="item toRouter"
|
||||
@click="fnToRouter('BaseStation_2096', { neType: 'MME' })"
|
||||
:title="t('views.dashboard.overview.toRouter')"
|
||||
>
|
||||
<div style="align-items: flex-start">
|
||||
<img :src="svgBase" style="width: 18px; margin-right: 8px; height: 2rem" />
|
||||
{{ skimState.eNbSumNum }}
|
||||
</div>
|
||||
<span>{{ t('views.dashboard.overview.skim.enbSumBase') }}</span>
|
||||
</div>
|
||||
<div class="item toRouter" @click="fnToRouter('BaseStation_2096', { neType: 'MME' })"
|
||||
:title="t('views.dashboard.overview.toRouter')">
|
||||
<div style="align-items: flex-start">
|
||||
<img :src="svgBase" style="width: 18px; margin-right: 8px; height: 2rem" />
|
||||
<img
|
||||
:src="svgBase"
|
||||
style="width: 18px; margin-right: 8px; height: 2rem"
|
||||
/>
|
||||
{{ skimState.enbNum }}
|
||||
</div>
|
||||
<span>{{ t('views.dashboard.overview.skim.enbBase') }}</span>
|
||||
</div>
|
||||
<div class="item toRouter" @click="fnToRouter('BaseStation_2096', { neType: 'MME' })"
|
||||
:title="t('views.dashboard.overview.toRouter')">
|
||||
<div
|
||||
class="item toRouter"
|
||||
@click="fnToRouter('BaseStation_2096', { neType: 'MME' })"
|
||||
:title="t('views.dashboard.overview.toRouter')"
|
||||
>
|
||||
<div style="align-items: flex-start">
|
||||
<UserOutlined style="color: #4096ff; margin-right: 8px; font-size: 1.1rem" />
|
||||
<UserOutlined
|
||||
style="color: #4096ff; margin-right: 8px; font-size: 1.1rem"
|
||||
/>
|
||||
{{ skimState.enbUeNum }}
|
||||
</div>
|
||||
<span>{{ t('views.dashboard.overview.skim.enbUeNum') }}</span>
|
||||
@@ -623,48 +508,150 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- 资源情况 -->
|
||||
<div class="resources panel">
|
||||
<!-- 用户行为 -->
|
||||
<div class="userActivity panel">
|
||||
<div class="inner">
|
||||
<h3 class="resources leftright">
|
||||
<span class="title">
|
||||
<DashboardOutlined style="color: #68d8fe;font-size: 20px;" />
|
||||
<div style="margin-left: -3px"> {{ t('views.dashboard.overview.resources.title') }}:</div>
|
||||
<a-dropdown :trigger="['click']" :get-Popup-Container="getPopupContainer">
|
||||
<div class="toDeep-text">
|
||||
{{ graphNodeClickID }}
|
||||
<DownOutlined style="margin-left: -2px; font-size: 12px" />
|
||||
</div>
|
||||
<template #overlay>
|
||||
<a-menu @click="fnSelectNeRe">
|
||||
<a-menu-item v-for="v in onlineOtions" :key="v.value">
|
||||
{{ v.label }}
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</span>
|
||||
<h3>
|
||||
<WhatsAppOutlined style="color: #68d8fe" />
|
||||
{{ t('views.dashboard.overview.userActivity.title') }}
|
||||
</h3>
|
||||
<div class="chart">
|
||||
<NeResources />
|
||||
<UserActivity />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- IMS用户行为 -->
|
||||
<div class="userActivity panel">
|
||||
</div>
|
||||
<div class="column" style="flex: 4; margin: 1.333rem 0.833rem 0">
|
||||
<!-- 实时流量 -->
|
||||
<div class="upfFlow panel">
|
||||
<div class="inner">
|
||||
<h3 class="leftright">
|
||||
<span class="title">
|
||||
<WhatsAppOutlined style="color: #68d8fe;font-size: 20px;" /> {{
|
||||
t('views.dashboard.overview.userActivity.imsTitle') }}
|
||||
<h3
|
||||
class="toRouter"
|
||||
:title="t('views.dashboard.overview.toRouter')"
|
||||
style="display: flex; align-items: center"
|
||||
>
|
||||
<AreaChartOutlined style="color: #68d8fe" />
|
||||
<span @click="fnToRouter('GoldTarget_2104')">{{
|
||||
t('views.dashboard.overview.upfFlow.title')
|
||||
}}</span>
|
||||
<a-select
|
||||
v-model:value="upfWhoId"
|
||||
:options="neOtions"
|
||||
:get-Popup-Container="getPopupContainer"
|
||||
class="toDeep"
|
||||
style="width: 100px; color: #fff; margin-left: auto"
|
||||
@change="fnSelectNe"
|
||||
/>
|
||||
</h3>
|
||||
|
||||
<div class="chart">
|
||||
<UPFFlow />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 网络拓扑 -->
|
||||
<div class="topology panel">
|
||||
<div class="inner">
|
||||
<h3
|
||||
class="toRouter"
|
||||
@click="fnToRouter('TopologyArchitecture_2128')"
|
||||
:title="t('views.dashboard.overview.toRouter')"
|
||||
>
|
||||
<span>
|
||||
<ApartmentOutlined style="color: #68d8fe" />
|
||||
{{ t('views.dashboard.overview.topology.title') }}
|
||||
</span>
|
||||
<span>
|
||||
{{ t('views.dashboard.overview.topology.normal') }}:
|
||||
<span class="normal"> {{ graphNodeStateNum[0] }} </span>
|
||||
{{ t('views.dashboard.overview.topology.abnormal') }}:
|
||||
<span class="abnormal"> {{ graphNodeStateNum[1] }} </span>
|
||||
</span>
|
||||
</h3>
|
||||
<div class="chart">
|
||||
<IMSActivity />
|
||||
<Topology />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
<!-- 流量统计 -->
|
||||
<div class="upfFlowTotal panel">
|
||||
<div class="inner">
|
||||
<h3>
|
||||
<span>
|
||||
<SwapOutlined style="color: #68d8fe" />
|
||||
{{ t('views.dashboard.overview.upfFlowTotal.title') }}
|
||||
</span>
|
||||
|
||||
<!-- 筛选 -->
|
||||
<div class="filter">
|
||||
<span
|
||||
:data-key="v"
|
||||
:class="{ active: upfTFActive === v }"
|
||||
v-for="v in ['0', '7', '30']"
|
||||
:key="v"
|
||||
@click="
|
||||
() => {
|
||||
upfTFActive = v;
|
||||
}
|
||||
"
|
||||
>
|
||||
{{
|
||||
v === '0'
|
||||
? '24' + t('common.units.hour')
|
||||
: v + t('common.units.day')
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
</h3>
|
||||
<div class="chart">
|
||||
<!-- 数据 -->
|
||||
<div class="data">
|
||||
<div class="item">
|
||||
<span>
|
||||
<ArrowUpOutlined style="color: #597ef7" />
|
||||
{{ t('views.dashboard.overview.upfFlowTotal.up') }}
|
||||
</span>
|
||||
<h4>{{ upfTotalFlow[upfTFActive].upFrom }}</h4>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span>
|
||||
<ArrowDownOutlined style="color: #52c41a" />
|
||||
{{ t('views.dashboard.overview.upfFlowTotal.down') }}
|
||||
</span>
|
||||
<h4>{{ upfTotalFlow[upfTFActive].downFrom }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 告警统计 -->
|
||||
<div class="alarmType panel">
|
||||
<div class="inner">
|
||||
<h3
|
||||
class="toRouter"
|
||||
@click="fnToRouter('HistoryAlarm_2097')"
|
||||
:title="t('views.dashboard.overview.toRouter')"
|
||||
>
|
||||
<PieChartOutlined style="color: #68d8fe" />
|
||||
{{ t('views.dashboard.overview.alarmTypeBar.alarmSum') }}
|
||||
</h3>
|
||||
<div class="chart">
|
||||
<AlarnTypeBar />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 资源情况 -->
|
||||
<div class="resources panel">
|
||||
<div class="inner">
|
||||
<h3>
|
||||
<DashboardOutlined style="color: #68d8fe" />
|
||||
{{ t('views.dashboard.overview.resources.title') }}:
|
||||
{{ graphNodeClickID }}
|
||||
</h3>
|
||||
<div class="chart">
|
||||
<NeResources />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -674,24 +661,22 @@ onBeforeUnmount(() => {
|
||||
|
||||
<style lang="less" scoped>
|
||||
@import url('./css/index.css');
|
||||
|
||||
.toDeep {
|
||||
--editor-background-color: blue;
|
||||
}
|
||||
|
||||
.toDeep :deep(.ant-select-selector) {
|
||||
background-color: #050F23;
|
||||
background-color: #101129;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.toDeep :deep(.ant-select-arrow) {
|
||||
color: #4c9bfd;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.toDeep :deep(.ant-select-selection-item) {
|
||||
color: #4c9bfd;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.toDeep-text {
|
||||
color: #4c9bfd !important;
|
||||
font-size: 0.844rem !important;
|
||||
|
||||
Reference in New Issue
Block a user