Files
reader-star/apps/admin/src/store/modules/competition.ts

130 lines
3.1 KiB
TypeScript
Raw Normal View History

import type { CompetitionData } from '@/views/user/types'
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import { useRouterPush } from '@/hooks/common/router'
import { AudioController } from '@/utils/audio'
import { mockData } from '@/views/user/data/mock'
export const useCompetitionStore = defineStore('competition', () => {
const { routerPushByKey } = useRouterPush()
// --- State ---
const data = ref<CompetitionData>(mockData)
const currentStep = ref(0) // Node 索引
const subStep = ref(0) // Question 索引
const timeLeft = ref(0)
const timerInterval = ref<number | null>(null)
// 音效控制器 (支持自定义音频文件,例如:{ start: '/audio/start.mp3' })
const audioController = new AudioController()
// --- Getters ---
const currentNode = computed(() => data.value.nodes[currentStep.value])
const currentQuestion = computed(() => {
const questions = currentNode.value?.questions || []
return questions[subStep.value] || questions[0]
})
const isLastQuestionInNode = computed(() => {
if (!currentNode.value)
return true
return subStep.value >= currentNode.value.questions.length - 1
})
const isLastNode = computed(() => {
return currentStep.value >= data.value.nodes.length - 1
})
// --- Actions ---
function initData() {
// 这里可以重置或者重新拉取数据
// data.value = ...
resetProgress()
}
function resetProgress() {
currentStep.value = 0
subStep.value = 0
stopTimer()
}
// --- Audio Helpers ---
// 音频相关逻辑已抽离到 @/utils/audio.ts
/**
*
*/
function startTimer() {
stopTimer()
if (!currentNode.value)
return
timeLeft.value = currentNode.value.config.timeLimit
audioController.play('start') // 播放开始音效
timerInterval.value = window.setInterval(() => {
if (timeLeft.value > 0) {
timeLeft.value--
// 剩余5秒播放倒计时音效
if (timeLeft.value <= 5) {
audioController.play('tick')
}
}
else {
stopTimer()
// 时间到,自动进入解析页
routerPushByKey('user_analysis')
}
}, 1000)
}
function stopTimer() {
if (timerInterval.value) {
clearInterval(timerInterval.value)
timerInterval.value = null
}
}
/**
*
* @returns 便
*/
function nextStep() {
stopTimer()
// A. 如果当前环节还有题
if (!isLastQuestionInNode.value) {
subStep.value++
// 回到抽题页
return 'user_draw'
}
// B. 当前环节结束,去下一个环节
else if (!isLastNode.value) {
currentStep.value++
subStep.value = 0
// 回到抽题页(新环节)
return 'user_draw'
}
// C. 全部结束
else {
resetProgress()
return 'user_cover'
}
}
return {
data,
currentStep,
subStep,
timeLeft,
currentNode,
currentQuestion,
initData,
startTimer,
stopTimer,
nextStep,
}
})