| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- import { EnumQuestionType } from "@/common/enum";
- import { getPaper } from '@/api/modules/study';
- import { Study } from "@/types";
- import { Question } from "@/types/study";
- export const useExam = () => {
- const questionTypeDesc: Record<EnumQuestionType, string> = {
- [EnumQuestionType.SINGLE_CHOICE]: '单选题',
- [EnumQuestionType.MULTIPLE_CHOICE]: '多选题',
- [EnumQuestionType.JUDGMENT]: '判断题',
- [EnumQuestionType.FILL_IN_THE_BLANK]: '填空题',
- [EnumQuestionType.SUBJECTIVE]: '主观题',
- [EnumQuestionType.SHORT_ANSWER]: '简答题',
- [EnumQuestionType.ESSAY]: '问答题',
- [EnumQuestionType.ANALYSIS]: '分析题',
- [EnumQuestionType.OTHER]: '阅读题'
- }
- // 题型顺序
- const questionTypeOrder = [
- EnumQuestionType.SINGLE_CHOICE,
- EnumQuestionType.MULTIPLE_CHOICE,
- EnumQuestionType.JUDGMENT,
- EnumQuestionType.FILL_IN_THE_BLANK,
- EnumQuestionType.SUBJECTIVE,
- EnumQuestionType.SHORT_ANSWER,
- EnumQuestionType.ESSAY,
- EnumQuestionType.ANALYSIS,
- EnumQuestionType.OTHER
- ];
- let interval: NodeJS.Timeout | null = null;
- const countDownCallback = ref<() => void>(() => { });
- // 练习时长
- const practiceDuration = ref<number>(0);
- const formatPracticeDuration = computed(() => {
- const hours = Math.floor(practiceDuration.value / 3600);
- const minutes = Math.floor((practiceDuration.value % 3600) / 60);
- const seconds = practiceDuration.value % 60;
- return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
- });
- // 考试时长
- const examDuration = ref<number>(0);
- const formatExamDuration = computed(() => {
- const hours = Math.floor(examDuration.value / 3600);
- const minutes = Math.floor((examDuration.value % 3600) / 60);
- const seconds = examDuration.value % 60;
- return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
- });
- const swiperDuration = ref<number>(300);
- const questionList = ref<Study.Question[]>([]);
- // 收藏列表
- const favoriteList = ref<Study.Question[]>([]);
- // 不会列表
- const notKnowList = ref<Study.Question[]>([]);
- // 重点标记列表
- const markList = ref<Study.Question[]>([]);
- // 包含状态的问题列表
- const stateQuestionList = computed(() => {
- return questionList.value.map(item => {
- return {
- ...item,
- isDone: isDone(item)
- }
- });
- });
- const groupedQuestionList = computed(() => {
- // 状态:已做、未做、是否不会、是否标记,整体按照题型分组
- const state = questionTypeOrder.map(type => {
- return {
- type,
- list: [] as {
- question: Study.Question;
- index: number
- }[]
- }
- });
- for (let i = 0; i <= questionList.value.length - 1; i++) {
- const qs = questionList.value[i];
- state.forEach(item => {
- if (qs.typeId === item.type) {
- qs.isDone = isDone(qs);
- item.list.push({
- question: qs,
- index: i
- });
- }
- });
- }
- return state;
- });
- const isAllDone = computed(() => {
- return questionList.value.every(q => isDone(q));
- });
- // 当前下标
- const currentIndex = ref<number>(0);
- const totalCount = computed(() => {
- return questionList.value.length;
- });
- const doneCount = computed(() => {
- // 有答案的或者不会做的,都认为是做了
- // return groupedQuestionList.value.reduce((acc, item) => acc + item.list.filter(q => q.question.isDone || q.question.isNotKnow).length, 0);
- return stateQuestionList.value.filter(q => q.isDone || q.isNotKnow).length;
- });
- const notDoneCount = computed(() => {
- // return questionList.value.length - doneCount.value;
- return stateQuestionList.value.length - doneCount.value;
- });
- const notKnowCount = computed(() => {
- // return groupedQuestionList.value.reduce((acc, item) => acc + item.list.filter(q => q.question.isNotKnow).length, 0);
- return stateQuestionList.value.filter(q => q.isNotKnow).length;
- });
- const markCount = computed(() => {
- // return groupedQuestionList.value.reduce((acc, item) => acc + item.list.filter(q => q.question.isMark).length, 0);
- return stateQuestionList.value.filter(q => q.isMark).length;
- });
- const isDone = (qs: Study.Question): boolean => {
- if (qs.subQuestions && qs.subQuestions.length > 0) {
- return qs.subQuestions.every(q => isDone(q));
- }
- return qs.answers && qs.answers.length > 0 || !!qs.isNotKnow;
- }
- const nextQuestion = () => {
- if (currentIndex.value >= questionList.value.length - 1) {
- return;
- }
- currentIndex.value++;
- }
- const prevQuestion = () => {
- if (currentIndex.value <= 0) {
- return;
- }
- currentIndex.value--;
- }
- const nextQuestionQuickly = () => {
- if (currentIndex.value >= questionList.value.length - 1) {
- return;
- }
- swiperDuration.value = 0;
- setTimeout(() => {
- nextQuestion();
- setTimeout(() => {
- swiperDuration.value = 300;
- }, 0);
- }, 0);
- }
- const prevQuestionQuickly = () => {
- if (currentIndex.value <= 0) {
- return;
- }
- swiperDuration.value = 0;
- setTimeout(() => {
- prevQuestion();
- setTimeout(() => {
- swiperDuration.value = 300;
- }, 0);
- }, 0);
- }
- const changeIndex = (index: number) => {
- swiperDuration.value = 0;
- setTimeout(() => {
- currentIndex.value = index;
- setTimeout(() => {
- swiperDuration.value = 300;
- }, 0);
- }, 0);
- }
- // 开始计时
- const startPracticeDuration = () => {
- interval = setInterval(() => {
- practiceDuration.value += 1;
- }, 1000);
- }
- // 停止计时
- const stopPracticeDuration = () => {
- interval && clearInterval(interval);
- interval = null;
- }
- // 开始倒计时
- const startExamDuration = () => {
- interval = setInterval(() => {
- if (examDuration.value <= 0) {
- console.log('停止倒计时')
- stopExamDuration();
- return;
- }
- examDuration.value -= 1;
- }, 1000);
- }
- // 停止倒计时
- const stopExamDuration = () => {
- interval && clearInterval(interval);
- interval = null;
- countDownCallback.value && countDownCallback.value();
- }
- const setExamDuration = (duration: number) => {
- examDuration.value = duration;
- }
- const setPracticeDuration = (duration: number) => {
- practiceDuration.value = duration;
- }
- const setCountDownCallback = (callback: () => void) => {
- countDownCallback.value = callback;
- }
- const setQuestionList = (list: Study.ApiQuestion[]) => {
- const orders = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
- // 数据预处理
- // 1、给每个项目补充额外字段
- const parseQuestion = (item: Study.ApiQuestion): Study.Question => {
- return {
- title: item.title,
- // 处理没有题型的大题,统一作为阅读题
- typeId: (item.typeId === null || item.typeId === undefined) ? EnumQuestionType.OTHER : item.typeId,
- id: item.id,
- answers: item.answers || [],
- subQuestions: item.subQuestions?.map(parseQuestion) || [],
- options: item.options?.map((option, index) => {
- return {
- name: option,
- no: orders[index],
- id: index,
- isAnswer: false
- } as Study.QuestionOption
- }) || [],
- isDone: false,
- isMark: item.isMark,
- isNotKnow: item.isNotKnow,
- isFavorite: item.isFavorite
- } as Study.Question
- }
- const arr: Study.Question[] = list.map(item => {
- return parseQuestion(item);
- });
- questionList.value = arr;
- }
- const reset = () => {
- questionList.value = questionList.value.map(item => {
- return {
- ...item,
- answers: [],
- isMark: false,
- isNotKnow: false
- } as Study.Question;
- });
- changeIndex(0);
- practiceDuration.value = 0;
- examDuration.value = 0;
- interval && clearInterval(interval);
- interval = null;
- }
- return {
- questionList,
- groupedQuestionList,
- stateQuestionList,
- favoriteList,
- notKnowList,
- markList,
- currentIndex,
- isAllDone,
- totalCount,
- doneCount,
- notDoneCount,
- notKnowCount,
- markCount,
- questionTypeDesc,
- nextQuestion,
- prevQuestion,
- nextQuestionQuickly,
- prevQuestionQuickly,
- swiperDuration,
- practiceDuration,
- examDuration,
- formatExamDuration,
- formatPracticeDuration,
- startPracticeDuration,
- stopPracticeDuration,
- startExamDuration,
- stopExamDuration,
- setExamDuration,
- setPracticeDuration,
- setCountDownCallback,
- setQuestionList,
- changeIndex,
- reset
- }
- }
|