feat:上网详单界面
This commit is contained in:
437
src/views/billing/Internetdetails/index.vue
Normal file
437
src/views/billing/Internetdetails/index.vue
Normal 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=1024MB,1MB=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>
|
||||
Reference in New Issue
Block a user