fix: ui
All checks were successful
构建并部署前端到生产环境 / build-and-deploy (push) Successful in 2m10s

This commit is contained in:
luo
2026-08-05 15:23:58 +08:00
parent 1891ea1e0d
commit 9f07f9d0ef
9 changed files with 122 additions and 70 deletions

View File

@@ -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;

View File

@@ -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>

View File

@@ -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;

View File

@@ -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;

View File

@@ -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; }

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB