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.

460 lines
11 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>
<div
id="lottery-draw"
class="body"
:style="{ 'background-image': 'url(' + bkg + ')' }"
>
<h3 class="title">
<span v-if="!$route.query.result"></span>
<span v-if="$route.query.result"></span>
{{ config.draw_prize.price_item }}
</h3>
<div class="container">
<div class="left">
<el-image
class="image"
:src="
config.draw_prize.image_file ? config.draw_prize.image_file.url : ''
"
fit="cover"
>
</el-image>
<div class="info">
<p>奖品 {{ config.draw_prize.name }} x {{ config.draw_prize.total }}</p>
<p>本次抽取 {{ config.draw_prize.has_total }} </p>
<p>赞助商 {{ config.draw_prize.apply }}</p>
</div>
</div>
<div class="right" :style="{ height: maxHeight }">
<div
class="numbers"
:class="{
'numbers-active': !isEnd,
}"
ref="numbers"
>
<div
class="numbers__item"
:style="{
'animation-timing-function': flag ? '' : 'ease-out',
}"
:class="{
'numbers__item--active': !isEnd
? !!resultNumbers.find((i) => i === index)
: !!resultNumbers.find((i) => i === item),
}"
v-for="(item, index) in numbers"
:key="$route.query.result ? index : item"
>
<span>{{ item }}</span>
</div>
<div
v-if="!$route.query.result"
v-show="!isEnd"
class="numbers__item"
:style="{
'animation-timing-function': flag ? '' : 'ease-out',
}"
:class="{
'numbers__item--active': !isEnd
? !!resultNumbers.find((i) => i === index)
: !!resultNumbers.find((i) => i === item),
}"
v-for="(item, index) in numbers"
:key="($route.query.result ? index : item) + 'b'"
>
<span>{{
isEnd ? config.numbers_list[Math.floor(Math.random() * 36)] : item
}}</span>
</div>
</div>
</div>
</div>
<button
class="btn"
:disabled="isOver"
:style="{ filter: isOver ? 'grayscale(90%)' : '' }"
v-if="$route.query.result != 1"
@click="draw"
>
<strong>{{ flag || isOver ? "结束抽奖" : "开始抽奖" }}</strong>
</button>
<!-- <el-image-->
<!-- :style="{ filter: flag ? 'grayscale(90%)' : '' }"-->
<!-- v-if="$route.query.result != 1"-->
<!-- :lazy="false"-->
<!-- class="btn"-->
<!-- :src="require('@/assets/mdLotteryDraw/button.png')"-->
<!-- fit="cover"-->
<!-- @click="draw"-->
<!-- ></el-image>-->
</div>
</template>
<script>
import bkg from "@/assets/mdLotteryDraw/bkg.png";
import { draw, drawConfig } from "@/api/mdLotteryDraw";
import { throttle } from "@/utils";
import { drawLog } from "@/api/activity/drawPrize";
export default {
data() {
return {
maxHeight: "40vh",
bkg,
flag: false, //是否开始
isEnd: true, //视图结束
isOver: false, //抽奖是否结束
timer: null,
config: {
draw_prize: {},
numbers_list: [],
},
result: [], //记录中奖
resultNumbers: [],
};
},
methods: {
init() {
const baseSize = 15;
const dom = document.getElementById("lottery-draw");
const scale = document.documentElement.clientWidth / 1920;
dom.style.fontSize = baseSize * Math.min(scale, 2) + "px";
this.$nextTick(() => {
this.maxHeight =
this.$refs["numbers"].getBoundingClientRect().height + "px";
});
},
async getConfig() {
const res = await drawConfig({
id: this.$route.params.id,
});
res.numbers_list = res.numbers_list.map((i) =>
i.toString().padStart(3, "0")
);
this.config = res;
this.$nextTick(() => {
this.maxHeight =
this.$refs["numbers"].getBoundingClientRect().height + "px";
});
},
async getResult() {
const res = await drawLog(
{
page: 1,
page_size: 9999,
activity_list_id: 8,
},
false
);
console.log(res);
this.resultNumbers = res.data
.filter((i) => i.draw_prize_id == this.$route.params.id)
.map((i) => i.mobile.padStart(3, "0"));
this.$nextTick(() => {
this.maxHeight =
this.$refs["numbers"].getBoundingClientRect().height + "px";
});
},
draw: throttle(async function () {
if (this.isOver) return;
if (!this.flag) {
console.log("开始抽奖");
try {
const result = await draw({
id: this.$route.params.id,
});
console.log(result);
result.draw_numbers = result.draw_numbers.map((i) =>
i.toString().padStart(3, "0")
);
this.result = result.draw_numbers;
this.flag = true;
this.isEnd = false;
this.timer = setInterval(() => {
// let set = new Set();
// while (set.size < result.draw_numbers.length) {
// let num = Math.floor(
// Math.random() * this.config.numbers_list.length
// );
// set.add(num);
// }
//
// this.resultNumbers = Array.from(set);
if (!this.flag) {
clearInterval(this.timer);
setTimeout(() => {
this.resultNumbers = result.draw_numbers;
this.isEnd = true;
this.isOver = true;
}, 150);
}
}, 150);
} catch (err) {
console.log(err);
this.isOver = true;
}
} else {
this.flag = false;
console.log("结束抽奖");
}
}),
},
computed: {
numbers() {
if (this.$route.query.result) {
return this.resultNumbers;
}
if (this.config.numbers_list) {
if (this.result.length > 0) {
let set = new Set();
this.result.forEach((i) => set.add(i));
while (set.size < 36 && set.size < this.config.numbers_list.length) {
set.add(
this.config.numbers_list[
Math.floor(Math.random() * this.config.numbers_list.length)
]
.toString()
.padStart(3, "0")
);
}
return Array.from(set).sort(() => Math.random() - 0.5);
}
let temp = this.config.numbers_list
.sort(() => Math.random() - 0.5)
.slice(0, 36);
console.log(temp);
return temp;
} else {
return [];
}
},
},
created() {
this.getConfig();
if (this.$route.query.result == 1) {
this.getResult();
}
},
mounted() {
this.init();
window.onresize = () => {
this.init();
};
},
};
</script>
<style scoped lang="scss">
.body {
height: 100vh;
width: 100vw;
background-size: cover;
background-repeat: no-repeat;
overflow: hidden;
transform-style: preserve-3d;
padding-top: 17.31vh;
.title {
letter-spacing: 2px;
font-size: 3.11em;
font-family: FZHanZhenGuangBiaoS-GB, sans-serif;
font-weight: 600;
color: #9e302e;
text-align: center;
background: linear-gradient(
to right,
#0000,
#dcbb78 8%,
#dcbb78 12%,
#dcbb78 34%,
#f1e2bb 40%,
#dcc68e 58%,
#dcc68e 66%,
#f5ecd0 92%,
#0000
);
}
.container {
width: 100vw;
font-size: 1em;
box-sizing: border-box;
display: flex;
align-items: center;
padding: 8vh 7.71vw 0 7.71vw;
.left {
font-size: 1em;
padding-top: 2vh;
margin-right: 9.13em;
.image {
width: 30.75em;
height: 17.03em;
}
.info {
font-weight: 400;
color: #ffffff;
line-height: 2.5em;
font-size: 1.6em;
font-family: FZZhengHeiS-M-GB, sans-serif;
margin-top: 3vh;
}
}
.right {
flex: 1;
overflow: hidden;
.numbers {
height: 100%;
display: flex;
flex-wrap: wrap;
align-content: center;
align-items: center;
justify-content: center;
& > div {
height: calc(100% / 6);
zoom: .95;
flex: 0 1 calc(100% / 6);
&:nth-child(6n) {
margin-right: 0;
}
}
//display: grid;
//grid-template-columns: repeat(6, 1fr);
////grid-template-rows: repeat(6, 1fr);
//grid-column-gap: 2.8em;
//grid-row-gap: 0.93vh;
//justify-content: center;
//align-content: center;
&-active {
& > div:nth-child(2n + 1) {
animation: blur 0.15s infinite linear;
}
& > div:nth-child(2n + 2) {
animation: blur 0.15s infinite linear reverse;
}
}
@keyframes blur {
from {
text-shadow: 2px 4px #00000066;
filter: blur(1.5px) drop-shadow(0 0 4px #00000055)
drop-shadow(0 0 8px #00000033);
}
to {
text-shadow: 2px 4px #00000066;
filter: blur(1.5px) drop-shadow(0 0 4px #00000055)
drop-shadow(0 0 8px #00000033);
transform: translateY(-200%);
}
}
&__item {
color: #ebd1a8;
text-align: center;
font-size: 3.4em;
height: 16.66%;
font-family: PingFang SC, sans-serif;
font-weight: 800;
border-radius: 2.8em;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease-out;
position: relative;
& > span {
position: relative;
}
&--active {
color: #a9262c;
&::before {
content: "";
transition: all 0.5s ease-out;
border-radius: 2.8em;
color: #a9262c;
background: linear-gradient(
264deg,
#f8eacc,
#e0c48a,
#f5e0b8,
#edddac,
#e1b872
);
z-index: 0;
position: absolute;
inset: 5px .4em 5px .4em;
}
}
}
}
}
}
@keyframes filter {
from {
filter: blur(5px);
}
to {
filter: blur(0);
color: #a9262c;
background: linear-gradient(
264deg,
#f8eacc,
#e0c48a,
#f5e0b8,
#edddac,
#e1b872
);
}
}
.btn {
border-width: 0;
display: block;
cursor: pointer;
text-align: center;
font-size: 2.6em;
width: 46.67%;
font-weight: 900;
transition: all 0.2s;
background: linear-gradient(
to bottom,
rgb(241, 170, 102) 20%,
rgb(234, 219, 188)
);
border-radius: 6px;
color: rgb(152, 50, 22);
box-shadow: 1px 4px 10px 6px #00000088;
transform: translateZ(0);
margin: 4.2vh auto 0 auto;
padding: 10px 0;
&:active {
transform: perspective(100px) translateZ(-5px);
}
}
}
</style>