index.tsx 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. import {
  2. ActionSheet,
  3. Button,
  4. Image,
  5. Popup,
  6. Swipe,
  7. SwipeItem,
  8. showToast
  9. } from 'vant';
  10. import {
  11. computed,
  12. defineComponent,
  13. nextTick,
  14. onMounted,
  15. onUnmounted,
  16. reactive,
  17. watch,
  18. ref
  19. } from 'vue';
  20. import { useRoute, useRouter } from 'vue-router';
  21. import styles from './index.module.less';
  22. import iconButtonList from '../images/icon-button-list.png';
  23. import MSticky from '@/components/m-sticky';
  24. import ChoiceQuestion from '../model/choice-question';
  25. import AnswerList from '../model/answer-list';
  26. import DragQuestion from '../model/drag-question';
  27. import KeepLookQuestion from '../model/keep-look-question';
  28. import PlayQuestion from '../model/play-question';
  29. import ErrorMode from '../model/error-mode';
  30. import ResultFinish from '../model/result-finish';
  31. import { eventUnit, QuestionType } from '../unit';
  32. import request from '@/helpers/request';
  33. import { useRect } from '@vant/use';
  34. import MHeader from '@/components/m-header';
  35. import { useEventListener, useInterval, useWindowScroll } from '@vueuse/core';
  36. import { browser } from '@/helpers/utils';
  37. export default defineComponent({
  38. name: 'unit-detail',
  39. setup() {
  40. const route = useRoute();
  41. const router = useRouter();
  42. const swipeRef = ref();
  43. const state = reactive({
  44. background: 'transparent',
  45. // color: '#323333',
  46. visiableError: false,
  47. visiableAnswer: false,
  48. id: route.query.id,
  49. currentIndex: 0,
  50. questionList: [] as any,
  51. page: 1,
  52. rows: 50,
  53. total: 0,
  54. isFinish: false, // 是否完成加载
  55. visiableInfo: {
  56. show: false,
  57. operationType: 'RESULT' as 'RESULT' | 'BACK' | 'CONTINUE' | 'GRASP',
  58. type: 'DEFAULT' as 'DEFAULT' | 'FAIL' | 'PASS' | 'GOOD' | 'COUNTDOWN',
  59. content: '',
  60. showCancelButton: false,
  61. confirmButtonText: '',
  62. cancelButtonText: '',
  63. title: '',
  64. graspItem: {} as any
  65. },
  66. nextStatus: false,
  67. swipeHeight: 'auto' as any,
  68. answerAnalysis: '',
  69. questionTypeCode: '',
  70. overResult: {
  71. time: '00:00', // 时长
  72. questionLength: 0, // 答题数
  73. errorLength: 0, // 错题数
  74. rate: 0 // 正确率
  75. }
  76. });
  77. // 计时
  78. const { counter, resume, pause } = useInterval(1000, { controls: true });
  79. const getExamDetails = async (
  80. maxStudentExaminationErrorEditionId?: string
  81. ) => {
  82. try {
  83. const { data } = await request.post(
  84. '/edu-app/studentUnitExamination/errorEdition',
  85. {
  86. data: {
  87. page: state.page,
  88. rows: state.rows,
  89. maxStudentExaminationErrorEditionId
  90. }
  91. }
  92. );
  93. const temp = data || {};
  94. state.total = temp.total || 0;
  95. state.isFinish = temp.current < temp.pages ? false : true;
  96. temp.records.forEach((item: any) => {
  97. item.showAnalysis = false; // 默认不显示解析
  98. item.grasp = false; // 是否掌握题目
  99. item.analysis = {
  100. message: item.answerAnalysis,
  101. topic: true, // 是否显示结果
  102. userResult: false // 用户答题对错
  103. };
  104. item.userAnswer = []; // 用户答题
  105. });
  106. state.questionList.push(...(temp.records || []));
  107. } catch {
  108. //
  109. }
  110. };
  111. // 监听索引
  112. watch(
  113. () => state.currentIndex,
  114. () => {
  115. // 判断是否在倒数第三题,并且没有加载完
  116. if (
  117. state.currentIndex + 3 >= state.questionList.length &&
  118. !state.isFinish
  119. ) {
  120. const lastQuestion =
  121. state.questionList[state.questionList.length - 1];
  122. state.page = state.page + 1;
  123. getExamDetails(lastQuestion.id);
  124. }
  125. }
  126. );
  127. /** 已掌握此题 */
  128. const onGraspQuestion = async (item: any) => {
  129. // 判断是否掌握此题
  130. if (item.grasp) return;
  131. state.visiableInfo.show = true;
  132. state.visiableInfo.title = '确定掌握此题?';
  133. state.visiableInfo.showCancelButton = true;
  134. state.visiableInfo.operationType = 'GRASP';
  135. state.visiableInfo.cancelButtonText = '取消';
  136. state.visiableInfo.confirmButtonText = '确定';
  137. state.visiableInfo.content = `你确定已掌握该题知识要点,此题将移除你的错题集。`;
  138. state.visiableInfo.graspItem = item;
  139. console.log(state.total, 'toa');
  140. if (state.total <= 1) {
  141. onAfter();
  142. }
  143. };
  144. /** 已掌握此题确认 */
  145. const onGraspQuestionConfirm = async () => {
  146. try {
  147. state.visiableInfo.show = false;
  148. await request.get('/edu-app/studentExaminationErrorEdition/del', {
  149. hideLoading: false,
  150. params: {
  151. questionId: state.visiableInfo.graspItem.id
  152. }
  153. });
  154. state.visiableInfo.graspItem.grasp = true;
  155. eventUnit.emit('unitAudioStop');
  156. // 只有一道题
  157. if (state.total <= 1) {
  158. router.back();
  159. router.back();
  160. return;
  161. }
  162. // 后面还有题
  163. if (state.total > state.currentIndex + 1) {
  164. const index = state.questionList.findIndex(
  165. (item: any) =>
  166. item.studentExaminationErrorEditionId ===
  167. state.visiableInfo.graspItem.studentExaminationErrorEditionId
  168. );
  169. state.questionList.splice(index, 1);
  170. state.total -= 1;
  171. resizeSwipeItemHeight();
  172. // swipeRef.value?.next();
  173. return;
  174. }
  175. // 后面没有题
  176. if (state.total == state.currentIndex + 1) {
  177. const index = state.questionList.findIndex(
  178. (item: any) =>
  179. item.studentExaminationErrorEditionId ===
  180. state.visiableInfo.graspItem.studentExaminationErrorEditionId
  181. );
  182. state.questionList.splice(index, 1);
  183. state.total -= 1;
  184. state.currentIndex -= 1;
  185. resizeSwipeItemHeight();
  186. // swipeRef.value?.prev();
  187. return;
  188. }
  189. } catch {
  190. //
  191. }
  192. };
  193. /**
  194. * @description 下一题 | 测试完成
  195. */
  196. const onNextQuestion = async () => {
  197. try {
  198. const questionList = state.questionList || [];
  199. const question: any = questionList[state.currentIndex];
  200. if (question?.userAnswer?.length <= 0) {
  201. showToast('题目尚未做答');
  202. state.nextStatus = false;
  203. return;
  204. }
  205. let result: any = {};
  206. questionList.forEach((question: any, index: number) => {
  207. // 格式化所有题目的答案
  208. if (index === state.currentIndex) {
  209. result = {
  210. questionId: question.id,
  211. details: question.userAnswer || []
  212. };
  213. }
  214. });
  215. const { data } = await request.post(
  216. '/edu-app/studentUnitExamination/submitTrainingAnswer',
  217. {
  218. hideLoading: true,
  219. data: result
  220. }
  221. );
  222. // 初始化是否显示解析
  223. questionList.forEach((question: any, index: number) => {
  224. // 格式化所有题目的答案
  225. if (index === state.currentIndex) {
  226. state.answerAnalysis = question.answerAnalysis;
  227. state.questionTypeCode = question.questionTypeCode;
  228. question.showAnalysis = true;
  229. question.analysis.userResult = data;
  230. }
  231. });
  232. // 判断是否是最后一题
  233. if (state.questionList.length === state.currentIndex + 1) {
  234. eventUnit.emit('unitAudioStop');
  235. state.visiableInfo.show = true;
  236. state.visiableInfo.title = '练习完成';
  237. state.visiableInfo.showCancelButton = true;
  238. state.visiableInfo.operationType = 'CONTINUE';
  239. state.visiableInfo.cancelButtonText = '再等等';
  240. state.visiableInfo.confirmButtonText = '确认完成';
  241. state.visiableInfo.content = `确认本次练习的题目都完成了吗?`;
  242. onAfter();
  243. return;
  244. }
  245. if (data) {
  246. swipeRef.value?.next();
  247. } else {
  248. state.visiableError = true;
  249. }
  250. } catch {
  251. //
  252. }
  253. };
  254. //
  255. const getAnswerResult = computed(() => {
  256. const questionList = state.questionList || [];
  257. let count = 0;
  258. let passCount = 0;
  259. let noPassCount = 0;
  260. questionList.forEach((item: any) => {
  261. if (item.showAnalysis) {
  262. count += 1;
  263. if (item.analysis.userResult) {
  264. passCount += 1;
  265. } else {
  266. noPassCount += 1;
  267. }
  268. }
  269. });
  270. return {
  271. count,
  272. passCount,
  273. noPassCount
  274. };
  275. });
  276. /**
  277. * @description 重置当前的题目高度
  278. * @param {any} scroll 是否滚动到顶部
  279. */
  280. let size = 0;
  281. const resizeSwipeItemHeight = (scroll = true) => {
  282. nextTick(() => {
  283. scroll && window.scrollTo(0, 0);
  284. setTimeout(() => {
  285. const currentItemDom: any = document
  286. .querySelectorAll('.van-swipe-item')
  287. [state.currentIndex]?.querySelector('.swipe-item-question');
  288. const allImg = currentItemDom?.querySelectorAll(
  289. '.answerTitleImg img'
  290. );
  291. let status = true;
  292. // console.log(allImg)
  293. allImg?.forEach((img: any) => {
  294. if (!img.complete) {
  295. status = false;
  296. }
  297. });
  298. // 判断图片是否加载完了
  299. if (!status && size < 3) {
  300. setTimeout(() => {
  301. size += 1;
  302. resizeSwipeItemHeight(scroll);
  303. }, 300);
  304. }
  305. if (status) {
  306. size = 0;
  307. }
  308. const rect = useRect(currentItemDom);
  309. state.swipeHeight = rect.height;
  310. }, 100);
  311. });
  312. };
  313. const onConfirmResult = () => {
  314. if (state.visiableInfo.operationType === 'RESULT') {
  315. state.visiableInfo.show = false;
  316. router.back();
  317. router.back();
  318. } else if (state.visiableInfo.operationType === 'BACK') {
  319. state.visiableInfo.show = false;
  320. window.history.pushState(null, '', document.URL);
  321. window.addEventListener('popstate', onBack, false);
  322. } else if (state.visiableInfo.operationType === 'CONTINUE') {
  323. onResultPopup();
  324. } else if (state.visiableInfo.operationType === 'GRASP') {
  325. onGraspQuestionConfirm();
  326. }
  327. };
  328. const onCloseResult = async () => {
  329. const operationType = state.visiableInfo.operationType;
  330. if (operationType === 'RESULT') {
  331. } else if (operationType === 'BACK') {
  332. state.visiableInfo.show = false;
  333. onAfter();
  334. } else if (operationType === 'CONTINUE') {
  335. state.visiableInfo.show = false;
  336. } else if (operationType === 'GRASP') {
  337. state.visiableInfo.show = false;
  338. window.history.pushState(null, '', document.URL);
  339. window.addEventListener('popstate', onBack, false);
  340. }
  341. };
  342. /** 结果页面弹窗 */
  343. const onResultPopup = () => {
  344. const answerResult = getAnswerResult.value;
  345. let rate = 0;
  346. if (answerResult.count > 0) {
  347. rate = Math.floor((answerResult.passCount / answerResult.count) * 100);
  348. }
  349. const times = counter.value;
  350. const minute =
  351. Math.floor(times / 60) >= 10
  352. ? Math.floor(times / 60)
  353. : '0' + Math.floor(times / 60);
  354. const seconds = times % 60 >= 10 ? times % 60 : '0' + (times % 60);
  355. state.overResult = {
  356. time: minute + ':' + seconds, // 时长
  357. questionLength: answerResult.count, // 答题数
  358. errorLength: answerResult.noPassCount, // 错题数
  359. rate // 正确率
  360. };
  361. // 重置计时
  362. pause();
  363. counter.value = 0;
  364. // 60 及格
  365. // 85 及以上优秀
  366. state.visiableInfo.show = true;
  367. state.visiableInfo.title = '已完成';
  368. state.visiableInfo.showCancelButton = false;
  369. state.visiableInfo.operationType = 'RESULT';
  370. state.visiableInfo.confirmButtonText = '确认';
  371. state.visiableInfo.content = `<div>您已完成本次测试,答对<span class='${
  372. styles.right
  373. }'>${answerResult.passCount}</span>,答错<span class='${styles.error}'>${
  374. answerResult.count - answerResult.passCount
  375. }</span>,正确率<span class='${styles.primary}'>${rate}%</span>~</div>`;
  376. };
  377. // 拦截
  378. const onBack = () => {
  379. const answerResult = getAnswerResult.value;
  380. state.visiableInfo.show = true;
  381. state.visiableInfo.title = '确认退出吗?';
  382. state.visiableInfo.showCancelButton = true;
  383. state.visiableInfo.operationType = 'BACK';
  384. state.visiableInfo.cancelButtonText = '退出';
  385. state.visiableInfo.confirmButtonText = '继续';
  386. state.visiableInfo.content = `您已经完成${
  387. answerResult.passCount + answerResult.noPassCount
  388. }道题了,继续做题可以巩固所学知识哦~`;
  389. eventUnit.emit('unitAudioStop');
  390. };
  391. const onAfter = () => {
  392. window.removeEventListener('popstate', onBack, false);
  393. router.back();
  394. };
  395. onMounted(async () => {
  396. useEventListener(document, 'scroll', () => {
  397. const { y } = useWindowScroll();
  398. if (y.value > 52) {
  399. state.background = '#fff';
  400. } else {
  401. state.background = 'transparent';
  402. }
  403. });
  404. await getExamDetails();
  405. resizeSwipeItemHeight();
  406. window.history.pushState(null, '', document.URL);
  407. window.addEventListener('popstate', onBack, false);
  408. });
  409. onUnmounted(() => {
  410. // 关闭所有音频
  411. eventUnit.emit('unitAudioStop');
  412. });
  413. return () => (
  414. <div
  415. class={[
  416. styles.unitDetail,
  417. browser().isTablet ? styles.unitDetailTablet : ''
  418. ]}>
  419. <MSticky position="top">
  420. <MHeader border={false} background={state.background} />
  421. </MSticky>
  422. <Swipe
  423. loop={false}
  424. showIndicators={false}
  425. ref={swipeRef}
  426. duration={300}
  427. touchable={false}
  428. class={styles.unitSwipe}
  429. style={{ paddingBottom: '12px' }}
  430. lazyRender
  431. height={state.swipeHeight}
  432. onChange={(index: number) => {
  433. eventUnit.emit('unitAudioStop');
  434. state.currentIndex = index;
  435. resizeSwipeItemHeight();
  436. }}>
  437. {state.questionList.map((item: any, index: number) => (
  438. <SwipeItem>
  439. <div class="swipe-item-question">
  440. {item.questionTypeCode === QuestionType.RADIO && (
  441. <ChoiceQuestion
  442. v-model:value={item.userAnswer}
  443. index={index + 1}
  444. data={item}
  445. type="radio"
  446. showAnalysis={item.showAnalysis}
  447. analysis={item.analysis}>
  448. {{
  449. title: () => (
  450. <div class={styles.questionTitle}>
  451. <div class={styles.questionNum}>
  452. <p class={styles.pointName}>
  453. {item.knowledgePointName}
  454. </p>
  455. <span>{state.currentIndex + 1}</span>/{state.total}
  456. </div>
  457. <Button
  458. round
  459. plain
  460. size="mini"
  461. color={item.grasp ? '#FF5A56' : '#1CACF1'}
  462. class={styles.controlBtn}
  463. disabled={item.grasp}
  464. onClick={() => onGraspQuestion(item)}>
  465. {item.grasp ? '已掌握此题' : '掌握此题'}
  466. </Button>
  467. </div>
  468. )
  469. }}
  470. </ChoiceQuestion>
  471. )}
  472. {item.questionTypeCode === QuestionType.CHECKBOX && (
  473. <ChoiceQuestion
  474. v-model:value={item.userAnswer}
  475. index={index + 1}
  476. data={item}
  477. type="checkbox"
  478. showAnalysis={item.showAnalysis}
  479. analysis={item.analysis}>
  480. {{
  481. title: () => (
  482. <div class={styles.questionTitle}>
  483. <div class={styles.questionNum}>
  484. <p class={styles.pointName}>
  485. {item.knowledgePointName}
  486. </p>
  487. <span>{state.currentIndex + 1}</span>/{state.total}
  488. </div>
  489. <Button
  490. round
  491. plain
  492. size="mini"
  493. color={item.grasp ? '#FF5A56' : '#1CACF1'}
  494. class={styles.controlBtn}
  495. disabled={item.grasp}
  496. onClick={() => onGraspQuestion(item)}>
  497. {item.grasp ? '已掌握此题' : '掌握此题'}
  498. </Button>
  499. </div>
  500. )
  501. }}
  502. </ChoiceQuestion>
  503. )}
  504. {item.questionTypeCode === QuestionType.SORT && (
  505. <DragQuestion
  506. v-model:value={item.userAnswer}
  507. onUpdate:value={() => {
  508. // 如果是空则滑动到顶部
  509. const status =
  510. item.userAnswer && item.userAnswer.length > 0
  511. ? false
  512. : true;
  513. resizeSwipeItemHeight(status);
  514. }}
  515. data={item}
  516. index={index + 1}
  517. showAnalysis={item.showAnalysis}
  518. analysis={item.analysis}>
  519. {{
  520. title: () => (
  521. <div class={styles.questionTitle}>
  522. <div class={styles.questionNum}>
  523. <p class={styles.pointName}>
  524. {item.knowledgePointName}
  525. </p>
  526. <span>{state.currentIndex + 1}</span>/{state.total}
  527. </div>
  528. <Button
  529. round
  530. plain
  531. size="mini"
  532. color={item.grasp ? '#FF5A56' : '#1CACF1'}
  533. class={styles.controlBtn}
  534. disabled={item.grasp}
  535. onClick={() => onGraspQuestion(item)}>
  536. {item.grasp ? '已掌握此题' : '掌握此题'}
  537. </Button>
  538. </div>
  539. )
  540. }}
  541. </DragQuestion>
  542. )}
  543. {item.questionTypeCode === QuestionType.LINK && (
  544. <KeepLookQuestion
  545. v-model:value={item.userAnswer}
  546. data={item}
  547. index={index + 1}
  548. showAnalysis={item.showAnalysis}
  549. analysis={item.analysis}>
  550. {{
  551. title: () => (
  552. <div class={styles.questionTitle}>
  553. <div class={styles.questionNum}>
  554. <p class={styles.pointName}>
  555. {item.knowledgePointName}
  556. </p>
  557. <span>{state.currentIndex + 1}</span>/{state.total}
  558. </div>
  559. <Button
  560. round
  561. plain
  562. size="mini"
  563. color={item.grasp ? '#FF5A56' : '#1CACF1'}
  564. class={styles.controlBtn}
  565. disabled={item.grasp}
  566. onClick={() => onGraspQuestion(item)}>
  567. {item.grasp ? '已掌握此题' : '掌握此题'}
  568. </Button>
  569. </div>
  570. )
  571. }}
  572. </KeepLookQuestion>
  573. )}
  574. {item.questionTypeCode === QuestionType.PLAY && (
  575. <PlayQuestion
  576. v-model:value={item.userAnswer}
  577. data={item}
  578. index={index + 1}
  579. unitId={state.id as any}
  580. showAnalysis={item.showAnalysis}
  581. analysis={item.analysis}>
  582. {{
  583. title: () => (
  584. <div class={styles.questionTitle}>
  585. <div class={styles.questionNum}>
  586. <span>{state.currentIndex + 1}</span>/{state.total}
  587. </div>
  588. {/* <div class={styles.questionType}>
  589. <i></i>
  590. <span>{item.knowledgePointName}</span>
  591. </div> */}
  592. <Button
  593. round
  594. plain
  595. size="mini"
  596. color={item.grasp ? '#FF5A56' : '#1CACF1'}
  597. disabled={item.grasp}
  598. class={styles.controlBtn}
  599. onClick={() => onGraspQuestion(item)}>
  600. {item.grasp ? '已掌握此题' : '掌握此题'}
  601. </Button>
  602. </div>
  603. )
  604. }}
  605. </PlayQuestion>
  606. )}
  607. </div>
  608. </SwipeItem>
  609. ))}
  610. </Swipe>
  611. <MSticky position="bottom">
  612. <div class={['btnGroup btnMore', styles.btnSection]}>
  613. <Button
  614. round
  615. block
  616. class={
  617. state.currentIndex > 0 ? styles.activePrevBtn : styles.prevBtn
  618. }
  619. disabled={state.currentIndex > 0 ? false : true}
  620. onClick={() => {
  621. swipeRef.value?.prev();
  622. }}>
  623. 上一题
  624. </Button>
  625. <Button
  626. block
  627. round
  628. class={styles.nextBtn}
  629. onClick={onNextQuestion}
  630. loading={state.nextStatus}
  631. disabled={state.nextStatus}>
  632. {state.questionList.length === state.currentIndex + 1
  633. ? '提交'
  634. : '下一题'}
  635. </Button>
  636. <Image
  637. src={iconButtonList}
  638. class={[styles.wapList, 'van-haptics-feedback']}
  639. onClick={() => (state.visiableAnswer = true)}
  640. />
  641. </div>
  642. </MSticky>
  643. {/* 题目集合 */}
  644. <ActionSheet
  645. v-model:show={state.visiableAnswer}
  646. title="题目列表"
  647. safeAreaInsetBottom>
  648. <AnswerList
  649. value={state.questionList}
  650. lookType={'PRACTICE'}
  651. statusList={[
  652. {
  653. text: '答对',
  654. color: '#1CACF1'
  655. },
  656. {
  657. text: '答错',
  658. color: '#FF8486'
  659. },
  660. {
  661. text: '未答',
  662. color: '#EAEAEA'
  663. }
  664. ]}
  665. isFinish={state.isFinish}
  666. onSelect={(item: any) => {
  667. // 跳转,并且跳过动画
  668. swipeRef.value?.swipeTo(item, {
  669. immediate: true
  670. });
  671. state.visiableAnswer = false;
  672. }}
  673. onLoadMore={() => {
  674. const lastQuestion =
  675. state.questionList[state.questionList.length - 1];
  676. state.page = state.page + 1;
  677. getExamDetails(lastQuestion.id);
  678. }}
  679. />
  680. </ActionSheet>
  681. <Popup
  682. v-model:show={state.visiableError}
  683. style={{ width: '90%',maxWidth: '520px' }}
  684. round
  685. closeOnClickOverlay={false}>
  686. <ErrorMode
  687. onClose={() => (state.visiableError = false)}
  688. answerAnalysis={state.answerAnalysis}
  689. questionTypeCode={state.questionTypeCode}
  690. onConform={() => {
  691. swipeRef.value?.next();
  692. setTimeout(() => {
  693. state.answerAnalysis = '';
  694. }, 500);
  695. }}
  696. />
  697. </Popup>
  698. <Popup
  699. v-model:show={state.visiableInfo.show}
  700. closeOnClickOverlay={false}
  701. style={{
  702. background: 'transparent',
  703. width: '100%',
  704. maxWidth: '100%',
  705. transform: 'translateY(-55%)'
  706. }}>
  707. <ResultFinish
  708. title={state.visiableInfo.title}
  709. showCancelButton={state.visiableInfo.showCancelButton}
  710. cancelButtonText={state.visiableInfo.cancelButtonText}
  711. confirmButtonText={state.visiableInfo.confirmButtonText}
  712. status={state.visiableInfo.type}
  713. content={state.visiableInfo.content}
  714. contentHtml
  715. onConform={onConfirmResult}
  716. onClose={onCloseResult}
  717. />
  718. </Popup>
  719. </div>
  720. );
  721. }
  722. });