feat: 电子药箱小程序 - 4Tab药品管理
- 电子药箱: 药品库存管理 + 手动录入 + 今日用药打卡 - 药品百科: 搜索 + 分类筛选 + 20种药品静态数据 - 惠教中心: 4条药品使用指南课程 - 我的: 家庭成员信息管理 - 自定义TabBar + navigation-bar组件 - SVG药品分类插图
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
// 定义接口类型
|
||||
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,
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user