Files
device-voice-h5/components/TrafficCard.vue
luo e084cdeb90
All checks were successful
构建并部署前端到生产环境 / build-and-deploy (push) Successful in 2m14s
fix: some
2026-10-26 15:00:05 +08:00

147 lines
3.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="card traffic-card">
<view class="card-header flex-row-sb mb-lg">
<view class="title">本月流量</view>
<view class="usage-percent">
<text class="title">{{ usedFlowPercent }}</text>
<text class="caption">%</text>
</view>
</view>
<view class="progress-section mb-lg">
<view class="progress-apple">
<view class="progress-fill" :style="{width: usedFlowPercent + '%'}"></view>
</view>
</view>
<view class="traffic-stats flex-row-sb">
<view class="stat-item flex-col-center">
<view class="caption mb-xs">已使用</view>
<view class="stat-value-container">
<text class="stat-value">{{ usedValue }}</text>
<text class="stat-unit">{{ usedUnit }}</text>
</view>
</view>
<view class="stat-item flex-col-center">
<view class="caption mb-xs">总流量</view>
<view class="stat-value-container">
<text class="stat-value">{{ totalValue }}</text>
<text class="stat-unit">{{ totalUnit }}</text>
</view>
</view>
<view class="stat-item flex-col-center">
<view class="caption mb-xs">剩余</view>
<view class="stat-value-container">
<text class="stat-value">{{ remainValue }}</text>
<text class="stat-unit">{{ remainUnit }}</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import {
computed
} from 'vue';
const props = defineProps({
assetInfo: {
type: Object,
default: null
}
});
// 和首页共用最新资产快照,不保留只在首次进入时加载的套餐缓存。
const metrics = computed(() => props.assetInfo?.current_package_usage_id
? getTrafficMetrics(props.assetInfo)
: { used: 0, total: 0, remain: 0 });
const usedMB = computed(() => metrics.value.used);
const totalMB = computed(() => metrics.value.total);
const remainMB = computed(() => metrics.value.remain);
const toMB = (value) => Number(value) || 0;
// 格式化流量数据(MB 转 GB)
const formatTraffic = (mb) => {
if (!mb || mb === 0) {
return {
value: '0.00',
unit: 'MB'
};
}
if (mb >= 1024) {
return {
value: (mb / 1024).toFixed(2),
unit: 'GB'
};
}
return {
value: mb.toFixed(2),
unit: 'MB'
};
};
// 已使用流量
const usedValue = computed(() => formatTraffic(usedMB.value).value);
const usedUnit = computed(() => formatTraffic(usedMB.value).unit);
// 总流量
const totalValue = computed(() => formatTraffic(totalMB.value).value);
const totalUnit = computed(() => formatTraffic(totalMB.value).unit);
// 剩余流量
const remainValue = computed(() => formatTraffic(remainMB.value).value);
const remainUnit = computed(() => formatTraffic(remainMB.value).unit);
// 使用百分比
const usedFlowPercent = computed(() => {
if (totalMB.value > 0) {
const percent = (usedMB.value / totalMB.value * 100);
return Math.min(percent, 100).toFixed(2);
}
return '0.00';
});
const getTrafficMetrics = (data) => {
const enableVirtualData = !!data.enable_virtual_data;
const used = enableVirtualData ? toMB(data.virtual_used_mb) : toMB(data.real_used_mb);
const total = toMB(data.real_total_mb);
const remain = Math.max(total - used, 0);
return {
used,
total,
remain
};
};
</script>
<style scoped lang="scss">
.traffic-card {
.usage-percent {
display: flex;
align-items: baseline;
gap: 4rpx;
.title {
font-size: 35rpx;
font-weight: 700;
margin-right: 5rpx;
}
}
.traffic-stats {
background: var(--gray-100);
border-radius: var(--radius-small);
padding: 20rpx;
margin-top: 16rpx;
.stat-item {
flex: 1;
}
}
}
</style>