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