Files
ruo-shan-cloud-pharmacy/miniprogram/components/my-quiz/my-quiz.ts
T
陈誉午 994b267f5c feat: 电子药箱小程序 - 4Tab药品管理
- 电子药箱: 药品库存管理 + 手动录入 + 今日用药打卡
- 药品百科: 搜索 + 分类筛选 + 20种药品静态数据
- 惠教中心: 4条药品使用指南课程
- 我的: 家庭成员信息管理
- 自定义TabBar + navigation-bar组件
- SVG药品分类插图
2026-07-29 11:20:52 +08:00

217 lines
6.1 KiB
TypeScript

// 定义接口类型
interface Question {
id: number;
type: number;
question: string;
option: Record<string, any>;
}
interface AnswerItem {
queId: string;
ans: string[];
suc?: boolean;
}
interface QuizComponent {
properties: {
questions: Question[];
answerList: AnswerItem[];
};
data: {
selectedAnswers: Record<number, string[]>;
renderQuestions: Array<
Question & { options: Array<{ key: string; value: string }> }
>;
};
setData: (data: Partial<Record<string, any>>, 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<number, string[]>);
this.setData({
renderQuestions,
selectedAnswers,
});
},
},
data: {
selectedAnswers: {} as Record<number, string[]>,
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,
};
},
},
});