This commit is contained in:
@@ -1,7 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="container">
|
<view class="container">
|
||||||
<!-- 空状态提示 -->
|
<!-- 空状态提示 -->
|
||||||
<view v-if="packageList.length === 0 && !loading" class="empty-state">
|
<view v-if="!historyLoaded || (loading && packageList.length === 0)" class="loading-state">
|
||||||
|
<up-loading-icon text="加载中" size="30"></up-loading-icon>
|
||||||
|
</view>
|
||||||
|
<view v-else-if="packageList.length === 0" class="empty-state">
|
||||||
<image class="empty-icon" src="/static/asset-package-history.png" mode="aspectFit" alt="资产套餐历史"></image>
|
<image class="empty-icon" src="/static/asset-package-history.png" mode="aspectFit" alt="资产套餐历史"></image>
|
||||||
<view class="empty-title">暂无套餐记录</view>
|
<view class="empty-title">暂无套餐记录</view>
|
||||||
<view class="empty-desc">当前账号下暂无套餐历史信息</view>
|
<view class="empty-desc">当前账号下暂无套餐历史信息</view>
|
||||||
@@ -69,6 +72,7 @@
|
|||||||
|
|
||||||
let packageList = reactive([]);
|
let packageList = reactive([]);
|
||||||
let loading = ref(false);
|
let loading = ref(false);
|
||||||
|
let historyLoaded = ref(false);
|
||||||
let noMore = ref(false);
|
let noMore = ref(false);
|
||||||
let page = ref(1);
|
let page = ref(1);
|
||||||
const pageSize = 10;
|
const pageSize = 10;
|
||||||
@@ -161,6 +165,7 @@
|
|||||||
console.error('加载套餐历史失败', e);
|
console.error('加载套餐历史失败', e);
|
||||||
}
|
}
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
historyLoaded.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadMore = () => {
|
const loadMore = () => {
|
||||||
@@ -176,6 +181,13 @@
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.container {
|
.container {
|
||||||
|
.loading-state {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 500rpx;
|
||||||
|
}
|
||||||
|
|
||||||
.empty-state {
|
.empty-state {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="container">
|
<view class="container">
|
||||||
<view v-if="list.length === 0 && !loading" class="empty-state">
|
<view v-if="!cardsLoaded || (loading && list.length === 0)" class="loading-state">
|
||||||
|
<up-loading-icon text="加载中" size="30"></up-loading-icon>
|
||||||
|
</view>
|
||||||
|
<view v-else-if="list.length === 0" class="empty-state">
|
||||||
<image class="empty-icon" src="/static/authentication.png" mode="aspectFit" alt="实名认证"></image>
|
<image class="empty-icon" src="/static/authentication.png" mode="aspectFit" alt="实名认证"></image>
|
||||||
<view class="empty-title">认证列表为空</view>
|
<view class="empty-title">认证列表为空</view>
|
||||||
<view class="empty-desc">当前账号下暂无可实名的卡片</view>
|
<view class="empty-desc">当前账号下暂无可实名的卡片</view>
|
||||||
@@ -18,10 +21,8 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="carrier-iccid">
|
<view class="carrier-iccid">
|
||||||
<text class="iccid-value-text">{{ item.iccid }}</text>
|
<text class="iccid-value-text">{{ item.iccid }}</text>
|
||||||
<view class="copy-icon" @tap.stop="copyIccid(item.iccid)" aria-label="复制ICCID">
|
<image class="copy-icon" src="/static/复制.png" mode="aspectFit"
|
||||||
<view class="copy-back"></view>
|
@tap.stop="copyIccid(item.iccid)" aria-label="复制ICCID"></image>
|
||||||
<view class="copy-front"></view>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="card-actions">
|
<view class="card-actions">
|
||||||
<button v-if="item.isRealName" class="btn-apple btn-primary action-button" disabled>已实名</button>
|
<button v-if="item.isRealName" class="btn-apple btn-primary action-button" disabled>已实名</button>
|
||||||
@@ -60,6 +61,7 @@
|
|||||||
|
|
||||||
let list = reactive([]);
|
let list = reactive([]);
|
||||||
let loading = ref(false);
|
let loading = ref(false);
|
||||||
|
let cardsLoaded = ref(false);
|
||||||
let showIccidModal = ref(false);
|
let showIccidModal = ref(false);
|
||||||
let currentModalIccid = ref('');
|
let currentModalIccid = ref('');
|
||||||
let currentCard = ref(null);
|
let currentCard = ref(null);
|
||||||
@@ -127,6 +129,7 @@
|
|||||||
console.error('加载卡列表失败', e);
|
console.error('加载卡列表失败', e);
|
||||||
}
|
}
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
cardsLoaded.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const toReal = async (card) => {
|
const toReal = async (card) => {
|
||||||
@@ -195,8 +198,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.slot-badge {
|
.slot-badge {
|
||||||
width: 40rpx;
|
width: 32rpx;
|
||||||
height: 40rpx;
|
height: 32rpx;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,26 +241,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.copy-icon {
|
.copy-icon {
|
||||||
position: relative;
|
|
||||||
width: 30rpx;
|
width: 30rpx;
|
||||||
height: 30rpx;
|
height: 30rpx;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.copy-back,
|
|
||||||
.copy-front {
|
|
||||||
position: absolute;
|
|
||||||
width: 15rpx;
|
|
||||||
height: 15rpx;
|
|
||||||
border: 3rpx solid var(--text-tertiary);
|
|
||||||
border-radius: 4rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy-back { top: 3rpx; left: 3rpx; }
|
|
||||||
.copy-front { right: 2rpx; bottom: 2rpx; background: var(--bg-primary); }
|
|
||||||
|
|
||||||
.card-actions {
|
.card-actions {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 20rpx;
|
margin-top: 20rpx;
|
||||||
@@ -369,4 +358,11 @@
|
|||||||
.empty-title { font-size: 32rpx; font-weight: 600; color: var(--text-primary); margin-bottom: 16rpx; }
|
.empty-title { font-size: 32rpx; font-weight: 600; color: var(--text-primary); margin-bottom: 16rpx; }
|
||||||
.empty-desc { font-size: 26rpx; color: var(--text-tertiary); text-align: center; }
|
.empty-desc { font-size: 26rpx; color: var(--text-tertiary); text-align: center; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading-state {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 500rpx;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="container">
|
<view class="container">
|
||||||
<view v-if="!exchangeData && !loading" class="empty-state">
|
<view v-if="!exchangeLoaded || (loading && !exchangeData)" class="loading-state">
|
||||||
|
<up-loading-icon text="加载中" size="30"></up-loading-icon>
|
||||||
|
</view>
|
||||||
|
<view v-else-if="!exchangeData" class="empty-state">
|
||||||
<image class="empty-icon" src="/static/change-shop.png" mode="aspectFit" alt="换货"></image>
|
<image class="empty-icon" src="/static/change-shop.png" mode="aspectFit" alt="换货"></image>
|
||||||
<view class="empty-title">暂无换货记录</view>
|
<view class="empty-title">暂无换货记录</view>
|
||||||
<view class="empty-desc">当前账号下暂无换货记录</view>
|
<view class="empty-desc">当前账号下暂无换货记录</view>
|
||||||
@@ -158,6 +161,7 @@
|
|||||||
|
|
||||||
const exchangeData = ref(null);
|
const exchangeData = ref(null);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
const exchangeLoaded = ref(false);
|
||||||
const showPopup = ref(false);
|
const showPopup = ref(false);
|
||||||
const showAreaPicker = ref(false);
|
const showAreaPicker = ref(false);
|
||||||
const areaPickerColumns = ref([]);
|
const areaPickerColumns = ref([]);
|
||||||
@@ -224,6 +228,7 @@
|
|||||||
exchangeData.value = null;
|
exchangeData.value = null;
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
exchangeLoaded.value = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -368,6 +373,13 @@
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.container {
|
.container {
|
||||||
|
.loading-state {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 500rpx;
|
||||||
|
}
|
||||||
|
|
||||||
.empty-state {
|
.empty-state {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -37,7 +37,10 @@
|
|||||||
>
|
>
|
||||||
<swiper-item class="swiper-item-content">
|
<swiper-item class="swiper-item-content">
|
||||||
<scroll-view scroll-y class="list-content" @scrolltolower="loadMoreRecharge">
|
<scroll-view scroll-y class="list-content" @scrolltolower="loadMoreRecharge">
|
||||||
<view v-if="rechargeList.length === 0 && !rechargeLoading" class="empty-state">
|
<view v-if="!rechargeLoaded || (rechargeLoading && rechargeList.length === 0)" class="loading-state">
|
||||||
|
<up-loading-icon text="加载中" size="30"></up-loading-icon>
|
||||||
|
</view>
|
||||||
|
<view v-else-if="rechargeList.length === 0" class="empty-state">
|
||||||
<image class="empty-icon" src="/static/wallet.png" mode="aspectFit" alt="钱包"></image>
|
<image class="empty-icon" src="/static/wallet.png" mode="aspectFit" alt="钱包"></image>
|
||||||
<view class="empty-title">暂无充值订单</view>
|
<view class="empty-title">暂无充值订单</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -85,7 +88,10 @@
|
|||||||
|
|
||||||
<swiper-item class="swiper-item-content">
|
<swiper-item class="swiper-item-content">
|
||||||
<scroll-view scroll-y class="list-content" @scrolltolower="loadMoreTransaction">
|
<scroll-view scroll-y class="list-content" @scrolltolower="loadMoreTransaction">
|
||||||
<view v-if="transactionList.length === 0 && !transactionLoading" class="empty-state">
|
<view v-if="!transactionLoaded || (transactionLoading && transactionList.length === 0)" class="loading-state">
|
||||||
|
<up-loading-icon text="加载中" size="30"></up-loading-icon>
|
||||||
|
</view>
|
||||||
|
<view v-else-if="transactionList.length === 0" class="empty-state">
|
||||||
<image class="empty-icon" src="/static/wallet.png" mode="aspectFit" alt="钱包"></image>
|
<image class="empty-icon" src="/static/wallet.png" mode="aspectFit" alt="钱包"></image>
|
||||||
<view class="empty-title">暂无钱包流水</view>
|
<view class="empty-title">暂无钱包流水</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -246,12 +252,14 @@
|
|||||||
|
|
||||||
const rechargeList = reactive([]);
|
const rechargeList = reactive([]);
|
||||||
const rechargeLoading = ref(false);
|
const rechargeLoading = ref(false);
|
||||||
|
const rechargeLoaded = ref(false);
|
||||||
const rechargeNoMore = ref(false);
|
const rechargeNoMore = ref(false);
|
||||||
const rechargePage = ref(1);
|
const rechargePage = ref(1);
|
||||||
const rechargePageSize = 5;
|
const rechargePageSize = 5;
|
||||||
|
|
||||||
const transactionList = reactive([]);
|
const transactionList = reactive([]);
|
||||||
const transactionLoading = ref(false);
|
const transactionLoading = ref(false);
|
||||||
|
const transactionLoaded = ref(false);
|
||||||
const transactionNoMore = ref(false);
|
const transactionNoMore = ref(false);
|
||||||
const transactionPage = ref(1);
|
const transactionPage = ref(1);
|
||||||
const transactionPageSize = 5;
|
const transactionPageSize = 5;
|
||||||
@@ -259,7 +267,7 @@
|
|||||||
const showRechargeModal = ref(false);
|
const showRechargeModal = ref(false);
|
||||||
const showRechargeOrderPaymentModal = ref(false);
|
const showRechargeOrderPaymentModal = ref(false);
|
||||||
const selectedRechargeOrder = ref(null);
|
const selectedRechargeOrder = ref(null);
|
||||||
const selectedAmount = ref(null);
|
const selectedAmount = ref(10000);
|
||||||
const isCustomAmount = ref(false);
|
const isCustomAmount = ref(false);
|
||||||
const customAmount = ref('');
|
const customAmount = ref('');
|
||||||
const rechargePaymentMethod = ref('alipay');
|
const rechargePaymentMethod = ref('alipay');
|
||||||
@@ -384,6 +392,9 @@
|
|||||||
rechargePaymentMethod.value = getDefaultPaymentMethod(
|
rechargePaymentMethod.value = getDefaultPaymentMethod(
|
||||||
rechargeAllowedPaymentMethods.value
|
rechargeAllowedPaymentMethods.value
|
||||||
);
|
);
|
||||||
|
selectedAmount.value = 10000;
|
||||||
|
isCustomAmount.value = false;
|
||||||
|
customAmount.value = '';
|
||||||
showRechargeModal.value = true;
|
showRechargeModal.value = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('充值前校验失败', error);
|
console.error('充值前校验失败', error);
|
||||||
@@ -488,6 +499,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
rechargeLoading.value = false;
|
rechargeLoading.value = false;
|
||||||
|
rechargeLoaded.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const normalizeTransactionItem = (item) => {
|
const normalizeTransactionItem = (item) => {
|
||||||
@@ -532,6 +544,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
transactionLoading.value = false;
|
transactionLoading.value = false;
|
||||||
|
transactionLoaded.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRechargeResult = async (rechargeData, paymentMethod) => {
|
const handleRechargeResult = async (rechargeData, paymentMethod) => {
|
||||||
@@ -1194,6 +1207,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading-state {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 360rpx;
|
||||||
|
}
|
||||||
|
|
||||||
.recharge-order-payment-popup {
|
.recharge-order-payment-popup {
|
||||||
.package-summary {
|
.package-summary {
|
||||||
padding: 40rpx 30rpx 30rpx;
|
padding: 40rpx 30rpx 30rpx;
|
||||||
|
|||||||
@@ -7,7 +7,10 @@
|
|||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-if="notifications.length === 0 && !loading" class="empty-state">
|
<view v-if="!notificationsLoaded || (loading && notifications.length === 0)" class="loading-state">
|
||||||
|
<up-loading-icon text="加载中" size="30"></up-loading-icon>
|
||||||
|
</view>
|
||||||
|
<view v-else-if="notifications.length === 0" class="empty-state">
|
||||||
<image src="/static/notification.png" mode="aspectFit" class="empty-icon" />
|
<image src="/static/notification.png" mode="aspectFit" class="empty-icon" />
|
||||||
<view class="empty-title">暂无通知</view>
|
<view class="empty-title">暂无通知</view>
|
||||||
<view class="empty-desc">当前没有可查看的业务通知</view>
|
<view class="empty-desc">当前没有可查看的业务通知</view>
|
||||||
@@ -47,6 +50,7 @@
|
|||||||
const total = ref(0);
|
const total = ref(0);
|
||||||
const unreadCount = ref(0);
|
const unreadCount = ref(0);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
const notificationsLoaded = ref(false);
|
||||||
const noMore = ref(false);
|
const noMore = ref(false);
|
||||||
|
|
||||||
const formatDate = (value) => {
|
const formatDate = (value) => {
|
||||||
@@ -107,6 +111,7 @@
|
|||||||
console.error('加载通知列表失败', error);
|
console.error('加载通知列表失败', error);
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
notificationsLoaded.value = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -165,6 +170,7 @@
|
|||||||
.notification-footer { margin-top: var(--space-md); }
|
.notification-footer { margin-top: var(--space-md); }
|
||||||
.notification-meta, .notification-time { color: var(--text-tertiary); font-size: 22rpx; }
|
.notification-meta, .notification-time { color: var(--text-tertiary); font-size: 22rpx; }
|
||||||
.empty-state { display: flex; flex-direction: column; align-items: center; padding: 140rpx 40rpx; }
|
.empty-state { display: flex; flex-direction: column; align-items: center; padding: 140rpx 40rpx; }
|
||||||
|
.loading-state { display: flex; align-items: center; justify-content: center; min-height: 400rpx; }
|
||||||
.empty-icon { width: 100rpx; height: 100rpx; opacity: 0.6; margin-bottom: 24rpx; }
|
.empty-icon { width: 100rpx; height: 100rpx; opacity: 0.6; margin-bottom: 24rpx; }
|
||||||
.empty-title { color: var(--text-primary); font-size: 30rpx; font-weight: 600; }
|
.empty-title { color: var(--text-primary); font-size: 30rpx; font-weight: 600; }
|
||||||
.empty-desc { color: var(--text-tertiary); font-size: 24rpx; margin-top: 12rpx; }
|
.empty-desc { color: var(--text-tertiary); font-size: 24rpx; margin-top: 12rpx; }
|
||||||
|
|||||||
@@ -22,7 +22,10 @@
|
|||||||
>
|
>
|
||||||
<swiper-item v-for="(item, index) in filterOptions" :key="item.value ?? 'all'" class="order-swiper-item">
|
<swiper-item v-for="(item, index) in filterOptions" :key="item.value ?? 'all'" class="order-swiper-item">
|
||||||
<scroll-view v-if="filterIndex === index" scroll-y class="scroll-container" @scrolltolower="loadMore">
|
<scroll-view v-if="filterIndex === index" scroll-y class="scroll-container" @scrolltolower="loadMore">
|
||||||
<view v-if="orderList.length === 0 && !loading" class="empty-state">
|
<view v-if="!ordersLoaded || (loading && orderList.length === 0)" class="loading-state">
|
||||||
|
<up-loading-icon text="加载中" size="30"></up-loading-icon>
|
||||||
|
</view>
|
||||||
|
<view v-else-if="orderList.length === 0" class="empty-state">
|
||||||
<image class="empty-icon" src="/static/order.png" mode="aspectFit" alt="我的订单"></image>
|
<image class="empty-icon" src="/static/order.png" mode="aspectFit" alt="我的订单"></image>
|
||||||
<view class="empty-title">暂无订单</view>
|
<view class="empty-title">暂无订单</view>
|
||||||
<view class="empty-desc">当前账号下暂无订单信息</view>
|
<view class="empty-desc">当前账号下暂无订单信息</view>
|
||||||
@@ -33,10 +36,7 @@
|
|||||||
<view class="card-header">
|
<view class="card-header">
|
||||||
<view class="order-number" @tap.stop="copyOrderNo(item.order_no)">
|
<view class="order-number" @tap.stop="copyOrderNo(item.order_no)">
|
||||||
<text class="order-no">{{ item.order_no || '-' }}</text>
|
<text class="order-no">{{ item.order_no || '-' }}</text>
|
||||||
<view class="copy-icon">
|
<image class="copy-icon" src="/static/复制.png" mode="aspectFit"></image>
|
||||||
<view class="copy-back"></view>
|
|
||||||
<view class="copy-front"></view>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="status-badge" :class="getStatusClass(item.payment_status)">
|
<view class="status-badge" :class="getStatusClass(item.payment_status)">
|
||||||
{{ item.payment_status_name }}
|
{{ item.payment_status_name }}
|
||||||
@@ -99,6 +99,7 @@
|
|||||||
|
|
||||||
const orderList = reactive([]);
|
const orderList = reactive([]);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
const ordersLoaded = ref(false);
|
||||||
const noMore = ref(false);
|
const noMore = ref(false);
|
||||||
const page = ref(1);
|
const page = ref(1);
|
||||||
const renewalPopupRef = ref(null);
|
const renewalPopupRef = ref(null);
|
||||||
@@ -203,6 +204,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
ordersLoaded.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadMore = () => {
|
const loadMore = () => {
|
||||||
@@ -282,7 +284,7 @@
|
|||||||
border-radius: 20rpx;
|
border-radius: 20rpx;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin-top: 20rpx;
|
margin: 20rpx 24rpx 0;
|
||||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
|
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
|
||||||
|
|
||||||
.tab-item {
|
.tab-item {
|
||||||
@@ -488,6 +490,13 @@
|
|||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading-state {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 500rpx;
|
||||||
|
}
|
||||||
|
|
||||||
/* Screenshot-aligned order list skin */
|
/* Screenshot-aligned order list skin */
|
||||||
.container {
|
.container {
|
||||||
top: var(--window-top);
|
top: var(--window-top);
|
||||||
@@ -640,26 +649,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.copy-icon {
|
.copy-icon {
|
||||||
position: relative;
|
|
||||||
width: 30rpx;
|
width: 30rpx;
|
||||||
height: 30rpx;
|
height: 30rpx;
|
||||||
margin-left: 14rpx;
|
margin-left: 14rpx;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.copy-back,
|
|
||||||
.copy-front {
|
|
||||||
position: absolute;
|
|
||||||
width: 15rpx;
|
|
||||||
height: 15rpx;
|
|
||||||
border: 3rpx solid #717782;
|
|
||||||
border-radius: 4rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy-back { top: 3rpx; left: 3rpx; }
|
|
||||||
.copy-front { right: 2rpx; bottom: 2rpx; background: #fff; }
|
|
||||||
|
|
||||||
.order-card .card-body {
|
.order-card .card-body {
|
||||||
padding: 0 0 28rpx;
|
padding: 0 0 28rpx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,10 @@
|
|||||||
>
|
>
|
||||||
<swiper-item v-for="tab in packageTypeTabs" :key="tab.value" class="package-swiper-item">
|
<swiper-item v-for="tab in packageTypeTabs" :key="tab.value" class="package-swiper-item">
|
||||||
<scroll-view v-if="activePackageType === tab.value" scroll-y class="package-scroll">
|
<scroll-view v-if="activePackageType === tab.value" scroll-y class="package-scroll">
|
||||||
<view v-if="packageList.length === 0 && !loading" class="empty-state">
|
<view v-if="!packagesLoaded || (loading && packageList.length === 0)" class="loading-state">
|
||||||
|
<up-loading-icon text="加载中" size="30"></up-loading-icon>
|
||||||
|
</view>
|
||||||
|
<view v-else-if="packageList.length === 0" class="empty-state">
|
||||||
<image class="empty-icon" src="/static/shop.png" mode="aspectFit" alt="套餐订购"></image>
|
<image class="empty-icon" src="/static/shop.png" mode="aspectFit" alt="套餐订购"></image>
|
||||||
<view class="empty-title">暂无{{ activePackageType === 'formal' ? '正式套餐' : '加油包' }}</view>
|
<view class="empty-title">暂无{{ activePackageType === 'formal' ? '正式套餐' : '加油包' }}</view>
|
||||||
<view class="empty-desc">当前资产暂无适用的套餐</view>
|
<view class="empty-desc">当前资产暂无适用的套餐</view>
|
||||||
@@ -128,6 +131,7 @@
|
|||||||
const currentPackage = ref(null);
|
const currentPackage = ref(null);
|
||||||
const packageList = reactive([]);
|
const packageList = reactive([]);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
const packagesLoaded = ref(false);
|
||||||
const paymentMethod = ref('alipay');
|
const paymentMethod = ref('alipay');
|
||||||
const walletBalance = ref(0);
|
const walletBalance = ref(0);
|
||||||
const paySubmitting = ref(false);
|
const paySubmitting = ref(false);
|
||||||
@@ -191,6 +195,7 @@
|
|||||||
|
|
||||||
const loadPackages = async (packageType = activePackageType.value) => {
|
const loadPackages = async (packageType = activePackageType.value) => {
|
||||||
const requestId = ++packageRequestId;
|
const requestId = ++packageRequestId;
|
||||||
|
packagesLoaded.value = false;
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
packageList.splice(0, packageList.length);
|
packageList.splice(0, packageList.length);
|
||||||
try {
|
try {
|
||||||
@@ -228,7 +233,10 @@
|
|||||||
if (requestId !== packageRequestId) return;
|
if (requestId !== packageRequestId) return;
|
||||||
console.error('加载套餐列表失败', error);
|
console.error('加载套餐列表失败', error);
|
||||||
} finally {
|
} finally {
|
||||||
if (requestId === packageRequestId) loading.value = false;
|
if (requestId === packageRequestId) {
|
||||||
|
loading.value = false;
|
||||||
|
packagesLoaded.value = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -704,6 +712,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading-state {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 400rpx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Screenshot-aligned package list skin */
|
/* Screenshot-aligned package list skin */
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="container">
|
<view class="container">
|
||||||
<view v-if="mchList.length === 0 && !loading" class="empty-state">
|
<view v-if="!cardsLoaded || (loading && mchList.length === 0)" class="loading-state">
|
||||||
|
<up-loading-icon text="加载中" size="30"></up-loading-icon>
|
||||||
|
</view>
|
||||||
|
<view v-else-if="mchList.length === 0" class="empty-state">
|
||||||
<image class="empty-icon" src="/static/change.png" mode="aspectFit" alt="切换运营商"></image>
|
<image class="empty-icon" src="/static/change.png" mode="aspectFit" alt="切换运营商"></image>
|
||||||
<view class="empty-title">运营商列表为空</view>
|
<view class="empty-title">运营商列表为空</view>
|
||||||
<view class="empty-desc">当前设备暂无可切换的运营商</view>
|
<view class="empty-desc">当前设备暂无可切换的运营商</view>
|
||||||
@@ -24,10 +27,8 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="carrier-iccid">
|
<view class="carrier-iccid">
|
||||||
<text class="iccid-value-text">{{ item.iccid }}</text>
|
<text class="iccid-value-text">{{ item.iccid }}</text>
|
||||||
<view class="copy-icon" @tap.stop="copyIccid(item.iccid)" aria-label="复制ICCID">
|
<image class="copy-icon" src="/static/复制.png" mode="aspectFit"
|
||||||
<view class="copy-back"></view>
|
@tap.stop="copyIccid(item.iccid)" aria-label="复制ICCID"></image>
|
||||||
<view class="copy-front"></view>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="card-actions">
|
<view class="card-actions">
|
||||||
<button v-if="item.is_current" class="btn-apple btn-primary action-button" disabled>当前使用</button>
|
<button v-if="item.is_current" class="btn-apple btn-primary action-button" disabled>当前使用</button>
|
||||||
@@ -71,6 +72,7 @@
|
|||||||
|
|
||||||
let mchList = reactive([]);
|
let mchList = reactive([]);
|
||||||
let loading = ref(false);
|
let loading = ref(false);
|
||||||
|
let cardsLoaded = ref(false);
|
||||||
let switching = ref(false);
|
let switching = ref(false);
|
||||||
let showIccidModal = ref(false);
|
let showIccidModal = ref(false);
|
||||||
let currentModalIccid = ref('');
|
let currentModalIccid = ref('');
|
||||||
@@ -151,6 +153,7 @@
|
|||||||
console.error('加载卡列表失败', e);
|
console.error('加载卡列表失败', e);
|
||||||
}
|
}
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
cardsLoaded.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const switchOperator = (item) => {
|
const switchOperator = (item) => {
|
||||||
@@ -284,8 +287,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.slot-badge {
|
.slot-badge {
|
||||||
width: 40rpx;
|
width: 32rpx;
|
||||||
height: 40rpx;
|
height: 32rpx;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,26 +331,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.copy-icon {
|
.copy-icon {
|
||||||
position: relative;
|
|
||||||
width: 30rpx;
|
width: 30rpx;
|
||||||
height: 30rpx;
|
height: 30rpx;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.copy-back,
|
|
||||||
.copy-front {
|
|
||||||
position: absolute;
|
|
||||||
width: 15rpx;
|
|
||||||
height: 15rpx;
|
|
||||||
border: 3rpx solid var(--text-tertiary);
|
|
||||||
border-radius: 4rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy-back { top: 3rpx; left: 3rpx; }
|
|
||||||
.copy-front { right: 2rpx; bottom: 2rpx; background: var(--bg-primary); }
|
|
||||||
|
|
||||||
.carrier-statuses {
|
.carrier-statuses {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -479,4 +468,11 @@
|
|||||||
.empty-title { font-size: 32rpx; font-weight: 600; color: var(--text-primary); margin-bottom: 16rpx; }
|
.empty-title { font-size: 32rpx; font-weight: 600; color: var(--text-primary); margin-bottom: 16rpx; }
|
||||||
.empty-desc { font-size: 26rpx; color: var(--text-tertiary); text-align: center; }
|
.empty-desc { font-size: 26rpx; color: var(--text-tertiary); text-align: center; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading-state {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 500rpx;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
BIN
static/复制.png
Normal file
BIN
static/复制.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
Reference in New Issue
Block a user