kaoshiChengjiInfo.vue 14 KB

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