index.vue 14 KB

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