fix: 资产套餐历史,设备换货
All checks were successful
构建并部署前端到生产环境 / build-and-deploy (push) Successful in 47s

This commit is contained in:
sexygoat
2026-04-14 11:11:24 +08:00
parent 5fa2b6dacf
commit 4ce6b8ddc1
4 changed files with 129 additions and 49 deletions

View File

@@ -47,16 +47,16 @@
<view class="flow-title">流量信息</view>
<view class="flow-stats">
<view class="flow-item">
<view class="flow-label">已用真流量</view>
<view class="flow-value">{{ formatMB(item.data_usage_mb) }}</view>
<view class="flow-label">使</view>
<view class="flow-value">{{ getUsedFlow(item) }}</view>
</view>
<view class="flow-item">
<view class="flow-label">量真流量</view>
<view class="flow-value">{{ formatMB(item.data_limit_mb) }}</view>
<view class="flow-label">总流量</view>
<view class="flow-value">{{ getTotalFlow(item) }}</view>
</view>
<view class="flow-item">
<view class="flow-label">剩余虚流量</view>
<view class="flow-value">{{ formatMB(item.virtual_remain_mb) }}</view>
<view class="flow-label">剩余</view>
<view class="flow-value">{{ getRemainFlow(item) }}</view>
</view>
</view>
<view class="progress-section">
@@ -101,16 +101,63 @@
};
const formatMB = (mb) => {
if (!mb) return '0';
if (!mb && mb !== 0) return '0 MB';
if (mb >= 1024) {
return (mb / 1024).toFixed(2) + ' GB';
}
return mb + ' MB';
return mb.toFixed(2) + ' MB';
};
// 获取已使用流量
const getUsedFlow = (item) => {
if (item.enable_virtual_data) {
// 启用虚流量,显示已用虚流量
return formatMB(item.virtual_used_mb || 0);
} else {
// 未启用虚流量,显示已用真流量
return formatMB(item.data_usage_mb || 0);
}
};
// 获取总流量
const getTotalFlow = (item) => {
if (item.enable_virtual_data) {
// 启用虚流量,显示虚流量总量
return formatMB(item.virtual_limit_mb || 0);
} else {
// 未启用虚流量,显示真流量总量
return formatMB(item.data_limit_mb || 0);
}
};
// 获取剩余流量
const getRemainFlow = (item) => {
if (item.enable_virtual_data) {
// 启用虚流量,显示剩余虚流量
return formatMB(item.virtual_remain_mb || 0);
} else {
// 未启用虚流量,计算剩余真流量
const remain = (item.data_limit_mb || 0) - (item.data_usage_mb || 0);
return formatMB(remain);
}
};
// 获取使用百分比
const getUsagePercent = (item) => {
if (!item.data_limit_mb) return 0;
return Math.min((item.data_usage_mb / item.data_limit_mb) * 100, 100).toFixed(2);
let used, total;
if (item.enable_virtual_data) {
// 启用虚流量
used = item.virtual_used_mb || 0;
total = item.virtual_limit_mb || 0;
} else {
// 未启用虚流量
used = item.data_usage_mb || 0;
total = item.data_limit_mb || 0;
}
if (!total) return 0;
return Math.min((used / total) * 100, 100).toFixed(2);
};
const formatDate = (dateStr) => {

View File

@@ -32,7 +32,7 @@
<script setup>
import { ref, reactive, onMounted } from 'vue';
import { deviceApi, realnameApi } from '@/api/index.js';
import { assetApi, deviceApi, realnameApi } from '@/api/index.js';
import { useUserStore } from '@/store/index.js';
const userStore = useUserStore();
@@ -55,13 +55,28 @@
const loadCards = async () => {
try {
const data = await deviceApi.getCards(userStore.state.identifier);
if (data.cards && data.cards.length > 0) {
list.splice(0, list.length, ...data.cards.map(card => ({
iccid: card.iccid,
category: getCarrierCategory(card.carrier_name),
isRealName: card.real_name_status === 1
})));
const assetData = await assetApi.getInfo(userStore.state.identifier);
// 判断是否为设备
if (assetData.asset_type === 'device') {
// 是设备,调用设备卡列表接口
const data = await deviceApi.getCards(userStore.state.identifier);
if (data.cards && data.cards.length > 0) {
list.splice(0, list.length, ...data.cards.map(card => ({
iccid: card.iccid,
category: getCarrierCategory(card.carrier_name),
isRealName: card.real_name_status === 1
})));
}
} else {
// 不是设备(单卡),直接使用 asset info 数据
if (assetData.identifier) {
list.splice(0, list.length, {
iccid: assetData.identifier,
category: getCarrierCategory(assetData.carrier_name),
isRealName: assetData.real_name_status === 1
});
}
}
} catch (e) {
console.error('加载卡列表失败', e);

View File

@@ -8,34 +8,34 @@
<view v-else-if="exchangeData" class="card exchange-card">
<view class="exchange-header flex-row-sb">
<view class="exchange-no">{{ exchangeData.exchange_no }}</view>
<view class="tag-apple" :class="getStatusClass(exchangeData.status)">{{ exchangeData.status_text }}</view>
<view class="exchange-no">{{ exchangeData?.exchange_no }}</view>
<view class="tag-apple" :class="getStatusClass(exchangeData?.status)">{{ exchangeData?.status_text }}</view>
</view>
<view class="exchange-info">
<view class="info-row flex-row-sb">
<view class="info-label">换货原因</view>
<view class="info-value">{{ exchangeData.exchange_reason }}</view>
<view class="info-value">{{ exchangeData?.exchange_reason }}</view>
</view>
<view class="info-row flex-row-sb">
<view class="info-label">申请时间</view>
<view class="info-value">{{ formatTime(exchangeData.created_at) }}</view>
<view class="info-value">{{ formatTime(exchangeData?.created_at) }}</view>
</view>
<view class="info-row flex-row-sb" v-if="exchangeData.recipient_name">
<view class="info-row flex-row-sb" v-if="exchangeData?.recipient_name">
<view class="info-label">收件人</view>
<view class="info-value">{{ exchangeData.recipient_name }}</view>
<view class="info-value">{{ exchangeData?.recipient_name }}</view>
</view>
<view class="info-row flex-row-sb" v-if="exchangeData.recipient_phone">
<view class="info-row flex-row-sb" v-if="exchangeData?.recipient_phone">
<view class="info-label">联系电话</view>
<view class="info-value">{{ exchangeData.recipient_phone }}</view>
<view class="info-value">{{ exchangeData?.recipient_phone }}</view>
</view>
<view class="info-row flex-row-sb" v-if="exchangeData.recipient_address">
<view class="info-row flex-row-sb" v-if="exchangeData?.recipient_address">
<view class="info-label">收货地址</view>
<view class="info-value address-value">{{ exchangeData.recipient_address }}</view>
<view class="info-value address-value">{{ exchangeData?.recipient_address }}</view>
</view>
</view>
<view class="exchange-actions" v-if="exchangeData.status === 1">
<view class="exchange-actions" v-if="exchangeData?.status === 1">
<button class="btn-apple btn-primary" @tap="openPopup">填写信息</button>
</view>
</view>
@@ -71,7 +71,7 @@
const userStore = useUserStore();
let exchangeData = reactive(null);
let exchangeData = ref(null);
let loading = ref(false);
let showPopup = ref(false);
let form = reactive({
@@ -100,11 +100,11 @@
loading.value = true;
try {
const data = await exchangeApi.getPending(userStore.state.identifier);
if (data) {
exchangeData.splice(0, exchangeData.length, data);
}
// 接口返回的是单个对象,不是数组
exchangeData.value = data || null;
} catch (e) {
console.error('加载换货记录失败', e);
exchangeData.value = null;
}
loading.value = false;
};
@@ -132,7 +132,7 @@
try {
await exchangeApi.submitShippingInfo(
exchangeData.id,
exchangeData.value.id,
form.recipient_name,
form.recipient_phone,
form.recipient_address

View File

@@ -14,9 +14,6 @@
</view>
</view>
<view class="flex-row-g20">
<view class="operator">
<up-tag type="primary" size="mini" v-if="item.is_current">当前使用</up-tag>
</view>
<view class="operator">
<up-tag :type="item.real_name_status === 1 ? 'primary' : 'success'" size="mini">{{ item.real_name_status === 1 ? '已实名' : '未实名' }}</up-tag>
</view>
@@ -25,7 +22,10 @@
</view>
</view>
<view class="btn flex-row-g20 mt-30">
<up-button class="btn-apple btn-success" v-if="!item.is_current" type="success" @tap="switchOperator(item)" :loading="switching">
<up-button class="btn-apple btn-primary" v-if="item.is_current" type="primary" disabled>
当前使用
</up-button>
<up-button class="btn-apple btn-success" v-else type="success" @tap="switchOperator(item)" :loading="switching">
切换此运营商
</up-button>
</view>
@@ -35,7 +35,7 @@
<script setup>
import { reactive, ref, onMounted } from 'vue';
import { deviceApi } from '@/api/index.js';
import { assetApi, deviceApi } from '@/api/index.js';
import { useUserStore } from '@/store/index.js';
const userStore = useUserStore();
@@ -56,16 +56,34 @@
const loadCards = async () => {
try {
const data = await deviceApi.getCards(userStore.state.identifier);
if (data.cards && data.cards.length > 0) {
mchList.splice(0, mchList.length, ...data.cards.map(card => ({
iccid: card.iccid,
carrier_name: card.carrier_name,
is_current: card.is_active,
real_name_status: card.real_name_status,
slot_position: card.slot_position,
category: getCarrierCategory(card.carrier_name)
})));
const assetData = await assetApi.getInfo(userStore.state.identifier);
// 判断是否为设备
if (assetData.asset_type === 'device') {
// 是设备,调用设备卡列表接口
const data = await deviceApi.getCards(userStore.state.identifier);
if (data.cards && data.cards.length > 0) {
mchList.splice(0, mchList.length, ...data.cards.map(card => ({
iccid: card.iccid,
carrier_name: card.carrier_name,
is_current: card.is_active,
real_name_status: card.real_name_status,
slot_position: card.slot_position,
category: getCarrierCategory(card.carrier_name)
})));
}
} else {
// 不是设备(单卡),直接使用 asset info 数据,只有一个卡
if (assetData.identifier) {
mchList.splice(0, mchList.length, {
iccid: assetData.identifier,
carrier_name: assetData.carrier_name,
is_current: true,
real_name_status: assetData.real_name_status,
slot_position: 1,
category: getCarrierCategory(assetData.carrier_name)
});
}
}
} catch (e) {
console.error('加载卡列表失败', e);