feat:流量格式化MB、GB

This commit is contained in:
zhongzm
2025-09-19 09:18:32 +08:00
parent 1c025c2cc1
commit 98e4d39cdf
2 changed files with 130 additions and 15 deletions

114
src/utils/traffic-utils.ts Normal file
View File

@@ -0,0 +1,114 @@
/**
* 流量数据转换工具类
* 提供字节(byte)到MB/GB的转换功能
*/
/**
* 流量转换结果类型
*/
export interface TrafficConversionResult {
/** 转换后的数值 */
value: number;
/** 单位 */
unit: 'MB' | 'GB';
/** 格式化后的字符串 */
formatted: string;
}
/**
* 将字节转换为MB或GB
* @param bytes 字节数
* @param precision 小数点精度默认为2位
* @returns 转换结果对象
*/
export function convertBytesToTraffic(bytes: number | string, precision: number = 2): TrafficConversionResult {
// 处理输入参数
const numBytes = typeof bytes === 'string' ? parseFloat(bytes) : bytes;
// 处理无效输入
if (isNaN(numBytes) || numBytes < 0) {
return {
value: 0,
unit: 'MB',
formatted: '0 MB'
};
}
// 转换常量
const MB = 1024 * 1024; // 1MB = 1024 * 1024 bytes
const GB = 1024 * 1024 * 1024; // 1GB = 1024 * 1024 * 1024 bytes
// 如果大于等于1GB转换为GB
if (numBytes >= GB) {
const value = parseFloat((numBytes / GB).toFixed(precision));
return {
value,
unit: 'GB',
formatted: `${value} GB`
};
}
// 否则转换为MB包括KB也转换为MB
const value = parseFloat((numBytes / MB).toFixed(precision));
return {
value,
unit: 'MB',
formatted: `${value} MB`
};
}
/**
* 批量转换流量数据
* @param dataList 包含流量字段的数据数组
* @param fields 需要转换的字段名数组
* @param precision 小数点精度默认为2位
* @returns 转换后的数据数组
*/
export function convertTrafficFields(
dataList: Record<string, any>[],
fields: string[],
precision: number = 2
): Record<string, any>[] {
return dataList.map(item => {
const convertedItem = { ...item };
fields.forEach(field => {
if (item[field] !== undefined && item[field] !== null) {
const conversion = convertBytesToTraffic(item[field], precision);
convertedItem[`${field}_converted`] = conversion;
}
});
return convertedItem;
});
}
/**
* 格式化流量显示(简化版本,直接返回格式化字符串)
* @param bytes 字节数
* @param precision 小数点精度默认为2位
* @returns 格式化后的流量字符串
*/
export function formatTraffic(bytes: number | string, precision: number = 2): string {
return convertBytesToTraffic(bytes, precision).formatted;
}
/**
* 计算总流量(上行+下行)
* @param uplink 上行流量(字节)
* @param downlink 下行流量(字节)
* @param precision 小数点精度默认为2位
* @returns 总流量的转换结果
*/
export function calculateTotalTraffic(
uplink: number | string,
downlink: number | string,
precision: number = 2
): TrafficConversionResult {
const uplinkBytes = typeof uplink === 'string' ? parseFloat(uplink) : uplink;
const downlinkBytes = typeof downlink === 'string' ? parseFloat(downlink) : downlink;
const totalBytes = (isNaN(uplinkBytes) ? 0 : uplinkBytes) + (isNaN(downlinkBytes) ? 0 : downlinkBytes);
return convertBytesToTraffic(totalBytes, precision);
}

View File

@@ -21,6 +21,7 @@ import PQueue from 'p-queue';
import saveAs from 'file-saver';
import dayjs, { type Dayjs } from 'dayjs';
import { useClipboard } from '@vueuse/core';
import { formatTraffic } from '@/utils/traffic-utils';
const { copy } = useClipboard({ legacy: true });
const { t } = useI18n();
const neListStore = useNeListStore();
@@ -155,7 +156,7 @@ let tableColumns = ref<ColumnsType>([
!Array.isArray(listOfMultipleUnitUsage) ||
listOfMultipleUnitUsage.length < 1
) {
return 0;
return formatTraffic(0);
}
let dataVolumeUplink = 0;
for (const v of listOfMultipleUnitUsage) {
@@ -165,7 +166,7 @@ let tableColumns = ref<ColumnsType>([
}
}
}
return dataVolumeUplink;
return formatTraffic(dataVolumeUplink);
},
},
{
@@ -180,7 +181,7 @@ let tableColumns = ref<ColumnsType>([
!Array.isArray(listOfMultipleUnitUsage) ||
listOfMultipleUnitUsage.length < 1
) {
return 0;
return formatTraffic(0);
}
let dataVolumeDownlink = 0;
for (const v of listOfMultipleUnitUsage) {
@@ -190,7 +191,7 @@ let tableColumns = ref<ColumnsType>([
}
}
}
return dataVolumeDownlink;
return formatTraffic(dataVolumeDownlink);
},
},
{
@@ -205,7 +206,7 @@ let tableColumns = ref<ColumnsType>([
!Array.isArray(listOfMultipleUnitUsage) ||
listOfMultipleUnitUsage.length < 1
) {
return 0;
return formatTraffic(0);
}
let dataTotalVolume = 0;
for (const v of listOfMultipleUnitUsage) {
@@ -215,7 +216,7 @@ let tableColumns = ref<ColumnsType>([
}
}
}
return dataTotalVolume;
return formatTraffic(dataTotalVolume);
},
},
{
@@ -812,15 +813,15 @@ onBeforeUnmount(() => {
<div>
<div>
<span>Data Total Volume: </span>
<span>{{ udata.dataTotalVolume }}</span>
<span>{{ formatTraffic(udata.dataTotalVolume || 0) }}</span>
</div>
<div>
<span>Data Volume Downlink: </span>
<span>{{ udata.dataVolumeDownlink }}</span>
<span>{{ formatTraffic(udata.dataVolumeDownlink || 0) }}</span>
</div>
<div>
<span>Data Volume Uplink: </span>
<span>{{ udata.dataVolumeUplink }}</span>
<span>{{ formatTraffic(udata.dataVolumeUplink || 0) }}</span>
</div>
<!-- <div>
<span>Time: </span>
@@ -835,19 +836,19 @@ onBeforeUnmount(() => {
<div>
<span>User Identifier: </span>
<span>{{
record.cdrJSON.pDUSessionChargingInformation?.userIdentifier
}}</span>
record.cdrJSON.pDUSessionChargingInformation?.userIdentifier
}}</span>
</div>
<div>
<span>SSC Mode: </span>
<span>{{
record.cdrJSON.pDUSessionChargingInformation?.sSCMode
}}</span>
record.cdrJSON.pDUSessionChargingInformation?.sSCMode
}}</span>
&nbsp;&nbsp;
<span>RAT Type: </span>
<span>{{
record.cdrJSON.pDUSessionChargingInformation?.rATType
}}</span>
record.cdrJSON.pDUSessionChargingInformation?.rATType
}}</span>
&nbsp;&nbsp;
<span>DNN ID: </span>
<span>