fix:首页仪表盘
This commit is contained in:
@@ -209,6 +209,15 @@ export function getDashboardOverview() {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/** 获取仪表盘站点列表 */
|
||||||
|
export function getDashboardSiteList(params: { pageNum: number; pageSize: number; name?: string }) {
|
||||||
|
return request<Api.DashboardSiteResponse>({
|
||||||
|
url: '/system/dashboard/page',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
77
src/typings/api.d.ts
vendored
77
src/typings/api.d.ts
vendored
@@ -608,44 +608,59 @@ declare namespace Api {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface DashboardOverview {
|
interface DashboardOverview {
|
||||||
cloud: {
|
cloud: {
|
||||||
connected: boolean;
|
connected: boolean;
|
||||||
};
|
};
|
||||||
sites: {
|
siteNum: number;
|
||||||
total: number;
|
|
||||||
countries: number;
|
|
||||||
connected: number;
|
|
||||||
disconnected: number;
|
|
||||||
};
|
|
||||||
devices: {
|
devices: {
|
||||||
gateways: {
|
totalGatewayNum: number;
|
||||||
connected: number;
|
connectedGatewayNum: number;
|
||||||
disconnected: number;
|
disconnectedGatewayNum: number;
|
||||||
};
|
totalSwitchNum: number;
|
||||||
switches: {
|
connectedSwitchNum: number;
|
||||||
connected: number;
|
disconnectedSwitchNum: number;
|
||||||
disconnected: number;
|
totalApNum: number;
|
||||||
};
|
connectedApNum: number;
|
||||||
olts: {
|
disconnectedApNum: number;
|
||||||
connected: number;
|
isolatedApNum: number;
|
||||||
disconnected: number;
|
|
||||||
};
|
|
||||||
ap: {
|
|
||||||
connected: number;
|
|
||||||
disconnected: number;
|
|
||||||
isolated: number;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
client: {
|
client: {
|
||||||
wiredUsers: number;
|
totalClientNum: number;
|
||||||
wirelessUsers: number;
|
wiredClientNum: number;
|
||||||
wirelessGuests: number;
|
wirelessClientNum: number;
|
||||||
};
|
guestNum: number;
|
||||||
alerts: number;
|
|
||||||
users: {
|
|
||||||
registered: number;
|
|
||||||
online: number;
|
|
||||||
};
|
};
|
||||||
|
registerUserNum: number;
|
||||||
|
onlineUserNum: number;
|
||||||
|
}
|
||||||
|
interface DashboardSite {
|
||||||
|
siteId: string;
|
||||||
|
name: string;
|
||||||
|
region: string;
|
||||||
|
tagIds: string[];
|
||||||
|
timeZone: string;
|
||||||
|
scenario: string;
|
||||||
|
totalGatewayNum: number;
|
||||||
|
connectedGatewayNum: number;
|
||||||
|
disconnectedGatewayNum: number;
|
||||||
|
totalSwitchNum: number;
|
||||||
|
connectedSwitchNum: number;
|
||||||
|
disconnectedSwitchNum: number;
|
||||||
|
totalApNum: number;
|
||||||
|
connectedApNum: number;
|
||||||
|
disconnectedApNum: number;
|
||||||
|
isolatedApNum: number;
|
||||||
|
totalClientNum: number;
|
||||||
|
wiredClientNum: number;
|
||||||
|
wirelessClientNum: number;
|
||||||
|
guestNum: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface DashboardSiteResponse {
|
||||||
|
rows: DashboardSite[];
|
||||||
|
total: number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/typings/auto-imports.d.ts
vendored
1
src/typings/auto-imports.d.ts
vendored
@@ -153,6 +153,7 @@ declare global {
|
|||||||
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||||
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||||
const getDashboardOverview: typeof import('../service/api/auth')['getDashboardOverview']
|
const getDashboardOverview: typeof import('../service/api/auth')['getDashboardOverview']
|
||||||
|
const getDashboardSiteList: typeof import('../service/api/auth')['getDashboardSiteList']
|
||||||
const getData: typeof import('../service/api/dictData')['getData']
|
const getData: typeof import('../service/api/dictData')['getData']
|
||||||
const getDefaultHomeTab: typeof import('../store/modules/tab/shared')['getDefaultHomeTab']
|
const getDefaultHomeTab: typeof import('../store/modules/tab/shared')['getDefaultHomeTab']
|
||||||
const getDictDataType: typeof import('../service/api/dict')['getDictDataType']
|
const getDictDataType: typeof import('../service/api/dict')['getDictDataType']
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
|
import type { TableColumnType } from 'ant-design-vue';
|
||||||
import {
|
import {
|
||||||
EnvironmentOutlined,
|
EnvironmentOutlined,
|
||||||
EditOutlined,
|
EditOutlined,
|
||||||
@@ -10,28 +11,59 @@ import {
|
|||||||
PlusOutlined
|
PlusOutlined
|
||||||
} from '@ant-design/icons-vue';
|
} from '@ant-design/icons-vue';
|
||||||
|
|
||||||
|
import { getDashboardSiteList } from '@/service/api/auth';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'CardData'
|
name: 'CardData'
|
||||||
});
|
});
|
||||||
|
|
||||||
interface SiteData {
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
region: string;
|
|
||||||
alerts: number;
|
|
||||||
gateway: string;
|
|
||||||
switches: string;
|
|
||||||
olts: string;
|
|
||||||
eaps: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 搜索和分页状态
|
// 搜索和分页状态
|
||||||
const searchValue = ref('');
|
const searchValue = ref('');
|
||||||
const currentPage = ref(1);
|
const currentPage = ref(1);
|
||||||
const pageSize = ref(10);
|
const pageSize = ref(10);
|
||||||
|
const loading = ref(false);
|
||||||
|
const total = ref(0);
|
||||||
|
|
||||||
|
const siteData = ref<Api.DashboardSite[]>([]);
|
||||||
|
|
||||||
|
const fetchSiteList = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const { data } = await getDashboardSiteList({
|
||||||
|
pageNum: currentPage.value,
|
||||||
|
pageSize: pageSize.value,
|
||||||
|
name: searchValue.value
|
||||||
|
});
|
||||||
|
console.log('API Response:', data);
|
||||||
|
if (data) {
|
||||||
|
siteData.value = data.rows || [];
|
||||||
|
total.value = data.total || 0;
|
||||||
|
console.log('Processed Site Data:', siteData.value);
|
||||||
|
console.log('Total:', total.value);
|
||||||
|
} else {
|
||||||
|
siteData.value = [];
|
||||||
|
total.value = 0;
|
||||||
|
}
|
||||||
|
}catch (error){
|
||||||
|
console.error('Failed to fetch site list:', error);
|
||||||
|
siteData.value = [];
|
||||||
|
total.value = 0;
|
||||||
|
}finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改监听方式
|
||||||
|
|
||||||
|
watch([currentPage, pageSize, searchValue], () => {
|
||||||
|
fetchSiteList();
|
||||||
|
}, { immediate: true });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 表格列定义
|
// 表格列定义
|
||||||
const columns = [
|
const columns: TableColumnType<Api.DashboardSite>[] = [
|
||||||
{
|
{
|
||||||
title: 'NAME',
|
title: 'NAME',
|
||||||
key: 'name',
|
key: 'name',
|
||||||
@@ -45,95 +77,69 @@ const columns = [
|
|||||||
{
|
{
|
||||||
title: 'ALERTS',
|
title: 'ALERTS',
|
||||||
key: 'alerts',
|
key: 'alerts',
|
||||||
dataIndex: 'alerts',
|
|
||||||
width: 100
|
width: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'GATEWAY',
|
title: 'GATEWAY',
|
||||||
key: 'gateway',
|
key: 'gateway',
|
||||||
dataIndex: 'gateway',
|
|
||||||
width: 100
|
width: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'SWITCHES',
|
title: 'SWITCHES',
|
||||||
key: 'switches',
|
key: 'switches',
|
||||||
dataIndex: 'switches',
|
|
||||||
width: 100
|
width: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'OLTS',
|
title: 'OLTS',
|
||||||
key: 'olts',
|
key: 'olts',
|
||||||
dataIndex: 'olts',
|
|
||||||
width: 100
|
width: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'EAPS',
|
title: 'EAPS',
|
||||||
key: 'eaps',
|
key: 'eaps',
|
||||||
dataIndex: 'eaps',
|
|
||||||
width: 100
|
width: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'ACTION',
|
title: 'CLIENTS',
|
||||||
key: 'action',
|
key: 'clients',
|
||||||
width: 150,
|
width: 150
|
||||||
fixed: 'right'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const siteData = computed<SiteData[]>(() => [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: 'wfc-dev-omada1-site1',
|
|
||||||
region: 'China mainland',
|
|
||||||
alerts: 0,
|
|
||||||
gateway: '-',
|
|
||||||
switches: '0 / 0',
|
|
||||||
olts: '0 / 0',
|
|
||||||
eaps: '1 / 1'
|
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
id: 2,
|
// title: 'ACTION',
|
||||||
name: 'wfc-dev-omada1-site2',
|
// key: 'action',
|
||||||
region: 'China mainland',
|
// width: 150,
|
||||||
alerts: 0,
|
// fixed: 'right'
|
||||||
gateway: '-',
|
// }
|
||||||
switches: '0 / 0',
|
];
|
||||||
olts: '0 / 0',
|
|
||||||
eaps: '0 / 1'
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 按钮操作处理函数
|
// 按钮操作处理函数
|
||||||
const handleEdit = (record: SiteData) => {
|
// const handleEdit = (record: Api.DashboardSite) => {
|
||||||
console.log('Edit:', record);
|
// console.log('Edit:', record);
|
||||||
};
|
// };
|
||||||
|
//
|
||||||
const handleCopy = (record: SiteData) => {
|
// const handleCopy = (record: Api.DashboardSite) => {
|
||||||
console.log('Copy:', record);
|
// console.log('Copy:', record);
|
||||||
};
|
// };
|
||||||
|
//
|
||||||
const handleDelete = (record: SiteData) => {
|
// const handleDelete = (record: Api.DashboardSite) => {
|
||||||
console.log('Delete:', record);
|
// console.log('Delete:', record);
|
||||||
};
|
// };
|
||||||
|
//
|
||||||
const handleHome = (record: SiteData) => {
|
// const handleHome = (record: Api.DashboardSite) => {
|
||||||
console.log('Home:', record);
|
// console.log('Home:', record);
|
||||||
};
|
// };
|
||||||
|
|
||||||
// 分页处理函数
|
// 分页处理函数
|
||||||
// const handlePageChange = (page: number) => {
|
const handlePageChange = (page: number, pageSize: number) => {
|
||||||
// currentPage.value = page;
|
currentPage.value = page;
|
||||||
// };
|
if (pageSize !== undefined) {
|
||||||
|
handlePageSizeChange(pageSize);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// const handlePageSizeChange = (size: number) => {
|
const handlePageSizeChange = (size: number) => {
|
||||||
// pageSize.value = size;
|
pageSize.value = size;
|
||||||
// currentPage.value = 1;
|
currentPage.value = 1;
|
||||||
// };
|
};
|
||||||
|
|
||||||
// const handleGoToPage = () => {
|
|
||||||
// // 处理跳转页面逻辑
|
|
||||||
// console.log('Go to page:', currentPage.value);
|
|
||||||
// };
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -141,7 +147,6 @@ const handleHome = (record: SiteData) => {
|
|||||||
<div class="flex justify-between items-center mb-16px">
|
<div class="flex justify-between items-center mb-16px">
|
||||||
<div class="flex items-center gap-8px">
|
<div class="flex items-center gap-8px">
|
||||||
<span class="text-16px font-medium">Site List</span>
|
<span class="text-16px font-medium">Site List</span>
|
||||||
<!-- <span class="text-12px text-gray-500">1-2 of 2 records</span>-->
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-16px">
|
<div class="flex items-center gap-16px">
|
||||||
<AInput
|
<AInput
|
||||||
@@ -154,65 +159,82 @@ const handleHome = (record: SiteData) => {
|
|||||||
<search-outlined />
|
<search-outlined />
|
||||||
</template>
|
</template>
|
||||||
</AInput>
|
</AInput>
|
||||||
<AButton type="primary">
|
<!-- <AButton type="primary">-->
|
||||||
<template #icon>
|
<!-- <template #icon>-->
|
||||||
<plus-outlined />
|
<!-- <plus-outlined />-->
|
||||||
</template>
|
<!-- </template>-->
|
||||||
Import Site
|
<!-- Import Site-->
|
||||||
</AButton>
|
<!-- </AButton>-->
|
||||||
<AButton type="primary">
|
<!-- <AButton type="primary">-->
|
||||||
<template #icon>
|
<!-- <template #icon>-->
|
||||||
<plus-outlined />
|
<!-- <plus-outlined />-->
|
||||||
</template>
|
<!-- </template>-->
|
||||||
Add New Site
|
<!-- Add New Site-->
|
||||||
</AButton>
|
<!-- </AButton>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ATable
|
<ATable
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data-source="siteData"
|
:data-source="siteData"
|
||||||
:pagination="false"
|
:pagination="{
|
||||||
|
current: currentPage,
|
||||||
|
pageSize: pageSize,
|
||||||
|
total: total,
|
||||||
|
showSizeChanger: true,
|
||||||
|
showQuickJumper: true,
|
||||||
|
showTotal: (total: number) => `共 ${total} 条`,
|
||||||
|
onChange: handlePageChange,
|
||||||
|
onShowSizeChange: handlePageSizeChange
|
||||||
|
}"
|
||||||
|
row-key="siteId"
|
||||||
:scroll="{ x: 1200 }"
|
:scroll="{ x: 1200 }"
|
||||||
row-key="id"
|
:loading="loading"
|
||||||
>
|
>
|
||||||
|
<!-- 添加一个调试信息 -->
|
||||||
|
<template #headerCell="{ column }">
|
||||||
|
<span>{{ column.title }}</span>
|
||||||
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
|
<!-- 添加调试信息 -->
|
||||||
|
{{ console.log('Rendering cell:', column.key, record) }}
|
||||||
<template v-if="column.key === 'name'">
|
<template v-if="column.key === 'name'">
|
||||||
<div class="flex items-center gap-8px">
|
<div class="flex items-center gap-8px">
|
||||||
<environment-outlined class="text-16px" />
|
<environment-outlined class="text-16px" />
|
||||||
<span>{{ record.name }}</span>
|
<span>{{ record.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-else-if="column.key === 'region'">
|
||||||
|
<span>{{ record.region }}</span>
|
||||||
|
</template>
|
||||||
<template v-else-if="column.key === 'alerts'">
|
<template v-else-if="column.key === 'alerts'">
|
||||||
<ATag v-if="record.alerts > 0" color="error">{{ record.alerts }}</ATag>
|
<span>0</span>
|
||||||
<span v-else>{{ record.alerts }}</span>
|
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="column.key === 'action'">
|
<template v-else-if="column.key === 'gateway'">
|
||||||
<div class="flex items-center gap-8px">
|
<span>{{ record.connectedGatewayNum }}/{{ record.disconnectedGatewayNum }}</span>
|
||||||
<edit-outlined class="cursor-pointer text-primary" @click="handleEdit(record)" />
|
|
||||||
<copy-outlined class="cursor-pointer text-primary" @click="handleCopy(record)" />
|
|
||||||
<delete-outlined class="cursor-pointer text-red-500" @click="handleDelete(record)" />
|
|
||||||
<home-outlined class="cursor-pointer text-primary" @click="handleHome(record)" />
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
<template v-else-if="column.key === 'switches'">
|
||||||
|
<span>{{ record.connectedSwitchNum }}/{{ record.disconnectedSwitchNum }}</span>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.key === 'olts'">
|
||||||
|
<span>0/0</span>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.key === 'eaps'">
|
||||||
|
<span>{{ record.connectedApNum }}/{{ record.disconnectedApNum }}/{{ record.isolatedApNum }}</span>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.key === 'clients'">
|
||||||
|
<span>{{ record.wiredClientNum }}/{{ record.wirelessClientNum }}/{{ record.guestNum }}</span>
|
||||||
|
</template>
|
||||||
|
<!-- <template v-else-if="column.key === 'action'">-->
|
||||||
|
<!-- <div class="flex items-center gap-8px">-->
|
||||||
|
<!-- <edit-outlined class="cursor-pointer text-primary" @click="handleEdit(record)" />-->
|
||||||
|
<!-- <copy-outlined class="cursor-pointer text-primary" @click="handleCopy(record)" />-->
|
||||||
|
<!-- <delete-outlined class="cursor-pointer text-red-500" @click="handleDelete(record)" />-->
|
||||||
|
<!-- <home-outlined class="cursor-pointer text-primary" @click="handleHome(record)" />-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </template>-->
|
||||||
</template>
|
</template>
|
||||||
</ATable>
|
</ATable>
|
||||||
|
|
||||||
<div class="flex justify-between items-center mt-16px">
|
|
||||||
<div class="text-12px text-gray-500">
|
|
||||||
Showing 1-2 of 2 records
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-8px">
|
|
||||||
<ASelect v-model:value="pageSize" style="width: 100px">
|
|
||||||
<ASelectOption :value="10">10 / page</ASelectOption>
|
|
||||||
<ASelectOption :value="20">20 / page</ASelectOption>
|
|
||||||
<ASelectOption :value="50">50 / page</ASelectOption>
|
|
||||||
</ASelect>
|
|
||||||
<span class="text-12px text-gray-500">Go to page:</span>
|
|
||||||
<AInput v-model:value="currentPage" style="width: 50px" />
|
|
||||||
<AButton>Go</AButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ACard>
|
</ACard>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import {
|
|||||||
UserAddOutlined,
|
UserAddOutlined,
|
||||||
UserSwitchOutlined
|
UserSwitchOutlined
|
||||||
} from '@ant-design/icons-vue';
|
} from '@ant-design/icons-vue';
|
||||||
|
import { computed, ref, onMounted } from 'vue';
|
||||||
|
import { getDashboardOverview } from '@/service/api/auth';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'HeaderBanner'
|
name: 'HeaderBanner'
|
||||||
@@ -14,25 +16,61 @@ defineOptions({
|
|||||||
|
|
||||||
const overviewData = ref<Api.DashboardOverview>({
|
const overviewData = ref<Api.DashboardOverview>({
|
||||||
cloud: { connected: false },
|
cloud: { connected: false },
|
||||||
sites: { total: 0, countries: 0, connected: 0, disconnected: 0 },
|
siteNum: 0,
|
||||||
devices: {
|
devices: {
|
||||||
gateways: { connected: 0, disconnected: 0 },
|
totalGatewayNum: 0,
|
||||||
switches: { connected: 0, disconnected: 0 },
|
connectedGatewayNum: 0,
|
||||||
olts: { connected: 0, disconnected: 0 },
|
disconnectedGatewayNum: 0,
|
||||||
ap: { connected: 0, disconnected: 0, isolated: 0 }
|
totalSwitchNum: 0,
|
||||||
|
connectedSwitchNum: 0,
|
||||||
|
disconnectedSwitchNum: 0,
|
||||||
|
totalApNum: 0,
|
||||||
|
connectedApNum: 0,
|
||||||
|
disconnectedApNum: 0,
|
||||||
|
isolatedApNum: 0
|
||||||
},
|
},
|
||||||
client: { wiredUsers: 0, wirelessUsers: 0, wirelessGuests: 0 },
|
client: {
|
||||||
alerts: 0,
|
totalClientNum: 0,
|
||||||
users: { registered: 0, online: 0 }
|
wiredClientNum: 0,
|
||||||
|
wirelessClientNum: 0,
|
||||||
|
guestNum: 0
|
||||||
|
},
|
||||||
|
registerUserNum: 0,
|
||||||
|
onlineUserNum: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchOverviewData = async () => {
|
const fetchOverviewData = async () => {
|
||||||
// try {
|
try {
|
||||||
// const data = await authStore.getDashboardOverview();
|
const { data } = await getDashboardOverview();
|
||||||
// overviewData.value = data;
|
if (data) {
|
||||||
// } catch (error) {
|
overviewData.value = {
|
||||||
// console.error('Failed to fetch overview data:', error);
|
cloud: { connected: data.cloud?.connected || false },
|
||||||
// }
|
siteNum: data.siteNum || 0,
|
||||||
|
devices: {
|
||||||
|
totalGatewayNum: data.devices?.totalGatewayNum || 0,
|
||||||
|
connectedGatewayNum: data.devices?.connectedGatewayNum || 0,
|
||||||
|
disconnectedGatewayNum: data.devices?.disconnectedGatewayNum || 0,
|
||||||
|
totalSwitchNum: data.devices?.totalSwitchNum || 0,
|
||||||
|
connectedSwitchNum: data.devices?.connectedSwitchNum || 0,
|
||||||
|
disconnectedSwitchNum: data.devices?.disconnectedSwitchNum || 0,
|
||||||
|
totalApNum: data.devices?.totalApNum || 0,
|
||||||
|
connectedApNum: data.devices?.connectedApNum || 0,
|
||||||
|
disconnectedApNum: data.devices?.disconnectedApNum || 0,
|
||||||
|
isolatedApNum: data.devices?.isolatedApNum || 0
|
||||||
|
},
|
||||||
|
client: {
|
||||||
|
totalClientNum: data.client?.totalClientNum || 0,
|
||||||
|
wiredClientNum: data.client?.wiredClientNum || 0,
|
||||||
|
wirelessClientNum: data.client?.wirelessClientNum || 0,
|
||||||
|
guestNum: data.client?.guestNum || 0
|
||||||
|
},
|
||||||
|
registerUserNum: data.registerUserNum || 0,
|
||||||
|
onlineUserNum: data.onlineUserNum || 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch overview data:', error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -40,18 +78,43 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const deviceStatus = computed(() => ({
|
const deviceStatus = computed(() => ({
|
||||||
ap: overviewData.value.devices.ap,
|
ap: {
|
||||||
client: overviewData.value.client,
|
connected: overviewData.value.devices.connectedApNum,
|
||||||
alerts: overviewData.value.alerts,
|
disconnected: overviewData.value.devices.disconnectedApNum,
|
||||||
users: overviewData.value.users
|
isolated: overviewData.value.devices.isolatedApNum
|
||||||
|
},
|
||||||
|
client: {
|
||||||
|
wiredUsers: overviewData.value.client.wiredClientNum,
|
||||||
|
wirelessUsers: overviewData.value.client.wirelessClientNum,
|
||||||
|
wirelessGuests: overviewData.value.client.guestNum
|
||||||
|
},
|
||||||
|
users: {
|
||||||
|
registered: overviewData.value.registerUserNum,
|
||||||
|
online: overviewData.value.onlineUserNum
|
||||||
|
},
|
||||||
|
alerts: 0
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const siteInfo = computed(() => overviewData.value.sites);
|
const siteInfo = computed(() => ({
|
||||||
|
total: overviewData.value.siteNum
|
||||||
|
}));
|
||||||
|
|
||||||
const otherDevices = computed(() => ({
|
const otherDevices = computed(() => ({
|
||||||
gateways: overviewData.value.devices.gateways,
|
gateways: {
|
||||||
switches: overviewData.value.devices.switches,
|
total: overviewData.value.devices.totalGatewayNum,
|
||||||
olts: overviewData.value.devices.olts
|
connected: overviewData.value.devices.connectedGatewayNum,
|
||||||
|
disconnected: overviewData.value.devices.disconnectedGatewayNum
|
||||||
|
},
|
||||||
|
switches: {
|
||||||
|
total: overviewData.value.devices.totalSwitchNum,
|
||||||
|
connected: overviewData.value.devices.connectedSwitchNum,
|
||||||
|
disconnected: overviewData.value.devices.disconnectedSwitchNum
|
||||||
|
},
|
||||||
|
olts: {
|
||||||
|
total: 0,
|
||||||
|
connected: 0,
|
||||||
|
disconnected: 0
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -87,9 +150,6 @@ const otherDevices = computed(() => ({
|
|||||||
<div class="border-t border-gray-100 my-4px"></div>
|
<div class="border-t border-gray-100 my-4px"></div>
|
||||||
<div class="flex flex-col text-12px text-gray-500">
|
<div class="flex flex-col text-12px text-gray-500">
|
||||||
<span>Total Sites: {{ siteInfo.total }}</span>
|
<span>Total Sites: {{ siteInfo.total }}</span>
|
||||||
<span>Countries: {{ siteInfo.countries }}</span>
|
|
||||||
<span>Connected: {{ siteInfo.connected }}</span>
|
|
||||||
<span>Disconnected: {{ siteInfo.disconnected }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -130,7 +190,7 @@ const otherDevices = computed(() => ({
|
|||||||
<div class="flex items-center gap-6px mb-6px">
|
<div class="flex items-center gap-6px mb-6px">
|
||||||
<div class="size-48px flex-center bg-gray-100 rounded-lg relative">
|
<div class="size-48px flex-center bg-gray-100 rounded-lg relative">
|
||||||
<group-outlined class="text-24px text-primary" />
|
<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.connected + otherDevices.olts.disconnected }}</span>
|
<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>
|
||||||
<div class="text-16px font-medium">OLTs</div>
|
<div class="text-16px font-medium">OLTs</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -213,8 +273,8 @@ const otherDevices = computed(() => ({
|
|||||||
</div>
|
</div>
|
||||||
<div class="border-t border-gray-100 my-4px"></div>
|
<div class="border-t border-gray-100 my-4px"></div>
|
||||||
<div class="flex flex-col text-12px text-gray-500">
|
<div class="flex flex-col text-12px text-gray-500">
|
||||||
<span>Total: {{ deviceStatus.alerts }}</span>
|
<span>Total: {{ deviceStatus.alerts || 0 }}</span>
|
||||||
<span>Active: {{ deviceStatus.alerts }}</span>
|
<span>Active: {{ deviceStatus.alerts || 0 }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user