修改综合仪表盘样式

This commit is contained in:
lai
2025-07-04 17:07:53 +08:00
parent edd3865094
commit 1a10a5a9d1
13 changed files with 912 additions and 539 deletions

View File

@@ -7,6 +7,7 @@ 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';
@@ -29,6 +30,11 @@ 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();
@@ -52,8 +58,11 @@ type SkimStateType = {
enbNum: number;
/**4G在线用户数量 */
enbUeNum: number;
/**5G用户总数量 */
gNbSumNum: number;
/**4G用户总数量 */
eNbSumNum: number;
};
/**概览状态信息 */
let skimState: SkimStateType = reactive({
udmSubNum: 0,
@@ -63,6 +72,9 @@ let skimState: SkimStateType = reactive({
gnbUeNum: 0,
enbNum: 0,
enbUeNum: 0,
gNbSumNum: 0,
eNbSumNum: 0,
});
/**网元参数 */
@@ -108,6 +120,10 @@ function fnGetNeState() {
/**获取概览信息 */
async function fnGetSkim() {
let tempGnbSumNum = 0;
let tempEnbSumNum = 0;
const neHandlers = new Map([
// [
// 'UDM',
@@ -139,13 +155,19 @@ async function fnGetSkim() {
'AMF',
{
request: (neId: string) => listBase5G({ neType: 'AMF', neId }),
process: (res: any) => {
process: async (res: any, neId: 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;
}
}
},
},
@@ -154,13 +176,20 @@ async function fnGetSkim() {
'MME',
{
request: (neId: string) => listBase5G({ neType: 'MME', neId }),
process: (res: any) => {
process: async (res: any, neId: 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;
}
}
},
},
@@ -176,6 +205,7 @@ async function fnGetSkim() {
? {
promise: handler.request(child.neId),
process: handler.process,
neId: child.neId, // 这里加上neId
}
: null;
})
@@ -194,14 +224,21 @@ async function fnGetSkim() {
enbNum: 0,
enbUeNum: 0,
});
results.forEach((result, index) => {
const processPromises = results.map((result, index) => {
const req = requests[index];
if (result.status === 'fulfilled') {
requests[index].process(result.value);
return req.process(result.value, req.neId);
} else {
requests[index].process(0);
return req.process(0, req.neId);
}
});
// 等待所有 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) {
@@ -382,12 +419,14 @@ onBeforeUnmount(() => {
</div>
<div class="column">
<!--概览-->
<div class="skim panel">
<div class="inner">
<h3>
<IdcardOutlined style="color: #68d8fe" />&nbsp;&nbsp;
{{ t('views.dashboard.overview.skim.userTitle') }}
<h3 class="leftright">
<span class="title">
<IdcardOutlined style="color: #68d8fe" />&nbsp;&nbsp;
{{ t('views.dashboard.overview.skim.userTitle') }}
</span>
</h3>
<div class="data">
<div class="item toRouter" :title="t('views.dashboard.overview.toRouter')">
@@ -434,13 +473,103 @@ 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" />&nbsp;&nbsp;
{{ 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" />&nbsp;&nbsp;
{{ 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" />&nbsp;&nbsp;
{{
t('views.dashboard.overview.upfFlow.title')
}}
</div>&nbsp;&nbsp;&nbsp;&nbsp;
<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" />&nbsp;&nbsp;
{{ 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>
<GlobalOutlined style="color: #68d8fe" />&nbsp;&nbsp; 5G
{{ t('views.dashboard.overview.skim.baseTitle') }}
<h3 class="leftright">
<span class="title">
<GlobalOutlined style="color: #68d8fe" />&nbsp;&nbsp;
{{t('views.dashboard.overview.skim.nodeBInfo')}}
</span>
</h3>
<div class="data">
<div class="data" style="margin-top: 20px;">
<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">
@@ -460,13 +589,20 @@ onBeforeUnmount(() => {
</div>
</div>
</div>
<div class="skim panel base" v-perms:has="['dashboard:overview:enbBase']">
<div class="inner">
<h3>
<GlobalOutlined style="color: #68d8fe" />&nbsp;&nbsp; 4G
{{ t('views.dashboard.overview.skim.baseTitle') }}
</h3>
<div class="data">
<div class="data" style="margin-top: 40px;">
<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">
@@ -487,143 +623,51 @@ onBeforeUnmount(() => {
</div>
</div>
<!-- 用户行为 -->
<div class="userActivity panel">
<div class="inner">
<h3>
<WhatsAppOutlined style="color: #68d8fe" />&nbsp;&nbsp;
{{ t('views.dashboard.overview.userActivity.title') }}
</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" :title="t('views.dashboard.overview.toRouter')"
style="display: flex; align-items: center">
<AreaChartOutlined style="color: #68d8fe" />&nbsp;&nbsp;
<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" />&nbsp;&nbsp;
{{ 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">
<Topology />
</div>
</div>
</div>
</div>
<div class="column">
<!-- 流量统计 -->
<div class="upfFlowTotal panel">
<div class="inner">
<h3>
<span>
<SwapOutlined style="color: #68d8fe" />&nbsp;&nbsp;
{{ 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" />&nbsp;&nbsp;
{{ t('views.dashboard.overview.alarmTypeBar.alarmSum') }}
</h3>
<div class="chart">
<AlarnTypeBar />
</div>
</div>
</div>
<!-- 资源情况 -->
<div class="resources panel">
<div class="inner">
<h3 style="display: flex; align-items: center;">
<DashboardOutlined style="color: #68d8fe" />&nbsp;&nbsp;
{{ t('views.dashboard.overview.resources.title') }}
<a-dropdown :trigger="['click']" :get-Popup-Container="getPopupContainer">
<div class="toDeep-text">
{{ graphNodeClickID }}
<DownOutlined style="margin-left: 12px; 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>
<h3 class="resources leftright">
<span class="title">
<DashboardOutlined style="color: #68d8fe;font-size: 20px;" />&nbsp;&nbsp;
<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>
<div class="chart">
<NeResources />
</div>
</div>
</div>
<!-- IMS用户行为 -->
<div class="userActivity panel">
<div class="inner">
<h3 class="leftright">
<span class="title">
<WhatsAppOutlined style="color: #68d8fe;font-size: 20px;" />&nbsp;&nbsp; {{
t('views.dashboard.overview.userActivity.imsTitle') }}
</span>
</h3>
<div class="chart">
<IMSActivity />
</div>
</div>
</div>
</div>
</div>
</template>
@@ -636,16 +680,16 @@ onBeforeUnmount(() => {
}
.toDeep :deep(.ant-select-selector) {
background-color: #101129;
background-color: #050F23;
border: none;
}
.toDeep :deep(.ant-select-arrow) {
color: #fff;
color: #4c9bfd;
}
.toDeep :deep(.ant-select-selection-item) {
color: #fff;
color: #4c9bfd;
}
.toDeep-text {