403 lines
11 KiB
Vue
403 lines
11 KiB
Vue
<template>
|
|
<view class="coupon-detail-page">
|
|
<view class="header-fixed-wrapper" :style="{ height: headerHeight + 'px' }">
|
|
<NavHeader title="优惠卷详情" />
|
|
</view>
|
|
<view class="main-wrap" :style="{ paddingTop: headerHeight + 'px' }">
|
|
<view v-if="!loading && detail" class="content">
|
|
<!-- 优惠卷基础信息卡片 -->
|
|
<view class="coupon-card">
|
|
<view class="coupon-left">
|
|
<view class="coupon-price" v-if="detail.type === 2">
|
|
<text class="amount">{{ (detail.discountPercent / 10).toFixed(1).replace(/\.0$/, '') }}</text>
|
|
<text class="symbol" style="font-size: 24rpx; margin-left: 4rpx;">折</text>
|
|
</view>
|
|
<view class="coupon-price" v-else>
|
|
<text class="symbol">¥</text>
|
|
<text class="amount">{{ formatAmount(detail.discountAmount || detail.discountPrice || detail.price || 0) }}</text>
|
|
</view>
|
|
<view class="coupon-condition" v-if="detail.usePrice">满{{ formatAmount(detail.usePrice) }}可用</view>
|
|
<view class="coupon-condition" v-else>无门槛</view>
|
|
</view>
|
|
<view class="coupon-right">
|
|
<view class="coupon-name">{{ detail.name }}</view>
|
|
<view class="coupon-time" v-if="detail.type === 2 && detail.discountLimit > 0">最多抵扣: ¥{{ formatAmount(detail.discountLimit) }}</view>
|
|
<view class="coupon-time" v-if="detail.validEndTime">有效期至: {{ formatTimeStr(detail.validEndTime) }}</view>
|
|
</view>
|
|
<view class="coupon-status-stamp" v-if="detail.status === 1">已使用</view>
|
|
<view class="coupon-status-stamp" v-else-if="detail.status === 2">已过期</view>
|
|
<view class="coupon-status-stamp" v-else-if="detail.status === 3">已作废</view>
|
|
</view>
|
|
|
|
<!-- 详细信息 -->
|
|
<view class="info-section">
|
|
<view class="info-title">使用说明</view>
|
|
<view class="info-item">
|
|
<text class="label">可用范围:</text>
|
|
<text class="value">{{ detail.productScope === 1 ? '全部代金券通用' : '指定代金券可用' }}</text>
|
|
</view>
|
|
<view class="info-item" v-if="detail.validStartTime && detail.validEndTime">
|
|
<text class="label">有效期限:</text>
|
|
<text class="value">{{ formatTimeStr(detail.validStartTime) }} 至 {{ formatTimeStr(detail.validEndTime) }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 适用商品列表 -->
|
|
<view class="goods-section" v-if="detail.productScope === 2 && detail.voucherList && detail.voucherList.length > 0">
|
|
<view class="section-title">可用代金卷</view>
|
|
<view class="goods-list">
|
|
<view class="goods-item" v-for="(item, index) in detail.voucherList" :key="index">
|
|
<image class="goods-img" :src="item.coverUrl || item.picUrl || '/static/home/entry_icon.png'" mode="aspectFill"></image>
|
|
<view class="goods-info">
|
|
<view class="goods-name">{{ item.name }}</view>
|
|
<view class="goods-shop-name" v-if="item.shopName">门店: {{ item.shopName }}</view>
|
|
<view class="goods-meta-list">
|
|
<view class="goods-meta-item" v-if="item.stock !== undefined">
|
|
<text class="meta-label">库存:</text>
|
|
<text class="meta-value">{{ item.stock }}份</text>
|
|
</view>
|
|
<view class="goods-meta-item" v-if="item.useRule">
|
|
<text class="meta-label">使用规则:</text>
|
|
<text class="meta-value">{{ item.useRule }}</text>
|
|
</view>
|
|
<view class="goods-meta-item" v-if="item.validDays">
|
|
<text class="meta-label">有效天数:</text>
|
|
<text class="meta-value">{{ item.validDays }}天</text>
|
|
</view>
|
|
</view>
|
|
<view class="goods-price-row">
|
|
<text class="goods-price">¥{{ formatAmount(item.salePrice || item.sellPrice) }}</text>
|
|
<text class="goods-original-price" v-if="item.originalPrice">¥{{ formatAmount(item.originalPrice) }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view v-if="loading" class="loading-state">
|
|
<text>加载中...</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import NavHeader from "@/components/NavHeader/NavHeader.vue";
|
|
import { getLuCouponDetail } from "@/api/service.js";
|
|
import { formatTime } from "@/utils/date.js";
|
|
|
|
export default {
|
|
components: {
|
|
NavHeader,
|
|
},
|
|
data() {
|
|
return {
|
|
statusBarHeight: 0,
|
|
couponId: null,
|
|
detail: null,
|
|
loading: true,
|
|
};
|
|
},
|
|
computed: {
|
|
headerHeight() {
|
|
return this.statusBarHeight + 44;
|
|
},
|
|
},
|
|
onLoad(options) {
|
|
const systemInfo = uni.getSystemInfoSync();
|
|
this.statusBarHeight = systemInfo.statusBarHeight || 0;
|
|
|
|
if (options.id) {
|
|
this.couponId = options.id;
|
|
this.loadDetail();
|
|
} else {
|
|
uni.showToast({
|
|
title: '参数错误',
|
|
icon: 'none'
|
|
});
|
|
setTimeout(() => {
|
|
uni.navigateBack();
|
|
}, 1500);
|
|
}
|
|
},
|
|
methods: {
|
|
async loadDetail() {
|
|
this.loading = true;
|
|
try {
|
|
const res = await getLuCouponDetail(this.couponId);
|
|
if (res) {
|
|
this.detail = res;
|
|
} else {
|
|
uni.showToast({
|
|
title: '获取详情失败',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error("加载优惠卷详情失败:", error);
|
|
uni.showToast({
|
|
title: '加载失败',
|
|
icon: 'none'
|
|
});
|
|
} finally {
|
|
this.loading = false;
|
|
}
|
|
},
|
|
formatTimeStr(timestamp) {
|
|
if (!timestamp) return '';
|
|
return formatTime(timestamp, 'YYYY-MM-DD HH:mm:ss');
|
|
},
|
|
formatAmount(amount) {
|
|
if (!amount) return '0';
|
|
const yuan = amount / 100;
|
|
return Number.isInteger(yuan) ? yuan.toString() : yuan.toFixed(2).replace(/\.?0+$/, '');
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.coupon-detail-page {
|
|
min-height: 100vh;
|
|
background-color: #f5f5f5;
|
|
}
|
|
|
|
.header-fixed-wrapper {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
z-index: 100;
|
|
background-color: #fff;
|
|
}
|
|
|
|
.main-wrap {
|
|
padding: 20rpx;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.loading-state {
|
|
display: flex;
|
|
justify-content: center;
|
|
padding-top: 100rpx;
|
|
color: #999;
|
|
font-size: 28rpx;
|
|
}
|
|
|
|
.coupon-card {
|
|
position: relative;
|
|
display: flex;
|
|
background-color: #fff;
|
|
border-radius: 16rpx;
|
|
margin-bottom: 30rpx;
|
|
padding: 40rpx 30rpx;
|
|
align-items: center;
|
|
overflow: hidden;
|
|
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
|
|
|
|
.coupon-left {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 180rpx;
|
|
border-right: 2rpx dashed #eee;
|
|
padding-right: 20rpx;
|
|
|
|
.coupon-price {
|
|
color: #d51c3c;
|
|
|
|
.symbol {
|
|
font-size: 28rpx;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.amount {
|
|
font-size: 56rpx;
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
|
|
.coupon-condition {
|
|
font-size: 22rpx;
|
|
color: #666;
|
|
margin-top: 10rpx;
|
|
}
|
|
}
|
|
|
|
.coupon-right {
|
|
flex: 1;
|
|
padding-left: 30rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
|
|
.coupon-name {
|
|
font-size: 34rpx;
|
|
color: #333;
|
|
font-weight: bold;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.coupon-time {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
margin-bottom: 6rpx;
|
|
}
|
|
}
|
|
|
|
.coupon-status-stamp {
|
|
position: absolute;
|
|
right: -20rpx;
|
|
top: 20rpx;
|
|
width: 120rpx;
|
|
height: 40rpx;
|
|
line-height: 40rpx;
|
|
text-align: center;
|
|
background-color: rgba(153, 153, 153, 0.1);
|
|
color: #999;
|
|
font-size: 20rpx;
|
|
transform: rotate(45deg);
|
|
transform-origin: center;
|
|
border: 1rpx solid #999;
|
|
}
|
|
}
|
|
|
|
.info-section {
|
|
background-color: #fff;
|
|
border-radius: 16rpx;
|
|
padding: 30rpx;
|
|
margin-bottom: 30rpx;
|
|
|
|
.info-title {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
color: #333;
|
|
margin-bottom: 24rpx;
|
|
padding-bottom: 20rpx;
|
|
border-bottom: 1rpx solid #eee;
|
|
}
|
|
|
|
.info-item {
|
|
display: flex;
|
|
margin-bottom: 16rpx;
|
|
font-size: 28rpx;
|
|
line-height: 1.5;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.label {
|
|
color: #666;
|
|
width: 140rpx;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.value {
|
|
color: #333;
|
|
flex: 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
.goods-section {
|
|
background-color: #fff;
|
|
border-radius: 16rpx;
|
|
padding: 30rpx;
|
|
|
|
.section-title {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
color: #333;
|
|
margin-bottom: 24rpx;
|
|
padding-bottom: 20rpx;
|
|
border-bottom: 1rpx solid #eee;
|
|
}
|
|
|
|
.goods-list {
|
|
.goods-item {
|
|
display: flex;
|
|
padding: 20rpx 0;
|
|
border-bottom: 1rpx solid #f5f5f5;
|
|
|
|
&:last-child {
|
|
border-bottom: none;
|
|
padding-bottom: 0;
|
|
}
|
|
|
|
.goods-img {
|
|
width: 160rpx;
|
|
height: 160rpx;
|
|
border-radius: 12rpx;
|
|
margin-right: 20rpx;
|
|
background-color: #f5f5f5;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.goods-info {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: flex-start;
|
|
|
|
.goods-name {
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
font-weight: bold;
|
|
display: -webkit-box;
|
|
-webkit-box-orient: vertical;
|
|
-webkit-line-clamp: 2;
|
|
overflow: hidden;
|
|
margin-bottom: 8rpx;
|
|
}
|
|
|
|
.goods-shop-name {
|
|
font-size: 24rpx;
|
|
color: #666;
|
|
margin-bottom: 8rpx;
|
|
}
|
|
|
|
.goods-meta-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
margin-bottom: 12rpx;
|
|
|
|
.goods-meta-item {
|
|
font-size: 22rpx;
|
|
color: #999;
|
|
margin-bottom: 4rpx;
|
|
|
|
.meta-label {
|
|
color: #999;
|
|
}
|
|
.meta-value {
|
|
color: #666;
|
|
}
|
|
}
|
|
}
|
|
|
|
.goods-price-row {
|
|
display: flex;
|
|
align-items: baseline;
|
|
margin-top: auto;
|
|
}
|
|
|
|
.goods-price {
|
|
font-size: 32rpx;
|
|
color: #d51c3c;
|
|
font-weight: bold;
|
|
margin-right: 12rpx;
|
|
}
|
|
|
|
.goods-original-price {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
text-decoration: line-through;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style> |