2
0

fix:cdr记录接口对接

This commit is contained in:
zhongzm
2024-12-18 17:28:12 +08:00
parent e2226aa944
commit f9b1274328

View File

@@ -1,40 +1,54 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref, onMounted } from 'vue'
import type { TableColumnsType } from 'ant-design-vue' import type { TableColumnsType } from 'ant-design-vue'
import { Table as ATable } from 'ant-design-vue' import { HistoryOutlined } from '@ant-design/icons-vue'
import {useI18n} from "vue-i18n"; import { useI18n } from "vue-i18n";
import { fetchCDRHistory } from '@/service/api/auth';
const {t} = useI18n(); const { t } = useI18n();
// 定义记录类型
interface CDRRecord { interface CDRRecord {
id: number id: number;
ap_name: string deviceName: string;
traffic_up: number macAddress: string;
traffic_down: number trafficUp: string;
up_time: string trafficDown: string;
last_seen_time: string startTime: string;
endTime: string;
} }
// 模拟数据 // 定义API返回的原始数据类型
const cdrData = ref<CDRRecord[]>([ interface RawCDRRecord {
{ id: number;
id: 1, clientName: string;
ap_name: 'AP-Office-01', clientMac: string;
traffic_up: 1024, trafficUp: number; // 字节数
traffic_down: 2048, trafficDown: number; // 字节数
up_time: '2024-03-15 08:00:00', startTime: number; // 时间戳
last_seen_time: '2024-03-15 17:30:00' endTime: number; // 时间戳
}, }
{
id: 2, // CDR记录数据
ap_name: 'AP-Meeting-02', const cdrData = ref<CDRRecord[]>([]);
traffic_up: 512, const loading = ref(false);
traffic_down: 1536, const pagination = ref({
up_time: '2024-03-15 09:15:00', current: 1,
last_seen_time: '2024-03-15 16:45:00' pageSize: 10,
}, total: 0
// 可以添加更多测试数据... });
])
// 展开行控制
const expandedRowKeys = ref<number[]>([]);
// 处理展开行变化
function handleExpandChange(expanded: boolean, record: CDRRecord) {
if (expanded) {
expandedRowKeys.value = [record.id];
} else {
expandedRowKeys.value = [];
}
}
// 格式化流量数据的函数 // 格式化流量数据的函数
const formatTraffic = (bytes: number): string => { const formatTraffic = (bytes: number): string => {
@@ -44,79 +58,167 @@ const formatTraffic = (bytes: number): string => {
return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB` return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`
} }
// 格式化时间戳
function formatTimestamp(timestamp: number): string {
const date = new Date(timestamp);
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
}
const columns: TableColumnsType = [ const columns: TableColumnsType = [
{ {
title: t('page.cdrlrecords.devicename'), title: t('page.cdrlrecords.devicename'),
dataIndex: 'ap_name', dataIndex: 'deviceName',
key: 'ap_name', key: 'deviceName',
width: 140 width: '40%'
}, },
{ {
title: t('page.cdrlrecords.uptraffic'), title: t('page.cdrlrecords.uptraffic'),
dataIndex: 'traffic_up', dataIndex: 'trafficUp',
key: 'traffic_up', key: 'trafficUp',
width: 100, width: '30%',
customRender: ({ text }) => formatTraffic(text) align: 'right'
}, },
{ {
title: t('page.cdrlrecords.downtraffic'), title: t('page.cdrlrecords.downtraffic'),
dataIndex: 'traffic_down', dataIndex: 'trafficDown',
key: 'traffic_down', key: 'trafficDown',
width: 100, width: '30%',
customRender: ({ text }) => formatTraffic(text) align: 'right'
},
{
title: t('page.cdrlrecords.uptime'),
dataIndex: 'up_time',
key: 'up_time',
width: 160
},
{
title: t('page.cdrlrecords.lasttime'),
dataIndex: 'last_seen_time',
key: 'last_seen_time',
width: 160
} }
] ];
// 获取CDR记录数据
async function getCDRHistory(page = pagination.value.current, pageSize = pagination.value.pageSize) {
loading.value = true;
try {
const { data, error } = await fetchCDRHistory({
pageNum: page,
pageSize: pageSize
});
if (!error && data) {
// 将原始数据映射为显示所需的格式
cdrData.value = data.rows.map((item: RawCDRRecord) => ({
id: item.id,
deviceName: item.clientName,
macAddress: item.clientMac,
trafficUp: formatTraffic(item.trafficUp), // 格式化上传流量
trafficDown: formatTraffic(item.trafficDown), // 格式化下载流量
startTime: formatTimestamp(item.startTime), // 格式化开始时间
endTime: formatTimestamp(item.endTime) // 格式化结束时间
}));
pagination.value.total = data.total;
}
} catch (err) {
console.error('Failed to fetch CDR history:', err);
} finally {
loading.value = false;
}
}
// 处理分页变化
function handleTableChange(pag: any) {
pagination.value.current = pag.current;
pagination.value.pageSize = pag.pageSize;
getCDRHistory(pag.current, pag.pageSize);
}
// 刷新设备列表
async function handleRefresh() {
await getCDRHistory();
}
// 组件挂载时获取数据
onMounted(() => {
getCDRHistory();
});
</script> </script>
<template> <template>
<div class="p-4"> <div class="device-list-container">
<div class="text-lg font-bold mb-4">{{t('page.cdrlrecords.cdr')}}</div> <a-card :bordered="false">
<div class="table-container"> <template #title>
<ATable <div class="card-title">
<HistoryOutlined />
<span>{{ t('page.cdrlrecords.cdr') }}</span>
</div>
</template>
<template #extra>
<a-button type="primary" :loading="loading" @click="handleRefresh">
<template #icon>
<span class="i-carbon:refresh"></span>
</template>
{{ t('page.cdrlrecords.refresh') }}
</a-button>
</template>
<a-table
:loading="loading"
:columns="columns" :columns="columns"
:data-source="cdrData" :data-source="cdrData"
:row-key="(record: CDRRecord) => record.id" :row-key="(record: CDRRecord) => record.id"
:expanded-row-keys="expandedRowKeys"
@expand="handleExpandChange"
:pagination="{ :pagination="{
pageSize: 10, current: pagination.current,
total: cdrData.length, pageSize: pagination.pageSize,
total: pagination.total,
showTotal: (total: number) => `${total}`, showTotal: (total: number) => `${total}`,
showSizeChanger: true, showSizeChanger: true,
showQuickJumper: true, showQuickJumper: true,
pageSizeOptions: ['10', '20', '50', '100'] pageSizeOptions: ['10', '20', '50', '100']
}" }"
/> @change="handleTableChange"
</div> >
<template #expandedRowRender="{ record }">
<div class="pl-4">
<div>{{ t('page.cdrlrecords.mac') }}: {{ record.macAddress }}</div>
<div>{{ t('page.cdrlrecords.uptime') }}: {{ record.startTime }}</div>
<div>{{ t('page.cdrlrecords.lasttime') }}: {{ record.endTime }}</div>
</div>
</template>
</a-table>
</a-card>
</div> </div>
</template> </template>
<style scoped> <style scoped>
.p-4 { .device-list-container {
padding: 1rem; padding: 8px;
background-color: #f5f5f7;
min-height: 100vh;
} }
.mb-4 {
margin-bottom: 1rem; .card-title {
display: flex;
align-items: center;
gap: 8px;
font-size: 16px;
font-weight: 500;
} }
.text-lg {
font-size: 1.125rem; :deep(.ant-card-head) {
border-bottom: 1px solid #f0f0f0;
padding: 0 12px;
} }
.font-bold {
font-weight: bold; :deep(.ant-card-body) {
padding: 12px;
} }
.table-container {
:deep(.ant-table-wrapper) {
width: 100%;
}
:deep(.ant-table) {
width: 100%; width: 100%;
overflow-x: auto;
} }
/* 使表格更紧凑的样式 */ /* 使表格更紧凑的样式 */
@@ -146,4 +248,14 @@ const columns: TableColumnsType = [
white-space: normal; white-space: normal;
word-break: break-word; word-break: break-word;
} }
@media screen and (min-width: 768px) {
.device-list-container {
padding: 16px;
}
}
.pl-4 {
padding-left: 1rem;
}
</style> </style>