kaoshiChengjiInfo.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  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/yuedu.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. }
  341. }
  342. // 切换阅读小题时更新当前试题解析
  343. function onYueduChange(qa) {
  344. yuduIndexQa.value = qa;
  345. }
  346. // 校验阅读解析
  347. function checkYueduJiexi() {
  348. debugger
  349. let qa = yuduIndexQa.value;
  350. let score = qa.userScore;
  351. let reply = '';
  352. let result = '';
  353. let answer = qa.answer;
  354. if (qa.stTypeId == 0) {
  355. // 单选题
  356. if (qa.reply && qa.reply.trim() !== '') {
  357. reply = getLetterByIndex(qa.reply)
  358. } else {
  359. reply = '未答'
  360. }
  361. if (qa.result) {
  362. result = getLetterByIndex(qa.result)
  363. } else {
  364. result = '无答案'
  365. }
  366. scoreAnswerRef.value.showPopup({
  367. score,
  368. reply,
  369. result,
  370. answer
  371. })
  372. }
  373. if (qa.stTypeId == 2) {
  374. // 多选题
  375. if (qa.reply && qa.reply.length) {
  376. reply = qa.reply.map(item => {
  377. if (item.trim()) {
  378. return getLetterByIndex(item.trim())
  379. }
  380. }).join(',')
  381. } else {
  382. reply = '未答'
  383. }
  384. if (qa.result) {
  385. result = qa.result.map(item => {
  386. if (item.trim()) {
  387. return getLetterByIndex(item.trim())
  388. }
  389. }).join(',')
  390. } else {
  391. result = '无答案'
  392. }
  393. scoreAnswerRef.value.showPopup({
  394. score,
  395. reply,
  396. result,
  397. answer
  398. })
  399. }
  400. if (qa.stTypeId == 3) {
  401. // 判断题
  402. if (qa.reply === '') {
  403. reply = '未答'
  404. } else if (qa.reply == 0) {
  405. reply = '错误'
  406. } else if (qa.reply == 1) {
  407. reply = '正确'
  408. }
  409. if (qa.result == 0) {
  410. result = '错误'
  411. } else if (qa.result == 1) {
  412. result = '正确'
  413. }
  414. scoreAnswerRef.value.showPopup({
  415. score,
  416. reply,
  417. result,
  418. answer
  419. })
  420. }
  421. if (qa.stTypeId == 4) {
  422. let reply = qa.reply || [];
  423. let result = qa.result || [];
  424. // 填空题
  425. scoreAnswerTkRef.value.showPopup({
  426. score,
  427. reply,
  428. result,
  429. answer
  430. })
  431. }
  432. if (qa.stTypeId == 5) {
  433. // 简单题
  434. let reply = qa.reply ? '未答' : qa.reply;
  435. let result = qa.result;
  436. scoreAnswerJdRef.value.showPopup({
  437. score,
  438. reply,
  439. result,
  440. answer
  441. })
  442. }
  443. }
  444. // 获取解析
  445. function handleCheckJiexi() {
  446. const qa = activeSt.value;
  447. let score = qa.userScore;
  448. let reply = '';
  449. let result = '';
  450. let answer = qa.answer;
  451. if (qa.stTypeId == 1) {
  452. // 单选题
  453. if (qa.reply && qa.reply.trim() !== '') {
  454. reply = getLetterByIndex(qa.reply)
  455. } else {
  456. reply = '未答'
  457. }
  458. if (qa.result) {
  459. result = getLetterByIndex(qa.result)
  460. } else {
  461. result = '无答案'
  462. }
  463. scoreAnswerRef.value.showPopup({
  464. score,
  465. reply,
  466. result,
  467. answer
  468. })
  469. }
  470. if (qa.stTypeId == 2) {
  471. // 多选题
  472. if (qa.reply && qa.reply.length) {
  473. reply = qa.reply.map(item => {
  474. if (item.trim()) {
  475. return getLetterByIndex(item.trim())
  476. }
  477. }).join(',')
  478. } else {
  479. reply = '未答'
  480. }
  481. if (qa.result) {
  482. result = qa.result.map(item => {
  483. if (item.trim()) {
  484. return getLetterByIndex(item.trim())
  485. }
  486. }).join(',')
  487. } else {
  488. result = '无答案'
  489. }
  490. scoreAnswerRef.value.showPopup({
  491. score,
  492. reply,
  493. result,
  494. answer
  495. })
  496. }
  497. if (qa.stTypeId == 3) {
  498. // 判断题
  499. if (qa.reply === '') {
  500. reply = '未答'
  501. } else if (qa.reply == 0) {
  502. reply = '错误'
  503. } else if (qa.reply == 1) {
  504. reply = '正确'
  505. }
  506. if (qa.result == 0) {
  507. result = '错误'
  508. } else if (qa.result == 1) {
  509. result = '正确'
  510. }
  511. scoreAnswerRef.value.showPopup({
  512. score,
  513. reply,
  514. result,
  515. answer
  516. })
  517. }
  518. if (qa.stTypeId == 4) {
  519. let reply = qa.reply || [];
  520. let result = qa.result || [];
  521. // 填空题
  522. scoreAnswerTkRef.value.showPopup({
  523. score,
  524. reply,
  525. result,
  526. answer
  527. })
  528. }
  529. if (qa.stTypeId == 5) {
  530. // 简单题
  531. let reply = qa.reply;
  532. let result = qa.result;
  533. scoreAnswerJdRef.value.showPopup({
  534. score,
  535. reply,
  536. result,
  537. answer
  538. })
  539. }
  540. if (qa.stTypeId == 6) {
  541. // 简单题
  542. checkYueduJiexi()
  543. }
  544. }
  545. function initKaoshi() {
  546. cjApi.lookChengjiView({
  547. hisId: data.hisId
  548. }).then(res => {
  549. const {
  550. hisId,
  551. duanluoList
  552. } = res.data;
  553. data.hisId = hisId;
  554. data.duanluo = duanluoList;
  555. formatDuanluoList(data.duanluo);
  556. uni.setNavigationBarTitle({
  557. title: data.name
  558. });
  559. })
  560. }
  561. </script>