<template>
|
<view class="container">
|
<!-- 抽奖机会卡片 -->
|
<view class="prize-card" v-if="prizeInfo.id">
|
<u-card :border="false" :head-style="{ padding: '30rpx' }" :body-style="{ padding: '0 30rpx 30rpx' }">
|
<!-- 头部:店铺信息 -->
|
<view slot="head" class="card-head">
|
<view class="store-info">
|
<u-icon name="home" size="36" color="#999"></u-icon>
|
<text class="store-name">{{ prizeInfo.storeName || '默认店铺' }}</text>
|
</view>
|
<u-tag v-if="prizeInfo.claimStatus === 'NOT_CLAIM'" text="未领取" type="warning" mode="plain" size="mini" />
|
<u-tag v-else-if="prizeInfo.claimStatus === 'CLAIM'" text="已领取" type="success" mode="plain" size="mini" />
|
<u-tag v-else text="已过期" type="info" mode="plain" size="mini" />
|
</view>
|
|
<!-- 主体:抽奖机会信息 -->
|
<view slot="body" class="card-body">
|
<!-- 封面图片 -->
|
<view class="cover-image" v-if="prizeInfo.activityCover">
|
<u-image
|
:src="prizeInfo.activityCover"
|
width="100%"
|
height="300rpx"
|
mode="aspectFill"
|
border-radius="10"
|
:fade="true"
|
duration="450"
|
></u-image>
|
</view>
|
|
<view class="prize-title">
|
<text class="title">{{ prizeInfo.activityName || prizeInfo.prizeName || '抽奖机会' }}</text>
|
</view>
|
|
<view class="prize-desc" v-if="prizeInfo.activityDes || prizeInfo.prizeDesc">
|
<text class="desc">{{ prizeInfo.activityDes || prizeInfo.prizeDesc }}</text>
|
</view>
|
|
<view class="prize-rule" v-if="prizeInfo.prizeRule">
|
<text class="rule-title">使用说明:</text>
|
<text class="rule-content">{{ prizeInfo.prizeRule }}</text>
|
</view>
|
|
<view class="prize-time" v-if="prizeInfo.beginTime && prizeInfo.endTime">
|
<u-icon name="clock" size="28" color="#999"></u-icon>
|
<text class="time-text">有效期:{{ formatDate(prizeInfo.beginTime) }} 至 {{ formatDate(prizeInfo.endTime) }}</text>
|
</view>
|
</view>
|
|
<!-- 底部:操作按钮 -->
|
<view slot="foot" class="card-foot">
|
<u-button
|
:type="prizeInfo.claimStatus === 'NOT_CLAIM' ? 'primary' : 'default'"
|
:disabled="prizeInfo.claimStatus !== 'NOT_CLAIM'"
|
:loading="loading"
|
@click="claimPrize"
|
:ripple="true"
|
:hair-line="false"
|
>
|
{{ prizeInfo.claimStatus === 'NOT_CLAIM' ? '立即领取' : prizeInfo.claimStatus === 'CLAIM' ? '已领取' : '已过期' }}
|
</u-button>
|
</view>
|
</u-card>
|
</view>
|
|
<!-- 空状态 -->
|
<view class="empty-state" v-else>
|
<u-empty text="抽奖机会信息不存在" mode="coupon" :icon-size="200"></u-empty>
|
</view>
|
|
<!-- 使用说明 -->
|
<view class="instructions">
|
<view class="instructions-title">
|
<u-icon name="info-circle" size="28" color="#999"></u-icon>
|
<text class="title-text">使用说明</text>
|
</view>
|
<view class="instructions-content">
|
<text class="content-text">1. 抽奖机会仅限在指定店铺使用\n2. 抽奖机会不可转让\n3. 请在有效期内使用</text>
|
</view>
|
</view>
|
|
<!-- 空白占位 -->
|
<view class="placeholder"></view>
|
</view>
|
</template>
|
|
<script>
|
import { getStorePrize, claimPrize } from '@/api/store-coupon.js';
|
|
export default {
|
data() {
|
return {
|
loading: false,
|
prizeId: '', // 抽奖机会ID
|
prizeInfo: {
|
id: "",
|
storeId: "",
|
storeName: "",
|
activityName: "", // 活动名称
|
prizeName: "抽奖机会",
|
prizeNo: "",
|
activityDes: "", // 活动描述
|
prizeDesc: "获得一次抽奖机会,可在指定活动中使用", // 抽奖机会描述
|
prizeRule: "每次抽奖消耗一次抽奖机会,抽中奖品后需及时领取", // 使用规则
|
beginTime: "", // 开始时间
|
endTime: "", // 结束时间
|
claimStatus: "NOT_CLAIM", // 领取状态
|
activityCover: "", // 封面图片
|
enableStatus: "ON" // 启用状态
|
}
|
}
|
},
|
onShow() {
|
if (this.prizeId) {
|
this.getPrizeDetail(this.prizeId);
|
}
|
},
|
onLoad(options) {
|
console.log('页面参数:', JSON.stringify(options));
|
// 获取传递的抽奖机会ID
|
if (options.id) {
|
this.prizeId = options.id;
|
this.getPrizeDetail(options.id);
|
} else if(options.q){
|
// 双重解码:微信对URL进行了两次编码
|
const decodedUrl = decodeURIComponent(decodeURIComponent(options.q));
|
console.log('原始URL:', decodedUrl);
|
|
// 解析URL中的查询参数
|
const params = this.parseUrlParams(decodedUrl);
|
this.prizeId = params.id;
|
this.getPrizeDetail(this.prizeId);
|
} else {
|
this.$u.toast('参数错误');
|
}
|
},
|
methods: {
|
// 解析URL参数
|
parseUrlParams(url) {
|
const params = {};
|
// 处理可能存在的hash(如果有的话)
|
const cleanUrl = url.split('#')[0];
|
const queryStr = cleanUrl.split('?')[1] || '';
|
|
queryStr.split('&').forEach(pair => {
|
const [key, value] = pair.split('=');
|
if (key) {
|
// 如果值存在,则解码,否则设为空字符串
|
params[key] = value ? decodeURIComponent(value) : '';
|
}
|
});
|
|
return params;
|
},
|
|
// 格式化日期
|
formatDate(dateStr) {
|
if (!dateStr) return '';
|
// 处理带时区的时间格式
|
const date = new Date(dateStr);
|
if (isNaN(date.getTime())) {
|
// 如果日期解析失败,返回原始字符串的日期部分
|
return dateStr.split('T')[0];
|
}
|
// 格式化为 YYYY-MM-DD
|
const year = date.getFullYear();
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
const day = String(date.getDate()).padStart(2, '0');
|
return `${year}-${month}-${day}`;
|
},
|
|
// 获取抽奖机会详情
|
async getPrizeDetail(prizeId) {
|
uni.showLoading({
|
title: '加载中...'
|
});
|
|
try {
|
console.log('请求奖品详情,ID:', prizeId);
|
const res = await getStorePrize(prizeId);
|
console.log('接口返回数据:', JSON.stringify(res));
|
|
if (res.statusCode === 200) {
|
// 根据你提供的接口数据结构处理
|
if (res.data && res.data.code === 200 && res.data.data) {
|
this.prizeInfo = {
|
...this.prizeInfo,
|
...res.data.data,
|
// 确保字段映射正确
|
id: res.data.data.id || "",
|
storeId: res.data.data.storeId || "",
|
storeName: res.data.data.storeName || "默认店铺",
|
activityName: res.data.data.activityName || "抽奖活动",
|
prizeName: res.data.data.prizeName || "抽奖机会",
|
prizeNo: res.data.data.no || "",
|
activityDes: res.data.data.activityDes || "获得一次抽奖机会,可在指定活动中使用",
|
prizeDesc: res.data.data.prizeDesc || "获得一次抽奖机会,可在指定活动中使用",
|
beginTime: res.data.data.beginTime || res.data.data.startTime || "",
|
endTime: res.data.data.endTime || "",
|
activityCover: res.data.data.activityCover || "",
|
enableStatus: res.data.data.enableStatus || "ON",
|
claimStatus: "NOT_CLAIM" // 默认为未领取状态
|
};
|
console.log('设置后的prizeInfo:', JSON.stringify(this.prizeInfo));
|
} else {
|
this.$u.toast(res.data.message || '获取抽奖机会详情失败');
|
}
|
} else {
|
this.$u.toast(res.data.message);
|
}
|
} catch (err) {
|
this.$u.toast('获取抽奖机会详情失败,请稍后重试');
|
console.error('获取抽奖机会详情失败:', err.message);
|
} finally {
|
uni.hideLoading();
|
}
|
},
|
|
// 领取抽奖机会
|
async claimPrize() {
|
if (this.prizeInfo.claimStatus !== 'NOT_CLAIM') {
|
this.$u.toast('该抽奖机会无法领取');
|
return;
|
}
|
|
// 确认领取
|
uni.showModal({
|
title: '提示',
|
content: `确定要领取"${this.prizeInfo.activityName || this.prizeInfo.prizeName || '本次抽奖机会'}"吗?`,
|
success: (res) => {
|
if (res.confirm) {
|
this.doClaimPrize();
|
}
|
}
|
});
|
},
|
|
// 执行领取抽奖机会操作
|
async doClaimPrize() {
|
this.loading = true;
|
try {
|
// 调用领取抽奖机会接口
|
const res = await claimPrize(this.prizeId);
|
console.log('领取接口返回:', JSON.stringify(res));
|
|
// 根据接口返回处理结果
|
if (res.statusCode === 200) {
|
// 检查返回的数据结构
|
if (res.data && res.data.code === 200) {
|
this.$u.toast('领取成功');
|
this.prizeInfo.claimStatus = 'CLAIM';
|
|
// 延迟返回上一页,让用户看到领取成功的提示
|
setTimeout(() => {
|
uni.navigateBack();
|
}, 1500);
|
} else {
|
this.$u.toast(res.data.message || '领取失败');
|
}
|
} else {
|
this.$u.toast('领取失败: ' + (res.data.message || '未知错误'));
|
}
|
} catch (err) {
|
this.$u.toast('领取失败,请稍后重试');
|
console.error('领取抽奖机会失败:', err.message);
|
} finally {
|
this.loading = false;
|
}
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.container {
|
background-color: #f5f5f5;
|
min-height: 100vh;
|
}
|
|
.prize-card {
|
margin: 20rpx;
|
}
|
|
.card-head {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
}
|
|
.store-info {
|
display: flex;
|
align-items: center;
|
}
|
|
.store-name {
|
margin-left: 10rpx;
|
font-size: 32rpx;
|
font-weight: bold;
|
color: #333;
|
}
|
|
.card-body {
|
padding-top: 20rpx;
|
}
|
|
.cover-image {
|
margin-bottom: 30rpx;
|
}
|
|
.prize-title {
|
margin-bottom: 30rpx;
|
display: flex;
|
align-items: center;
|
flex-wrap: wrap;
|
}
|
|
.title {
|
font-size: 36rpx;
|
font-weight: bold;
|
color: #333;
|
}
|
|
.prize-desc {
|
margin-bottom: 30rpx;
|
}
|
|
.desc {
|
font-size: 28rpx;
|
color: #666;
|
}
|
|
.prize-rule {
|
margin-bottom: 30rpx;
|
}
|
|
.rule-title {
|
font-size: 28rpx;
|
color: #333;
|
font-weight: bold;
|
}
|
|
.rule-content {
|
font-size: 26rpx;
|
color: #666;
|
}
|
|
.prize-time {
|
display: flex;
|
align-items: center;
|
margin-bottom: 20rpx;
|
}
|
|
.time-text {
|
font-size: 24rpx;
|
color: #999;
|
margin-left: 10rpx;
|
}
|
|
.card-foot {
|
padding: 20rpx 0;
|
}
|
|
.instructions {
|
background-color: #ffffff;
|
margin: 20rpx;
|
padding: 30rpx;
|
border-radius: 16rpx;
|
}
|
|
.instructions-title {
|
display: flex;
|
align-items: center;
|
margin-bottom: 20rpx;
|
}
|
|
.title-text {
|
margin-left: 10rpx;
|
font-size: 30rpx;
|
font-weight: bold;
|
color: #333;
|
}
|
|
.instructions-content {
|
padding-left: 40rpx;
|
}
|
|
.content-text {
|
font-size: 26rpx;
|
color: #666;
|
line-height: 1.6;
|
}
|
|
.placeholder {
|
height: 40rpx;
|
}
|
|
.empty-state {
|
margin-top: 200rpx;
|
}
|
</style>
|