index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. <template>
  2. <view class="box" @touchstart="touchStart" @touchend="touchEnd">
  3. <nav-bar :title="navTitle"> </nav-bar>
  4. <view style="text-align: center">
  5. <van-count-down :time="time"></van-count-down>
  6. </view>
  7. <m-do-topic
  8. type="exam"
  9. :bottomFunc="['previous', 'next', 'submitExam', 'catalogue']"
  10. :midFunc="['collect', 'readQuestion', 'readQuestionAndAnswer']"
  11. :hiddenMode="true"
  12. :hiddenAnswer="true"
  13. :trueNum.sync="trueNum"
  14. :falseNum.sync="falseNum"
  15. :query="query"
  16. :problemListIndex.sync="problemListIndex"
  17. ></m-do-topic>
  18. <!-- #ifdef MP-WEIXIN -->
  19. <van-tabbar>
  20. <van-tabbar-item @click="goBeforeTopics"
  21. ><van-icon
  22. slot="icon"
  23. custom-style="transform: rotate(90deg);"
  24. custom-class="last-subject"
  25. name="down"
  26. size="18px"
  27. />上一题
  28. </van-tabbar-item>
  29. <van-tabbar-item
  30. ><van-icon slot="icon" size="18px" name="description" />{{
  31. problemListIndex + 1
  32. }}/{{ problemListTotal }}
  33. </van-tabbar-item>
  34. <van-tabbar-item @click="submitExam"
  35. ><van-icon slot="icon" size="18px" name="records" />交卷
  36. </van-tabbar-item>
  37. <van-tabbar-item @click="goNextTopics"
  38. ><van-icon
  39. slot="icon"
  40. custom-style="transform: rotate(-90deg);"
  41. custom-class="last-subject"
  42. name="down"
  43. size="18px"
  44. />下一题
  45. </van-tabbar-item>
  46. </van-tabbar>
  47. <!-- #endif -->
  48. <!-- #ifdef MP-TOUTIAO -->
  49. <!-- <tabbar height="35px">
  50. <view @click="goBeforeTopics" class="flex-all-center h-full">
  51. <van-icon
  52. slot="icon"
  53. custom-style="transform: rotate(90deg);"
  54. custom-class="last-subject"
  55. name="down"
  56. size="18px"
  57. /><text> 上一题 </text>
  58. </view>
  59. <view class="flex-all-center h-full">
  60. <van-icon size="18px" name="description" />{{ problemListIndex + 1 }}/{{
  61. problemListTotal
  62. }}
  63. </view>
  64. <view @click="submitExam" class="flex-all-center h-full">
  65. <van-icon slot="icon" size="18px" name="records" />交卷
  66. </view>
  67. <view @click="goNextTopics" class="flex-all-center h-full">
  68. 下一题
  69. <van-icon
  70. custom-style="transform: rotate(-90deg);"
  71. custom-class="last-subject"
  72. name="down"
  73. size="18px"
  74. />
  75. </view>
  76. </tabbar> -->
  77. <!-- #endif -->
  78. </view>
  79. </template>
  80. <script>
  81. import navBar from "./components/navBar.vue";
  82. import api from "@/api/index";
  83. import utils from "@/utils/index";
  84. import tabbar from "./components/tabbar.vue";
  85. import mRadio from "@/components/m-radio/m-radio.vue";
  86. import mRadioGroup from "@/components/m-radio-group/m-radio-group.vue";
  87. import mCheckbox from "@/components/m-checkbox/m-checkbox.vue";
  88. import mCheckboxGroup from "@/components/m-checkbox-group/m-checkbox-group.vue";
  89. export default {
  90. data() {
  91. return {
  92. query: {
  93. cert: "",
  94. vehicle: "",
  95. subject: "",
  96. title: "",
  97. },
  98. gsMap: {
  99. xc: "小车",
  100. hc: "货车",
  101. mtc: "摩托车",
  102. kc: "客车",
  103. },
  104. examTimer: 0,
  105. examTimeUse: 0,
  106. time: 45 * 60 * 1000,
  107. problemListTotal: 1,
  108. problemList: [
  109. {
  110. answer: "×",
  111. answerkeyword: "",
  112. answermp3:
  113. "https://t1-1305573081.file.myqcloud.com/kt/answer_mp3/answer1389.mp3",
  114. classIssue: "54",
  115. classIssueName: "车内开关/装置",
  116. classSort: 16,
  117. createTime: "2022-04-21 13:33:46",
  118. excellIssue: "23",
  119. excellIssueName: "必学题三",
  120. excellSort: 4,
  121. explainGif:
  122. "https://t1-1305573081.file.myqcloud.com/kt/explain_gif/explain1389.gif",
  123. explainJq:
  124. "看图答题:红色圆圈套在杆子中间.答对;不在中间或没有圆圈的.答错。",
  125. explainJs:
  126. "图中所示为左右转向灯开关转向灯操作:上提是右转向灯亮起,下压是左转向灯。",
  127. explainMp3:
  128. "https://t1-1305573081.file.myqcloud.com/kt/explain_mp3/explain1389.mp3",
  129. explainjsmp3:
  130. "https://t1-1305573081.file.myqcloud.com/kt/explain_js_mp3/explainJS1389.mp3",
  131. id: 831,
  132. idKt: 1389,
  133. idYdt: 950,
  134. image:
  135. "https://t1-1305573081.file.myqcloud.com/kt/image/image1389.png",
  136. imageYdt:
  137. "https://t1-1305573081.file.myqcloud.com/kt/image_ydt/5eb4d75agw1e291vmniovj.jpg",
  138. issue: "将转向灯开关向上提,左转向灯亮。",
  139. issuemp3:
  140. "https://t1-1305573081.file.myqcloud.com/kt/issue_mp3/issue1389.mp3",
  141. liceBus: "1",
  142. liceCar: "1",
  143. liceMoto: null,
  144. liceTruck: "1",
  145. number: 831,
  146. opts: "√-×",
  147. optsArr: ["√", "×"],
  148. placeIssue: null,
  149. placeIssueName: null,
  150. placeSort: null,
  151. questionType: 1,
  152. sequeIssue: "7",
  153. sequeIssueName: "机械仪表",
  154. sequeSort: 25,
  155. skillkeyword: "没有圆圈-答错",
  156. subject: 1,
  157. titlekeyword: "",
  158. updateTime: "2022-04-22 13:43:07",
  159. userAnswer: [],
  160. },
  161. ],
  162. touchx: 0,
  163. touchy: 0,
  164. problemListIndex: 0,
  165. };
  166. },
  167. filters: {
  168. questionType: function (value) {
  169. let question = "";
  170. switch (value) {
  171. case 1:
  172. case "1":
  173. question = "判断题";
  174. break;
  175. case 2:
  176. case "2":
  177. question = "单选题";
  178. break;
  179. case 3:
  180. case "3":
  181. question = "多选题";
  182. break;
  183. }
  184. return question;
  185. },
  186. },
  187. methods: {
  188. confirmMult() {
  189. this.$set(this.problemList[this.problemListIndex], "isCompleted", true);
  190. if (
  191. JSON.stringify(
  192. this.problemList[this.problemListIndex].answer.split("-").sort()
  193. ) ===
  194. JSON.stringify(
  195. this.problemList[this.problemListIndex].userAnswer.sort()
  196. )
  197. ) {
  198. this.trueNum++;
  199. } else {
  200. this.falseNum++;
  201. api.exam.studentQuestionWrong({
  202. questionId: this.problemList[this.problemListIndex].id,
  203. carType: this.gsMap[this.query.gs],
  204. km: this.query.subject === "4" ? "科目四" : "科目一",
  205. });
  206. }
  207. },
  208. touchStart(e) {
  209. var that = this;
  210. (this.touchx = e.changedTouches[0].clientX),
  211. (this.touchy = e.changedTouches[0].clientY);
  212. },
  213. touchEnd(e) {
  214. console.log(e);
  215. var that = this;
  216. let x = e.changedTouches[0].clientX;
  217. let y = e.changedTouches[0].clientY;
  218. let turn = "";
  219. if (x - that.touchx > 50 && Math.abs(y - that.touchy) < 50) {
  220. //右滑
  221. turn = "right";
  222. this.problemListIndex <= 0
  223. ? uni.showToast({
  224. title: "到底了",
  225. icon: "none",
  226. })
  227. : this.problemListIndex--;
  228. } else if (x - that.touchx < -50 && Math.abs(y - that.touchy) < 50) {
  229. //左滑
  230. turn = "left";
  231. this.problemListIndex >= this.problemList.length - 1
  232. ? uni.showToast({
  233. title: "到底了",
  234. icon: "none",
  235. })
  236. : this.problemListIndex++;
  237. }
  238. if (y - that.touchy > 50 && Math.abs(x - that.touchx) < 50) {
  239. //下滑
  240. turn = "down";
  241. } else if (y - that.touchy < -50 && Math.abs(x - that.touchx) < 50) {
  242. //上滑
  243. turn = "up";
  244. }
  245. //根据方向进行操作
  246. if (turn == "down") {
  247. //下滑触发操作
  248. }
  249. console.log(turn);
  250. },
  251. submitExam(e) {
  252. let score = 0;
  253. let query = this.query;
  254. let that = this;
  255. let scorePerQuestion = 0;
  256. query.subject === "4" ? (scorePerQuestion = 2) : (scorePerQuestion = 1);
  257. score = this.trueNum * scorePerQuestion;
  258. uni.showModal({
  259. title: "是否交卷",
  260. content: "交卷后不可再修改了",
  261. success(res) {
  262. if (res.confirm) {
  263. let useTime = "";
  264. let useTimer = new Date(that.examTimeUse);
  265. clearInterval(that.examTimer);
  266. useTime = `${useTimer.getMinutes()}:${useTimer.getSeconds()}`;
  267. uni.navigateTo({
  268. url:
  269. "/otherPages/mockExamEnd/index?" +
  270. utils.mapToUrlQuery({
  271. score,
  272. useTime,
  273. ...that.query,
  274. }),
  275. });
  276. }
  277. },
  278. fail() {},
  279. });
  280. },
  281. goBeforeTopics() {
  282. if (this.problemListIndex <= 0) {
  283. uni.showToast({
  284. title: "到底了",
  285. icon: "none",
  286. });
  287. return;
  288. }
  289. this.problemListIndex = this.problemListIndex - 1;
  290. },
  291. goNextTopics() {
  292. if (this.problemListIndex >= this.problemList.length - 1) {
  293. uni.showToast({
  294. title: "到底了",
  295. icon: "none",
  296. });
  297. return;
  298. }
  299. this.problemListIndex = this.problemListIndex + 1;
  300. },
  301. readQuestion(e) {
  302. let globalAudio = utils.wxUtils.getGlobAudio();
  303. if (globalAudio) {
  304. globalAudio.src = e;
  305. globalAudio.stop();
  306. globalAudio.play();
  307. }
  308. },
  309. changeRadioGroup(e) {
  310. this.$set(
  311. this.problemList[this.problemListIndex],
  312. "userAnswer",
  313. e.detail
  314. );
  315. //错题
  316. if (e.detail !== this.problemList[this.problemListIndex].answer) {
  317. api.exam.studentQuestionWrong({
  318. questionId: this.problemList[this.problemListIndex].id,
  319. carType: this.gsMap[this.query.gs],
  320. km: this.query.subject === "4" ? "科目四" : "科目一",
  321. });
  322. }
  323. this.problemList[this.problemListIndex].optsArr.forEach((item, index) => {
  324. if (e.detail === item.value) {
  325. item.selected = true;
  326. this.$set(
  327. this.problemList[this.problemListIndex].optsArr[index],
  328. "selected",
  329. true
  330. );
  331. } else {
  332. item.selected = false;
  333. this.$set(
  334. this.problemList[this.problemListIndex].optsArr[index],
  335. "selected",
  336. false
  337. );
  338. }
  339. });
  340. this.$set(this.problemList[this.problemListIndex], "isCompleted", true);
  341. // this.problemList[this.problemListIndex].optsArr.forEach((item) => {
  342. // if (e.detail.value === item.value) {
  343. // item.selected = true;
  344. // } else {
  345. // item.selected = false;
  346. // }
  347. // });
  348. },
  349. changeCheckboxGroup(e) {
  350. this.$set(
  351. this.problemList[this.problemListIndex],
  352. "userAnswer",
  353. e.detail
  354. );
  355. this.problemList[this.problemListIndex].optsArr.forEach((item, index) => {
  356. if (e.detail.includes(item.value)) {
  357. item.selected = true;
  358. this.$set(
  359. this.problemList[this.problemListIndex].optsArr[index],
  360. "selected",
  361. true
  362. );
  363. } else {
  364. item.selected = false;
  365. this.$set(
  366. this.problemList[this.problemListIndex].optsArr[index],
  367. "selected",
  368. false
  369. );
  370. }
  371. });
  372. },
  373. changeGroup(e) {
  374. console.log(e);
  375. this.$set(
  376. this.problemList[this.problemListIndex],
  377. "userAnswer",
  378. e.detail
  379. );
  380. },
  381. changeCheckbox(e) {
  382. console.log(e);
  383. },
  384. numberToLetter(index) {
  385. index = Number(index);
  386. return String.fromCharCode(index + 65);
  387. },
  388. },
  389. onLoad(query) {
  390. let that = this;
  391. this.query = query;
  392. },
  393. computed: {
  394. //liceCar=1&liceTruck=&liceBus=&liceMoto=&name=科目一&cert=C1/C2/C3&vehicle=轿车&subject=1&title=顺序练习&sort=3
  395. navTitle() {
  396. let subjectName = this.query.subject == 1 ? "科目一" : "科目四";
  397. return `(${this.query.cert})/${subjectName}/${this.query.title}`;
  398. },
  399. },
  400. onUnload() {
  401. clearInterval(this.examTimer);
  402. },
  403. components: {
  404. navBar,
  405. tabbar,
  406. mRadio,
  407. mRadioGroup,
  408. mCheckbox,
  409. mCheckboxGroup,
  410. },
  411. };
  412. </script>
  413. <style lang="scss" scoped>
  414. .flex-all-center {
  415. display: flex;
  416. align-content: center;
  417. align-items: center;
  418. }
  419. .divider {
  420. width: 100%;
  421. height: 24rpx;
  422. background-color: #f2f3f5;
  423. }
  424. .box {
  425. width: 100%;
  426. height: 100vh;
  427. background: #fff;
  428. .last-subject {
  429. transform: rotate(90deg);
  430. }
  431. .function-list {
  432. width: 100%;
  433. font-size: 13px;
  434. display: flex;
  435. justify-content: space-around;
  436. flex-wrap: wrap;
  437. padding: 15px;
  438. box-sizing: border-box;
  439. .function-item {
  440. margin-bottom: 20px;
  441. width: 30%;
  442. display: flex;
  443. flex-direction: column;
  444. align-items: center;
  445. font-size: 13px;
  446. font-weight: 400;
  447. color: #8a9099;
  448. span {
  449. margin-top: 5px;
  450. }
  451. }
  452. }
  453. .problem-box {
  454. padding: 15rpx;
  455. background: #fff;
  456. /deep/ .van-checkbox {
  457. padding-bottom: 15rpx;
  458. }
  459. /deep/ .van-radio {
  460. padding-bottom: 15rpx;
  461. }
  462. .problem-issue {
  463. font-size: 42rpx;
  464. }
  465. .problem-select {
  466. display: flex;
  467. align-content: center;
  468. align-items: center;
  469. margin-top: 15rpx;
  470. padding-left: 30rpx;
  471. }
  472. .problem-type {
  473. padding-left: 10rpx;
  474. padding-right: 10rpx;
  475. padding-top: 4rpx;
  476. padding-bottom: 4rpx;
  477. font-size: 24rpx;
  478. border-radius: 16rpx 16rpx 0 16rpx;
  479. background: #498ef5;
  480. margin-right: 10rpx;
  481. color: #fff;
  482. font-size: 32rpx;
  483. }
  484. .problem-ops {
  485. margin-top: 30rpx;
  486. padding-left: 30rpx;
  487. .problem-checkbox {
  488. height: 100rpx;
  489. }
  490. }
  491. .problem-op {
  492. width: 75rpx;
  493. height: 75rpx;
  494. line-height: 75rpx;
  495. border-radius: 50%;
  496. text-align: center;
  497. overflow: hidden;
  498. background: #fff;
  499. box-shadow: 0px 4rpx 12rpx rgba(0, 0, 0, 0.16);
  500. }
  501. .problem-op_green {
  502. width: 75rpx;
  503. height: 75rpx;
  504. line-height: 75rpx;
  505. border-radius: 50%;
  506. text-align: center;
  507. overflow: hidden;
  508. background: #01c18d;
  509. box-shadow: 0px 4rpx 12rpx rgba(0, 0, 0, 0.16);
  510. }
  511. .problem-op_selected {
  512. background: #498ef5;
  513. }
  514. .problem-img {
  515. width: 100%;
  516. margin-top: 20rpx;
  517. display: flex;
  518. justify-content: center;
  519. image {
  520. margin: 0 auto;
  521. }
  522. }
  523. }
  524. }
  525. </style>