import { ActionSheet, Button, Image, Popup, Swipe, SwipeItem } from 'vant'; import { 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 ResultFinish from '../model/result-finish'; import { eventUnit, QuestionType } from '../unit'; import request from '@/helpers/request'; import { CurrentTime, useCountDown, useRect } from '@vant/use'; import MHeader from '@/components/m-header'; import { useEventListener, 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, // 教材编号 studentUnitExaminationId: '', // 测验编号 background: 'transparent', color: '#fff', visiableAnswer: false, examDetail: {} as any, currentIndex: 0, time: 0, questionList: [], visiableInfo: { show: false, operationType: 'RESULT' as 'RESULT' | 'BACK' | 'CONTINUE' | 'TIME', type: 'DEFAULT' as 'DEFAULT' | 'FAIL' | 'PASS' | 'GOOD' | 'COUNTDOWN', content: '', showCancelButton: false, confirmButtonText: '', cancelButtonText: '', title: '' }, nextStatus: false, swipeHeight: 'auto' as any, countDownOver: false // 是否已显示时间倒计时 }); // 计时 const countDownRef = useCountDown({ // 倒计时 60 秒 time: state.time, onChange(current: CurrentTime) { const diffTime = 5 * 60 * 1000; if (diffTime >= current.total && !state.countDownOver) { state.visiableInfo.show = true; state.visiableInfo.title = '倒计时5分钟'; state.visiableInfo.showCancelButton = false; state.visiableInfo.operationType = 'TIME'; state.visiableInfo.type = 'COUNTDOWN'; state.visiableInfo.confirmButtonText = '确认'; state.visiableInfo.content = `距离交卷时间还剩五分钟哦,请尽快答题~`; state.countDownOver = true; } }, onFinish: async () => { eventUnit.emit('unitAudioStop'); await onResultPopup(); } }); const getExamDetails = async () => { try { let temp: any = {}; if (state.type === 'ai') { const { data } = await request.post( '/edu-app/studentUnitExamination/pointRandomSave', { data: { knowledgePointIds: state.knowledgePointIds } } ); temp = data || {}; } else { const { data } = await request.post( '/edu-app/studentUnitExamination/mockExamination', { data: { lessonCoursewareId: state.lessonCoursewareId } } ); temp = data || {}; } temp.examinationQuestionAdds.forEach((item: any) => { item.showAnalysis = false; // 默认不显示解析 item.analysis = { message: item.answerAnalysis, topic: true, // 是否显示结果 userResult: false // 用户答题对错 }; item.userAnswer = []; // 用户答题 }); state.questionList = temp.examinationQuestionAdds || []; state.studentUnitExaminationId = temp.unitExaminationId; state.examDetail = temp || {}; calcTime(); } catch { // } }; /** * @description 计算考试时间剩余时间 */ const calcTime = async () => { const examDetail = state.examDetail || {}; const timeMinutes = examDetail.timeMinutes || 0; // 测验时间 state.time = Math.ceil(timeMinutes * 60 * 1000); setTimeout(() => { countDownRef.reset(timeMinutes * 60 * 1000); countDownRef.start(); }, 10); }; /** * @description 下一题 | 测试完成 */ const onNextQuestion = async () => { try { const questionList = state.questionList || []; const userAnswerList: any = []; // 所有题目的答案 questionList.forEach((question: any, index: number) => { // 格式化所有题目的答案 if (question.userAnswer && question.userAnswer.length > 0) { userAnswerList.push({ questionId: question.id, details: question.userAnswer }); } }); // 判断是否是最后一题 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.type = 'DEFAULT'; state.visiableInfo.cancelButtonText = '再等等'; state.visiableInfo.confirmButtonText = '确认完成'; state.visiableInfo.content = `确认本次测验的题目都完成了吗?`; return; } state.nextStatus = true; await request.post('/edu-app/studentUnitExamination/submitAnswer', { hideLoading: true, data: { answers: userAnswerList, studentUnitExaminationId: state.studentUnitExaminationId } }); swipeRef.value?.next(); state.nextStatus = false; } catch { // } }; /** * @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 onConfirmResult = () => { if (state.visiableInfo.operationType === 'RESULT') { state.visiableInfo.show = false; router.back(); onAfter(); } else if (state.visiableInfo.operationType === 'BACK') { onResultPopup(); } else if (state.visiableInfo.operationType === 'CONTINUE') { onResultPopup(); } else if (state.visiableInfo.operationType === 'TIME') { state.visiableInfo.show = false; } }; const onCloseResult = async (status: boolean) => { if (state.visiableInfo.operationType === 'BACK') { if (status) { state.visiableInfo.show = false; window.history.pushState(null, '', document.URL); window.addEventListener('popstate', onBack, false); return; } try { await request.get('/edu-app/studentUnitExamination/dropExamination', { params: { studentUnitExaminationId: state.studentUnitExaminationId } }); state.visiableInfo.show = false; onAfter(); } catch { // } } else if (state.visiableInfo.operationType === 'CONTINUE') { state.visiableInfo.show = false; } }; /** 结果页面弹窗 */ const onResultPopup = async () => { try { const questionList = state.questionList || []; const userAnswerList: any = []; // 所有题目的答案 questionList.forEach((question: any) => { // 格式化所有题目的答案 if (question.userAnswer && question.userAnswer.length > 0) { userAnswerList.push({ questionId: question.id, details: question.userAnswer }); } }); const { data } = await request.post( '/edu-app/studentUnitExamination/completionExamination', { hideLoading: false, data: { answers: userAnswerList, studentUnitExaminationId: state.studentUnitExaminationId } } ); // 60 及格 // 85 及以上优秀 state.visiableInfo.show = true; state.visiableInfo.title = data.score + '分'; state.visiableInfo.showCancelButton = false; state.visiableInfo.operationType = 'RESULT'; state.visiableInfo.confirmButtonText = '确认'; if (data.status === 'A_EXCELLENT') { state.visiableInfo.type = 'GOOD'; state.visiableInfo.content = '