You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

470 lines
9.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="wrap">
<!-- 背景图 -->
<image src="@/static/prize_bg.png" class="bg-image" mode="aspectFill"></image>
<!-- 顶部Logo -->
<view class="logo-container">
<image src="@/static/prize_logo.png" class="logo-image" mode="aspectFit"></image>
</view>
<!-- 盲盒区域 -->
<view class="box-container">
<view class="box-grid">
<view
v-for="(box, index) in boxList"
:key="index"
class="box-item"
:class="{ 'selected': box.selected }"
@click="selectBox(index)"
>
<image
:src="box.selected ? require('@/static/prize_box_current.png') : require('@/static/prize_box.png')"
class="box-image"
mode="aspectFit"
></image>
</view>
</view>
<!-- 底部按钮 -->
<view class="button-container">
<view class="select-button" :class="{ 'selected': selectedIndex !== -1 }" @click="confirmSelect">
<text class="button-text">{{ selectedIndex === -1 ? '点击选择盲盒' : '确认选择' }}</text>
</view>
</view>
</view>
<!-- 中奖表单弹窗 -->
<view v-show="showWinForm" class="win-form-popup-mask" @click.stop>
<view class="win-form-wrapper" @click.stop>
<view class="win-form-popup">
<view class="win-form-header">
<view class="win-title">
<text>恭喜您抽中</text>
<text class="prize-text">科普图书</text>
<text>一本!</text>
</view>
</view>
<view class="win-form-content">
<view class="form-submit">
<u-button
type="primary"
@click="submitWinAddress"
:custom-style="submitBtnStyle"
:loading="submitting"
>填写奖品快递地址</u-button>
</view>
</view>
</view>
</view>
</view>
<!-- 未中奖弹窗 -->
<view v-show="showNoWin" class="no-win-popup" @click.stop>
<view class="no-win-content">
<image src="@/static/no-win.png" class="no-win-image" mode="aspectFit"></image>
<view class="no-win-text">很遗憾,未中奖</view>
<view class="no-win-buttons">
<u-button
size="mini"
:throttle-time="1000"
shape="circle"
type="default"
:custom-style="parStyle"
@click="continueAnswer"
>继续答题</u-button>
<u-button
size="mini"
:throttle-time="1000"
shape="circle"
type="default"
:custom-style="parStyle"
@click="goBack"
>返回</u-button>
</view>
</view>
</view>
</view>
</template>
<script>
import { toast } from "@/common/util.js";
export default {
data() {
return {
boxList: [
{ selected: false },
{ selected: false },
{ selected: false },
{ selected: false },
{ selected: false },
{ selected: false },
{ selected: false },
{ selected: false },
{ selected: false }
],
selectedIndex: -1,
loading: false,
showWinForm: false, // 中奖表单弹窗
showNoWin: false, // 未中奖弹窗
winAddressForm: {
name: "",
mobile: "",
address: ""
},
submitting: false,
parStyle: {
background: 'linear-gradient(to right, #58b3fe, #446efd)',
color: '#fff',
'font-size': '32rpx',
padding: '30rpx',
width: '45%',
height: '90rpx'
},
submitBtnStyle: {
background: 'linear-gradient(to right, #58b3fe, #446efd)',
color: '#fff',
'font-size': '32rpx',
padding: '0',
'border-radius': '50rpx',
width: '60%',
height: '100rpx'
}
}
},
methods: {
selectBox(index) {
// 重置所有选中状态
this.boxList.forEach((box, i) => {
box.selected = i === index
})
this.selectedIndex = index
},
confirmSelect() {
if (this.selectedIndex === -1) {
toast('请先选择一个盲盒')
return
}
if (this.loading) {
return
}
this.loading = true
// 调用抽奖接口
this.$u.api.drawDynamic().then(async (res) => {
this.loading = false
console.log('抽奖结果:', res)
// 根据接口返回的 name 字段判断是否中奖
if (res.name === '已中奖') {
// 先获取用户信息预填充表单
await this.getUserInfo()
// 显示中奖表单弹窗
this.showWinForm = true
} else if (res.name === '未中奖') {
// 显示未中奖弹窗
this.showNoWin = true
} else {
toast('抽奖结果异常')
}
}).catch((error) => {
this.loading = false
console.error('抽奖失败:', error)
toast('抽奖失败,请稍后再试')
})
},
async getUserInfo() {
try {
const res = await this.$u.api.user()
this.winAddressForm = {
name: res.name || "",
mobile: res.mobile || "",
address: res.address || ""
}
} catch (error) {
console.error('获取用户信息失败:', error)
// 如果获取失败,表单保持为空
this.winAddressForm = {
name: "",
mobile: "",
address: ""
}
}
},
submitWinAddress() {
// 不再在本页提交表单,跳转到“我的”页面,由“我的”页面弹出奖品快递地址弹窗
uni.redirectTo({
url: '/pages/me/me?fromPrize=1'
})
},
continueAnswer() {
this.showNoWin = false
uni.redirectTo({
url: '/pages/answer/index'
})
},
goBack() {
this.showNoWin = false
uni.redirectTo({
url: '/pages/me/me'
})
}
}
}
</script>
<style lang="scss" scoped>
.wrap {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.bg-image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
}
.logo-container {
position: relative;
z-index: 1;
display: flex;
justify-content: center;
align-items: center;
padding-top: 100rpx;
}
.logo-image {
width: 620rpx;
height: 185rpx;
}
.box-container {
position: absolute;
top: 43.3%;
left: 130rpx;
z-index: 1;
}
.box-grid {
display: grid;
grid-template-columns: repeat(3, 154rpx);
grid-template-rows: repeat(3, 157rpx);
gap: 20rpx;
}
.box-item {
position: relative;
width: 154rpx;
height: 157rpx;
transition: transform 0.2s ease;
&:active {
transform: scale(0.95);
}
.box-image {
width: 100%;
height: 100%;
}
}
.button-container {
position: absolute;
top: calc(100% + 70rpx);
left: 50%;
transform: translateX(-50%);
z-index: 2;
width: 50%;
}
.select-button {
background: linear-gradient(to right, #58b3fe, #446efd);
border-radius: 50rpx;
padding: 20rpx;
text-align: center;
box-shadow: 0 4rpx 20rpx rgba(88, 179, 254, 0.3);
transition: background 0.3s ease;
&.selected {
background: linear-gradient(to right, #ffd6a3, #ff9d25);
box-shadow: 0 4rpx 20rpx rgba(255, 157, 37, 0.3);
}
.button-text {
color: #fff;
font-size: 32rpx;
font-weight: bold;
}
}
// 中奖表单弹窗样式
.win-form-popup-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 999;
display: flex;
align-items: center;
justify-content: center;
overflow: visible;
}
.win-form-wrapper {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
width: 680rpx;
}
.prize-book-image {
position: absolute;
top: -50rpx; // 减少超出距离
left: 50%;
transform: translateX(-50%);
width: 266rpx;
height: 266rpx;
z-index: 1000;
pointer-events: none; // 不阻挡点击事件
}
.win-form-popup {
position: relative;
width: 100%;
background: #f3f8ff;
border-radius: 20rpx;
margin-top: 50rpx; // 为图片留出空间
max-height: 90vh;
overflow-y: auto;
z-index: 999;
.win-form-header {
display: flex;
flex-direction: column;
align-items: center;
padding: 80rpx 30rpx 30rpx; // 增加顶部padding避免文字被图片遮挡
.win-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
.prize-text {
color: #fd9d0c;
}
}
.address-tip {
font-size: 40rpx;
font-weight: bold;
color: #333;
}
}
.win-form-content {
background: #f3f8ff;
padding: 0 40rpx 40rpx;
padding-bottom: 100rpx;
.form-item {
margin-bottom: 30rpx;
.form-label {
display: block;
font-size: 28rpx;
color: #333;
margin-bottom: 20rpx;
}
.address-textarea {
width: 100%;
min-height: 200rpx;
background: #fff;
border-radius: 0;
padding: 20rpx 30rpx;
font-size: 28rpx;
color: #333;
box-sizing: border-box;
}
}
.form-submit {
margin-top: 40rpx;
display: flex;
justify-content: center;
}
}
}
// 未中奖弹窗样式
.no-win-popup {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 999;
display: flex;
align-items: center;
justify-content: center;
.no-win-content {
position: relative;
display: flex;
align-items: center;
justify-content: center;
.no-win-image {
width: 725rpx;
height: 956rpx;
}
.no-win-text {
position: absolute;
top: 35%;
left: 50%;
transform: translateX(-50%);
font-size: 40rpx;
color: #2f6cf6;
font-weight: bold;
text-align: center;
white-space: nowrap;
}
.no-win-buttons {
position: absolute;
top: 60%;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 30rpx;
justify-content: center;
align-items: center;
width: 100%;
padding: 0 50rpx;
box-sizing: border-box;
::v-deep .u-btn {
flex: 0 0 auto;
width: 45%!important;
}
}
}
}
</style>