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

This commit is contained in:
luo
2026-07-30 14:35:40 +08:00
parent 49175f8a73
commit 7ecb4709c8
6 changed files with 75 additions and 200 deletions

View File

@@ -8,20 +8,16 @@
<view class="card carrier-card" v-for="item in list" :key="item.iccid">
<view class="carrier-main">
<view class="carrier-left">
<view class="carrier-logo">
<image :src="getCarrier(item.carrier_type).logo" mode="aspectFit"></image>
</view>
<view class="carrier-logo">
<image :src="getCarrier(item.carrier_type).logo" mode="aspectFit"></image>
</view>
<view class="carrier-details">
<view class="carrier-name">{{ getCarrier(item.carrier_type).name }}</view>
<view class="carrier-iccid">
<text class="field-label">ICCID</text>
<text class="iccid-value-text">{{ item.iccid }}</text>
</view>
</view>
<view class="carrier-right">
<view v-if="item.isDevice" class="slot-panel">
<image class="slot-icon" :src="getSlotIcon(item.slot_position)" mode="aspectFit"></image>
<text class="slot-label">卡槽 {{ item.slot_position || '-' }}</text>
<image v-if="item.isDevice" class="slot-icon" :src="getSlotIcon(item.slot_position)" mode="aspectFit"></image>
<text v-if="item.isDevice" class="slot-label">卡槽 {{ item.slot_position || '-' }}</text>
</view>
<view class="card-actions">
<button v-if="item.isRealName" class="btn-apple btn-primary action-button" disabled>已实名</button>
@@ -48,6 +44,13 @@
import { ref, reactive, onMounted } from 'vue';
import { assetApi, realnameApi } from '@/api/index.js';
import { useUserStore } from '@/store/index.js';
import cmccLogo from '@/static/中国移动.png';
import cuccLogo from '@/static/中国联通.png';
import ctccLogo from '@/static/中国电信.png';
import cbnLogo from '@/static/中国广电.png';
import slot1Icon from '@/static/卡槽1.png';
import slot2Icon from '@/static/卡槽2.png';
import slot3Icon from '@/static/卡槽3.png';
const userStore = useUserStore();
@@ -65,16 +68,16 @@
};
const carrierLogoMap = {
CMCC: '/static/中国移动.png',
CUCC: '/static/中国联通.png',
CTCC: '/static/中国电信.png',
CBN: '/static/中国广电.png'
CMCC: cmccLogo,
CUCC: cuccLogo,
CTCC: ctccLogo,
CBN: cbnLogo
};
const slotIconMap = {
1: '/static/卡槽1.png',
2: '/static/卡槽2.png',
3: '/static/卡槽3.png'
1: slot1Icon,
2: slot2Icon,
3: slot3Icon
};
const getCarrier = (carrierType) => {
@@ -161,22 +164,15 @@
.carrier-main {
display: flex;
align-items: stretch;
align-items: flex-start;
justify-content: space-between;
gap: 24rpx;
}
.carrier-left {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.carrier-logo {
width: 112rpx;
height: 112rpx;
flex-shrink: 0;
padding: 10rpx;
box-sizing: border-box;
border-radius: 24rpx;
@@ -184,8 +180,14 @@
image { width: 100%; height: 100%; }
}
.carrier-details {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
}
.carrier-name {
margin-top: 16rpx;
color: var(--text-primary);
font-size: 30rpx;
font-weight: 600;
@@ -193,17 +195,18 @@
}
.carrier-iccid {
width: 100%;
display: flex;
align-items: flex-start;
align-items: center;
gap: 12rpx;
margin-top: 14rpx;
min-width: 0;
}
.field-label,
.slot-label {
color: var(--text-tertiary);
font-size: 24rpx;
white-space: nowrap;
}
.iccid-value-text {
@@ -215,30 +218,15 @@
word-break: break-all;
}
.carrier-right {
width: 190rpx;
flex-shrink: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
gap: 20rpx;
}
.slot-panel {
display: flex;
flex-direction: column;
align-items: center;
gap: 8rpx;
}
.slot-icon {
width: 96rpx;
height: 96rpx;
width: 56rpx;
height: 56rpx;
flex-shrink: 0;
}
.card-actions {
width: 100%;
width: 240rpx;
margin-top: 20rpx;
}
.action-button {

View File

@@ -1,78 +0,0 @@
<template>
<view class="container">
<view v-if="loading" class="state">加载中...</view>
<view v-else-if="!order" class="state">订单信息不存在</view>
<view v-else>
<view class="card">
<view class="card-title">订单信息</view>
<view class="info-row"><text>订单号</text><text>{{ order.order_no || '-' }}</text></view>
<view class="info-row"><text>支付方式</text><text>{{ formatPaymentMethod(order.payment_method) }}</text></view>
<view class="info-row"><text>支付状态</text><text>{{ order.payment_status_name || getStatusText(order.payment_status) }}</text></view>
<view class="info-row"><text>订单金额</text><text class="amount">¥{{ formatMoney(order.total_amount) }}</text></view>
<view class="info-row"><text>创建时间</text><text>{{ formatDateTime(order.created_at) }}</text></view>
<view class="info-row"><text>支付时间</text><text>{{ formatDateTime(order.paid_at) }}</text></view>
<view class="info-row"><text>完成时间</text><text>{{ formatDateTime(order.completed_at) }}</text></view>
</view>
<view class="card">
<view class="card-title">套餐明细</view>
<view v-if="!order.packages?.length" class="empty-detail">暂无套餐明细</view>
<view v-for="item in order.packages || []" :key="item.package_id" class="package-row">
<view>
<view class="package-name">{{ item.package_name || '-' }}</view>
<view class="package-type">{{ item.package_type === 'addon' ? '加油包' : '正式套餐' }} × {{ item.quantity || 1 }}</view>
</view>
<view class="amount">¥{{ formatMoney(item.price) }}</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { orderApi } from '@/api/index.js';
import { formatDateTime, formatMoney } from '@/utils/display.js';
const order = ref(null);
const loading = ref(false);
const formatPaymentMethod = (method) => ({
wechat: '微信支付',
alipay: '支付宝支付',
wallet: '钱包支付'
}[method] || method || '-');
const getStatusText = (status) => ({
1: '待支付',
2: '已支付',
3: '已取消',
4: '已退款'
}[status] || '未知');
onLoad(async ({ id }) => {
if (!id) return;
loading.value = true;
try {
order.value = await orderApi.getDetail(id);
} catch (error) {
console.error('加载订单详情失败', error);
} finally {
loading.value = false;
}
});
</script>
<style lang="scss" scoped>
.container { min-height: 100vh; padding: 24rpx; background: var(--bg-secondary); box-sizing: border-box; }
.card { margin-bottom: 24rpx; padding: 28rpx; background: #fff; border-radius: 20rpx; }
.card-title { margin-bottom: 20rpx; font-size: 32rpx; font-weight: 600; color: var(--text-primary); }
.info-row, .package-row { display: flex; justify-content: space-between; gap: 24rpx; padding: 18rpx 0; border-bottom: 1rpx solid var(--gray-200); color: var(--text-secondary); font-size: 26rpx; }
.info-row:last-child, .package-row:last-child { border-bottom: 0; }
.info-row text:last-child { color: var(--text-primary); text-align: right; word-break: break-all; }
.amount { color: var(--danger) !important; font-weight: 600; }
.package-name { color: var(--text-primary); }
.package-type, .empty-detail, .state { color: var(--text-tertiary); }
.state { padding: 200rpx 0; text-align: center; }
</style>

View File

@@ -21,7 +21,7 @@
</view>
<view v-else class="order-list">
<view class="order-card" v-for="item in orderList" :key="item.order_id" @tap="openOrderDetail(item)">
<view class="order-card" v-for="item in orderList" :key="item.order_id">
<view class="card-header">
<view class="order-number" @tap.stop="copyOrderNo(item.order_no)">
<text class="order-label">订单号</text>
@@ -50,8 +50,6 @@
<view class="card-footer">
<view class="created-time">下单时间{{ item.created_at || '-' }}</view>
<view class="order-actions">
<button class="order-action-button detail-action-button"
@tap.stop="openOrderDetail(item)">查看详情</button>
<button v-if="item.payment_status === 1" class="order-action-button primary-action-button"
@tap.stop="showOrderPaymentMethods(item)">
立即支付
@@ -228,11 +226,6 @@
});
};
const openOrderDetail = (order) => {
if (!order?.order_id) return;
uni.navigateTo({ url: `/pages/order-detail/order-detail?id=${order.order_id}` });
};
const startOrderRenewal = (order) => {
const packageIds = Array.isArray(order?.package_ids) ? order.package_ids.filter(Boolean) : [];
if (!packageIds.length) {
@@ -730,16 +723,6 @@
line-height: 56rpx;
}
.detail-action-button {
border-color: #d9dde2;
background: #fff;
color: #17191c;
}
.order-card .card-body .card-footer .detail-action-button {
margin-right: auto;
}
.primary-action-button {
border-color: var(--primary);
background: var(--primary);

View File

@@ -8,14 +8,16 @@
<view class="card carrier-card" v-for="item in mchList" :key="item.iccid">
<view class="carrier-main">
<view class="carrier-left">
<view class="carrier-logo">
<image :src="getCarrier(item.carrier_type).logo" mode="aspectFit"></image>
</view>
<view class="carrier-logo">
<image :src="getCarrier(item.carrier_type).logo" mode="aspectFit"></image>
</view>
<view class="carrier-details">
<view class="carrier-name">{{ getCarrier(item.carrier_type).name }}</view>
<view class="carrier-iccid">
<text class="field-label">ICCID</text>
<text class="iccid-value-text">{{ item.iccid }}</text>
<image class="slot-icon" :src="getSlotIcon(item.slot_position)" mode="aspectFit"></image>
<text class="slot-label">卡槽 {{ item.slot_position || '-' }}</text>
</view>
<view class="carrier-statuses">
<up-tag :type="item.real_name_status === 1 ? 'primary' : 'success'" size="mini">
@@ -23,12 +25,6 @@
</up-tag>
<up-tag v-if="item.network_status" type="info" size="mini">{{ item.network_status }}</up-tag>
</view>
</view>
<view class="carrier-right">
<view class="slot-panel">
<image class="slot-icon" :src="getSlotIcon(item.slot_position)" mode="aspectFit"></image>
<text class="slot-label">卡槽 {{ item.slot_position || '-' }}</text>
</view>
<view class="card-actions">
<button v-if="item.is_current" class="btn-apple btn-primary action-button" disabled>当前使用</button>
<button v-else class="btn-apple btn-primary action-button" :disabled="switching" @tap="switchOperator(item)">
@@ -59,6 +55,13 @@
import { reactive, ref, onMounted } from 'vue';
import { assetApi, deviceApi, realnameApi } from '@/api/index.js';
import { useUserStore } from '@/store/index.js';
import cmccLogo from '@/static/中国移动.png';
import cuccLogo from '@/static/中国联通.png';
import ctccLogo from '@/static/中国电信.png';
import cbnLogo from '@/static/中国广电.png';
import slot1Icon from '@/static/卡槽1.png';
import slot2Icon from '@/static/卡槽2.png';
import slot3Icon from '@/static/卡槽3.png';
const userStore = useUserStore();
@@ -76,16 +79,16 @@
};
const carrierLogoMap = {
CMCC: '/static/中国移动.png',
CUCC: '/static/中国联通.png',
CTCC: '/static/中国电信.png',
CBN: '/static/中国广电.png'
CMCC: cmccLogo,
CUCC: cuccLogo,
CTCC: ctccLogo,
CBN: cbnLogo
};
const slotIconMap = {
1: '/static/卡槽1.png',
2: '/static/卡槽2.png',
3: '/static/卡槽3.png'
1: slot1Icon,
2: slot2Icon,
3: slot3Icon
};
const getCarrier = (carrierType) => {
@@ -194,22 +197,15 @@
.carrier-main {
display: flex;
align-items: stretch;
align-items: flex-start;
justify-content: space-between;
gap: 24rpx;
}
.carrier-left {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.carrier-logo {
width: 112rpx;
height: 112rpx;
flex-shrink: 0;
padding: 10rpx;
box-sizing: border-box;
border-radius: 24rpx;
@@ -217,8 +213,14 @@
image { width: 100%; height: 100%; }
}
.carrier-details {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
}
.carrier-name {
margin-top: 16rpx;
color: var(--text-primary);
font-size: 30rpx;
font-weight: 600;
@@ -226,17 +228,18 @@
}
.carrier-iccid {
width: 100%;
display: flex;
align-items: flex-start;
align-items: center;
gap: 12rpx;
margin-top: 14rpx;
min-width: 0;
}
.field-label,
.slot-label {
color: var(--text-tertiary);
font-size: 24rpx;
white-space: nowrap;
}
.iccid-value-text {
@@ -256,30 +259,15 @@
margin-top: 14rpx;
}
.carrier-right {
width: 190rpx;
flex-shrink: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
gap: 20rpx;
}
.slot-panel {
display: flex;
flex-direction: column;
align-items: center;
gap: 8rpx;
}
.slot-icon {
width: 96rpx;
height: 96rpx;
width: 56rpx;
height: 56rpx;
flex-shrink: 0;
}
.card-actions {
width: 100%;
margin-top: 20rpx;
display: flex;
flex-direction: column;
gap: 12rpx;