import { computed } from 'vue' import { roundTypeOptions, scoreTypeOptions } from '@/constants/business' export interface QuestionItem { id: string questionId: string | null score: number time: number title: string scoreType: Api.Competition.QuestionScoreType uiType?: string templateId?: number } export interface RoundModel { id: string name: string questions: QuestionItem[] } function generateId() { return `q_${Date.now()}_${Math.random().toString(36).slice(2, 9)}` } 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 }) }) // 新增轮次 function addRound(customName?: string, customCount?: number, roundType?: Api.Competition.CompetitionRoundType) { 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, roundType: roundType || roundTypeOptions[0].value, questions: Array.from({ length: count }).map(() => ({ id: generateId(), questionId: null, score: 5, time: 30, title: '', scoreType: scoreTypeOptions[0].value, })), }) } // 删除轮次 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({ id: generateId(), value: null, score: 5, time: 30, title: '', scoreType: scoreTypeOptions[0].value, }) } } // 删除题目 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++) { const question = round.questions[j] const questionPrefix = `${round.name} 第 ${j + 1} 题` if (!question.questionId) { window.$message?.error(`${questionPrefix}未选择题型`) return false } if (!question.uiType) { window.$message?.error(`${questionPrefix}未选择UI类型`) return false } if (!question.templateId) { window.$message?.error(`${questionPrefix}未选择模板`) return false } if (!question.time) { window.$message?.error(`${questionPrefix}未设置答题时间`) return false } if (!question.scoreType) { window.$message?.error(`${questionPrefix}未设置分数规则`) return false } if (!question.title) { window.$message?.error(`${questionPrefix}未填写标题`) return false } if (question.score === null || question.score === undefined) { window.$message?.error(`${questionPrefix}未设置分数`) return false } } } return true } function reset() { // 默认重置为1个轮次,10个题目 props.modelValue.rounds = [] addRound() } return { getRoundScore, getRoundTime, totalStats, addRound, removeRound, addQuestion, removeQuestion, validate, reset, } }