|
|
@ -13,21 +13,14 @@ |
|
|
|
<Mascot /> |
|
|
|
|
|
|
|
<!-- 透明弹窗 --> |
|
|
|
<div v-if="showPrizeExhaustedModal" class="prize-exhausted-modal"> |
|
|
|
<div v-if="modalConfig.show" class="prize-exhausted-modal"> |
|
|
|
<div class="modal-content"> |
|
|
|
<p class="modal-text">该礼品已抽取完毕,请揭秘下一个礼品</p> |
|
|
|
<p class="modal-text">{{ modalConfig.text }}</p> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div v-if="showPrizeExhaustedModal1" class="prize-exhausted-modal"> |
|
|
|
<div class="modal-content"> |
|
|
|
<p class="modal-text">请先揭秘一个礼品</p> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div v-if="showPrizeExhaustedModal2" class="prize-exhausted-modal"> |
|
|
|
<div class="modal-content"> |
|
|
|
<p class="modal-text">该礼品已抽取完毕</p> |
|
|
|
<div v-if="yonghuyichouwan" class="yonghuyichouwan-modal"> |
|
|
|
<div class="yonghuyichouwan-modal-content"> |
|
|
|
<p class="yonghuyichouwan-modal-text">恭喜所有中奖用户!</p> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
@ -53,7 +46,7 @@ import ControlBar from "./lottery/ControlBar.vue"; |
|
|
|
import Qipao from "./lottery/Qipao.vue"; |
|
|
|
import UserList from "./lottery/UserList.vue"; |
|
|
|
import Mascot from "./lottery/Mascot.vue"; |
|
|
|
import { ref, onMounted, nextTick, computed, watch } from "vue"; |
|
|
|
import { ref, onMounted, onBeforeMount, nextTick, computed, watch } from "vue"; |
|
|
|
import { useDataManager } from "./lottery/dataManager.js"; |
|
|
|
import { useLotteryEngine } from "./lottery/lotteryEngine.js"; |
|
|
|
|
|
|
@ -62,9 +55,24 @@ import { drawLottery } from "../../api/API"; |
|
|
|
|
|
|
|
const qipaoText = ref(""); |
|
|
|
const showQipao = ref(false); |
|
|
|
const showPrizeExhaustedModal = ref(false); |
|
|
|
const showPrizeExhaustedModal1 = ref(false); |
|
|
|
const showPrizeExhaustedModal2 = ref(false); |
|
|
|
|
|
|
|
// 弹窗配置 |
|
|
|
const modalConfig = ref({ |
|
|
|
show: false, |
|
|
|
text: "" |
|
|
|
}); |
|
|
|
|
|
|
|
// 显示弹窗的方法 |
|
|
|
function showModal(text, duration = 1000) { |
|
|
|
modalConfig.value = { |
|
|
|
show: true, |
|
|
|
text: text |
|
|
|
}; |
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
|
modalConfig.value.show = false; |
|
|
|
}, duration); |
|
|
|
} |
|
|
|
|
|
|
|
// const lotteryState = ref('idle'); // idle, ready, rotating, result |
|
|
|
|
|
|
@ -109,6 +117,16 @@ const lotteryEngine = useLotteryEngine(dataManager, { |
|
|
|
selectCard: (...args) => lottery3DRef.value?.selectCard?.(...args), |
|
|
|
}); |
|
|
|
|
|
|
|
// 页面加载之前的钩子函数 |
|
|
|
onBeforeMount(() => { |
|
|
|
console.log("页面即将加载(onBeforeMount)"); |
|
|
|
lastRevealed.value = -1; |
|
|
|
lotteryState.value="idle"; |
|
|
|
|
|
|
|
// 可以在这里做一些初始化操作,比如重置store、准备数据等 |
|
|
|
// 例如:lotteryStore.resetState && lotteryStore.resetState(); |
|
|
|
}); |
|
|
|
|
|
|
|
onMounted(async () => { |
|
|
|
isDisabled.value = true; |
|
|
|
|
|
|
@ -166,6 +184,7 @@ const playing = ref(false); |
|
|
|
const musicSrc1 = musicFile1; |
|
|
|
const audioRef1 = ref(null); |
|
|
|
const playing1 = ref(false); |
|
|
|
const yonghuyichouwan = ref(false); |
|
|
|
|
|
|
|
async function toggleMusic() { |
|
|
|
if (!audioRef.value) return; |
|
|
@ -253,10 +272,7 @@ async function handleLotteryClick() { |
|
|
|
if (waitingForNextReveal.value) { |
|
|
|
console.log("waitingForNextReveal.value", waitingForNextReveal.value); |
|
|
|
// 显示弹窗提示 |
|
|
|
showPrizeExhaustedModal.value = true; |
|
|
|
setTimeout(() => { |
|
|
|
showPrizeExhaustedModal.value = false; |
|
|
|
}, 1000); |
|
|
|
showModal("该礼品已抽取完毕,请揭秘下一个礼品"); |
|
|
|
isDisabled.value = false; |
|
|
|
|
|
|
|
break; |
|
|
@ -264,10 +280,7 @@ async function handleLotteryClick() { |
|
|
|
|
|
|
|
if (lastRevealed.value === -1) { |
|
|
|
console.log("lastRevealed.value", lastRevealed.value); |
|
|
|
showPrizeExhaustedModal1.value = true; |
|
|
|
setTimeout(() => { |
|
|
|
showPrizeExhaustedModal1.value = false; |
|
|
|
}, 1000); |
|
|
|
showModal("请先揭秘一个礼品"); |
|
|
|
isDisabled.value = false; |
|
|
|
|
|
|
|
break; |
|
|
@ -280,10 +293,7 @@ async function handleLotteryClick() { |
|
|
|
// 如果是最后一个奖品且剩余数量为0,则跳出 |
|
|
|
// const currentPrize = dataManager.state.basicData.prizes[lastRevealed.value]; |
|
|
|
// if (currentPrize && currentPrize.remainNum === 0) { |
|
|
|
showPrizeExhaustedModal2.value = true; |
|
|
|
setTimeout(() => { |
|
|
|
showPrizeExhaustedModal2.value = false; |
|
|
|
}, 1000); |
|
|
|
showModal("该礼品已抽取完毕"); |
|
|
|
isDisabled.value = false; |
|
|
|
break; |
|
|
|
|
|
|
@ -304,12 +314,26 @@ async function handleLotteryClick() { |
|
|
|
|
|
|
|
// 同时请求接口 |
|
|
|
try { |
|
|
|
winnerList.value = await drawLottery({ |
|
|
|
const res = await drawLottery({ |
|
|
|
perWin: prize.perWin, |
|
|
|
remainNum: prize.remainNum, |
|
|
|
gradeId: prize.gradeId, |
|
|
|
prizeId: prize.prizeId, |
|
|
|
}); |
|
|
|
console.log("res是", res); |
|
|
|
winnerList.value = res; |
|
|
|
if(res.data.round === false && res.data.data.length === 0){ |
|
|
|
isDisabled.value = true; |
|
|
|
console.log("isDisabled.value是", isDisabled.value); |
|
|
|
// showModal("用户已抽完",100000); |
|
|
|
yonghuyichouwan.value = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
|
isDisabled.value = false; |
|
|
|
}, 2000); |
|
|
@ -465,4 +489,118 @@ function handleNextPrize() { |
|
|
|
opacity: 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* 用户已抽完弹窗样式 - 从下方飞入到中央 */ |
|
|
|
.yonghuyichouwan-modal { |
|
|
|
position: fixed; |
|
|
|
top: 0; |
|
|
|
left: 0; |
|
|
|
width: 100%; |
|
|
|
height: 100%; |
|
|
|
display: flex; |
|
|
|
justify-content: center; |
|
|
|
align-items: center; |
|
|
|
z-index: 10000; |
|
|
|
background: rgba(0, 0, 0, 0.7); |
|
|
|
animation: modalFadeIn 0.5s ease-out; |
|
|
|
} |
|
|
|
|
|
|
|
.yonghuyichouwan-modal-content { |
|
|
|
background: linear-gradient(135deg, #e68907 0%, #b01717 100%); |
|
|
|
border-radius: 20px; |
|
|
|
padding: 40px 60px; |
|
|
|
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3); |
|
|
|
text-align: center; |
|
|
|
min-width: 800px; |
|
|
|
min-height: 600px; |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
animation: cardFlyIn 0.8s ease-out; |
|
|
|
border: 3px solid #fff; |
|
|
|
position: relative; |
|
|
|
overflow: hidden; |
|
|
|
} |
|
|
|
|
|
|
|
.yonghuyichouwan-modal-content::before { |
|
|
|
content: ''; |
|
|
|
position: absolute; |
|
|
|
top: 0; |
|
|
|
left: 0; |
|
|
|
right: 0; |
|
|
|
bottom: 0; |
|
|
|
background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.1) 50%, transparent 70%); |
|
|
|
animation: shimmer 2s infinite; |
|
|
|
} |
|
|
|
|
|
|
|
.yonghuyichouwan-modal-text { |
|
|
|
color: #fbff11; |
|
|
|
font-size: 80px; |
|
|
|
font-weight: bold; |
|
|
|
margin: 0; |
|
|
|
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); |
|
|
|
position: relative; |
|
|
|
z-index: 1; |
|
|
|
} |
|
|
|
|
|
|
|
/* 弹窗淡入动画 */ |
|
|
|
@keyframes modalFadeIn { |
|
|
|
0% { |
|
|
|
opacity: 0; |
|
|
|
} |
|
|
|
100% { |
|
|
|
opacity: 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* 卡牌从下方飞入动画 */ |
|
|
|
@keyframes cardFlyIn { |
|
|
|
0% { |
|
|
|
transform: translateY(100vh) scale(0.3); |
|
|
|
opacity: 0; |
|
|
|
} |
|
|
|
50% { |
|
|
|
transform: translateY(-20px) scale(1.1); |
|
|
|
opacity: 0.8; |
|
|
|
} |
|
|
|
100% { |
|
|
|
transform: translateY(0) scale(1); |
|
|
|
opacity: 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* 闪光效果 */ |
|
|
|
@keyframes shimmer { |
|
|
|
0% { |
|
|
|
transform: translateX(-100%); |
|
|
|
} |
|
|
|
100% { |
|
|
|
transform: translateX(100%); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* 响应式设计 */ |
|
|
|
@media (max-width: 768px) { |
|
|
|
.yonghuyichouwan-modal-content { |
|
|
|
min-width: 300px; |
|
|
|
min-height: 150px; |
|
|
|
padding: 30px 40px; |
|
|
|
} |
|
|
|
|
|
|
|
.yonghuyichouwan-modal-text { |
|
|
|
font-size: 24px; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@media (max-width: 480px) { |
|
|
|
.yonghuyichouwan-modal-content { |
|
|
|
min-width: 250px; |
|
|
|
min-height: 120px; |
|
|
|
padding: 20px 30px; |
|
|
|
} |
|
|
|
|
|
|
|
.yonghuyichouwan-modal-text { |
|
|
|
font-size: 20px; |
|
|
|
} |
|
|
|
} |
|
|
|
</style> |