import { ActionSheet, Button, Image, Popup, Swipe, SwipeItem } from 'vant'; import { computed, defineComponent, nextTick, onMounted, onUnmounted, reactive, ref } from 'vue'; import { useRoute, useRouter } from 'vue-router'; import styles from './index.module.less'; import iconButtonList from '../images/icon-button-list.png'; import MSticky from '@/components/m-sticky'; import ChoiceQuestion from '../model/choice-question'; import AnswerList from '../model/answer-list'; import DragQuestion from '../model/drag-question'; import KeepLookQuestion from '../model/keep-look-question'; import PlayQuestion from '../model/play-question'; import ErrorMode from '../model/error-mode'; import ResultFinish from '../model/result-finish'; import { eventUnit, QuestionType } from '../unit'; import request from '@/helpers/request'; import { useRect } from '@vant/use'; import MHeader from '@/components/m-header'; import { useEventListener, useInterval, useWindowScroll } from '@vueuse/core'; export default defineComponent({ name: 'unit-detail', setup() { const route = useRoute(); const router = useRouter(); const swipeRef = ref(); const state = reactive({ type: route.query.type, // 类型 knowledgePointIds: route.query.knowledgePointIds, // 智能组卷 多个编号 lessonCoursewareId: route.query.lessonCoursewareId, // 教材编号 background: 'transparent', color: '#fff', visiableError: false, visiableAnswer: false, id: route.query.id, currentIndex: 0, questionList: [], visiableInfo: { show: false, operationType: 'RESULT' as 'RESULT' | 'BACK' | 'CONTINUE', type: 'DEFAULT' as 'DEFAULT' | 'FAIL' | 'PASS' | 'GOOD' | 'COUNTDOWN', content: '', showCancelButton: false, confirmButtonText: '', cancelButtonText: '', title: '' }, nextStatus: false, swipeHeight: 'auto' as any, answerAnalysis: '', questionTypeCode: '', overResult: { time: '00:00', // 时长 questionLength: 0, // 答题数 errorLength: 0, // 错题数 rate: 0 // 正确率 } }); // 计时 const { counter, resume, pause } = useInterval(1000, { controls: true }); const getExamDetails = async () => { try { const { data } = await request.post( '/edu-app/studentUnitExamination/queryPracticeModeExam', { data: { lessonCoursewareId: state.lessonCoursewareId } } ); const temp = data || {}; temp.examinationQuestionAdds.forEach((item: any) => { item.showAnalysis = false; // 默认不显示解析 item.analysis = { message: item.answerAnalysis, topic: true, // 是否显示结果 isAnswer: false, // 是否答题 userResult: false // 用户答题对错 }; item.userAnswer = []; // 用户答题 }); state.questionList = temp.examinationQuestionAdds || []; } catch { // } }; /** * @description 下一题 | 测试完成 */ const onNextQuestion = async () => { try { const questionList: any = state.questionList || []; let currentStatus = true; if (!questionList[state.currentIndex]?.analysis.isAnswer) { let result: any = {}; questionList.forEach((question: any, index: number) => { // 格式化所有题目的答案 if (index === state.currentIndex) { result = { questionId: question.id, details: question.userAnswer || [] }; } }); const { data } = await request.post( '/edu-app/studentUnitExamination/submitTrainingAnswer', { hideLoading: true, data: result } ); currentStatus = data; // 初始化是否显示解析 questionList.forEach((question: any, index: number) => { // 格式化所有题目的答案 if (index === state.currentIndex) { state.answerAnalysis = question.answerAnalysis; state.questionTypeCode = question.questionTypeCode; question.showAnalysis = true; question.analysis.userResult = data; question.analysis.isAnswer = true; // 是否答题 } }); } // 判断是否是最后一题 if (state.questionList.length === state.currentIndex + 1) { eventUnit.emit('unitAudioStop'); state.visiableInfo.show = true; state.visiableInfo.title = '练习完成'; state.visiableInfo.showCancelButton = true; state.visiableInfo.operationType = 'CONTINUE'; state.visiableInfo.cancelButtonText = '再等等'; state.visiableInfo.confirmButtonText = '确认完成'; state.visiableInfo.content = `确认本次练习的题目都完成了吗?`; return; } if (currentStatus) { swipeRef.value?.next(); } else { state.visiableError = true; } } catch { // } }; // const getAnswerResult = computed(() => { const questionList = state.questionList || []; let count = 0; let passCount = 0; let noPassCount = 0; questionList.forEach((item: any) => { if (item.showAnalysis) { count += 1; if (item.analysis.userResult) { passCount += 1; } else { noPassCount += 1; } } }); return { count, passCount, noPassCount }; }); /** * @description 重置当前的题目高度 * @param {any} scroll 是否滚动到顶部 */ let size = 0; const resizeSwipeItemHeight = (scroll = true) => { nextTick(() => { scroll && window.scrollTo(0, 0); setTimeout(() => { const currentItemDom: any = document .querySelectorAll('.van-swipe-item') [state.currentIndex]?.querySelector('.swipe-item-question'); const allImg = currentItemDom?.querySelectorAll( '.answerTitleImg img' ); let status = true; // console.log(allImg) allImg?.forEach((img: any) => { console.log(img.complete); if (!img.complete) { status = false; } }); // 判断图片是否加载完了 if (!status && size < 3) { setTimeout(() => { size += 1; resizeSwipeItemHeight(scroll); }, 300); } if (status) { size = 0; } const rect = useRect(currentItemDom); state.swipeHeight = rect.height; }, 100); }); }; const onConfirmExam = () => { // }; const onConfirmResult = () => { if (state.visiableInfo.operationType === 'RESULT') { state.visiableInfo.show = false; router.back(); onAfter(); } else if (state.visiableInfo.operationType === 'BACK') { state.visiableInfo.show = false; onAfter(); } else if (state.visiableInfo.operationType === 'CONTINUE') { onResultPopup(); } }; const onCloseResult = async () => { if (state.visiableInfo.operationType === 'RESULT') { } else if (state.visiableInfo.operationType === 'BACK') { state.visiableInfo.show = false; window.history.pushState(null, '', document.URL); window.addEventListener('popstate', onBack, false); } else if (state.visiableInfo.operationType === 'CONTINUE') { state.visiableInfo.show = false; } }; /** 结果页面弹窗 */ const onResultPopup = () => { const answerResult = getAnswerResult.value; let rate = 0; if (answerResult.count > 0) { rate = Math.floor((answerResult.passCount / answerResult.count) * 100); } const times = counter.value; const minute = Math.floor(times / 60) >= 10 ? Math.floor(times / 60) : '0' + Math.floor(times / 60); const seconds = times % 60 >= 10 ? times % 60 : '0' + (times % 60); state.overResult = { time: minute + ':' + seconds, // 时长 questionLength: answerResult.count, // 答题数 errorLength: answerResult.noPassCount, // 错题数 rate // 正确率 }; // 重置计时 pause(); counter.value = 0; // 60 及格 // 85 及以上优秀 state.visiableInfo.show = true; state.visiableInfo.title = '已完成'; state.visiableInfo.showCancelButton = false; state.visiableInfo.operationType = 'RESULT'; state.visiableInfo.confirmButtonText = '确认'; state.visiableInfo.content = `