|
@ -9,7 +9,7 @@ |
|
|
@reset="handleReset" |
|
|
@reset="handleReset" |
|
|
@export="handleExport" |
|
|
@export="handleExport" |
|
|
/> |
|
|
/> |
|
|
<MusicPlayer ref="musicPlayerRef" /> |
|
|
|
|
|
|
|
|
<!-- <MusicPlayer ref="musicPlayerRef" /> --> |
|
|
<Mascot /> |
|
|
<Mascot /> |
|
|
|
|
|
|
|
|
<!-- 透明弹窗 --> |
|
|
<!-- 透明弹窗 --> |
|
@ -41,13 +41,15 @@ |
|
|
/> --> |
|
|
/> --> |
|
|
<!-- <Qipao :text="qipaoText" :show="showQipao" /> --> |
|
|
<!-- <Qipao :text="qipaoText" :show="showQipao" /> --> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<audio ref="audioRef" :src="musicSrc" loop preload="auto"></audio> |
|
|
|
|
|
<audio ref="audioRef1" :src="musicSrc1" preload="auto"></audio> |
|
|
</template> |
|
|
</template> |
|
|
|
|
|
|
|
|
<script setup> |
|
|
<script setup> |
|
|
import Lottery3D from "./lottery/Lottery3D.vue"; |
|
|
import Lottery3D from "./lottery/Lottery3D.vue"; |
|
|
import PrizePanel from "./lottery/PrizePanel.vue"; |
|
|
import PrizePanel from "./lottery/PrizePanel.vue"; |
|
|
import ControlBar from "./lottery/ControlBar.vue"; |
|
|
import ControlBar from "./lottery/ControlBar.vue"; |
|
|
import MusicPlayer from "./lottery/MusicPlayer.vue"; |
|
|
|
|
|
|
|
|
// import MusicPlayer from "./lottery/MusicPlayer.vue"; |
|
|
import Qipao from "./lottery/Qipao.vue"; |
|
|
import Qipao from "./lottery/Qipao.vue"; |
|
|
import UserList from "./lottery/UserList.vue"; |
|
|
import UserList from "./lottery/UserList.vue"; |
|
|
import Mascot from "./lottery/Mascot.vue"; |
|
|
import Mascot from "./lottery/Mascot.vue"; |
|
@ -109,7 +111,7 @@ const lotteryEngine = useLotteryEngine(dataManager, { |
|
|
|
|
|
|
|
|
onMounted(async () => { |
|
|
onMounted(async () => { |
|
|
isDisabled.value = true; |
|
|
isDisabled.value = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await dataManager.getBasicData(); |
|
|
await dataManager.getBasicData(); |
|
|
|
|
|
|
|
|
await dataManager.getUsers(); |
|
|
await dataManager.getUsers(); |
|
@ -117,19 +119,30 @@ onMounted(async () => { |
|
|
isDisabled.value = false; |
|
|
isDisabled.value = false; |
|
|
}, 3800); |
|
|
}, 3800); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 将 dataManager 挂载到 window 对象,供子组件使用 |
|
|
// 将 dataManager 挂载到 window 对象,供子组件使用 |
|
|
window.dataManager = dataManager; |
|
|
window.dataManager = dataManager; |
|
|
|
|
|
|
|
|
// 延迟一点时间确保音乐播放器组件已经加载完成 |
|
|
|
|
|
setTimeout(() => { |
|
|
|
|
|
if (musicPlayerRef.value && !musicPlayerRef.value.isPlaying()) { |
|
|
|
|
|
// 触发音乐播放 |
|
|
|
|
|
musicPlayerRef.value.toggleMusic(); |
|
|
|
|
|
} |
|
|
|
|
|
}, 1000); |
|
|
|
|
|
|
|
|
// 预加载音频文件以减少播放延迟 |
|
|
|
|
|
preloadAudio(); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// 预加载音频文件 |
|
|
|
|
|
function preloadAudio() { |
|
|
|
|
|
if (audioRef.value) { |
|
|
|
|
|
audioRef.value.load(); |
|
|
|
|
|
// 设置音频缓冲 |
|
|
|
|
|
audioRef.value.addEventListener('canplaythrough', () => { |
|
|
|
|
|
console.log('背景音乐预加载完成'); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
if (audioRef1.value) { |
|
|
|
|
|
audioRef1.value.load(); |
|
|
|
|
|
audioRef1.value.addEventListener('canplaythrough', () => { |
|
|
|
|
|
console.log('音效预加载完成'); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
function showLotteryQipao() { |
|
|
function showLotteryQipao() { |
|
|
const luckys = dataManager.state.currentLuckys; |
|
|
const luckys = dataManager.state.currentLuckys; |
|
|
const prize = dataManager.state.currentPrize; |
|
|
const prize = dataManager.state.currentPrize; |
|
@ -145,6 +158,75 @@ function showLotteryQipao() { |
|
|
}, 3000); |
|
|
}, 3000); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
import musicFile from "/src/assets/worldcup.mp3"; |
|
|
|
|
|
import musicFile1 from "/src/assets/dong.mp3"; |
|
|
|
|
|
const musicSrc = musicFile; |
|
|
|
|
|
const audioRef = ref(null); |
|
|
|
|
|
const playing = ref(false); |
|
|
|
|
|
const musicSrc1 = musicFile1; |
|
|
|
|
|
const audioRef1 = ref(null); |
|
|
|
|
|
const playing1 = ref(false); |
|
|
|
|
|
|
|
|
|
|
|
async function toggleMusic() { |
|
|
|
|
|
if (!audioRef.value) return; |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
if (audioRef.value.paused) { |
|
|
|
|
|
// 确保音频已经准备好播放 |
|
|
|
|
|
if (audioRef.value.readyState < 2) { |
|
|
|
|
|
await new Promise((resolve) => { |
|
|
|
|
|
audioRef.value.addEventListener('canplay', resolve, { once: true }); |
|
|
|
|
|
audioRef.value.load(); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
await audioRef.value.play(); |
|
|
|
|
|
playing.value = true; |
|
|
|
|
|
} else { |
|
|
|
|
|
audioRef.value.pause(); |
|
|
|
|
|
playing.value = false; |
|
|
|
|
|
} |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
console.error('播放音乐失败:', error); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async function playMusic1() { |
|
|
|
|
|
if (!audioRef1.value) return; |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
// 重置音频到开始位置 |
|
|
|
|
|
audioRef1.value.currentTime = 0; |
|
|
|
|
|
|
|
|
|
|
|
// 确保音频已经准备好播放 |
|
|
|
|
|
if (audioRef1.value.readyState < 2) { |
|
|
|
|
|
await new Promise((resolve) => { |
|
|
|
|
|
audioRef1.value.addEventListener('canplay', resolve, { once: true }); |
|
|
|
|
|
audioRef1.value.load(); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
await audioRef1.value.play(); |
|
|
|
|
|
playing1.value = true; |
|
|
|
|
|
|
|
|
|
|
|
// 监听音频播放结束事件 |
|
|
|
|
|
audioRef1.value.addEventListener('ended', () => { |
|
|
|
|
|
playing1.value = false; |
|
|
|
|
|
}, { once: true }); |
|
|
|
|
|
|
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
console.error('播放音效失败:', error); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function isPlaying1() { |
|
|
|
|
|
return playing1.value; |
|
|
|
|
|
} |
|
|
|
|
|
// 检查是否正在播放 |
|
|
|
|
|
function isPlaying() { |
|
|
|
|
|
return playing.value; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
async function handleLotteryClick() { |
|
|
async function handleLotteryClick() { |
|
|
if (isDisabled.value) return; // 2秒内不能重复点击 |
|
|
if (isDisabled.value) return; // 2秒内不能重复点击 |
|
|
isDisabled.value = true; |
|
|
isDisabled.value = true; |
|
@ -191,20 +273,25 @@ async function handleLotteryClick() { |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (lastRevealed.value === 0 && dataManager.state.basicData.prizes[lastRevealed.value].remainNum === 0) { |
|
|
|
|
|
|
|
|
if ( |
|
|
|
|
|
lastRevealed.value === 0 && |
|
|
|
|
|
dataManager.state.basicData.prizes[lastRevealed.value].remainNum === 0 |
|
|
|
|
|
) { |
|
|
// 如果是最后一个奖品且剩余数量为0,则跳出 |
|
|
// 如果是最后一个奖品且剩余数量为0,则跳出 |
|
|
// const currentPrize = dataManager.state.basicData.prizes[lastRevealed.value]; |
|
|
// const currentPrize = dataManager.state.basicData.prizes[lastRevealed.value]; |
|
|
// if (currentPrize && currentPrize.remainNum === 0) { |
|
|
// if (currentPrize && currentPrize.remainNum === 0) { |
|
|
showPrizeExhaustedModal2.value = true; |
|
|
|
|
|
setTimeout(() => { |
|
|
|
|
|
showPrizeExhaustedModal2.value = false; |
|
|
|
|
|
}, 1000); |
|
|
|
|
|
isDisabled.value = false; |
|
|
|
|
|
|
|
|
showPrizeExhaustedModal2.value = true; |
|
|
|
|
|
setTimeout(() => { |
|
|
|
|
|
showPrizeExhaustedModal2.value = false; |
|
|
|
|
|
}, 1000); |
|
|
|
|
|
isDisabled.value = false; |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
// } |
|
|
// } |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
toggleMusic(); |
|
|
|
|
|
|
|
|
console.log("lotteryState 变更前:", lotteryState.value, "-> rotating"); |
|
|
console.log("lotteryState 变更前:", lotteryState.value, "-> rotating"); |
|
|
lotteryState.value = "rotating"; |
|
|
lotteryState.value = "rotating"; |
|
|
console.log("lotteryState 变更后:", lotteryState.value); |
|
|
console.log("lotteryState 变更后:", lotteryState.value); |
|
@ -228,6 +315,16 @@ async function handleLotteryClick() { |
|
|
}, 2000); |
|
|
}, 2000); |
|
|
|
|
|
|
|
|
console.log("drawLottery 调用成功,结果:", winnerList.value); |
|
|
console.log("drawLottery 调用成功,结果:", winnerList.value); |
|
|
|
|
|
|
|
|
|
|
|
// 开奖成功后更新获奖名单数据 |
|
|
|
|
|
// if (window.dataManager && window.dataManager.updatePrizeList) { |
|
|
|
|
|
// try { |
|
|
|
|
|
// await window.dataManager.updatePrizeList(); |
|
|
|
|
|
// console.log("开奖后获奖名单数据已更新"); |
|
|
|
|
|
// } catch (error) { |
|
|
|
|
|
// console.error("更新获奖名单数据失败:", error); |
|
|
|
|
|
// } |
|
|
|
|
|
// } |
|
|
} catch (error) { |
|
|
} catch (error) { |
|
|
console.error("drawLottery 调用失败:", error); |
|
|
console.error("drawLottery 调用失败:", error); |
|
|
} |
|
|
} |
|
@ -239,24 +336,17 @@ async function handleLotteryClick() { |
|
|
setTimeout(() => { |
|
|
setTimeout(() => { |
|
|
isDisabled.value = false; |
|
|
isDisabled.value = false; |
|
|
}, 2000); |
|
|
}, 2000); |
|
|
// 停止转动并开奖 |
|
|
|
|
|
// const prize = dataManager.state.basicData.prizes[lastRevealed.value]; |
|
|
|
|
|
// console.log("准备调用 drawLottery,prize:", prize); |
|
|
|
|
|
// console.log("lastRevealed.value:", lastRevealed.value); |
|
|
|
|
|
// try { |
|
|
|
|
|
// winnerList.value = await drawLottery({ |
|
|
|
|
|
// perWin: prize.perWin, |
|
|
|
|
|
// remainNum: prize.remainNum, |
|
|
|
|
|
// gradeId: prize.gradeId, |
|
|
|
|
|
// prizeId: prize.prizeId, |
|
|
|
|
|
// }); |
|
|
|
|
|
// console.log("drawLottery 调用成功,结果:", winnerList.value); |
|
|
|
|
|
// } catch (error) { |
|
|
|
|
|
// console.error("drawLottery 调用失败:", error); |
|
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// toggleMusic(); |
|
|
|
|
|
|
|
|
|
|
|
// toggleMusic(); |
|
|
|
|
|
|
|
|
await lottery3DRef.value?.rotateBallStop?.(); |
|
|
await lottery3DRef.value?.rotateBallStop?.(); |
|
|
|
|
|
toggleMusic(); |
|
|
|
|
|
playMusic1(); |
|
|
|
|
|
|
|
|
await lotteryEngine.executeLottery(); |
|
|
await lotteryEngine.executeLottery(); |
|
|
|
|
|
|
|
|
await nextTick(); |
|
|
await nextTick(); |
|
|
showLotteryQipao(); |
|
|
showLotteryQipao(); |
|
|
console.log("lotteryState 变更前:", lotteryState.value, "-> idle"); |
|
|
console.log("lotteryState 变更前:", lotteryState.value, "-> idle"); |
|
@ -359,13 +449,20 @@ function handleNextPrize() { |
|
|
font-weight: bold; |
|
|
font-weight: bold; |
|
|
margin: 0; |
|
|
margin: 0; |
|
|
white-space: nowrap; |
|
|
white-space: nowrap; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@keyframes fadeInOut { |
|
|
@keyframes fadeInOut { |
|
|
0% { opacity: 0; } |
|
|
|
|
|
20% { opacity: 1; } |
|
|
|
|
|
80% { opacity: 1; } |
|
|
|
|
|
100% { opacity: 0; } |
|
|
|
|
|
|
|
|
0% { |
|
|
|
|
|
opacity: 0; |
|
|
|
|
|
} |
|
|
|
|
|
20% { |
|
|
|
|
|
opacity: 1; |
|
|
|
|
|
} |
|
|
|
|
|
80% { |
|
|
|
|
|
opacity: 1; |
|
|
|
|
|
} |
|
|
|
|
|
100% { |
|
|
|
|
|
opacity: 0; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
</style> |
|
|
</style> |