Files
fe.wfc/src/views/dashboard/modules/header-banner.vue
T

342 lines
13 KiB
Vue

<script setup lang="ts">
import {
EnvironmentOutlined,
SafetyOutlined,
HddOutlined,
GroupOutlined,
UserAddOutlined,
UserSwitchOutlined
} from '@ant-design/icons-vue';
import { computed, ref, onMounted } from 'vue';
import { getDashboardOverview } from '@/service/api/auth';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
const { t } = useI18n();
const router = useRouter();
//AP跳转
const handleApClick = () => {
router.push('/device/apdevice');
};
//用户跳转
const handleUserClick = () =>{
router.push('/user-center/user')
};
//终端跳转
const handleterminalClick = () => {
router.push('/device/terminal');
};
//告警跳转
const handAlertsClick = () => {
router.push('/device/alerts');
};
defineOptions({
name: 'HeaderBanner'
});
const overviewData = ref<Api.DashboardOverview>({
cloud: { connected: false },
siteNum: 0,
totalGatewayNum: 0,
connectedGatewayNum: 0,
disconnectedGatewayNum: 0,
totalSwitchNum: 0,
connectedSwitchNum: 0,
disconnectedSwitchNum: 0,
totalApNum: 0,
connectedApNum: 0,
disconnectedApNum: 0,
isolatedApNum: 0,
totalClientNum: 0,
wiredClientNum: 0,
wirelessClientNum: 0,
guestNum: 0,
registerUserNum: 0,
onlineUserNum: 0
});
const fetchOverviewData = async () => {
try {
const { data } = await getDashboardOverview();
if (data) {
overviewData.value = {
cloud: { connected: data.cloud?.connected ?? false },
siteNum: data.siteNum ?? 0,
totalGatewayNum: data.totalGatewayNum ?? 0,
connectedGatewayNum: data.connectedGatewayNum ?? 0,
disconnectedGatewayNum: data.disconnectedGatewayNum ?? 0,
totalSwitchNum: data.totalSwitchNum ?? 0,
connectedSwitchNum: data.connectedSwitchNum ?? 0,
disconnectedSwitchNum: data.disconnectedSwitchNum ?? 0,
totalApNum: data.totalApNum ?? 0,
connectedApNum: data.connectedApNum ?? 0,
disconnectedApNum: data.disconnectedApNum ?? 0,
isolatedApNum: data.isolatedApNum ?? 0,
totalClientNum: data.totalClientNum ?? 0,
wiredClientNum: data.wiredClientNum ?? 0,
wirelessClientNum: data.wirelessClientNum ?? 0,
guestNum: data.guestNum ?? 0,
registerUserNum: data.registerUserNum ?? 0,
onlineUserNum: data.onlineUserNum ?? 0
};
}
} catch (error) {
}
};
onMounted(() => {
fetchOverviewData();
});
const deviceStatus = computed(() => {
const status = {
ap: {
connected: Number(overviewData.value.connectedApNum) || 0,
disconnected: Number(overviewData.value.disconnectedApNum) || 0,
isolated: Number(overviewData.value.isolatedApNum) || 0
},
client: {
wiredUsers: Number(overviewData.value.wiredClientNum) || 0,
wirelessUsers: Number(overviewData.value.wirelessClientNum) || 0,
wirelessGuests: Number(overviewData.value.guestNum) || 0
},
users: {
registered: Number(overviewData.value.registerUserNum) || 0,
online: Number(overviewData.value.onlineUserNum) || 0
},
alerts: 0
};
return status;
});
const siteInfo = computed(() => ({
total: Number(overviewData.value.siteNum) || 0
}));
const otherDevices = computed(() => ({
gateways: {
total: Number(overviewData.value.totalGatewayNum) || 0,
connected: Number(overviewData.value.connectedGatewayNum) || 0,
disconnected: Number(overviewData.value.disconnectedGatewayNum) || 0
},
switches: {
total: Number(overviewData.value.totalSwitchNum) || 0,
connected: Number(overviewData.value.connectedSwitchNum) || 0,
disconnected: Number(overviewData.value.disconnectedSwitchNum) || 0
},
olts: {
total: 0,
connected: 0,
disconnected: 0
}
}));
</script>
<template>
<ACard :bordered="false" class="card-wrapper">
<div class="text-16px font-bold mb-4px">{{ t('page.headerbanner.controller') }}</div>
<ARow :gutter="[16, 16]">
<ACol :span="24">
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-8px">
<!-- Connected Status -->
<div class="flex flex-col p-6px">
<div class="flex items-center gap-6px mb-6px">
<div class="size-48px flex-center bg-blue-50 rounded-lg">
<icon-mdi-cloud class="text-primary text-24px" />
</div>
<div class="text-16px font-medium">{{ t('page.headerbanner.connected') }}</div>
</div>
<div class="border-t border-gray-100 my-4px"></div>
<div class="text-12px text-gray-500">
{{ t('page.headerbanner.cloud') }}
</div>
</div>
<!-- Sites -->
<div class="flex flex-col p-6px">
<div class="flex items-center gap-6px mb-6px">
<div class="size-48px flex-center bg-gray-100 rounded-lg relative">
<environment-outlined class="text-24px text-primary" />
<span class="text-20px font-semibold absolute -right-2 -top-2 bg-primary text-white rounded-full w-6 h-6 flex-center">{{ siteInfo.total }}</span>
</div>
<div class="text-16px font-medium">{{ t('page.headerbanner.sites') }}</div>
</div>
<div class="border-t border-gray-100 my-4px"></div>
<div class="flex flex-col text-12px text-gray-500">
<span>{{ t('page.headerbanner.totalsite') }}: {{ siteInfo.total }}</span>
</div>
</div>
<!-- &lt;!&ndash; Gateways &ndash;&gt;-->
<!-- <div class="flex flex-col p-6px">-->
<!-- <div class="flex items-center gap-6px mb-6px">-->
<!-- <div class="size-48px flex-center bg-gray-100 rounded-lg relative">-->
<!-- <safety-outlined class="text-24px text-primary" />-->
<!-- <span class="text-20px font-semibold absolute -right-2 -top-2 bg-primary text-white rounded-full w-6 h-6 flex-center">{{ otherDevices.gateways.connected + otherDevices.gateways.disconnected }}</span>-->
<!-- </div>-->
<!-- <div class="text-16px font-medium">{{ t('page.headerbanner.gateway') }}</div>-->
<!-- </div>-->
<!-- <div class="border-t border-gray-100 my-4px"></div>-->
<!-- <div class="flex flex-col text-12px text-gray-500">-->
<!-- <span>{{ t('page.headerbanner.connect') }}: {{ otherDevices.gateways.connected }}</span>-->
<!-- <span>{{ t('page.headerbanner.disconnect') }}: {{ otherDevices.gateways.disconnected }}</span>-->
<!-- </div>-->
<!-- </div>-->
<!-- &lt;!&ndash; Switches &ndash;&gt;-->
<!-- <div class="flex flex-col p-6px">-->
<!-- <div class="flex items-center gap-6px mb-6px">-->
<!-- <div class="size-48px flex-center bg-gray-100 rounded-lg relative">-->
<!-- <hdd-outlined class="text-24px text-primary" />-->
<!-- <span class="text-20px font-semibold absolute -right-2 -top-2 bg-primary text-white rounded-full w-6 h-6 flex-center">{{ otherDevices.switches.connected + otherDevices.switches.disconnected }}</span>-->
<!-- </div>-->
<!-- <div class="text-16px font-medium">{{ t('page.headerbanner.switches') }}</div>-->
<!-- </div>-->
<!-- <div class="border-t border-gray-100 my-4px"></div>-->
<!-- <div class="flex flex-col text-12px text-gray-500">-->
<!-- <span>{{ t('page.headerbanner.connect') }}: {{ otherDevices.switches.connected }}</span>-->
<!-- <span>{{ t('page.headerbanner.disconnect') }}: {{ otherDevices.switches.disconnected }}</span>-->
<!-- </div>-->
<!-- </div>-->
<!-- &lt;!&ndash; OLTs &ndash;&gt;-->
<!-- <div class="flex flex-col p-6px">-->
<!-- <div class="flex items-center gap-6px mb-6px">-->
<!-- <div class="size-48px flex-center bg-gray-100 rounded-lg relative">-->
<!-- <group-outlined class="text-24px text-primary" />-->
<!-- <span class="text-20px font-semibold absolute -right-2 -top-2 bg-primary text-white rounded-full w-6 h-6 flex-center">{{ otherDevices.olts.total }}</span>-->
<!-- </div>-->
<!-- <div class="text-16px font-medium">OLTs</div>-->
<!-- </div>-->
<!-- <div class="border-t border-gray-100 my-4px"></div>-->
<!-- <div class="flex flex-col text-12px text-gray-500">-->
<!-- <span>{{ t('page.headerbanner.connect') }}: {{ otherDevices.olts.connected }}</span>-->
<!-- <span>{{ t('page.headerbanner.disconnect') }}: {{ otherDevices.olts.disconnected }}</span>-->
<!-- </div>-->
<!-- </div>-->
<!-- Register Users -->
<div class="flex flex-col p-6px">
<div class="flex items-center gap-6px mb-6px">
<div class="size-48px flex-center bg-blue-50 rounded-lg relative hover:bg-green-100">
<user-add-outlined class="text-primary text-24px cursor-pointer" @click="handleUserClick"/>
</div>
<div class="text-16px font-medium">{{ t('page.headerbanner.register') }}</div>
</div>
<div class="border-t border-gray-100 my-4px"></div>
<div class="flex flex-col text-12px text-gray-500">
<span>{{ t('page.headerbanner.registuser') }}: {{ deviceStatus.users.registered }}</span>
</div>
</div>
<!-- Online Users -->
<div class="flex flex-col p-6px">
<div class="flex items-center gap-6px mb-6px">
<div class="size-48px flex-center bg-green-50 rounded-lg">
<user-switch-outlined class="text-primary text-24px" />
</div>
<div class="text-16px font-medium">{{ t('page.headerbanner.online') }}</div>
</div>
<div class="border-t border-gray-100 my-4px"></div>
<div class="flex flex-col text-12px text-gray-500">
<span>{{ t('page.headerbanner.onlineuser') }}: {{ deviceStatus.users.online }}</span>
</div>
</div>
<!-- AP Status -->
<div class="flex flex-col p-6px" >
<div class="flex items-center gap-6px mb-6px">
<div class="size-48px flex-center bg-green-50 rounded-lg relative hover:bg-green-100">
<icon-mdi-access-point class="text-primary text-24px cursor-pointer" @click="handleApClick" />
<span class="text-20px font-semibold absolute -right-2 -top-2 bg-primary text-white rounded-full w-6 h-6 flex-center">
{{ overviewData.totalApNum }}
</span>
</div>
<div class="text-16px font-medium">AP</div>
</div>
<div class="border-t border-gray-100 my-4px"></div>
<div class="flex flex-col text-12px text-gray-500">
<span>{{ t('page.headerbanner.connect') }}: {{ deviceStatus.ap.connected }}</span>
<span>{{ t('page.headerbanner.disconnect') }}: {{ deviceStatus.ap.disconnected }}</span>
<span>{{ t('page.headerbanner.isolated') }}: {{ deviceStatus.ap.isolated }}</span>
</div>
</div>
<!-- Client Status -->
<div class="flex flex-col p-6px">
<div class="flex items-center gap-6px mb-6px">
<div class="size-48px flex-center bg-purple-50 rounded-lg relative hover:bg-green-100">
<icon-mdi-laptop class="text-primary text-24px cursor-pointer" @click="handleterminalClick"/>
<span class="text-20px font-semibold absolute -right-2 -top-2 bg-primary text-white rounded-full w-6 h-6 flex-center">
{{ overviewData.totalClientNum }}
</span>
</div>
<div class="text-16px font-medium">{{ t('page.headerbanner.client') }}</div>
</div>
<div class="border-t border-gray-100 my-4px"></div>
<div class="flex flex-col text-12px text-gray-500">
<span>{{ t('page.headerbanner.wired') }}: {{ deviceStatus.client.wiredUsers }}</span>
<span>{{ t('page.headerbanner.wireless') }}: {{ deviceStatus.client.wirelessUsers }}</span>
<span>{{ t('page.headerbanner.guest') }}: {{ deviceStatus.client.wirelessGuests }}</span>
</div>
</div>
<!-- Alerts -->
<div class="flex flex-col p-6px">
<div class="flex items-center gap-6px mb-6px">
<div class="size-48px flex-center bg-yellow-50 rounded-lg relative hover:bg-green-100">
<icon-mdi-alert class="text-warning text-24px cursor-pointer" @click="handAlertsClick"/>
</div>
<div class="text-16px font-medium">{{ t('page.headerbanner.alerts') }}</div>
</div>
<div class="border-t border-gray-100 my-4px"></div>
<div class="flex flex-col text-12px text-gray-500">
<span>{{ t('page.headerbanner.alert') }}: {{ deviceStatus.alerts || 0 }}</span>
</div>
</div>
</div>
</ACol>
</ARow>
</ACard>
</template>
<style scoped>
.card-wrapper {
margin-bottom: 16px;
padding: 12px;
}
.flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.size-48px {
width: 48px;
height: 48px;
position: relative;
}
.flex-col > span {
line-height: 1.5;
}
.bg-gray-50 {
background-color: #fafafa;
}
.p-6px {
padding: 6px;
}
.mt-8px {
margin-top: 8px;
}
.mb-6px {
margin-bottom: 6px;
}
</style>