// 定义接口类型 interface Question { id: number; type: number; question: string; option: Record; } interface AnswerItem { queId: string; ans: string[]; suc?: boolean; } interface QuizComponent { properties: { questions: Question[]; answerList: AnswerItem[]; }; data: { selectedAnswers: Record; renderQuestions: Array< Question & { options: Array<{ key: string; value: string }> } >; }; setData: (data: Partial>, callback?: () => void) => void; triggerEvent: (name: string, data?: any) => void; isSelected: (qid: string | number, key: string) => boolean; getSelectedAnswer: (qid: string | number, index: number) => string; isCorrect: (qid: string, key: string) => boolean; isWrong: (qid: string, key: string) => boolean; handleRadioChange: (e: WechatMiniprogram.RadioGroupChange) => void; handleCheckboxChange: (e: WechatMiniprogram.CheckboxGroupChange) => void; getFormattedAnswers: () => Array<{ questionId: number; answers: string[]; questionType: number; }>; getAllAnswers: () => Array<{ questionId: number; answers: string[]; questionType: number; }>; isAllAnswered: () => boolean; getProgress: () => { answered: number; total: number; percentage: number }; } // 定义常量 const QUESTION_TYPE = { SINGLE: 1, MULTIPLE: 2, }; Component({ properties: { questions: { type: Array, value: [], }, answerList: { type: Array, value: [], }, }, observers: { "questions, answerList": function (this: QuizComponent) { const renderQuestions = (this.properties.questions || []).map( (q: Question) => ({ ...q, options: Object.keys(q.option || {}).map((k) => ({ key: k, value: q.option[k], })), }) ); const answerList = Array.isArray(this.properties.answerList) ? this.properties.answerList : []; const selectedAnswers = answerList.reduce((acc, item) => { if (item && item.queId && item.ans) { acc[Number(item.queId)] = Array.isArray(item.ans) ? item.ans : [item.ans]; } return acc; }, {} as Record); this.setData({ renderQuestions, selectedAnswers, }); }, }, data: { selectedAnswers: {} as Record, renderQuestions: [] as Array< Question & { options: Array<{ key: string; value: string }> } >, }, methods: { isSelected(this: QuizComponent, qid: string | number, key: string) { const selected = this.data.selectedAnswers[Number(qid)]; return Array.isArray(selected) && selected.includes(key); }, getSelectedAnswer(this: QuizComponent, qid: string | number, index: number) { const selected = this.data.selectedAnswers[Number(qid)]; return Array.isArray(selected) ? selected[index] : ""; }, isCorrect(this: QuizComponent, qid: string, key: string) { const answerList = Array.isArray(this.properties.answerList) ? this.properties.answerList : []; return answerList.some((item: AnswerItem) => { const answers = Array.isArray(item.ans) ? item.ans : []; return String(item.queId) === String(qid) && answers.includes(key) && item.suc; }); }, isWrong(this: QuizComponent, qid: string, key: string) { const answerList = Array.isArray(this.properties.answerList) ? this.properties.answerList : []; return answerList.some((item: AnswerItem) => { const answers = Array.isArray(item.ans) ? item.ans : []; return String(item.queId) === String(qid) && answers.includes(key) && !item.suc; }); }, // 处理单选变化 { queId: q.id, ans: selectedAnswers } handleRadioChange( this: QuizComponent, e: WechatMiniprogram.RadioGroupChange ) { const { questionId } = e.currentTarget.dataset; const value = e.detail.value; if (!questionId) return; const numericQuestionId = Number(questionId); const newAnswers = value ? [value] : []; this.setData({ [`selectedAnswers.${numericQuestionId}`]: newAnswers, }); this.triggerEvent("change", { queId: numericQuestionId, ans: newAnswers, }); }, // 处理多选变化 handleCheckboxChange( this: QuizComponent, e: WechatMiniprogram.CheckboxGroupChange ) { const { questionId } = e.currentTarget.dataset; const values = Array.isArray(e.detail.value) ? e.detail.value : []; if (!questionId) return; const numericQuestionId = Number(questionId); this.setData({ [`selectedAnswers.${numericQuestionId}`]: values, }); this.triggerEvent("change", { queId: numericQuestionId, ans: values, }); }, getFormattedAnswers(this: QuizComponent) { const answers = []; for (const [questionId, selectedOptions] of Object.entries( this.data.selectedAnswers )) { if (selectedOptions && selectedOptions.length > 0) { answers.push({ queId: Number(questionId), ans: selectedOptions, }); } } return answers; }, getAllAnswers(this: QuizComponent) { return this.getFormattedAnswers(); }, isAllAnswered(this: QuizComponent) { const totalQuestions = this.properties.questions.length; const answeredQuestions = Object.values(this.data.selectedAnswers).filter( (answers) => answers && answers.length > 0 ).length; return totalQuestions === answeredQuestions; }, getProgress(this: QuizComponent) { const totalQuestions = this.data.renderQuestions.length; const answeredQuestions = Object.values(this.data.selectedAnswers).filter( (answers) => answers && answers.length > 0 ).length; return { answered: answeredQuestions, total: totalQuestions, percentage: totalQuestions > 0 ? Math.round((answeredQuestions / totalQuestions) * 100) : 0, }; }, }, });