kaoshiChengjiInfo.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. <template>
  2. <view class="mobile-shiti-page mobile-score-page">
  3. <customNavbarVue :title="data.name" :show-back-btn="true" @back="handleBack"></customNavbarVue>
  4. <!-- 第一行 -->
  5. <view class="shiti-page-title kaoshi-page-title">
  6. <view v-if="activeSt" class="title-types">{{dlName}}</view>
  7. </view>
  8. <view class="shiti-content-box">
  9. <!-- 内容区域 -->
  10. <!-- 试题区域 -->
  11. <view v-if="activeSt">
  12. <template v-if="activeSt.stTypeId == 1">
  13. <!-- 单选 -->
  14. <danxuan :question="activeSt" :key="activeSt.stId"></danxuan>
  15. </template>
  16. <template v-if="activeSt.stTypeId == 2">
  17. <!-- 多选 -->
  18. <duoxuan :question="activeSt" :key="activeSt.stId"></duoxuan>
  19. </template>
  20. <template v-if="activeSt.stTypeId == 3">
  21. <!-- 判断 -->
  22. <panduan :question="activeSt" :key="activeSt.stId"></panduan>
  23. </template>
  24. <template v-if="activeSt.stTypeId == 4">
  25. <!-- 填空 -->
  26. <tiankong :question="activeSt" :key="activeSt.stId"></tiankong>
  27. </template>
  28. <template v-if="activeSt.stTypeId == 5">
  29. <!-- 简答 -->
  30. <jianda :question="activeSt" :key="activeSt.stId"></jianda>
  31. </template>
  32. <template v-if="activeSt.stTypeId == 6">
  33. <!-- 阅读 -->
  34. <yuedu :question="activeSt" :key="activeSt.stId" @yudu-change="onYueduChange"></yuedu>
  35. </template>
  36. </view>
  37. </view>
  38. <view class="shiti-bottom-box">
  39. <view class="shiti-num-box kecheng-bottom-box">
  40. <icon class="answer-score-icon"></icon>
  41. <text class="orange-big-color">{{data.userScore}}</text> / {{data.ksScore}}分
  42. </view>
  43. <view class="shiti-num-box" @click="showAnswerCard" >
  44. <icon class="shiti-num-icon"></icon>
  45. <text class="blue-big-color">{{activeSt ? activeSt.onlyNum: 0}}</text>/ {{data.StListForSearch.length}}
  46. </view>
  47. </view>
  48. <template v-if="activeSt">
  49. <button type="default" size="mini" hover-class="none" class="phone-green-btn st-btn-prev"
  50. @click="handlePrev" v-if="!isFistStId">上一题</button>
  51. <button type="default" size="mini" hover-class="none" class="phone-green-btn st-btn-next"
  52. @click="handleNext" v-if="!isLastStId">下一题</button>
  53. </template>
  54. <uni-popup ref="popupRef" background-color="#fff" :animation="false" :is-mask-click="false" :mask-click="false">
  55. <view class="answer-card-popup">
  56. <view class="icon-title-navBar-box">
  57. <view @click="handlePopupBack" class="nav-bar-icon"> </view>
  58. <text class="nav-bar-title">答题卡</text>
  59. </view>
  60. <view class="card-content-box">
  61. <view class="answer-card-content" v-for="(paragraph,paragraphIndex) in questionData"
  62. :key="paragraphIndex">
  63. <view class="paragraph-title">
  64. {{paragraph.name}}
  65. </view>
  66. <view class="paragraph-qa" v-for="(qa,qaIndex) in paragraph.qas" :key="qaIndex"
  67. :class="getQaClass(qa)" @click="answerCardItemClick(qa)">{{qa.onlyNum}}
  68. </view>
  69. </view>
  70. </view>
  71. </view>
  72. </uni-popup>
  73. <!-- 答案解析 -->
  74. <scoreAndAnswerVue ref="scoreAnswerRef"></scoreAndAnswerVue>
  75. <scoreAndAnswerAdminTiankong ref="scoreAnswerTkRef"></scoreAndAnswerAdminTiankong>
  76. <scoreAndAnswerAdminJianda ref="scoreAnswerJdRef"></scoreAndAnswerAdminJianda>
  77. </view>
  78. </template>
  79. <script setup>
  80. import {
  81. ref,
  82. reactive,
  83. computed,
  84. watch
  85. } from "vue";
  86. import {
  87. onLoad
  88. } from "@dcloudio/uni-app";
  89. import * as cjApi from "@/api/chengji.js"
  90. import danxuan from "@/components/questionsChengji/danxuan.vue";
  91. import duoxuan from "@/components/questionsChengji/duoxuan.vue";
  92. import tiankong from "@/components/questionsChengji/tiankong.vue";
  93. import panduan from "@/components/questionsChengji/panduan.vue";
  94. import jianda from "@/components/questionsChengji/jianda.vue";
  95. import yuedu from "@/components/questionsChengji/yuedu.vue";
  96. import scoreAndAnswerVue from "@/components/scoreAndAnswer/scoreAndAnswerAdmin.vue";
  97. import scoreAndAnswerAdminTiankong from "@/components/scoreAndAnswer/scoreAndAnswerAdminTiankong.vue";
  98. import scoreAndAnswerAdminJianda from "@/components/scoreAndAnswer/scoreAndAnswerJianda.vue";
  99. import customNavbarVue from "@/components/custom-navbar/custom-navbar.vue";
  100. import {
  101. useQuestionTools
  102. } from "@/components/questions/useQuestionTools.js";
  103. const {
  104. checkDanxuanReply,
  105. checkDuoxuanReply,
  106. checkPanduanReply,
  107. checkTiankongReply,
  108. getLetterByIndex,
  109. checkJiandaReply,
  110. checkYueduReply
  111. } = useQuestionTools();
  112. const stTypes = {
  113. 1: '单选题',
  114. 2: '多选题',
  115. 3: '判断题',
  116. 4: '填空题',
  117. }
  118. const popupRef = ref(null)
  119. const scoreAnswerRef = ref(null)
  120. const scoreAnswerTkRef = ref(null)
  121. const startCountDown = ref(false);
  122. const scoreAnswerJdRef = ref(null);
  123. const data = reactive({
  124. hisId: null,
  125. name: '',
  126. ksScore: '',
  127. scoreData: '',
  128. stTotal: 0,
  129. stScore: 0,
  130. biaoji: null,
  131. endSecond: 0,
  132. pageSize: 0,
  133. toggleScreenFlag: 0,
  134. toggleScreenSecond: 0,
  135. zhuapai: 0,
  136. duanluo: [],
  137. markDB: [],
  138. StListForSearch: [],
  139. })
  140. const yuduIndexQa = ref(null);
  141. const questionData = ref([]);
  142. const progress = reactive({
  143. dlIndex: 0,
  144. dtIndex: 0
  145. })
  146. const dlName = computed(() => {
  147. if (data.StListForSearch && activeSt.value) {
  148. return data.StListForSearch[activeSt.value.onlyNum - 1].paragraphName
  149. } else {
  150. return ''
  151. }
  152. })
  153. watch(() => data.duanluo, (newVal) => {
  154. // 计算已答试题数量
  155. }, {
  156. deep: true
  157. })
  158. const activeSt = computed(() => {
  159. if (questionData.value.length) {
  160. return questionData.value.length && questionData.value[progress.dlIndex].qas[progress.dtIndex];
  161. } else {
  162. return null
  163. }
  164. })
  165. const isFistStId = computed(() => {
  166. if (data.StListForSearch.length) {
  167. return data.StListForSearch[0].stId == activeSt.value.stId
  168. } else {
  169. return false
  170. }
  171. });
  172. const isLastStId = computed(() => {
  173. if (data.StListForSearch.length) {
  174. return data.StListForSearch[data.StListForSearch.length - 1].stId == activeSt.value.stId
  175. } else {
  176. return false
  177. }
  178. });
  179. onLoad((option) => {
  180. data.hisId = option.hisId;
  181. data.name = option.name;
  182. data.userScore = option.userScore;
  183. data.ksScore = option.ksScore;
  184. initKaoshi();
  185. })
  186. function onTimeUp() {
  187. console.log('end')
  188. }
  189. function answerCardItemClick(qa) {
  190. const actQa = data.StListForSearch.find(item => item.stId == qa.stId);
  191. skipQuestion(actQa.dlIndex, actQa.dtIndex)
  192. }
  193. function skipQuestion(dlIndex, dtIndex) {
  194. progress.dlIndex = dlIndex;
  195. progress.dtIndex = dtIndex;
  196. handlePopupBack()
  197. // 切换试题时清空阅读提解析
  198. yuduIndexQa.value = null;
  199. }
  200. function getQaClass(qa) {
  201. if (qa.marked && qa.marked === true) {
  202. return 'paragraph-qa-block-mark';
  203. } else {
  204. if (qa.stTypeId == 1) {
  205. if (checkDanxuanReply(qa)) {
  206. return 'paragraph-qa-block-done';
  207. } else {
  208. return 'paragraph-qa-block-init';
  209. }
  210. } else if (qa.stTypeId == 2) {
  211. if (checkDuoxuanReply(qa)) {
  212. return 'paragraph-qa-block-done';
  213. } else {
  214. return 'paragraph-qa-block-init';
  215. }
  216. } else if (qa.stTypeId == 3) {
  217. if (checkPanduanReply(qa)) {
  218. return 'paragraph-qa-block-done';
  219. } else {
  220. return 'paragraph-qa-block-init';
  221. }
  222. } else if (qa.stTypeId == 4) {
  223. if (checkTiankongReply(qa)) {
  224. return 'paragraph-qa-block-done';
  225. } else {
  226. return 'paragraph-qa-block-init';
  227. }
  228. } else if (qa.stTypeId == 5) {
  229. if (checkJiandaReply(qa)) {
  230. return 'paragraph-qa-block-done';
  231. } else {
  232. return 'paragraph-qa-block-init';
  233. }
  234. } else if (qa.stTypeId == 6) {
  235. if (checkYueduReply(qa)) {
  236. return 'paragraph-qa-block-done';
  237. } else {
  238. return 'paragraph-qa-block-init';
  239. }
  240. }
  241. }
  242. }
  243. function showAnswerCard() {
  244. popupRef.value.open('top')
  245. }
  246. function handlePopupBack() {
  247. popupRef.value.close()
  248. }
  249. function handlePrev() {
  250. const qa = data.StListForSearch.find(item => item.stId == activeSt.value.stId);
  251. const index = qa.num - 1;
  252. if (index > 0) {
  253. const result = data.StListForSearch[index - 1];
  254. progress.dlIndex = result.dlIndex;
  255. progress.dtIndex = result.dtIndex
  256. }
  257. // 切换试题时清空阅读提解析
  258. yuduIndexQa.value = null;
  259. }
  260. function handleNext() {
  261. const qa = data.StListForSearch.find(item => item.stId == activeSt.value.stId);
  262. const index = qa.num - 1;
  263. if (index < data.StListForSearch.length) {
  264. const result = data.StListForSearch[index + 1];
  265. console.log('resultresult',result);
  266. progress.dlIndex = result.dlIndex;
  267. progress.dtIndex = result.dtIndex
  268. }
  269. // 切换试题时清空阅读提解析
  270. yuduIndexQa.value = null
  271. }
  272. function formatDuanluoList(dlData) {
  273. let uIndex = 0; // 试题num
  274. let iDuanluo = 0; // 段落num
  275. let result = [];
  276. for (const duanluo of data.duanluo) {
  277. let paragraph = {
  278. qas: [],
  279. };
  280. paragraph.name = duanluo.name;
  281. let iQa = 0; // 当前试题序号
  282. let order = 0; // 当前题型中第几题
  283. for (const iDanxuan of duanluo.danxuan) {
  284. iDanxuan.type = 'danxuan';
  285. iDanxuan.marked = false;
  286. iDanxuan.onlyNum = uIndex + 1;
  287. iDanxuan.order = order;
  288. iDanxuan.iQa = iQa;
  289. iDanxuan.reply = iDanxuan.result;
  290. paragraph.qas.push(iDanxuan);
  291. uIndex++;
  292. order++;
  293. iQa++;
  294. data.StListForSearch.push({
  295. stId: iDanxuan.stId,
  296. paragraphName: paragraph.name,
  297. dlIndex: iDuanluo,
  298. dtIndex: iDanxuan.iQa,
  299. num: iDanxuan.onlyNum
  300. })
  301. }
  302. order = 0;
  303. for (const iDuoxuan of duanluo.duoxuan) {
  304. iDuoxuan.type = 'duoxuan';
  305. iDuoxuan.marked = false;
  306. iDuoxuan.onlyNum = uIndex + 1;
  307. iDuoxuan.order = order;
  308. paragraph.qas.push(iDuoxuan);
  309. iDuoxuan.reply = iDuoxuan.result;
  310. iDuoxuan.iQa = iQa;
  311. uIndex++;
  312. order++;
  313. iQa++;
  314. data.StListForSearch.push({
  315. stId: iDuoxuan.stId,
  316. paragraphName: paragraph.name,
  317. dlIndex: iDuanluo,
  318. dtIndex: iDuoxuan.iQa,
  319. num: iDuoxuan.onlyNum
  320. })
  321. }
  322. order = 0;
  323. for (const iPanduan of duanluo.panduan) {
  324. iPanduan.type = 'panduan';
  325. iPanduan.marked = false;
  326. iPanduan.onlyNum = uIndex + 1;
  327. iPanduan.order = order;
  328. paragraph.qas.push(iPanduan);
  329. iPanduan.reply = iPanduan.result;
  330. iPanduan.iQa = iQa;
  331. uIndex++;
  332. order++;
  333. iQa++;
  334. data.StListForSearch.push({
  335. stId: iPanduan.stId,
  336. paragraphName: paragraph.name,
  337. dlIndex: iDuanluo,
  338. dtIndex: iPanduan.iQa,
  339. num: iPanduan.onlyNum
  340. })
  341. }
  342. order = 0;
  343. for (const iTiankong of duanluo.tiankong) {
  344. iTiankong.type = 'tiankong';
  345. iTiankong.marked = false;
  346. iTiankong.onlyNum = uIndex + 1;
  347. iTiankong.order = order;
  348. paragraph.qas.push(iTiankong);
  349. iTiankong.reply = iTiankong.result.map(item => item[0]);
  350. iTiankong.iQa = iQa;
  351. uIndex++;
  352. order++;
  353. iQa++;
  354. data.StListForSearch.push({
  355. stId: iTiankong.stId,
  356. paragraphName: paragraph.name,
  357. dlIndex: iDuanluo,
  358. dtIndex: iTiankong.iQa,
  359. num: iTiankong.onlyNum
  360. })
  361. }
  362. order = 0;
  363. for (const iJianda of duanluo.jianda) {
  364. iJianda.marked = false;
  365. iJianda.type = 'jianda';
  366. iJianda.onlyNum = uIndex + 1;
  367. iJianda.order = order;
  368. iJianda.iQa = iQa;
  369. paragraph.qas.push(iJianda);
  370. iJianda.reply = '';
  371. uIndex++;
  372. order++;
  373. iQa++;
  374. data.StListForSearch.push({
  375. stId: iJianda.stId,
  376. paragraphName: paragraph.name,
  377. dlIndex: iDuanluo,
  378. dtIndex: iJianda.iQa,
  379. num: iJianda.onlyNum
  380. })
  381. }
  382. order = 0;
  383. for (const iYuedu of duanluo.yuedu) {
  384. iYuedu.marked = false;
  385. iYuedu.type = 'yuedu';
  386. iYuedu.onlyNum = uIndex + 1;
  387. iYuedu.order = order;
  388. iYuedu.iQa = iQa;
  389. if (iYuedu.duoxuan && iYuedu.duoxuan.length) {
  390. iYuedu.duoxuan.map((qIt) => {
  391. qIt.reply = qIt.reply || [];
  392. return qIt
  393. })
  394. }
  395. if (iYuedu.tiankong && iYuedu.tiankong.length) {
  396. iYuedu.tiankong.map((qIt) => {
  397. qIt.reply = new Array(qIt.count).fill('');
  398. return qIt;
  399. });
  400. }
  401. paragraph.qas.push(iYuedu);
  402. iYuedu.reply = [];
  403. uIndex++;
  404. order++;
  405. iQa++;
  406. data.StListForSearch.push({
  407. stId: iYuedu.stId,
  408. paragraphName: paragraph.name,
  409. dlIndex: iDuanluo,
  410. dtIndex: iYuedu.iQa,
  411. num: iYuedu.onlyNum
  412. })
  413. }
  414. iDuanluo++;
  415. questionData.value.push(paragraph)
  416. console.log(questionData.value)
  417. console.log(paragraph)
  418. }
  419. }
  420. // 切换阅读小题时更新当前试题解析
  421. function onYueduChange(qa) {
  422. yuduIndexQa.value = qa;
  423. }
  424. // 校验阅读解析
  425. function checkYueduJiexi() {
  426. debugger
  427. let qa = yuduIndexQa.value;
  428. let score = qa.userScore;
  429. let reply = '';
  430. let result = '';
  431. let answer = qa.answer;
  432. if (qa.stTypeId == 0) {
  433. // 单选题
  434. if (qa.reply && qa.reply.trim() !== '') {
  435. reply = getLetterByIndex(qa.reply)
  436. } else {
  437. reply = '未答'
  438. }
  439. if (qa.result) {
  440. result = getLetterByIndex(qa.result)
  441. } else {
  442. result = '无答案'
  443. }
  444. scoreAnswerRef.value.showPopup({
  445. score,
  446. reply,
  447. result,
  448. answer
  449. })
  450. }
  451. if (qa.stTypeId == 2) {
  452. // 多选题
  453. if (qa.reply && qa.reply.length) {
  454. reply = qa.reply.map(item => {
  455. if (item.trim()) {
  456. return getLetterByIndex(item.trim())
  457. }
  458. }).join(',')
  459. } else {
  460. reply = '未答'
  461. }
  462. if (qa.result) {
  463. result = qa.result.map(item => {
  464. if (item.trim()) {
  465. return getLetterByIndex(item.trim())
  466. }
  467. }).join(',')
  468. } else {
  469. result = '无答案'
  470. }
  471. scoreAnswerRef.value.showPopup({
  472. score,
  473. reply,
  474. result,
  475. answer
  476. })
  477. }
  478. if (qa.stTypeId == 3) {
  479. // 判断题
  480. if (qa.reply === '') {
  481. reply = '未答'
  482. } else if (qa.reply == 0) {
  483. reply = '错误'
  484. } else if (qa.reply == 1) {
  485. reply = '正确'
  486. }
  487. if (qa.result == 0) {
  488. result = '错误'
  489. } else if (qa.result == 1) {
  490. result = '正确'
  491. }
  492. scoreAnswerRef.value.showPopup({
  493. score,
  494. reply,
  495. result,
  496. answer
  497. })
  498. }
  499. if (qa.stTypeId == 4) {
  500. let reply = qa.reply || [];
  501. let result = qa.result || [];
  502. // 填空题
  503. scoreAnswerTkRef.value.showPopup({
  504. score,
  505. reply,
  506. result,
  507. answer
  508. })
  509. }
  510. if (qa.stTypeId == 5) {
  511. // 简单题
  512. let reply = qa.reply ? '未答' : qa.reply;
  513. let result = qa.result;
  514. scoreAnswerJdRef.value.showPopup({
  515. score,
  516. reply,
  517. result,
  518. answer
  519. })
  520. }
  521. }
  522. // 获取解析
  523. function handleCheckJiexi() {
  524. const qa = activeSt.value;
  525. let score = qa.userScore;
  526. let reply = '';
  527. let result = '';
  528. let answer = qa.answer;
  529. if (qa.stTypeId == 1) {
  530. // 单选题
  531. if (qa.reply && qa.reply.trim() !== '') {
  532. reply = getLetterByIndex(qa.reply)
  533. } else {
  534. reply = '未答'
  535. }
  536. if (qa.result) {
  537. result = getLetterByIndex(qa.result)
  538. } else {
  539. result = '无答案'
  540. }
  541. scoreAnswerRef.value.showPopup({
  542. score,
  543. reply,
  544. result,
  545. answer
  546. })
  547. }
  548. if (qa.stTypeId == 2) {
  549. // 多选题
  550. if (qa.reply && qa.reply.length) {
  551. reply = qa.reply.map(item => {
  552. if (item.trim()) {
  553. return getLetterByIndex(item.trim())
  554. }
  555. }).join(',')
  556. } else {
  557. reply = '未答'
  558. }
  559. if (qa.result) {
  560. result = qa.result.map(item => {
  561. if (item.trim()) {
  562. return getLetterByIndex(item.trim())
  563. }
  564. }).join(',')
  565. } else {
  566. result = '无答案'
  567. }
  568. scoreAnswerRef.value.showPopup({
  569. score,
  570. reply,
  571. result,
  572. answer
  573. })
  574. }
  575. if (qa.stTypeId == 3) {
  576. // 判断题
  577. if (qa.reply === '') {
  578. reply = '未答'
  579. } else if (qa.reply == 0) {
  580. reply = '错误'
  581. } else if (qa.reply == 1) {
  582. reply = '正确'
  583. }
  584. if (qa.result == 0) {
  585. result = '错误'
  586. } else if (qa.result == 1) {
  587. result = '正确'
  588. }
  589. scoreAnswerRef.value.showPopup({
  590. score,
  591. reply,
  592. result,
  593. answer
  594. })
  595. }
  596. if (qa.stTypeId == 4) {
  597. let reply = qa.reply || [];
  598. let result = qa.result || [];
  599. // 填空题
  600. scoreAnswerTkRef.value.showPopup({
  601. score,
  602. reply,
  603. result,
  604. answer
  605. })
  606. }
  607. if (qa.stTypeId == 5) {
  608. // 简单题
  609. let reply = qa.reply;
  610. let result = qa.result;
  611. scoreAnswerJdRef.value.showPopup({
  612. score,
  613. reply,
  614. result,
  615. answer
  616. })
  617. }
  618. if (qa.stTypeId == 6) {
  619. // 简单题
  620. checkYueduJiexi()
  621. }
  622. }
  623. function handleBack() {
  624. // uni.redirectTo({
  625. // url: "/pages/score/index"
  626. // })
  627. uni.navigateBack()
  628. }
  629. function initKaoshi() {
  630. cjApi.lookChengjiView({
  631. hisId: data.hisId
  632. }).then(res => {
  633. const {
  634. hisId,
  635. duanluoList
  636. } = res.data;
  637. data.hisId = hisId;
  638. data.duanluo = duanluoList;
  639. formatDuanluoList(data.duanluo);
  640. uni.setNavigationBarTitle({
  641. title: data.name
  642. });
  643. })
  644. }
  645. </script>