import { ActionSheet, Button, Cell, CountDown, Grid, GridItem, Icon, Image, Popup, showDialog, Swipe, SwipeItem, Tag } from 'vant' import { computed, defineComponent, nextTick, onMounted, 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 OSticky from '@/components/o-sticky' import ChoiceQuestion from '../model/choice-question' import AnswerList from '../model/answer-list' import ODialog from '@/components/o-dialog' 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 OHeader from '@/components/o-header' import { useInterval } from '@vueuse/core' export default defineComponent({ name: 'unit-detail', setup() { const route = useRoute() const router = useRouter() const countDownRef = ref() const swipeRef = ref() const state = reactive({ examId: route.query.examId, name: route.query.name, visiableError: false, visiableAnswer: false, visiableResult: false, id: route.query.id, currentIndex: 0, questionList: [], visiableSure: false, resultInfo: {} as any, resultStatusType: 'SUCCESS', // 'SUCCESS' | 'FAIL' visiableExam: false, // 考试已结束 nextStatus: false, swipeHeight: 'auto' as any, answerAnalysis: '', overResult: { time: '00:00', // 时长 questionLength: 0, // 答题数 errorLength: 0, // 错题数 rate: 0 // 正确率 }, knowledgelist: [] as any, // 知识点列表 quitStatus: false }) // 计时 const { counter, resume, pause } = useInterval(1000, { controls: true }) const getExamDetails = async () => { try { const { data } = await request.post('/api-student/examinationQuestion/randomPage', { data: { page: 1, row: 50, categoryId: state.id } }) const temp = data || [] temp.forEach((item: any) => { item.showAnalysis = false // 默认不显示解析 item.analysis = { message: item.answerAnalysis, topic: true, // 是否显示结果 userResult: false // 用户答题对错 } item.userAnswer = [] // 用户答题 }) state.questionList = temp } catch { // } } // 获取所在知识点 const getDetails = async () => { try { const { data } = await request.post('/api-student/unitExamination/queryKnowledgePoint', { requestType: 'form', data: { unitExaminationId: state.examId } }) state.knowledgelist = data.lists || [] } catch { // } } /** * @description 下一题 | 测试完成 */ const onNextQuestion = async () => { try { const questionList = state.questionList || [] 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( '/api-student/studentUnitExamination/submitTrainingAnswer', { hideLoading: true, data: result } ) // 初始化是否显示解析 questionList.forEach((question: any, index: number) => { // 格式化所有题目的答案 if (index === state.currentIndex) { state.answerAnalysis = question.answerAnalysis question.showAnalysis = true question.analysis.userResult = data } }) // 判断是否是最后一题 if (state.questionList.length === state.currentIndex + 1) { state.visiableSure = true return } if (data) { 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') console.log('🚀 ~ setTimeout ~ currentItemDom', currentItemDom) 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 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 state.visiableResult = true } // 重新练习 const onCloseResult = async () => { state.questionList = [] await getExamDetails() setTimeout(async () => { swipeRef.value?.swipeTo(0, { immediate: true }) state.swipeHeight = 'auto' state.answerAnalysis = '' state.overResult = { time: '00:00', // 时长 questionLength: 0, // 答题数 errorLength: 0, // 错题数 rate: 0 // 正确率 } state.visiableResult = false // 恢复计时 resume() resizeSwipeItemHeight() }, 100) } // 下一个考点 const onConfirmResult = () => { const knowledgelist = state.knowledgelist || [] console.log('🚀 ~ file: index.tsx:246 ~ onConfirmResult ~ knowledgelist', knowledgelist) // 当前正在考试的节点 const knownleIndex = knowledgelist.findIndex((item: any) => item.id === state.id) console.log('🚀 ~ file: index.tsx:249 ~ onConfirmResult ~ knownleIndex', knownleIndex) let currentKnowle: any = {} if (knownleIndex + 1 >= knowledgelist.length || knownleIndex < 0) { currentKnowle = knowledgelist[0] } else { currentKnowle = knowledgelist[knownleIndex + 1] } state.id = currentKnowle.id state.visiableResult = false state.currentIndex = 0 // 重置 onCloseResult() } // 拦截 const onBack = () => { // showDialog({ // title: '提示', // message: '您是否退出?', // theme: 'round-button', // confirmButtonColor: '#ff8057' // }).then(() => { // onAfter() // }) state.quitStatus = true } const onAfter = () => { window.removeEventListener('popstate', onBack, false) router.back() } onMounted(async () => { await getExamDetails() await getDetails() resizeSwipeItemHeight() // window.history.pushState(null, '', document.URL) // window.addEventListener('popstate', onBack, false) }) return () => (
{state.overResult.time}
练习时长
{state.overResult.questionLength | 0}
答题数
{state.overResult.errorLength | 0}
错题数