定义好奖品下标,计时器开始抽奖,请求接口,出现中奖奖品之后,获取中奖商品对应的奖品下标,再次计时器判断当前移动的小标是否为中奖商品的下标,并且是否转到3圈(防止转1圈就停止),如果时就清除两次计时器。
当前代码封装为九宫格的组件;
vue代码:
<template>
<view class="page" v-if="merchantInfo.cdn_static">
<image class="bg" :src="merchantInfo.cdn_static +'statistics/luckDrawImg/sudoku/page_bg.png'" mode="aspectFill"></image>
<view class="content">
<view class="logo">
<image :src="merchantInfo.logo" mode="heightFix"></image>
</view>
<view class="box">
<view class="awards">
<view class="awardsItem" v-for="(item,index) in awardsList" :key="index" :class="item.active ? 'awardsActive' : ''" @click="startPlay(index)">
<view class="play" v-if="index == 4">
<view class="go">{{item.title}}</view>
<view v-if="index == 4" class="count">{{total}}次机会</view>
</view>
<image :src="merchantInfo.cdn_static + item.img" v-else></image>
</view>
</view>
<view class="notification">
<image :src="merchantInfo.cdn_static +'statistics/luckDrawImg/sudoku/notification.png'" mode="heightFix"></image>
<text>好礼转不停</text>
</view>
<view class="btns">
<view class="btn" @click="rule_show=true">
<image :src="merchantInfo.cdn_static +'statistics/luckDrawImg/sudoku/rule.png'"></image>
</view>
<view class="btn" @click="getResult()">
<image :src="merchantInfo.cdn_static +'statistics/luckDrawImg/sudoku/prize.png'"></image>
</view>
</view>
</view>
</view>
<view class="win" v-if="rule_show">
<scroll-view scroll-y class="win_box .win_box_bg">
<mp-html :content="luckDrawInfo.rule" />
</scroll-view>
<text class="iconfont iconcolseIcon theme-font-white" @click="rule_show=false"></text>
</view>
<view class="win" v-if="result_show">
<view class="win_box1">
<image class="win_bg" :src="merchantInfo.cdn_static +'statistics/luckDrawImg/result_bg.png'" mode=""></image>
<view class="win_content">
<view class="win_tips theme-font-white">{{currentPrize.desc}}</view>
<view class="win_title">{{currentPrize.title}}</view>
<view class="win_btn" @click="choiseAddress()">{{currentPrize.is_address==1?'选择地址':'确定'}}</view>
</view>
</view>
</view>
<view class="win" v-if="prize_show">
<view class="win_tit theme-font-white">我的奖品</view>
<view class="win_box2">
<view class="items">
<view class="left i_title">奖品</view>
<view class="right i_title">中奖时间</view>
</view>
<scroll-view scroll-y class="list">
<view class="item" v-for="(item,index) in list" :key="index">
<view class="left">{{item.lottery_prize_title}}</view>
<view class="right" v-if="item.is_address==1&&!item.address_id">
<view class="r_btn" @click="choiseAddress1(item)">去领奖</view>
</view>
<view class="right" v-else>{{item.created_time}}</view>
</view>
</scroll-view>
</view>
<text class="iconfont iconcolseIcon theme-font-white" @click="prize_show=false"></text>
</view>
</view>
</template>
<script>
import { luckDrawInfo } from '@/api/luckDraw.js';
import colors from '@/mixins/color';
export default {
mixins: [colors],
data() {
return {//https://cdn.dev.scrm.juplus.cn/InQLzDLoAl2S9LyNJUXQ45gpA.png
mask: true,
wtf:true,
luckDrawInfo: {},
rule_show:false,
result_show:false,
prize_show:false,
total:0,
currentPrize:{},
list:[],
id: "",
awardsList: [],
indexArray: [0, 1, 2, 5, 8, 7, 6, 3],
num: 0,
count: 0,
timer: null
}
},
props: {
userId: {
type: [Number,String]
},
type:{
type: [Number,String]
}
},
//渲染完了
mounted() {
this.id = this.userId;
this.init();
},
methods: {
/**
* 设置奖项
*/
setAwardsList(data){
this.awardsList = [];
let arrayBefore = data.length > 0 ? data.slice(0,4) : [];
let arrayAfter = data.length > 0 ? data.slice(4) : [];
this.awardsList = [...arrayBefore];
this.awardsList.push({
title: "抽"
});
this.awardsList = [...this.awardsList,...arrayAfter];
this.awardsList.forEach((item,index) => {
item.active = index == 4 ? true : false;
});
},
init(){
if(this.userInfo){
this.getInfo()
}else{
setTimeout(()=>{
this.init()
},500)
}
},
getInfo(){
luckDrawInfo.getDetail({id:this.id}).then(res => {
this.luckDrawInfo=res.data
this.total=res.data.my_can_num
this.setAwardsList(res.data.lottery_prize);
this.action('lottery',this.id,0,2,this.luckDrawInfo.title,'','lottery')
})
},
choiseAddress(){
this.currentPrize.is_address==1?uni.navigateTo({
url:'/pages/address/address'
}):''
this.result_show=false
// 重置抽奖
this.awardsList.forEach((item,index) => {
item.active = index == 4 ? true : false;
});
this.num = 0;
this.count = 0;
this.timer = null;
},
choiseAddress1(data){
this.currentPrize=data
uni.navigateTo({
url:'/pages/address/address'
})
this.prize_show=false
},
setAddress(id){
luckDrawInfo.setAddress({address_id:id,history_id:this.currentPrize.history_id||this.currentPrize.id}).then(res => {
uni.showToast({
title:"地址设置成功",
icon:'none'
})
})
},
getResult(){
if(!this.wtf){
return false
}
luckDrawInfo.getResult({lottery_id:this.id}).then(res => {
this.list=res.data.data
this.prize_show=true
})
},
// 点击开始,请求接口抽奖
startPlay(index) {
if (index != 4) return false;
if(this.luckDrawInfo.is_register==1&&!this.userInfo.type){
uni.navigateTo({
url:'/pages/login/login'
})
return false
}
if(this.luckDrawInfo.is_form==1&&this.luckDrawInfo.user_form_count==0){
uni.navigateTo({
url:'/pages/form/form?id='+this.luckDrawInfo.form_id+'&type_id=' + this.id + '&type=lottery'
})
return false
}
if(!this.wtf){
return false
}
// 活动未开始或活动已结束
let startTimeMs = new Date(this.luckDrawInfo.start_time).getTime();
let endTimeMs = new Date(this.luckDrawInfo.end_time).getTime();
let nowTimeMs = new Date().getTime();
if (nowTimeMs < startTimeMs) {
uni.showToast({
icon: "none",
title: "活动未开始"
})
return false;
}
if (nowTimeMs > endTimeMs) {
uni.showToast({
icon: "none",
title: "活动已结束"
})
return false;
}
this.mask = false;
this.wtf = false;
// 抽奖开始
clearInterval(this.timer)
this.timer = setInterval(() => {
this.awardsList.forEach((item,index) => {
item.active = false;
});
this.awardsList[this.indexArray[this.num]].active = true;
this.num++;
if (this.num >= this.indexArray.length) {
this.num = 0;
this.count++;
}
},100);
luckDrawInfo.run({id:this.id}).then(res => {
this.currentPrize = res.data;
this.total = res.data.row_lottery_new.my_can_num;
// 抽奖停止
let prizeIndex = this.awardsList.findIndex(item => item.id == this.currentPrize.id);
let prizeNumIndex = prizeIndex != -1 ? this.indexArray.findIndex(item => item == prizeIndex) : null;
let delayTimer = setInterval(()=>{
// 奖品选中
if (this.count >= 3 && this.num == prizeNumIndex) {
clearInterval(this.timer);
clearInterval(delayTimer);
this.awardsList.forEach((item,index) => {
item.active = index == prizeIndex ? true : false;
this.$set(this.awardsList, index, {...this.awardsList[index], active: item.active});
});
setTimeout(() => {
this.result_show = true;
this.wtf = true;
},600);
}
},100)
}).catch(err => {
this.wtf = true;
});
}
}
}
</script>
<style scoped lang="scss">
@import 'index.scss';
/**/
</style>
scss代码:
.page{
width: 750rpx;
height: 100vh;
position: relative;
}
.bg{
width: 750rpx;
height: 100vh;
}
.content{
width: 750rpx;
min-height: 100vh;
height: 1448rpx;
position: absolute;
top: 0;
left: 0;
}
.logo{
height: 60rpx;
display: flex;
justify-content: center;
margin-top: 90rpx;
image{
height: 60rpx;
}
}
.box{
width: 680rpx;
margin: 0 auto;
margin-top: 330rpx;
.awards{
width: 525rpx;
height: 525rpx;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-content:space-between;
.awardsItem{
width: 161rpx;
height: 161rpx;
background: linear-gradient(132deg, #FFCEA4 0%, #FFE6CB 100%);
box-shadow: 0rpx 6rpx 0rpx 0rpx #E98F5D;
border-radius: 15rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
image{
width: 132rpx;
height: 132rpx;
border-radius: 12rpx;
}
.play{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.go{
font-size: 68rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #A10B14;
}
.count{
font-size: 24rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #A10B14;
}
}
}
.awardsActive{
background: linear-gradient(132deg, #FFECBB 0%, #FFB100 100%);
box-shadow: 0rpx 6rpx 0rpx 0rpx #E38800, inset 0rpx 2rpx 6rpx 0rpx rgba(255,255,255,0.65), inset 0rpx -2rpx 6rpx 0rpx rgba(255,255,255,0.3);
}
}
.notification{
height: 40rpx;
margin-top: 226rpx;
display: flex;
justify-content: center;
align-items: center;
image{
height: 32rpx;
margin-right: 16rpx;
}
text{
font-size: 28rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #FF8D3B;
}
}
.btns{
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 38rpx;
}
.btn{
width: 332rpx;
height: 110rpx;
image{
width: 100%;
height: 100%;
}
}
}
.win{
width: 750rpx;
height: 100vh;
background: rgba(0, 0, 0, 0.8);
position: fixed;
top: 0;
left: 0;
z-index: 2;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.win_box{
width: 662rpx;
height: 60%;
padding: 40rpx;
box-sizing: border-box;
border-radius: 24rpx;
}
.win_box_bg{
background: #FFCE2B;
}
.bg3{
background: #C3E5FE;
}
.iconcolseIcon{
font-size: 58rpx;
margin-top: 98rpx;
}
.win_box1{
width: 630rpx;
height: 922rpx;
position: relative;
}
.win_bg{
width: 630rpx;
height: 922rpx;
}
.win_content{
width: 630rpx;
height: 922rpx;
position: absolute;
left: 0;
top: 0;
display: flex;
flex-direction: column;
align-items: center;
}
.win_tips{
font-size: 48rpx;
font-family: SourceHanSansSC-Medium, SourceHanSansSC;
font-weight: bold;
margin-top: 290rpx;
}
.win_title{
font-size: 48rpx;
font-family: SourceHanSansSC-Medium, SourceHanSansSC;
font-weight: bold;
color: #FE6631;
margin: 170rpx 0;
}
.win_btn{
width: 280rpx;
height: 80rpx;
line-height: 80rpx;
text-align: center;
background: #FFE047;
border-radius: 46rpx;
font-size: 32rpx;
font-family: SourceHanSansSC-Medium, SourceHanSansSC;
font-weight: bold;
color: #13112C;
}
.win_tit{
font-size: 48rpx;
font-family: SourceHanSansSC-Medium, SourceHanSansSC;
font-weight: bold;
margin-bottom: 32rpx;
}
.win_box2{
width: 662rpx;
height: 900rpx;
background: #FFFFFF;
border-radius: 24rpx;
display: flex;
flex-direction: column;
}
.items{
width: 662rpx;
height: 108rpx;
background: #C3E5FE;
border-radius: 24rpx 24rpx 0rpx 0rpx;
display: flex;
align-items: center;
flex-shrink:0
}
.left,.right{
width: 50%;
text-align: center;
font-family: SourceHanSansSC-Medium, SourceHanSansSC;
font-weight: bold;
}
.i_title{
font-size: 36rpx;
}
.list{
height: 792rpx;
padding-bottom: 20rpx;
overflow: hidden;
}
.item{
width: 662rpx;
height: 88rpx;
display: flex;
align-items: center;
justify-content: space-around;
}
.item:nth-child(2n){
background-color: #F4F4F4;
}
.r_btn{
width: 160rpx;
height: 60rpx;
line-height: 60rpx;
text-align: center;
background: #FFC659;
border-radius: 46rpx;
font-family: SourceHanSansSC-Medium, SourceHanSansSC;
font-weight: bold;
font-size: 32rpx;
margin:0 auto;
}
效果: