2
0

feat:上网详单界面

This commit is contained in:
zhongzm
2024-12-11 09:37:58 +08:00
parent b8111b27c7
commit 16eb770cf1

View File

@@ -0,0 +1,437 @@
<script setup lang="ts">
import { ref, watch } from 'vue'
import { Card, Radio, Statistic } from 'ant-design-vue'
import {useI18n} from "vue-i18n";
const {t} = useI18n();
interface InternetRecord {
id: number
network_type: string
location: string
start_time: string
total_traffic: number
fee: number
}
// 修改月份选择相关的代码
const getCurrentYearMonth = () => {
const now = new Date()
return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`
}
// 生成月份数组
const generateMonths = () => {
const months: string[] = []
const now = new Date()
const currentYear = now.getFullYear()
// 添加去年12月
months.push(`${currentYear - 1}-12`)
// 添加今年的月份从1月到当前月
for (let i = 1; i <= 12; i++) {
months.push(`${currentYear}-${String(i).padStart(2, '0')}`)
}
return months.reverse() // 反转数组使最近的月份在前面
}
// 更新月份选择相关的变量
const selectedMonth = ref(getCurrentYearMonth())
const months = generateMonths()
// 总流量统计
const totalTraffic = ref(15.65) // GB
// 模拟数据
const internetData = ref<InternetRecord[]>([
{
id: 1,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-11-01 00:28:04',
total_traffic: 17 * 1024, // 17KB
fee: 0
},
{
id: 2,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-11-01 02:28:10',
total_traffic: 16 * 1024, // 16KB
fee: 0
}
])
// 修改流量格式化和计算方法
const formatTraffic = (bytes: number): string => {
const KB = 1024;
const MB = KB * 1024;
const GB = MB * 1024;
if (bytes < KB) {
return `${Math.max(1, bytes)}KB`; // 最小单位为1KB
} else if (bytes < MB) {
return `${(bytes / KB).toFixed(1)}KB`;
} else if (bytes < GB) {
return `${(bytes / MB).toFixed(1)}MB`;
} else {
return `${(bytes / GB).toFixed(2)}GB`;
}
};
// 修改总流量计算方法
const calculateTotalTraffic = (data: InternetRecord[]): number => {
const KB = 1024;
const MB = KB * 1024;
const GB = MB * 1024;
// 计算总字节数
const totalBytes = data.reduce((sum, record) => {
// 确保最小单位为1KB
const bytes = Math.max(record.total_traffic, KB);
return sum + bytes;
}, 0);
// 转换为GB并保留两位小数
return Number((totalBytes / GB).toFixed(2));
};
// 修改模拟数据,为每个月添加详单
const getMonthData = (month: string) => {
const KB = 1024;
const MB = KB * 1024;
const GB = MB * 1024;
const mockData: Record<string, InternetRecord[]> = {
'2024-12': [
{
id: 1,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-12-01 08:28:04',
total_traffic: 3.5 * GB, // 3.5GB
fee: 0
},
{
id: 2,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-12-05 14:30:00',
total_traffic: 800 * KB, // 800KB
fee: 0
}
],
'2024-11': [
{
id: 3,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-11-01 00:28:04',
total_traffic: 17 * KB, // 17KB
fee: 0
},
{
id: 4,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-11-01 02:28:10',
total_traffic: 16 * KB, // 16KB
fee: 0
},
{
id: 5,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-11-01 04:28:17',
total_traffic: 15.65 * GB, // 15.65GB
fee: 0
}
],
'2024-10': [
{
id: 6,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-10-15 14:20:00',
total_traffic: 8.2 * GB, // 8.2GB
fee: 0
},
{
id: 7,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-10-20 09:15:00',
total_traffic: 150 * MB, // 150MB
fee: 0
}
],
'2024-09': [
{
id: 8,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-09-10 10:15:00',
total_traffic: 5.8 * GB, // 5.8GB
fee: 0
},
{
id: 9,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-09-25 16:30:00',
total_traffic: 2.4 * GB, // 2.4GB
fee: 0
}
],
'2024-08': [
{
id: 10,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-08-05 16:45:00',
total_traffic: 12.3 * GB, // 12.3GB
fee: 0
},
{
id: 11,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-08-18 11:20:00',
total_traffic: 450 * MB, // 450MB
fee: 0
}
],
'2024-07': [
{
id: 12,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-07-01 09:30:00',
total_traffic: 6.7 * GB, // 6.7GB
fee: 0
},
{
id: 13,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-07-15 14:45:00',
total_traffic: 3.2 * GB, // 3.2GB
fee: 0
}
],
'2024-06': [
{
id: 14,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-06-10 11:20:00',
total_traffic: 4.9 * GB, // 4.9GB
fee: 0
},
{
id: 15,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2024-06-28 15:40:00',
total_traffic: 750 * MB, // 750MB
fee: 0
}
],
'2023-12': [
{
id: 16,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2023-12-20 20:15:00',
total_traffic: 7.8 * GB, // 7.8GB
fee: 0
},
{
id: 17,
network_type: 'CMNET',
location: '广东省 4G/5G',
start_time: '2023-12-31 23:59:59',
total_traffic: 1.2 * GB, // 1.2GB
fee: 0
}
]
};
return mockData[month] || [];
};
// 初始化数据
internetData.value = getMonthData(selectedMonth.value)
totalTraffic.value = calculateTotalTraffic(internetData.value)
// 监听月份变化时重新计算总流量
watch(selectedMonth, (newMonth: string) => {
internetData.value = getMonthData(newMonth)
totalTraffic.value = calculateTotalTraffic(internetData.value)
})
</script>
<template>
<div class="internet-details p-4">
<!-- 月份选择 -->
<div class="month-selector-wrapper">
<Radio.Group v-model:value="selectedMonth" class="month-selector">
<Radio.Button v-for="month in months" :key="month" :value="month">
<div class="month-label">
<div class="month">{{ month.split('-')[1] }}{{ t('page.Internetdetails.month') }}</div>
<div class="year">{{ month.split('-')[0] }}{{ t('page.Internetdetails.year') }}</div>
</div>
</Radio.Button>
</Radio.Group>
</div>
<!-- 流量统计 -->
<Card class="mb-4">
<div class="text-gray-400 text-sm mb-2">
流量单位换算关系为1GB=1024MB1MB=1024KB如上网流量不足1KB则向1KB累进移动计费准确请您放心使用
</div>
<Statistic
:title="t('page.Internetdetails.monthtraffic')"
:value="totalTraffic"
:precision="2"
suffix="GB"
/>
</Card>
<!-- 修改详单列表部分 -->
<div class="records-list">
<div v-for="record in internetData" :key="record.id" class="record-card">
<div class="record-header">
<div class="network-type">{{ record.network_type }}</div>
<div class="location">{{ record.location }}</div>
</div>
<div class="record-details">
<div class="detail-item">
<span class="label">{{ t('page.Internetdetails.starttime') }}</span>
<span class="value">{{ record.start_time }}</span>
</div>
<div class="detail-item">
<span class="label">{{ t('page.Internetdetails.totaltraffic') }}</span>
<span class="value">{{ formatTraffic(record.total_traffic) }}</span>
</div>
<div class="detail-item">
<span class="label">{{ t('page.Internetdetails.fee') }}</span>
<span class="value fee">¥{{ record.fee.toFixed(2) }}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.internet-details {
background: #fff;
}
.mb-4 {
margin-bottom: 1rem;
}
.month-selector-wrapper {
margin-bottom: 1rem;
overflow-x: auto;
-webkit-overflow-scrolling: touch; /* 为 iOS 添加弹性滚动 */
}
.month-selector {
display: flex;
flex-wrap: nowrap;
padding-bottom: 5px; /* 为滚动条预留空间 */
}
.month-selector :deep(.ant-radio-button-wrapper) {
height: auto;
padding: 4px 12px;
min-width: 85px;
text-align: center;
}
.month-label {
display: flex;
flex-direction: column;
align-items: center;
line-height: 1.4;
padding: 2px 0;
}
.month {
font-size: 16px;
font-weight: 500;
}
.year {
font-size: 12px;
color: #666;
margin-top: 2px;
}
/* 隐藏滚动条但保持功能 - 针对 Webkit 浏览器 */
.month-selector-wrapper::-webkit-scrollbar {
height: 4px;
}
.month-selector-wrapper::-webkit-scrollbar-track {
background: #f1f1f1;
}
.month-selector-wrapper::-webkit-scrollbar-thumb {
background: #888;
border-radius: 2px;
}
/* 修改详单列表样式 */
.records-list {
display: flex;
flex-direction: column;
gap: 12px;
width: 100%;
}
.record-card {
background: #fff;
border-radius: 8px;
padding: 16px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
border: 1px solid #f0f0f0;
width: 100%;
}
.record-header {
display: flex;
justify-content: space-between;
margin-bottom: 12px;
font-size: 16px;
font-weight: 500;
}
.record-details {
display: flex;
flex-direction: column;
gap: 8px;
}
.detail-item {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 14px;
line-height: 1.5;
padding: 4px 0;
}
.label {
color: #666;
}
.value {
color: #333;
}
.fee {
color: #1890ff;
}
.network-type {
color: #333;
}
.location {
color: #666;
}
</style>