|
|
@@ -3,6 +3,15 @@
|
|
|
<!-- 黄色导航栏 -->
|
|
|
<NavBar :title="navTitle" :showBack="true" />
|
|
|
|
|
|
+ <!-- 加载状态 -->
|
|
|
+ <view class="load-tip" v-if="!order">
|
|
|
+ <view class="dot-row">
|
|
|
+ <view class="pulse-dot"></view>
|
|
|
+ <view class="pulse-dot"></view>
|
|
|
+ <view class="pulse-dot"></view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
<scroll-view class="detail-scroll" scroll-y v-if="order">
|
|
|
<!-- 状态区域 -->
|
|
|
<view class="status-section">
|
|
|
@@ -25,7 +34,7 @@
|
|
|
<!-- 订单明细 -->
|
|
|
<view class="section">
|
|
|
<text class="section-title">订单明细</text>
|
|
|
- <view class="product-list">
|
|
|
+ <view class="product-list" v-if="order.products && order.products.length > 0">
|
|
|
<view class="product-item" v-for="item in order.products" :key="item.productId">
|
|
|
<image
|
|
|
class="product-img"
|
|
|
@@ -34,17 +43,20 @@
|
|
|
/>
|
|
|
<view class="product-main">
|
|
|
<text class="product-name">{{ item.productName }}</text>
|
|
|
- <text class="product-meta">销量 x{{ item.productNum }}</text>
|
|
|
- <text class="product-meta">销售单价 ¥{{ formatMoney(item.price) }}</text>
|
|
|
+ <text class="product-meta">数量 x{{ item.productNum }}</text>
|
|
|
+ <text class="product-meta">单价 ¥{{ formatMoney(item.price) }}</text>
|
|
|
</view>
|
|
|
<view class="product-right">
|
|
|
- <text class="deal-price">成交单价 ¥{{ formatMoney(item.price) }}</text>
|
|
|
+ <text class="deal-price">¥{{ formatMoney(item.price * item.productNum) }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
+ <view class="product-empty" v-else>
|
|
|
+ <text>暂无商品明细</text>
|
|
|
+ </view>
|
|
|
<view class="amount-row">
|
|
|
<text class="amount-label">实付款</text>
|
|
|
- <text class="amount-value">合计¥{{ formatMoney(order.paidAmount) }}</text>
|
|
|
+ <text class="amount-value">¥{{ formatMoney(order.paidAmount) }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
@@ -53,14 +65,16 @@
|
|
|
<text class="section-title">订单信息</text>
|
|
|
<view class="info-row">
|
|
|
<text class="info-label">订单编号</text>
|
|
|
- <view class="info-value-wrapper">
|
|
|
+ <view class="info-value-row">
|
|
|
<text class="info-value">{{ order.orderNo }}</text>
|
|
|
- <view class="copy-icon" @click="copyText(order.orderNo)"></view>
|
|
|
+ <view class="copy-btn" @click="copyText(order.orderNo)">
|
|
|
+ <text class="copy-btn-text">复制</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="info-row">
|
|
|
<text class="info-label">下单时间</text>
|
|
|
- <text class="info-value">{{ order.createTime }}</text>
|
|
|
+ <text class="info-value">{{ order.createTime || '-' }}</text>
|
|
|
</view>
|
|
|
<view class="info-row" v-if="order.payTime">
|
|
|
<text class="info-label">支付时间</text>
|
|
|
@@ -78,53 +92,73 @@
|
|
|
<text class="info-label">设备编号</text>
|
|
|
<text class="info-value">{{ order.deviceId || '-' }}</text>
|
|
|
</view>
|
|
|
- <view class="info-row">
|
|
|
+ <view class="info-row" v-if="order.deviceAddress">
|
|
|
<text class="info-label">设备地址</text>
|
|
|
- <text class="info-value">-</text>
|
|
|
+ <text class="info-value">{{ order.deviceAddress }}</text>
|
|
|
</view>
|
|
|
- <view class="info-row">
|
|
|
+ <view class="info-row" v-if="order.phone">
|
|
|
<text class="info-label">联系消费者</text>
|
|
|
- <view class="info-value-wrapper">
|
|
|
- <view class="copy-icon" @click="copyText(order.phone || '')"></view>
|
|
|
- <view class="phone-icon" @click="callPhone(order.phone)"></view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <view class="info-row blacklist-row">
|
|
|
- <view class="blacklist-label">
|
|
|
- <text class="info-label">黑名单</text>
|
|
|
- <text class="blacklist-tip">移入黑名单后,消费者将无法在"此设备所属子商家"的所有设备中消费</text>
|
|
|
+ <view class="info-value-row">
|
|
|
+ <text class="info-value">{{ formatPhone(order.phone) }}</text>
|
|
|
+ <view class="action-btn call-btn" @click="callPhone(order.phone)">
|
|
|
+ <text class="action-btn-text">呼叫</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
- <switch class="blacklist-switch" :checked="false" @change="toggleBlacklist" />
|
|
|
- </view>
|
|
|
- <view class="info-row">
|
|
|
- <text class="info-label">已发送短信催缴次数</text>
|
|
|
- <text class="info-value">0次</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</scroll-view>
|
|
|
|
|
|
<!-- 底部操作 -->
|
|
|
<view class="bottom-bar" v-if="order && canRefund(order)">
|
|
|
- <button class="refund-btn" @click="handleRefund">退款</button>
|
|
|
+ <view class="refund-btn" @click="handleRefund">
|
|
|
+ <text class="refund-btn-text">退款</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, onMounted, computed } from 'vue';
|
|
|
+import { ref, computed } from 'vue';
|
|
|
import { onLoad } from '@dcloudio/uni-app';
|
|
|
import NavBar from '@/components/NavBar.vue';
|
|
|
import { getOrderDetail, handleRefund as refundOrder } from '@/api/order';
|
|
|
-import { formatMoney as formatMoneyUtil, showToast, showConfirm } from '@/utils/common';
|
|
|
+import { formatMoney as formatMoneyUtil, formatPhone as formatPhoneUtil, showToast, showConfirm } from '@/utils/common';
|
|
|
+
|
|
|
+interface OrderProduct {
|
|
|
+ productId: string;
|
|
|
+ productName: string;
|
|
|
+ productNum: number;
|
|
|
+ price: number;
|
|
|
+ pic?: string;
|
|
|
+}
|
|
|
+
|
|
|
+interface OrderDetail {
|
|
|
+ id: string;
|
|
|
+ orderNo: string;
|
|
|
+ status: number;
|
|
|
+ payStatus: string;
|
|
|
+ payStatusLabel?: string;
|
|
|
+ paidAmount: number;
|
|
|
+ createTime: string;
|
|
|
+ payTime?: string;
|
|
|
+ shopName?: string;
|
|
|
+ deviceId?: string;
|
|
|
+ deviceName?: string;
|
|
|
+ deviceAddress?: string;
|
|
|
+ phone?: string;
|
|
|
+ videoUrl?: string;
|
|
|
+ products?: OrderProduct[];
|
|
|
+}
|
|
|
|
|
|
-const order = ref<any>(null);
|
|
|
+const order = ref<OrderDetail | null>(null);
|
|
|
const formatMoney = formatMoneyUtil;
|
|
|
+const formatPhone = formatPhoneUtil;
|
|
|
|
|
|
const navTitle = computed(() => {
|
|
|
return `${order.value?.deviceId || '订单'}-订单详情`;
|
|
|
});
|
|
|
|
|
|
-const getPayStatusText = (payStatus: string) => {
|
|
|
+const getPayStatusText = (payStatus: string): string => {
|
|
|
const map: Record<string, string> = {
|
|
|
'UNPAID': '未支付',
|
|
|
'PAID': '已支付',
|
|
|
@@ -133,13 +167,13 @@ const getPayStatusText = (payStatus: string) => {
|
|
|
return map[payStatus] || '未知';
|
|
|
};
|
|
|
|
|
|
-const getPayStatusClass = (payStatus: string) => {
|
|
|
+const getPayStatusClass = (payStatus: string): 'success' | 'danger' | 'warning' => {
|
|
|
if (payStatus === 'PAID') return 'success';
|
|
|
if (payStatus === 'REFUND') return 'danger';
|
|
|
return 'warning';
|
|
|
};
|
|
|
|
|
|
-const getStatusDesc = (status: number, payStatus: string) => {
|
|
|
+const getStatusDesc = (status: number, payStatus: string): string => {
|
|
|
if (payStatus === 'PAID') return '交易成功';
|
|
|
if (payStatus === 'REFUND') return '已退款';
|
|
|
if (status === 1) return '等待支付';
|
|
|
@@ -148,8 +182,8 @@ const getStatusDesc = (status: number, payStatus: string) => {
|
|
|
return '';
|
|
|
};
|
|
|
|
|
|
-const canRefund = (order: any) => {
|
|
|
- return order.payStatus === 'PAID' && order.status === 2;
|
|
|
+const canRefund = (o: OrderDetail): boolean => {
|
|
|
+ return o.payStatus === 'PAID' && o.status === 2;
|
|
|
};
|
|
|
|
|
|
const copyText = (text: string) => {
|
|
|
@@ -164,17 +198,9 @@ const copyText = (text: string) => {
|
|
|
};
|
|
|
|
|
|
const callPhone = (phone: string) => {
|
|
|
- if (!phone) {
|
|
|
- showToast('暂无联系方式');
|
|
|
- return;
|
|
|
- }
|
|
|
uni.makePhoneCall({ phoneNumber: phone });
|
|
|
};
|
|
|
|
|
|
-const toggleBlacklist = () => {
|
|
|
- showToast('功能开发中');
|
|
|
-};
|
|
|
-
|
|
|
const loadDetail = async (id?: string) => {
|
|
|
if (!id) {
|
|
|
showToast('订单ID不存在');
|
|
|
@@ -182,7 +208,7 @@ const loadDetail = async (id?: string) => {
|
|
|
}
|
|
|
try {
|
|
|
order.value = await getOrderDetail(id);
|
|
|
- } catch (error) {
|
|
|
+ } catch {
|
|
|
showToast('加载订单详情失败');
|
|
|
}
|
|
|
};
|
|
|
@@ -196,29 +222,29 @@ const handleRefund = async () => {
|
|
|
showToast('退款处理成功', 'success');
|
|
|
setTimeout(() => {
|
|
|
const pages = getCurrentPages();
|
|
|
- const currentPage = pages[pages.length - 1] as any;
|
|
|
+ const currentPage = pages[pages.length - 1] as { options?: Record<string, string> };
|
|
|
loadDetail(currentPage?.options?.id);
|
|
|
}, 1000);
|
|
|
- } catch (error) {
|
|
|
+ } catch {
|
|
|
showToast('退款处理失败');
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-onLoad((options: any) => {
|
|
|
+onLoad((options?: Record<string, string>) => {
|
|
|
loadDetail(options?.id);
|
|
|
});
|
|
|
-
|
|
|
-onMounted(() => {
|
|
|
- // onLoad 中已处理加载
|
|
|
-});
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
+$font-stack: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', system-ui, sans-serif;
|
|
|
+
|
|
|
.page {
|
|
|
- min-height: 100vh;
|
|
|
+ height: 100vh;
|
|
|
background: $bg-color-page;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
+ font-family: $font-stack;
|
|
|
+ overflow-x: hidden;
|
|
|
}
|
|
|
|
|
|
.detail-scroll {
|
|
|
@@ -227,27 +253,53 @@ onMounted(() => {
|
|
|
padding-bottom: 140rpx;
|
|
|
}
|
|
|
|
|
|
-/* 状态区域 */
|
|
|
+// ====== Loading ======
|
|
|
+.load-tip {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 120rpx 0;
|
|
|
+}
|
|
|
+
|
|
|
+.dot-row {
|
|
|
+ display: flex;
|
|
|
+ gap: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.pulse-dot {
|
|
|
+ width: 9rpx; height: 9rpx;
|
|
|
+ background: $text-color-placeholder;
|
|
|
+ border-radius: 50%;
|
|
|
+ animation: pulse 1.2s ease-in-out infinite;
|
|
|
+ &:nth-child(2) { animation-delay: 0.2s; }
|
|
|
+ &:nth-child(3) { animation-delay: 0.4s; }
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes pulse {
|
|
|
+ 0%, 80%, 100% { transform: scale(0.5); opacity: 0.4; }
|
|
|
+ 40% { transform: scale(1); opacity: 1; }
|
|
|
+}
|
|
|
+
|
|
|
+// ====== Status section ======
|
|
|
.status-section {
|
|
|
background: $bg-color-card;
|
|
|
- padding: 24rpx 32rpx;
|
|
|
- margin-bottom: 16rpx;
|
|
|
+ padding: $spacing-3 $spacing-4;
|
|
|
+ margin-bottom: $spacing-2;
|
|
|
|
|
|
.status-row {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- margin-bottom: 12rpx;
|
|
|
+ margin-bottom: $spacing-1;
|
|
|
|
|
|
.status-tag {
|
|
|
- padding: 6rpx 16rpx;
|
|
|
- border-radius: 6rpx;
|
|
|
- font-size: 24rpx;
|
|
|
+ padding: 4rpx $spacing-2;
|
|
|
+ border-radius: $radius-sm;
|
|
|
+ font-size: $font-size-sm;
|
|
|
font-weight: 500;
|
|
|
- margin-right: 16rpx;
|
|
|
+ margin-right: $spacing-2;
|
|
|
|
|
|
&.success {
|
|
|
- background: $primary-color-bg;
|
|
|
- color: $primary-color;
|
|
|
+ background: $success-color-bg;
|
|
|
+ color: $success-color;
|
|
|
}
|
|
|
|
|
|
&.danger {
|
|
|
@@ -256,13 +308,13 @@ onMounted(() => {
|
|
|
}
|
|
|
|
|
|
&.warning {
|
|
|
- background: $accent-color-bg;
|
|
|
- color: $accent-color;
|
|
|
+ background: $warning-color-bg;
|
|
|
+ color: $warning-color;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.order-no-text {
|
|
|
- font-size: 30rpx;
|
|
|
+ font-size: $font-size-md;
|
|
|
font-weight: 600;
|
|
|
color: $text-color-primary;
|
|
|
}
|
|
|
@@ -271,56 +323,48 @@ onMounted(() => {
|
|
|
.status-desc {
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
- &.success {
|
|
|
- color: $primary-color;
|
|
|
- }
|
|
|
-
|
|
|
- &.danger {
|
|
|
- color: $error-color;
|
|
|
- }
|
|
|
-
|
|
|
- &.warning {
|
|
|
- color: $accent-color;
|
|
|
- }
|
|
|
+ &.success { color: $success-color; }
|
|
|
+ &.danger { color: $error-color; }
|
|
|
+ &.warning { color: $warning-color; }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/* 视频区域 */
|
|
|
+// ====== Video ======
|
|
|
.video-section {
|
|
|
background: $bg-color-card;
|
|
|
- padding: 20rpx 32rpx;
|
|
|
- margin-bottom: 16rpx;
|
|
|
+ padding: 20rpx $spacing-4;
|
|
|
+ margin-bottom: $spacing-2;
|
|
|
|
|
|
.order-video {
|
|
|
width: 100%;
|
|
|
height: 400rpx;
|
|
|
- border-radius: 12rpx;
|
|
|
- background: #000000;
|
|
|
+ border-radius: $radius-base;
|
|
|
+ background: $bg-color-secondary;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/* 通用卡片 */
|
|
|
+// ====== Section card ======
|
|
|
.section {
|
|
|
background: $bg-color-card;
|
|
|
- margin-bottom: 16rpx;
|
|
|
- padding: 24rpx 32rpx;
|
|
|
+ margin-bottom: $spacing-2;
|
|
|
+ padding: $spacing-3 $spacing-4;
|
|
|
|
|
|
.section-title {
|
|
|
display: block;
|
|
|
- font-size: 30rpx;
|
|
|
+ font-size: $font-size-md;
|
|
|
font-weight: 600;
|
|
|
color: $text-color-primary;
|
|
|
- margin-bottom: 20rpx;
|
|
|
+ margin-bottom: $spacing-2;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/* 商品列表 */
|
|
|
+// ====== Product list ======
|
|
|
.product-list {
|
|
|
.product-item {
|
|
|
display: flex;
|
|
|
align-items: flex-start;
|
|
|
- padding: 16rpx 0;
|
|
|
- border-bottom: 1rpx solid $bg-color-page;
|
|
|
+ padding: $spacing-2 0;
|
|
|
+ border-bottom: 1rpx solid $border-color-light;
|
|
|
|
|
|
&:last-child {
|
|
|
border-bottom: none;
|
|
|
@@ -329,7 +373,7 @@ onMounted(() => {
|
|
|
.product-img {
|
|
|
width: 120rpx;
|
|
|
height: 120rpx;
|
|
|
- border-radius: 8rpx;
|
|
|
+ border-radius: $radius-sm;
|
|
|
background: $bg-color-page;
|
|
|
margin-right: 20rpx;
|
|
|
flex-shrink: 0;
|
|
|
@@ -340,14 +384,14 @@ onMounted(() => {
|
|
|
|
|
|
.product-name {
|
|
|
display: block;
|
|
|
- font-size: 28rpx;
|
|
|
+ font-size: $font-size-base;
|
|
|
color: $text-color-primary;
|
|
|
- margin-bottom: 8rpx;
|
|
|
+ margin-bottom: $spacing-1;
|
|
|
}
|
|
|
|
|
|
.product-meta {
|
|
|
display: block;
|
|
|
- font-size: 24rpx;
|
|
|
+ font-size: $font-size-sm;
|
|
|
color: $text-color-muted;
|
|
|
margin-bottom: 4rpx;
|
|
|
}
|
|
|
@@ -358,155 +402,132 @@ onMounted(() => {
|
|
|
align-items: flex-end;
|
|
|
|
|
|
.deal-price {
|
|
|
- font-size: 24rpx;
|
|
|
+ font-size: $font-size-sm;
|
|
|
color: $text-color-muted;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+.product-empty {
|
|
|
+ padding: $spacing-5 0;
|
|
|
+ text-align: center;
|
|
|
+ font-size: $font-size-sm;
|
|
|
+ color: $text-color-placeholder;
|
|
|
+}
|
|
|
+
|
|
|
.amount-row {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
- padding: 20rpx 0 0;
|
|
|
- border-top: 1rpx solid $bg-color-page;
|
|
|
- margin-top: 16rpx;
|
|
|
+ padding: $spacing-2 0 0;
|
|
|
+ border-top: 1rpx solid $border-color-light;
|
|
|
+ margin-top: $spacing-2;
|
|
|
|
|
|
.amount-label {
|
|
|
- font-size: 28rpx;
|
|
|
+ font-size: $font-size-base;
|
|
|
color: $text-color-secondary;
|
|
|
}
|
|
|
|
|
|
.amount-value {
|
|
|
- font-size: 32rpx;
|
|
|
+ font-size: $font-size-lg;
|
|
|
font-weight: 700;
|
|
|
color: $text-color-primary;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/* 订单信息 */
|
|
|
+// ====== Info rows ======
|
|
|
.info-row {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
- padding: 16rpx 0;
|
|
|
- border-bottom: 1rpx solid $bg-color-page;
|
|
|
+ padding: $spacing-3 0;
|
|
|
+ border-bottom: 1rpx solid $border-color-light;
|
|
|
|
|
|
&:last-child {
|
|
|
border-bottom: none;
|
|
|
}
|
|
|
|
|
|
.info-label {
|
|
|
- font-size: 28rpx;
|
|
|
+ font-size: $font-size-base;
|
|
|
color: $text-color-muted;
|
|
|
+ flex-shrink: 0;
|
|
|
}
|
|
|
|
|
|
.info-value {
|
|
|
- font-size: 28rpx;
|
|
|
+ font-size: $font-size-base;
|
|
|
color: $text-color-primary;
|
|
|
+ text-align: right;
|
|
|
}
|
|
|
|
|
|
- .info-value-wrapper {
|
|
|
+ .info-value-row {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- gap: 16rpx;
|
|
|
+ gap: $spacing-2;
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- .copy-icon {
|
|
|
- width: 32rpx;
|
|
|
- height: 32rpx;
|
|
|
- background: $bg-color-page;
|
|
|
- border-radius: 4rpx;
|
|
|
- position: relative;
|
|
|
-
|
|
|
- &::before {
|
|
|
- content: '';
|
|
|
- position: absolute;
|
|
|
- top: 50%;
|
|
|
- left: 50%;
|
|
|
- transform: translate(-50%, -50%);
|
|
|
- width: 16rpx;
|
|
|
- height: 20rpx;
|
|
|
- border: 2rpx solid $text-color-muted;
|
|
|
- border-radius: 2rpx;
|
|
|
- }
|
|
|
+// ====== Action buttons ======
|
|
|
+.copy-btn, .action-btn {
|
|
|
+ padding: 8rpx $spacing-3;
|
|
|
+ border-radius: $radius-sm;
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
|
- &::after {
|
|
|
- content: '';
|
|
|
- position: absolute;
|
|
|
- top: 4rpx;
|
|
|
- right: 4rpx;
|
|
|
- width: 8rpx;
|
|
|
- height: 8rpx;
|
|
|
- background: $bg-color-card;
|
|
|
- }
|
|
|
- }
|
|
|
+ &:active { opacity: 0.7; }
|
|
|
+}
|
|
|
|
|
|
- .phone-icon {
|
|
|
- width: 40rpx;
|
|
|
- height: 40rpx;
|
|
|
- background: $primary-color;
|
|
|
- border-radius: 50%;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- position: relative;
|
|
|
-
|
|
|
- &::before {
|
|
|
- content: '';
|
|
|
- position: absolute;
|
|
|
- width: 16rpx;
|
|
|
- height: 20rpx;
|
|
|
- background: $bg-color-card;
|
|
|
- border-radius: 4rpx 4rpx 8rpx 8rpx;
|
|
|
- }
|
|
|
- }
|
|
|
+.copy-btn {
|
|
|
+ background: $bg-color-page;
|
|
|
+
|
|
|
+ .copy-btn-text {
|
|
|
+ font-size: $font-size-xs;
|
|
|
+ color: $text-color-secondary;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-.blacklist-row {
|
|
|
- align-items: flex-start;
|
|
|
+.action-btn {
|
|
|
+ .action-btn-text {
|
|
|
+ font-size: $font-size-xs;
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- .blacklist-label {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
+.call-btn {
|
|
|
+ background: $primary-color-bg;
|
|
|
|
|
|
- .blacklist-tip {
|
|
|
- font-size: 22rpx;
|
|
|
- color: $text-color-muted;
|
|
|
- margin-top: 4rpx;
|
|
|
- line-height: 1.4;
|
|
|
- }
|
|
|
+ .action-btn-text {
|
|
|
+ color: $primary-color-dark;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/* 底部操作 */
|
|
|
+// ====== Bottom bar ======
|
|
|
.bottom-bar {
|
|
|
position: fixed;
|
|
|
bottom: 0;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
background: $bg-color-card;
|
|
|
- padding: 20rpx 32rpx;
|
|
|
- padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
|
|
- box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
|
|
|
+ padding: $spacing-3 $spacing-4;
|
|
|
+ padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
|
|
|
+ border-top: 1rpx solid $border-color-light;
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
|
.refund-btn {
|
|
|
width: 100%;
|
|
|
- height: 96rpx;
|
|
|
background: $primary-color;
|
|
|
- color: $text-color-primary;
|
|
|
- font-size: 32rpx;
|
|
|
- font-weight: 600;
|
|
|
- border-radius: 16rpx;
|
|
|
- border: none;
|
|
|
+ border-radius: $radius-xl;
|
|
|
+ padding: 28rpx 0;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ transition: opacity 0.15s ease;
|
|
|
|
|
|
- &::after {
|
|
|
- border: none;
|
|
|
- }
|
|
|
+ &:active { opacity: 0.8; }
|
|
|
|
|
|
- &:active {
|
|
|
- background: $primary-color-dark;
|
|
|
+ .refund-btn-text {
|
|
|
+ font-size: $font-size-lg;
|
|
|
+ font-weight: 600;
|
|
|
+ color: $text-color-primary;
|
|
|
}
|
|
|
}
|
|
|
}
|