显示页面(lottery.vue):
<template>
<img id="bg" src="@/assets/bg.png" alt="">
<div class="card-container one">
<div :class="per_class" v-for="(item,index) in show_num" :key="item">
<!-- <video class="loop-animate" :ref="el=>{loopFlashes.value.push(el)}" muted custom-cache="{
{false}}" :src="'/src/assets/video/' + show_video_src_arr.value[index]"></video> -->
<video class="loop-animate" :ref="el=>{loopFlashes.value.push(el)}" muted custom-cache="{
{false}}" :src="webmsrc_dic[show_video_src_arr.value[index]]"></video>
<h1>{
{show_video_src_arr.value[index]}}</h1>
<p :class="seat_num_class('area')">{
{ cur_lottery_arr.value[index].area }}</p>
<p :class="seat_num_class('row')">{
{ cur_lottery_arr.value[index].row }}</p>
<p :class="seat_num_class('seat')">{
{ cur_lottery_arr.value[index].seat }}</p>
</div>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, onMounted, reactive, ref } from 'vue'
import Lottery from './lottery'
import car from '../assets/video/car.webm'
import account from '../assets/video/account.webm'
import diamond from '../assets/video/diamond.webm'
import mobilephone from '../assets/video/mobilephone.webm'
import earphone from '../assets/video/earphone.webm'
export default defineComponent({
name: 'QQSpeedLottery',
setup(){
const { max_area,
max_row,
max_seat,
getRandomByRange } = Lottery();
let show_num = ref(0);
let show_video_src_arr = reactive({value: [] as any[]});
let per_class = computed(() => {
return {
'per-card': true,
'card3-margin': show_num.value == 3,
'card4-margin': show_num.value == 4,
'card5-margin': show_num.value == 5,
}
})
const loopFlashes = reactive({value: [] as any[]});
// 1. 翻转动画
function reverse(){
for (let i = 0; i < loopFlashes.value.length; i++) {
if (loopFlashes.value[i] != null) {
loopFlashes.value[i].play();
}
}
let t1 = setTimeout(() => {
lottery_state.value = -1;
clearTimeout(t1);
}, 1100);
}
let lottery_state = ref(-1);
let seat_num_class = computed(() => {
return function(type: string){
return {
'seat-num': true,
area: type == 'area',
row: type == 'row',
seat: type == 'seat',
end: lottery_state.value == -1
}
}
})
let cur_lottery_arr = reactive({value: [
{area: '00', row: '00', seat: '00'}
,{area: '00', row: '00', seat: '00'}
,{area: '00', row: '00', seat: '00'}
,{area: '00', row: '00', seat: '00'}
,{area: '00', row: '00', seat: '00'}
]});
// 2. 滚动数字
function lottery(){
let area = getRandomByRange(1,max_area);
let row = getRandomByRange(1,max_row);
let seat = getRandomByRange(1,max_seat);
cur_lottery_arr.value = [];
for (let i = 0; i < show_num.value; i++) {
cur_lottery_arr.value.push({
area: area < 10 ? '0'+area.toString() : area.toString(),
row: row < 10 ? '0'+row.toString() : row.toString(),
seat: seat < 10 ? '0'+seat.toString() : seat.toString()
})
}
}
// 3. 暂停
function stop(){
clearInterval(lottery_interval);
}
let lottery_interval: any;
window.addEventListener("storage", (e) => {
let newValue = e.newValue;
let data_json;
if (newValue != null) {
data_json = JSON.parse(newValue);
}
// 奖品类型及个数
if (e.key == "awardTypeAndNum"){
show_num.value = data_json.award_num;
show_video_src_arr.value = [];
for (let i = 0; i < show_num.value; i++) {
show_video_src_arr.value.push(data_json.award_type_src);
}
// 隐藏座位号,重置动画素材
lottery_state.value = 1;
for (let i = 0; i < loopFlashes.value.length; i++) {
if (loopFlashes.value[i] != null) {
loopFlashes.value[i].load();
}
}
cur_lottery_arr.value = [
{area: '00', row: '00', seat: '00'}
,{area: '00', row: '00', seat: '00'}
,{area: '00', row: '00', seat: '00'}
,{area: '00', row: '00', seat: '00'}
,{area: '00', row: '00', seat: '00'}
];
} else if (e.key == "reverseState"){
reverse();
} else if (e.key == "lotteryState") {
if (data_json.state == 1) {
lottery_interval = setInterval(() => {
lottery();
}, 50);
} else {
stop();
cur_lottery_arr.value = data_json.cur_luckyer_list;
}
}
});
onMounted(() => {
localStorage.clear();
})
let webmsrc_dic: any = {
'car': car,
'account': account,
'diamond': diamond,
'mobilephone': mobilephone,
'earphone':earphone
}
return {
per_class,
reverse,
show_num,
loopFlashes,
show_video_src_arr,
seat_num_class,
cur_lottery_arr,
webmsrc_dic
}
}
})
</script>
<style scoped>
#bg{
position: absolute;
top: 0;
left: 0;
width: 1920px;
height: 1080px;
}
.card-container{
position: absolute;
top: 380px;
left: 0;
display: flex;
width: 1920px;
height: 378px;
justify-content: center;
}
.per-card{
position: relative;
width: 272px;
height: inherit;
border-radius: 10px;
transition: transform 1s;
}
.per-card:nth-child(1){
margin-left: 0;
}
.card3-margin{
margin-left: 106px;
}
.card4-margin{
margin-left: 118px;
}
.card5-margin{
margin-left: 118px;
}
.card5-margin{
margin-left: 59px;
}
.loop-animate{
position: absolute;
left: -356px;
top: -360px;
width: 990px;
height: auto;
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.face{
transform: rotateY(0deg) scale(1);
}
.back{
transform: rotateY(180deg) scale(1.2);
}
@font-face{
font-family: num;
src: url(../assets/FZRuiZHK_Zhong.TTF);
}
.seat-num{
position: absolute;
color: #fff;
font-size: 34px;
font-family: num;
font-style: italic;
transform: rotateY(90deg);
opacity: .9;
}
.area{top: 278px;right: 154px;}
.row{top: 320px;right: 190px;}
.seat{top: 322px;right: 101px;}
.end{
transform: rotateY(0deg);
transition: transform .3s;
}
</style>
操作页面(option.vue):
<template>
<div id="option-container">
<el-select v-model="award_type" placeholder="请选择奖品类型" filterable>
<el-option
v-for="(type, award_type_index) in award_type_list"
:key="'award-type-'+award_type_index"
:label="type.name"
:value="award_type_index">
</el-option>
</el-select>
<el-select v-model="award_num" placeholder="请选择奖品个数" filterable style="margin: 0 10px">
<el-option
v-for="(num, award_num_index) in award_num_list"
:key="'award-'+award_num_index"
:label="num.name"
:value="award_num_index">
</el-option>
</el-select>
<el-button size="small" @click="certainAwardTypeNum">确认奖品类型及个数</el-button>
<el-button @click="reverseEvent" :disabled="reverse_is_able">翻转</el-button>
<el-button @click="startEvent" :disabled="start_is_able">开始</el-button>
<el-button @click="pauseEvent" :disabled="stop_is_able">暂停</el-button>
<el-button @click="clearAll">清空已抽奖的纪录</el-button>
</div>
<h4 id="tip">当前H5展示奖品为:<span>{
{ cur_show_award_name }}</span>,奖品个数:<span>{
{ cur_show_award_num }}</span>。</h4>
</template>
<script lang="ts">
import { computed, defineComponent, onMounted, ref } from 'vue'
import GHttp from '@/composables/GHttp'
import Lottery from './lottery'
import { ElMessage } from 'element-plus';
export default defineComponent({
name: 'LotteryOption',
setup(){
const { seats_list,
getRandomByRange } = Lottery();//解构导入的方法
// 设置按钮可点击状态
let reverse_is_able = ref(true);
let start_is_able = ref(true);
let stop_is_able = ref(true);
const award_type_list = [
{name: '钻石', type: 1, src: 'diamond'}
,{name: 'S-天行者', type: 2, src: 'car'}
,{name: '真我Buds Air2耳机', type: 3, src: 'earphone'}
,{name: '真我GT手机', type: 4, src: 'mobilephone'}
,{name: '全A车账号', type: 5, src: 'account'}
];
let award_type = ref();
const award_num_list = [
{name: '1个', val: 1}
,{name: '3个', val: 3}
,{name: '4个', val: 4}
,{name: '5个', val: 5}
];
let award_num = ref();
// 设置奖品类型及个数
let cur_show_award_name = ref('暂无');
let cur_show_award_num = ref('暂无');
let award_type_num_state = ref(-1);
function certainAwardTypeNum(){
if (award_type.value > -1 && award_num.value > -1) {
cur_show_award_name.value = award_type.value > -1 ? award_type_list[award_type.value].name : '暂无';
cur_show_award_num.value = award_num.value > -1 ? award_num_list[award_num.value].name : '暂无';
let award_type_num_data = {
state: award_type_num_state.value,
award_type_src: award_type_list[award_type.value].src,
award_num: award_num_list[award_num.value].val
};
setLocalStorage('awardTypeAndNum', award_type_num_data);
award_type_num_state.value = -award_type_num_state.value;
reverse_is_able.value = false;
} else {
ElMessage({
showClose: true,
message: '请选择奖品类型、个数',
type: 'error'
});
}
}
// 翻转
let reverse_state = ref(-1);
function reverseEvent(){
setLocalStorage('reverseState', reverse_state.value);
reverse_state.value = -reverse_state.value;
start_is_able.value = false;
}
// 开始
function startEvent(){
let start_data = {
state: 1
};
setLocalStorage('lotteryState', start_data);
stop_is_able.value = false;
}
// 暂停
function pauseEvent(){
lottery_count = 0;
cur_all_seats_arr = [];
getLottery();
stop_is_able.value = true;
}
interface resData{
errcode: number,
errmsg: string,
[key: string]: any
}
let lottery_count = 0;
let cur_all_seats_arr = [] as any[];
function getLottery(){
let final_seat_index = getRandomByRange(0, seats_list.length - 1);
let final_seat = seats_list[final_seat_index];
let final_seat_str = final_seat.area + '区' + final_seat.row + '排' + final_seat.seat + '座';
let final_seat_obj = {area: final_seat.area, row: final_seat.row, seat: final_seat.seat};
let add_luckyer_param = {
luckyerlist: final_seat_str
};
if (lottery_count < award_num_list[award_num.value].val) {
GHttp.post('/addLuckyer', add_luckyer_param).then((res: resData) => {
if (res.errcode == 0) {
cur_all_seats_arr.push(final_seat_obj);
lottery_count ++;
}
getLottery();
})
} else {
let stop_data = {
state: -1,
cur_luckyer_list: cur_all_seats_arr
};
setLocalStorage('lotteryState', stop_data);
}
}
onMounted(() => {
localStorage.clear();
// /auth/getToken {user_id:10086}
// /getLuckyer
// /initLuckyer
// /addLuckyer {luckyerlist: "1,2,3,4"}
let token_param = {
"user_id": 10086
};
GHttp.post('/auth/getToken', token_param).then((res: resData) => {
// console.log(res)
})
})
function setLocalStorage(method: string, data: any){
let data_str = JSON.stringify(data);
localStorage.setItem(method, data_str);
}
// 清空
function clearAll(){
GHttp.get('/initLuckyer').then((res: resData) => {