page-exam-item-doing.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. <template>
  2. <div v-if="isInited" class="page-exam-question-box">
  3. <van-nav-bar title="考试" />
  4. <!-- 倒计时 -->
  5. <div class="exam-question-countdown">
  6. <span>剩余考试时间:{{ timeDiff }}</span>
  7. </div>
  8. <!-- 题序盒子 -->
  9. <div class="exam-question-list">
  10. <!-- 辅助间隙,样式问题 -->
  11. <div class="exam-question-start">st</div>
  12. <!-- 题序 -->
  13. <div
  14. :class="{
  15. 'exam-question-item': true,
  16. 'exam-question-item-on': answerIndex === index,
  17. 'exam-question-item-down': examQuestionList[index].userAnswer.length,
  18. }"
  19. v-for="(item, index) in examQuestionList"
  20. :key="index"
  21. @click="handleExamQuestionItemFun(item, index)"
  22. >
  23. <div>{{ index + 1 }}</div>
  24. </div>
  25. <!-- 辅助间隙,样式问题 -->
  26. <div class="exam-question-end">en</div>
  27. </div>
  28. <!-- 题目卡片 -->
  29. <div class="exam-question-div">
  30. <div class="exam-question-card">
  31. <!-- 标题、分数、题页 -->
  32. <div v-if="examQuestionList.length" class="exam-question-head">
  33. <div class="exam-question-head-left">
  34. <div class="exam-question-head-left-icon"></div>
  35. <div class="exam-question-head-left-txt">
  36. {{ examQuestionList[answerIndex].typeTxt || "undefind" }}
  37. </div>
  38. <span class="exam-question-head-left-txt"
  39. >{{ examQuestionList[answerIndex].grade || "undefind" }} 分</span
  40. >
  41. </div>
  42. <div class="exam-question-head-right">
  43. <span class="exam-question-head-right-now">{{
  44. answerIndex + 1
  45. }}</span>
  46. <span>/</span>
  47. <span>{{ examQuestionList.length }}</span>
  48. </div>
  49. </div>
  50. <!-- 描述 -->
  51. <div v-if="examQuestionList.length" class="exam-question-describe">
  52. {{
  53. examQuestionList[answerIndex].questionContent ||
  54. examQuestionList[answerIndex].content
  55. }}
  56. </div>
  57. <!-- 答题列表 -->
  58. <!-- 单选题、多选题的选项区域 -->
  59. <div
  60. v-if="
  61. examQuestionList.length &&
  62. (examQuestionList[answerIndex].type === questionType.singleChoice ||
  63. examQuestionList[answerIndex].type ===
  64. questionType.multipleChoice)
  65. "
  66. class="exam-question-options"
  67. >
  68. <div
  69. v-for="(item, index) in examQuestionList[answerIndex].answers"
  70. :key="index"
  71. :class="{
  72. 'exam-question-options-item': true,
  73. 'exam-question-options-item-checked': answerValue.includes(item),
  74. }"
  75. @click="handleExamQuestionOptionsItemFun(item)"
  76. >
  77. {{ formatQuestionIndex(index) }}. {{ item }}
  78. </div>
  79. </div>
  80. <!-- 填空题的答题区域 -->
  81. <div
  82. v-if="
  83. examQuestionList.length &&
  84. examQuestionList[answerIndex].type === questionType.gapFilling
  85. "
  86. class="exam-question-gapFilling"
  87. >
  88. <textarea
  89. v-for="(item, index) in examQuestionList[answerIndex]
  90. .questionInputNum"
  91. :key="index"
  92. :ref="'questionInputRef' + index"
  93. v-model="inputValue[index]"
  94. maxlength="200"
  95. rows="1"
  96. @change="handleExamQuestionOptionsItemFun(inputValue, index)"
  97. />
  98. </div>
  99. <div class="exam-question-button-box">
  100. <van-button
  101. class="exam-question-button"
  102. type="primary"
  103. color="#0088e9"
  104. @click="handleSureFun"
  105. >确定</van-button
  106. >
  107. <van-button
  108. v-if="answerIndex + 1 === examQuestionList.length"
  109. class="exam-question-button"
  110. type="primary"
  111. color="#0088e9"
  112. :disabled="this.timeDiff === '00:00:00'"
  113. @click="handleSubmitFun"
  114. >交卷</van-button
  115. >
  116. </div>
  117. </div>
  118. </div>
  119. <!-- 拍照用 -->
  120. <input
  121. ref="uploadUserInput"
  122. type="file"
  123. name="file"
  124. accept="image/*"
  125. capture="user"
  126. @change="startTakePhotoFUn"
  127. style="display: none"
  128. />
  129. </div>
  130. </template>
  131. <script>
  132. import { mapState } from "vuex";
  133. import { Dialog, Toast } from "vant";
  134. export default {
  135. name: "page-exam-item-doing",
  136. components: {},
  137. data() {
  138. return {
  139. questionType: {
  140. singleChoice: "DanXuan", // 单选题
  141. multipleChoice: "DuoXuan", // 多选题
  142. gapFilling: "TianKong" // 填空题
  143. }, // 试题类型
  144. examEndTimeSeconds: null, // 考试结束时的毫秒秒数
  145. examBeforeHalfEndTimeSeconds: null, // 开始考试一半时间的毫秒秒数
  146. startTimeSeconds: 0, // 当前开始考试的毫秒秒数时长
  147. timeDiff: "00:00:00", // 距离考试结束的时间
  148. interval: null, // 计时器
  149. examQuestionList: [], // 试题列表
  150. answerIndex: null, // 当前试题的下标索引
  151. answerValue: [], // 当前试题的所答
  152. inputValue: [], // 填空题时输入框的值
  153. isInited: false, // 是否已初始化完毕
  154. isOverHalfTime: false, // 是否已超过1/3的考试时间
  155. answerTime: {
  156. startTime: 0,
  157. endTime: 0
  158. } // 答题的开始、结束时间
  159. };
  160. },
  161. mounted() {
  162. // window.onbeforeunload = function() {
  163. // return "正在考试,无法退出";
  164. // };
  165. // history.pushState(null, null, document.URL);
  166. // window.addEventListener("popstate", function() {
  167. // Toast("正在考试中,无法退出");
  168. // history.pushState(null, null, document.URL);
  169. // });
  170. this.initDataFun(); // 初始化数据信息
  171. },
  172. beforeDestroy() {
  173. console.log("in");
  174. if (this.interval) {
  175. clearInterval(this.interval); // 销毁前清空计时器
  176. }
  177. },
  178. watch: {},
  179. computed: {
  180. ...mapState({
  181. examItem: state => state.exam.examItem,
  182. userInfo: state => state.user.userInfo
  183. })
  184. },
  185. methods: {
  186. // 初始化数据信息
  187. initDataFun() {
  188. if (!this.examItem) {
  189. Dialog.alert({
  190. message: "试题信息有误,请重新进入当前页面",
  191. theme: "round-button"
  192. }).then(() => {
  193. // window.removeEventListener("popstate", function() {
  194. // Toast("正在考试中,无法退出");
  195. // history.pushState(null, null, document.URL);
  196. // });
  197. this.$router.back();
  198. });
  199. return;
  200. }
  201. this.examStartFun(); // 方法:开始考试
  202. },
  203. // 方法:开始考试
  204. examStartFun() {
  205. this.$store.commit("toggleLoading", true);
  206. // let params = {
  207. // type: "aaaaaaaa"
  208. // };
  209. this.$_http
  210. .post(
  211. this.$pathParams(this.$_API.POST_JTXT_GET_EXAMS_START, {
  212. examId: this.examItem.id
  213. }),
  214. this.userInfo
  215. // { params }
  216. )
  217. .then(res => {
  218. if (res.data) {
  219. let httpResultData = [];
  220. res.data.forEach((item, index) => {
  221. this.getExamQuestionsListFun(
  222. item,
  223. httpResultData,
  224. index === res.data.length - 1
  225. );
  226. });
  227. }
  228. })
  229. .catch(() => {
  230. this.$store.commit("toggleLoading", false);
  231. });
  232. },
  233. // 查询:试题信息
  234. async getExamQuestionsListFun(questionId, httpResultData, isLast) {
  235. this.$_http
  236. .get(
  237. this.$pathParams(this.$_API.GET_JTXT_GET_EXAMS_ONE_QUESTIONS_LIST, {
  238. questionId: questionId
  239. })
  240. )
  241. .then(res => {
  242. let resData = { ...res.data };
  243. httpResultData.push(this.setPersonDataFun(resData));
  244. if (isLast) {
  245. this.examQuestionList = httpResultData;
  246. this.handleExamQuestionItemFun(this.examQuestionList[0], 0); // 设置第一题开始
  247. this.isInited = true;
  248. this.getExamTimeFun(); // 获取:当前时间及考试限时
  249. this.setIntervalFun(); // 设置:倒计时定时器
  250. this.$store.commit("toggleLoading", false);
  251. }
  252. })
  253. .catch(() => {
  254. this.$store.commit("toggleLoading", false);
  255. });
  256. },
  257. // 方法:过滤试题的类型,添加用户作答的字段
  258. setPersonDataFun(httpResultDataItme) {
  259. let results = this.formatQuestionType(
  260. httpResultDataItme.type,
  261. httpResultDataItme.content
  262. );
  263. httpResultDataItme.typeTxt = results.typeTxt;
  264. httpResultDataItme.questionContent = results.questionContent;
  265. httpResultDataItme.questionInputNum = results.questionInputNum;
  266. httpResultDataItme.userAnswer = [];
  267. return httpResultDataItme;
  268. },
  269. // 获取:考试限定的时间点
  270. getExamTimeFun() {
  271. let tarTime = this.getTimeHoursMinuteSecondsTogetherFun(
  272. this.examItem.examTimeMins
  273. );
  274. let curTime = new Date();
  275. this.answerTime.startTime = curTime; // 赋值开始时间
  276. // 在当前时间curTime变量上加上小时
  277. let addHour = curTime.setHours(curTime.getHours() + tarTime.hours);
  278. curTime = new Date(addHour);
  279. // 在当前时间curTime变量上加上分钟
  280. let addMinute = new Date(
  281. curTime.setMinutes(curTime.getMinutes() + tarTime.minute)
  282. );
  283. curTime = new Date(addMinute);
  284. // 在当前时间curTime变量上加上秒
  285. let addSeconds = new Date(
  286. curTime.setSeconds(curTime.getSeconds() + tarTime.seconds + 1)
  287. );
  288. curTime = new Date(addSeconds);
  289. this.answerTime.endTime = curTime; // 赋值结束时间-标准时间格式
  290. this.examEndTimeSeconds = curTime.getTime(); // 赋值结束时间的毫秒秒数
  291. },
  292. // 方法:分别获取时 分 秒
  293. getTimeHoursMinuteSecondsTogetherFun(e) {
  294. let time = e;
  295. let len = time.split(":");
  296. if (len.length === 3) {
  297. let hour = time.split(":")[0];
  298. let min = time.split(":")[1];
  299. let sec = time.split(":")[2];
  300. return {
  301. hours: Number(hour),
  302. minute: Number(min),
  303. seconds: Number(sec)
  304. };
  305. }
  306. if (len.length === 2) {
  307. let min = time.split(":")[0];
  308. let sec = time.split(":")[1];
  309. return { hours: 0, minute: Number(min), seconds: Number(sec) };
  310. }
  311. if (len.length === 1) {
  312. let sec = time.split(":")[0];
  313. return { hours: 0, minute: 0, seconds: Number(sec) };
  314. }
  315. return { hours: 0, minute: 0, seconds: 0 };
  316. },
  317. // 设置:倒计时定时器
  318. setIntervalFun() {
  319. let _self = this;
  320. let isStart = false;
  321. // 获取距离目标时间的毫秒时间戳
  322. this.interval = setInterval(() => {
  323. let curTime = Date.now(); // 获取当前时间的毫秒时间戳
  324. if (!isStart) {
  325. this.examBeforeHalfEndTimeSeconds = this.examEndTimeSeconds - curTime; // 获取当前开始考试的时间的毫秒秒数
  326. console.log(
  327. "examBeforeHalfEndTimeSeconds:",
  328. this.examBeforeHalfEndTimeSeconds
  329. );
  330. isStart = true;
  331. }
  332. let diffTime = this.examEndTimeSeconds - curTime; // 计算出当前时间距离目标时间的时间差
  333. // 判断倒计时是否完成,成立则清除定时器,关闭函数执行
  334. if (diffTime <= 0) {
  335. Dialog.close(); // 关闭弹框提示框
  336. clearInterval(_self.interval);
  337. _self.timeDiff = "00:00:00";
  338. this.examsEndFun(true); // 自动交卷
  339. return;
  340. }
  341. this.startTimeSeconds = this.startTimeSeconds + 1000; // 新增开始进行了考试的时长
  342. console.log(this.startTimeSeconds);
  343. if (
  344. this.examBeforeHalfEndTimeSeconds / 2 > diffTime &&
  345. !this.isOverHalfTime
  346. ) {
  347. console.log("超过一半考试时间了");
  348. // this.$nextTick(() => {
  349. // this.$refs.uploadUserInput.click(); // 调用拍照工具
  350. // });
  351. this.isOverHalfTime = true;
  352. }
  353. let hours = Math.floor(diffTime / (1000 * 60 * 60));
  354. let minutes = Math.floor(
  355. (diffTime - hours * 60 * 60 * 1000) / (1000 * 60)
  356. );
  357. let seconds = Math.floor(
  358. (diffTime - hours * 60 * 60 * 1000 - minutes * 60 * 1000) / 1000
  359. );
  360. let timeDiff = zero(hours) + ":" + zero(minutes) + ":" + zero(seconds);
  361. _self.timeDiff = timeDiff;
  362. // 数字补零
  363. function zero(num) {
  364. return num < 10 ? "0" + num : num;
  365. }
  366. }, 1000);
  367. },
  368. // 方法:过滤试题的类型、填空题的题目、填空题的回答框个数
  369. formatQuestionType(type, content) {
  370. let typeTxt = "";
  371. let questionContent = "";
  372. let questionInputNum = 0;
  373. switch (type) {
  374. case this.questionType.singleChoice:
  375. typeTxt = "单选题";
  376. break;
  377. case this.questionType.multipleChoice:
  378. typeTxt = "多选题";
  379. break;
  380. case this.questionType.gapFilling:
  381. typeTxt = "填空题";
  382. console.log(content);
  383. questionInputNum = this.getPlaceholderCount(content);
  384. questionContent = content.replace("$PH$", "()");
  385. console.log(questionContent, questionInputNum);
  386. break;
  387. default:
  388. break;
  389. }
  390. return {
  391. typeTxt: typeTxt,
  392. questionContent: questionContent,
  393. questionInputNum: questionInputNum
  394. };
  395. },
  396. // 方法:统计字符串中包含的特定字符个数
  397. getPlaceholderCount(strSource) {
  398. // 统计字符串中包含{}或{xxXX}的个数
  399. let thisCount = 0;
  400. strSource.replace("$PH$", function(m, i) {
  401. // m为找到的{xx}元素、i为索引
  402. thisCount++;
  403. });
  404. return thisCount;
  405. },
  406. // 操作:点击了某个题序
  407. handleExamQuestionItemFun(item, index) {
  408. if (this.answerIndex === index || !this.examQuestionList.length) {
  409. return;
  410. }
  411. this.answerIndex = index;
  412. switch (item.type) {
  413. case this.questionType.singleChoice:
  414. case this.questionType.multipleChoice:
  415. this.answerValue = [...new Set(item.userAnswer)];
  416. break;
  417. case this.questionType.gapFilling:
  418. this.answerValue = [...new Set(item.userAnswer)];
  419. this.inputValue = this.answerValue || [];
  420. break;
  421. default:
  422. break;
  423. }
  424. },
  425. // 操作:作答了某个选项
  426. handleExamQuestionOptionsItemFun(value, index) {
  427. let answerQuestionType = this.examQuestionList[this.answerIndex].type;
  428. switch (answerQuestionType) {
  429. // 单选题
  430. case this.questionType.singleChoice:
  431. this.answerValue = [value];
  432. break;
  433. // 多选题
  434. case this.questionType.multipleChoice:
  435. // 遍历所答的数组,看是否有重复的
  436. let repetitiveIndex = null;
  437. for (let i = 0; i < this.answerValue.length; i++) {
  438. let it = this.answerValue[i];
  439. if (value === it) {
  440. repetitiveIndex = i;
  441. break;
  442. }
  443. }
  444. // 如果有重复的就移除
  445. if (repetitiveIndex !== null) {
  446. this.answerValue.splice(repetitiveIndex, 1);
  447. } else {
  448. this.answerValue.push(value);
  449. }
  450. break;
  451. // 填空题
  452. case this.questionType.gapFilling:
  453. this.$refs["questionInputRef" + index][0].blur(); // 清除input的焦点
  454. this.answerValue = value;
  455. break;
  456. default:
  457. break;
  458. }
  459. },
  460. // 方法:下一题
  461. handleNextFun() {
  462. let nextIndex = this.answerIndex + 1;
  463. if (nextIndex >= this.examQuestionList.length) {
  464. return;
  465. }
  466. this.handleExamQuestionItemFun(
  467. this.examQuestionList[nextIndex],
  468. nextIndex
  469. );
  470. },
  471. // 操作:确定
  472. handleSureFun() {
  473. if (!this.examQuestionList.length) {
  474. return;
  475. }
  476. this.examQuestionList[this.answerIndex].userAnswer = this.answerValue;
  477. this.handleNextFun();
  478. // 若超过了了考试时间的1/3,则需要调用拍照
  479. if (this.isOverHalfTime) {
  480. this.$refs.uploadUserInput.click(); // 调用拍照工具
  481. }
  482. },
  483. // 操作:交卷 isAuto:true(时间到了的自动交卷) false(手动交卷)
  484. handleSubmitFun() {
  485. let isAuto = this.timeDiff === "00:00:00";
  486. if (isAuto) {
  487. this.examsEndFun(isAuto);
  488. } else {
  489. Dialog.confirm({
  490. title: "温馨提示",
  491. message: "确认交卷?"
  492. })
  493. .then(() => {
  494. clearInterval(this.interval); // 销毁前清空计时器
  495. this.answerTime.endTime = new Date();
  496. this.examsEndFun(isAuto);
  497. })
  498. .catch(() => {});
  499. }
  500. },
  501. // 方法:结束考试
  502. examsEndFun(isAuto) {
  503. if (isAuto) {
  504. Dialog({ message: "考试时间已到,该考试已结束,并自动交卷" });
  505. }
  506. // window.removeEventListener("popstate", function() {
  507. // Toast("正在考试中,无法退出");
  508. // history.pushState(null, null, document.URL);
  509. // });
  510. this.$store.commit("toggleLoading", true);
  511. let grades = this.getUserExamAllPointsFun(); // 方法:计算成绩
  512. let answers = this.getUserExamAllAnswersFun(); // 方法:获取当前用户所有题目作答的答案
  513. let params = {
  514. userId: this.userInfo.id,
  515. examId: this.answerRecruitId,
  516. points: grades, // 成绩:分数
  517. startTime: this.answerTime.startTime,
  518. endTime: this.answerTime.endTime,
  519. userAnswers: answers
  520. };
  521. this.$_http
  522. .post(
  523. this.$pathParams(this.$_API.POST_JTXT_GET_EXAMS_END, {
  524. examId: this.examItem.id
  525. }),
  526. params
  527. )
  528. .then(res => {
  529. this.$store.commit("toggleLoading", false);
  530. this.$router.replace({
  531. name: "ExamResult",
  532. params: { grades: grades }
  533. });
  534. })
  535. .catch(() => {
  536. this.$store.commit("toggleLoading", false);
  537. Dialog.close();
  538. Dialog({ message: "结束考试异常,请联系系统管理员" });
  539. this.$router.back();
  540. });
  541. },
  542. // 方法:计算成绩
  543. getUserExamAllPointsFun() {
  544. let grades = 0;
  545. this.examQuestionList.forEach((item, index) => {
  546. let sureNum = 0;
  547. item.finalAnswer.forEach(it => {
  548. item.userAnswer.forEach(answerItem => {
  549. if (it === answerItem) {
  550. sureNum++;
  551. }
  552. });
  553. });
  554. if (sureNum === item.finalAnswer.length) {
  555. grades++; // 默认每题一分
  556. }
  557. });
  558. return grades;
  559. },
  560. // 方法:获取题目的答案
  561. getUserExamAllAnswersFun() {
  562. let answers = [];
  563. this.examQuestionList.forEach((item, index) => {
  564. // answers[index] = item.userAnswer;
  565. answers[index] = item.userAnswer.join("||");
  566. });
  567. return answers;
  568. },
  569. // 方法:开始考试
  570. startTakePhotoFUn(event) {
  571. let file = event.target.files[0]; // 获取文件对象
  572. if (file) {
  573. // let fd = new FormData(); // 构造formdata对象
  574. // fd.append("file", file); // 向formdata里面存放键值对存放图片文件
  575. // fd.append("userId", this.userInfo.id); // 向formdata里面存放用户的ID
  576. // console.log(fd);
  577. this.$router.replace({ name: "Exam" });
  578. } else {
  579. Toast("请完成拍照后,再进行考试");
  580. }
  581. }
  582. }
  583. };
  584. </script>
  585. <style lang="scss" scoped>
  586. @import "~@/styles/mixin";
  587. .page-exam-question-box {
  588. width: 100%;
  589. height: 100%;
  590. overflow-y: auto;
  591. overflow-x: hidden;
  592. font-size: 0.6rem;
  593. .exam-question-countdown {
  594. height: 2rem;
  595. background-color: #f4f7ff;
  596. display: flex;
  597. justify-content: flex-end;
  598. align-items: center;
  599. padding: 0 0.5rem;
  600. font-size: 0.65rem;
  601. span {
  602. color: #666;
  603. }
  604. }
  605. .exam-question-list {
  606. display: flex;
  607. flex-wrap: nowrap;
  608. overflow-x: scroll;
  609. overflow-y: hidden;
  610. padding: 0.25rem 0;
  611. background-color: #fff;
  612. .exam-question-start {
  613. width: 0.2rem;
  614. height: 100%;
  615. color: #fff;
  616. }
  617. .exam-question-end {
  618. width: 1em;
  619. height: 1.5rem;
  620. color: #fff;
  621. }
  622. .exam-question-item {
  623. margin-left: 0.3rem;
  624. background-color: #f3f3f3;
  625. border: 1px solid transparent;
  626. > div {
  627. width: 1.25rem;
  628. height: 1.5rem;
  629. text-align: center;
  630. line-height: 1.5rem;
  631. }
  632. }
  633. .exam-question-item-down {
  634. background-color: #f4f7ff;
  635. }
  636. .exam-question-item-on {
  637. border-color: #0088e9;
  638. color: #0088e9;
  639. }
  640. }
  641. .exam-question-div {
  642. padding: 0.5rem 0.5rem;
  643. .exam-question-card {
  644. padding: 0.5rem 0.5rem;
  645. background-color: #fff;
  646. border-radius: 4px;
  647. box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
  648. .exam-question-head {
  649. display: flex;
  650. justify-content: space-between;
  651. align-items: center;
  652. flex-wrap: nowrap;
  653. border-bottom: 1px solid #0088e9;
  654. padding-bottom: 0.25rem;
  655. height: 1.25rem;
  656. font-size: 0.65rem;
  657. .exam-question-head-left {
  658. display: flex;
  659. align-items: center;
  660. flex-wrap: nowrap;
  661. .exam-question-head-left-icon {
  662. width: 0.25rem;
  663. height: 1rem;
  664. background-color: #0088e9;
  665. }
  666. .exam-question-head-left-txt {
  667. margin-left: 0.25rem;
  668. font-weight: bold;
  669. }
  670. }
  671. .exam-question-head-right {
  672. span {
  673. color: #666;
  674. }
  675. .exam-question-head-right-now {
  676. font-weight: bold;
  677. color: #000;
  678. }
  679. }
  680. }
  681. .exam-question-describe {
  682. padding: 0.5rem 0;
  683. font-size: 0.65rem;
  684. }
  685. .exam-question-options {
  686. .exam-question-options-item {
  687. width: 100%;
  688. padding: 0.5rem 0.25rem;
  689. background-color: #f3f3f3;
  690. margin-bottom: 0.5rem;
  691. border: 1px solid transparent;
  692. }
  693. .exam-question-options-item-checked {
  694. border-color: #0088e9;
  695. color: #0088e9;
  696. }
  697. }
  698. .exam-question-gapFilling {
  699. padding-top: 0.5rem;
  700. textarea {
  701. width: 100%;
  702. padding: 0.25rem 0.25rem;
  703. background-color: #f3f3f3;
  704. margin-bottom: 0.5rem;
  705. border: 1px solid transparent;
  706. &:active,
  707. &:focus {
  708. border-color: #0088e9;
  709. }
  710. }
  711. }
  712. .exam-question-button-box {
  713. display: flex;
  714. flex-direction: column;
  715. justify-content: center;
  716. align-items: center;
  717. .exam-question-button {
  718. width: 6rem;
  719. height: auto;
  720. padding: 0.5rem 0.5rem;
  721. font-size: 0.65rem;
  722. margin-top: 0.75rem;
  723. }
  724. }
  725. }
  726. }
  727. }
  728. </style>