171 lines
4.7 KiB
TypeScript
171 lines
4.7 KiB
TypeScript
|
|
import { computed } from 'vue'
|
|||
|
|
|
|||
|
|
export interface QuestionItem {
|
|||
|
|
value: string | null
|
|||
|
|
score: number
|
|||
|
|
time: number
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export interface RoundModel {
|
|||
|
|
id: string
|
|||
|
|
name: string
|
|||
|
|
questions: QuestionItem[]
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export interface QuestionConfigModel {
|
|||
|
|
rounds: RoundModel[]
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export function useQuestionConfig(props: any) {
|
|||
|
|
// 计算每个轮次的分数
|
|||
|
|
const getRoundScore = (roundIndex: number) => {
|
|||
|
|
const round = props.modelValue?.rounds?.[roundIndex]
|
|||
|
|
if (!round)
|
|||
|
|
return 0
|
|||
|
|
return round.questions.reduce((sum: number, item: any) => sum + (Number(item.score) || 0), 0)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 计算每个轮次的时长
|
|||
|
|
const getRoundTime = (roundIndex: number) => {
|
|||
|
|
const round = props.modelValue?.rounds?.[roundIndex]
|
|||
|
|
if (!round)
|
|||
|
|
return 0
|
|||
|
|
return round.questions.reduce((sum: number, item: any) => sum + (Number(item.time) || 0), 0)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 总计统计
|
|||
|
|
const totalStats = computed(() => {
|
|||
|
|
const rounds = props.modelValue?.rounds || []
|
|||
|
|
return rounds.reduce((acc: any, round: any) => {
|
|||
|
|
acc.count += round.questions.length
|
|||
|
|
acc.score += round.questions.reduce((sum: number, item: any) => sum + (Number(item.score) || 0), 0)
|
|||
|
|
acc.time += round.questions.reduce((sum: number, item: any) => sum + (Number(item.time) || 0), 0)
|
|||
|
|
return acc
|
|||
|
|
}, { count: 0, score: 0, time: 0 })
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
const questionOptions = [
|
|||
|
|
{ label: '汉字听写 - 根据提示书写汉字', value: 'hanzi' },
|
|||
|
|
{ label: '同音字辨析 - 根据拼音书写', value: 'tongyin' },
|
|||
|
|
{ label: '偏旁部首 - 按要求写字', value: 'pianpang' },
|
|||
|
|
{ label: '词语听写 - 综合练习', value: 'ciyu' },
|
|||
|
|
{ label: '成语填空 - 四字成语', value: 'chengyu' },
|
|||
|
|
{ label: '反义词挑战', value: 'fanyi' },
|
|||
|
|
{ label: '近义词挑战', value: 'jinyi' },
|
|||
|
|
{ label: '看图猜字', value: 'kantu' },
|
|||
|
|
{ label: '古诗词接龙', value: 'gushi' },
|
|||
|
|
{ label: '名句听写', value: 'mingju' },
|
|||
|
|
{ label: '极速成语接龙 - 每题10秒', value: 'speed10' },
|
|||
|
|
{ label: '极速成语接龙 - 每题20秒', value: 'speed20' },
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
const scoreOptions = [
|
|||
|
|
{ label: '1分', value: 1 },
|
|||
|
|
{ label: '2分', value: 2 },
|
|||
|
|
{ label: '3分', value: 3 },
|
|||
|
|
{ label: '5分', value: 5 },
|
|||
|
|
{ label: '10分', value: 10 },
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
const timeOptions = [
|
|||
|
|
{ label: '15s', value: 15 },
|
|||
|
|
{ label: '30s', value: 30 },
|
|||
|
|
{ label: '45s', value: 45 },
|
|||
|
|
{ label: '60s', value: 60 },
|
|||
|
|
{ label: '90s', value: 90 },
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
// 新增轮次
|
|||
|
|
function addRound(customName?: string, customCount?: number) {
|
|||
|
|
if (!props.modelValue.rounds) {
|
|||
|
|
props.modelValue.rounds = []
|
|||
|
|
}
|
|||
|
|
const index = props.modelValue.rounds.length + 1
|
|||
|
|
const count = typeof customCount === 'number' ? customCount : 10
|
|||
|
|
const name = typeof customName === 'string' ? customName : `第${index}轮:比赛环节`
|
|||
|
|
|
|||
|
|
props.modelValue.rounds.push({
|
|||
|
|
id: `round_${Date.now()}`,
|
|||
|
|
name,
|
|||
|
|
questions: Array.from({ length: count }).map(() => ({
|
|||
|
|
value: null,
|
|||
|
|
score: 5,
|
|||
|
|
time: 30,
|
|||
|
|
})),
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 删除轮次
|
|||
|
|
function removeRound(index: number) {
|
|||
|
|
props.modelValue.rounds.splice(index, 1)
|
|||
|
|
// 重命名剩余轮次
|
|||
|
|
props.modelValue.rounds.forEach((round: RoundModel, idx: number) => {
|
|||
|
|
round.name = round.name.replace(/第\d+轮/, `第${idx + 1}轮`)
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 新增题目
|
|||
|
|
function addQuestion(roundIndex: number) {
|
|||
|
|
const round = props.modelValue.rounds[roundIndex]
|
|||
|
|
if (round) {
|
|||
|
|
round.questions.push({
|
|||
|
|
value: null,
|
|||
|
|
score: 5,
|
|||
|
|
time: 30,
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 删除题目
|
|||
|
|
function removeQuestion(roundIndex: number, questionIndex: number) {
|
|||
|
|
const round = props.modelValue.rounds[roundIndex]
|
|||
|
|
if (round) {
|
|||
|
|
round.questions.splice(questionIndex, 1)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function validate() {
|
|||
|
|
const rounds = props.modelValue?.rounds || []
|
|||
|
|
if (rounds.length === 0) {
|
|||
|
|
window.$message?.error('请至少配置一个比赛环节')
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (let i = 0; i < rounds.length; i++) {
|
|||
|
|
const round = rounds[i]
|
|||
|
|
if (round.questions.length === 0) {
|
|||
|
|
window.$message?.error(`${round.name} 至少需要配置一道题目`)
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
for (let j = 0; j < round.questions.length; j++) {
|
|||
|
|
if (!round.questions[j].value) {
|
|||
|
|
window.$message?.error(`${round.name} 第 ${j + 1} 题未选择题型`)
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return true
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function reset() {
|
|||
|
|
// 默认重置为1个轮次,10个题目
|
|||
|
|
props.modelValue.rounds = []
|
|||
|
|
addRound()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
getRoundScore,
|
|||
|
|
getRoundTime,
|
|||
|
|
totalStats,
|
|||
|
|
questionOptions,
|
|||
|
|
scoreOptions,
|
|||
|
|
timeOptions,
|
|||
|
|
addRound,
|
|||
|
|
removeRound,
|
|||
|
|
addQuestion,
|
|||
|
|
removeQuestion,
|
|||
|
|
validate,
|
|||
|
|
reset,
|
|||
|
|
}
|
|||
|
|
}
|