Просмотр исходного кода

配置项bug修复和侧边栏bug

JXDS18FUJT 1 год назад
Родитель
Сommit
f946f095b7

+ 17 - 0
package-lock.json

@@ -1669,6 +1669,12 @@
         "@types/node": "*"
       }
     },
+    "@types/js-cookie": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/@types/js-cookie/-/js-cookie-3.0.3.tgz",
+      "integrity": "sha512-Xe7IImK09HP1sv2M/aI+48a20VX+TdRJucfq4vfRVy6nWN8PYPOEnlMRSgxJAgYQIXJVL8dZ4/ilAM7dWNaOww==",
+      "dev": true
+    },
     "@types/json-schema": {
       "version": "7.0.11",
       "resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.11.tgz",
@@ -6100,6 +6106,11 @@
         "@sideway/pinpoint": "^2.0.0"
       }
     },
+    "js-cookie": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmmirror.com/js-cookie/-/js-cookie-3.0.5.tgz",
+      "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw=="
+    },
     "js-message": {
       "version": "1.0.7",
       "resolved": "https://registry.npmmirror.com/js-message/-/js-message-1.0.7.tgz",
@@ -6128,6 +6139,12 @@
       "dev": true,
       "optional": true
     },
+    "jsencrypt": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmmirror.com/jsencrypt/-/jsencrypt-3.3.2.tgz",
+      "integrity": "sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A==",
+      "dev": true
+    },
     "jsesc": {
       "version": "2.5.2",
       "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz",

+ 3 - 0
package.json

@@ -15,6 +15,7 @@
     "buzz": "^1.2.1",
     "core-js": "^3.8.3",
     "howler": "^2.2.3",
+    "js-cookie": "^3.0.5",
     "moment": "^2.29.4",
     "vue": "^3.2.13",
     "vue-router": "^4.0.3",
@@ -23,6 +24,7 @@
   },
   "devDependencies": {
     "@types/howler": "^2.2.7",
+    "@types/js-cookie": "^3.0.3",
     "@typescript-eslint/eslint-plugin": "^5.4.0",
     "@typescript-eslint/parser": "^5.4.0",
     "@vue/cli-plugin-babel": "~5.0.0",
@@ -36,6 +38,7 @@
     "babel-plugin-import": "^1.13.6",
     "eslint": "^7.32.0",
     "eslint-plugin-vue": "^8.0.3",
+    "jsencrypt": "^3.3.2",
     "less": "^2.7.3",
     "less-loader": "^11.1.0",
     "postcss": "^8.4.23",

+ 3 - 1
src/api/index.ts

@@ -2,12 +2,14 @@
 import login from './login/login'
 import open from './open/open'
 import question from './question/question'
+import three from './three/three'
 import traffic from './traffic/traffic'
 const api  = {
     login,
     open,
     question,
-    traffic
+    traffic,
+    three
 
     
 

+ 7 - 1
src/api/login/login.ts

@@ -16,7 +16,7 @@ export default {
         password: string,
         uuid: string
 
-    }):Promise<loginApi.loginRes> {
+    }): Promise<loginApi.loginRes> {
         return request({
             url: '/login',
             method: 'post',
@@ -24,6 +24,12 @@ export default {
             headers: { isLogin: '1' }
         })
 
+    },
+    logout(): Promise<loginApi.loginRes> {
+        return request({
+            url: '/logout',
+            method: 'post'
+        })
     }
 
 

+ 3 - 0
src/api/login/type.d.ts

@@ -11,4 +11,7 @@ declare namespace loginApi {
         }
 
     }
+    interface loginOut extends Res {
+        data:string
+    }
 }

+ 1 - 1
src/api/request.ts

@@ -36,7 +36,7 @@ request.interceptors.response.use((res) => {
 			})
 			break;
 		case 500:
-			message.error('服务器错误')
+			message.error(res.data.msg||'服务器错误',3000)
 			break;
 
 	}

+ 19 - 0
src/api/three/three.ts

@@ -0,0 +1,19 @@
+import request from "../request"
+import { threeApi } from "./type"
+export default {
+    //查询三力测试列表
+    threeForceList(): Promise<any> {
+        return request({
+            url: "/three/force/list",
+            method: 'get'
+        })
+    },
+    //获取三力测试模拟考题
+    threeForceSelectTestQuestionInfoList(): Promise<any> {
+        return request({
+            url: "/three/force/selectTestQuestionInfoList",
+            method: 'get'
+        })
+    }
+
+}

+ 46 - 0
src/api/three/type.d.ts

@@ -0,0 +1,46 @@
+interface Res {
+    code: number,
+    msg: string
+
+}
+export declare namespace threeApi {
+    interface threeForceList extends Res {
+        rows: {
+            "id": number,
+            "type": number,
+            "intnumber": string,
+            "strtppe": string,
+            "strtypeL": string,
+            "licensetype": string,
+            "question": string,
+            "an1": string,
+            "an2": string,
+            "an3": string,
+            "an4": string,
+            "an5": string,
+            "an6": string,
+            "an7": string,
+            "answertrue": string,
+            "explain": string,
+            "bestanswerid": string,
+            "kemu": number,
+            "jieshiFrom": string,
+            "moretypes": string,
+            "chapterid": number,
+            "sinaimg": string,
+            "videoUrl": string,
+            "diffDegree": number,
+            "cityid": number,
+            "gs": string,
+            "keyword": string,
+            "errorRate": number,
+            "mediaUrl": string,
+            "showOptionType": number,
+            "questionSource": number,
+            "bestExplainNew": string
+        }[]
+
+
+    }
+}
+

+ 9 - 3
src/router/index.ts

@@ -2,7 +2,6 @@ import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
 import Login from '../views/login/index.vue'
 
 const routes: Array<RouteRecordRaw> = [
-
   // {
   //   path: '/about',
   //   name: 'about',
@@ -23,6 +22,10 @@ const routes: Array<RouteRecordRaw> = [
     path: '/studySkill',
     component: () => import('../views/studySkill/index.vue')
   },
+  {
+    path: '/threeExam',
+    component: () => import('../views/threeExam/index.vue')
+  },
   {
     path: '/examInstructions',
     component: () => import('../views/examInstructions/index.vue')
@@ -54,8 +57,11 @@ const routes: Array<RouteRecordRaw> = [
       component: () => import('../views/home/markLine/index.vue')
     },
     {
-      path: 'selectExamSubject',
-      component: () => import('../views/home/selectExamSubject/index.vue')
+      path: 'selectDriveExamSubject',
+      component: () => import('../views/home/selectDriveExamSubject/index.vue')
+    },{
+      path: 'threeExam',
+      component: () => import('../views/home/threeExam/index.vue')
     }, {
       path: 'logOut',
       component: () => import('../views/home/logOut/index.vue')

+ 30 - 0
src/utils/jsencrypt.ts

@@ -0,0 +1,30 @@
+import JSEncrypt from 'jsencrypt/bin/jsencrypt'
+
+// 密钥对生成 http://web.chacuo.net/netrsakeypair
+
+const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' +
+  'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
+
+const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
+  '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
+  'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
+  'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
+  'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
+  'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
+  'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
+  'UP8iWi1Qw0Y='
+
+// 加密
+export function encrypt(txt:string) {
+  const encryptor = new JSEncrypt()
+  encryptor.setPublicKey(publicKey) // 设置公钥
+  return encryptor.encrypt(txt) // 对数据进行加密
+}
+
+// 解密
+export function decrypt(txt:string) {
+  const encryptor = new JSEncrypt()
+  encryptor.setPrivateKey(privateKey) // 设置私钥
+  return encryptor.decrypt(txt) // 对数据进行解密
+}
+

+ 2 - 2
src/views/home/components/leftTab/index.vue

@@ -199,7 +199,7 @@ export default defineComponent({
             {
               text: "模拟考试",
               isSelect: false,
-              path: "/home/selectExamSubject",
+              path: "/home/selectDriveExamSubject",
               query: {
                 subject: 4,
               },
@@ -215,7 +215,7 @@ export default defineComponent({
           children: [],
           isOpen: false,
           isSelect: false,
-          path: "/home/markLine",
+          path: "/home/threeExam",
         },
         {
           text: "标志标线大全",

+ 31 - 14
src/views/home/logOut/index.vue

@@ -1,24 +1,41 @@
 <template>
-    <div class="W-full pr30 pl30 pt30">
-        <div class="w-full bg-white h720">
-            <span></span>
-        </div>
-
+  <div class="W-full pr30 pl30 pt30">
+    <div class="w-full bg-white h720">
+      <div class="pt30 pb30">
+        <span class="font-bold font36">是否退出登录,回到登录页?</span>
+      </div>
+      <div class="w-full justify-center flex round5 overflow-hidden cursor-pointer">
+        <div @click="logOut" class="bg-primary-yellow w110 h40 lh40">安全退出</div>
+      </div>
     </div>
+  </div>
 </template>
 
 <script lang="ts">
-import { defineComponent } from 'vue'
-
+import { defineComponent } from "vue";
+import api from '@/api'
+import router from "@/router";
+const logOut = ()=>{
+    api.login.logout().then(res=>{
+        router.push('/login')
+    })
+}
 export default defineComponent({
-    setup () {
-        
-
-        return {}
-    }
-})
+  setup() {
+    return {
+        logOut
+    };
+  },
+});
 </script>
 
 <style scoped>
-
+.bg-primary-yellow {
+  background-color: #f9de5b;
+}
+.select-border1:hover {
+  border: 1px solid #f9de5b;
+  background-color: #f9de5b;
+  cursor: pointer;
+}
 </style>

+ 0 - 0
src/views/home/selectExamSubject/index.vue → src/views/home/selectDriveExamSubject/index.vue


+ 102 - 0
src/views/home/threeExam/index.vue

@@ -0,0 +1,102 @@
+<template>
+  <div class="content">
+    <div class="bg-white pl50 pt30">
+      <div class="flex items-center mb20">
+        <div class="vertical-line mr10"></div>
+        <span class="font20 font-bold mr15">练习技巧</span>
+
+        <div class="flex">
+          <div @click="goThreeExam" class="lh34 ml15 select-border1 round4 pr15 pl15">练习</div>
+        </div>
+        <div class="lh34 ml15 select-border1 round4 pr15 pl15">错误回顾</div>
+      </div>
+      <div class="flex items-center">
+        <div class="vertical-line mr10"></div>
+        <span class="font20 font-bold mr15">仿真模拟考试</span>
+
+        <div class="flex">
+          <div @click="goThreeExam" class="lh34 ml15 select-border1 round4 pr15 pl15">考试</div>
+        </div>
+        <div class="lh34 ml15 select-border1 round4 pr15 pl15">错误回顾</div>
+      </div>
+      <div class="flex items-center pt30 pb30">
+        <div class="vertical-line mr10"></div>
+        <span class="font20 font-bold mr15">全部错误题回顾</span>
+        <div class="lh34 round4 pr15 pl15 select-border1 mr15">错误回顾</div>
+        <div class="lh34 round4 pr15 pl15 select-border1">清空全部错题</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from "vue";
+
+export default defineComponent({
+  setup() {
+    return {
+
+    };
+  },
+  methods: {
+    goThreeExam() {
+      this.$router.push({
+        path: "/threeExam",
+        query: {
+         
+          ...this.$route.query,
+        },
+      });
+    },
+  },
+});
+</script>
+
+<style lang="scss" scoped>
+.select-border1 {
+  border: 1px solid #f9de5b;
+}
+.select-border2 {
+  border: 1px solid #f9de5b;
+}
+.select-border3 {
+  border: 1px solid #d8d8d8;
+}
+.select-border1:hover {
+  border: 1px solid #f9de5b;
+  background-color: #f9de5b;
+  cursor: pointer;
+}
+.select-border2:hover {
+  border: 1px solid #f9de5b;
+  background-color: rgba(255, 247, 204, 1);
+  cursor: pointer;
+}
+.radius4 {
+  border-radius: 4px;
+}
+.bg-primary-yellow {
+  background-color: #f9de5b;
+}
+.bg-light-yellow {
+  background: #fff7cc;
+}
+
+.w1603 {
+  width: 1603px;
+}
+
+.content {
+  padding: 0 30px;
+  padding-top: 21px;
+  padding-bottom: 30px;
+
+  .vertical-line {
+    width: 5px;
+    height: 20px;
+    background: #f9de5b;
+    border-radius: 4px 4px 4px 4px;
+    opacity: 1;
+  }
+}
+</style>

+ 29 - 3
src/views/login/index.vue

@@ -25,14 +25,18 @@
             <img class="preicon" src="@/assets/img/login/password_icon.png" />
             <input
               v-model="loginForm.password"
-              :checked="isSavePassword"
               placeholder="请输入密码"
               type="password"
               class="password"
             />
           </div>
           <div class="row mt20 flex justify-between">
-            <img class="w80 h30" v-if="codeUrl" :src="codeUrl" />
+            <img
+              @click="getCaptchaImage"
+              class="w80 h30 cursor-pointer"
+              v-if="codeUrl"
+              :src="codeUrl"
+            />
             <input
               @keydown.enter="loginByPassword"
               v-model="loginForm.code"
@@ -43,7 +47,11 @@
           </div>
 
           <div class="w-full save">
-            <input class="save-input" type="checkbox" />
+            <input
+              v-model="loginForm.rememberMe"
+              class="save-input"
+              type="checkbox"
+            />
             <span class="save-text">记住用户名和密码</span>
           </div>
           <div class="submit">
@@ -85,7 +93,9 @@
 <script lang="ts">
 import api from "@/api";
 import router from "@/router";
+import Cookies from "js-cookie";
 import { defineComponent, reactive, toRefs } from "vue";
+import { encrypt, decrypt } from '@/utils/jsencrypt'
 export default defineComponent({
   setup() {
     const state = reactive({
@@ -94,6 +104,7 @@ export default defineComponent({
       loginForm: {
         uuid: "",
         code: "",
+        rememberMe: false,
         username: "hc",
         password: "123456",
       },
@@ -103,9 +114,23 @@ export default defineComponent({
     };
   },
   mounted() {
+    this.getCookie()
     this.getCaptchaImage();
   },
   methods: {
+    getCookie() {
+      const username = Cookies.get("username");
+      const password = Cookies.get("password");
+      const rememberMe = Cookies.get("rememberMe");
+      this.loginForm = {
+        uuid:"",
+        code:'',
+        username: username === undefined ? this.loginForm.username : username,
+        password:
+          password === undefined ? this.loginForm.password : decrypt(password),
+        rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
+      };
+    },
     loginByPassword() {
       console.log("登录了");
       api.login.login(this.loginForm).then((res) => {
@@ -291,4 +316,5 @@ export default defineComponent({
 .bg-primary-darkyellow {
   background-color: #f2c900;
 }
+
 </style>

+ 362 - 0
src/views/threeExam/index.vue

@@ -0,0 +1,362 @@
+<template>
+  <div class="pt30 pb30 pr30 pl30 w100vw h100vh flex flex-col">
+    <div
+      class="w-full h-full flex content-start items-start border-gray-200 border flex-col"
+    >
+      <div class="w-full flex h440">
+        <div class="w215">
+          <div class="w-full h50 lh50 font-semibold">视频输入设备</div>
+          <div
+            class="w-full h50 lh50 font-semibold"
+            style="background-color: #fff5cc"
+          >
+            第1考台
+          </div>
+          <div class="pt30 pb30 pr45 pl45">
+            <img src="@/assets/img/driverExam/user_img.png" />
+          </div>
+          <div
+            style="background-color: #fff5cc"
+            class="pt20 pb20 text-left pl30"
+          >
+            <div class="font20 font-bold">姓名 中国驾考网</div>
+            <div class="font20 font-bold">性别 男</div>
+            <div class="font20 font-bold">车型 C1</div>
+            <div class="font20 font-bold">科目一理论考试</div>
+          </div>
+        </div>
+        <div class="w1196 flex-1">
+          <div style="background-color: #fff5cc" class="lh50 font-bold">
+            考试题目
+          </div>
+          <div class="text-left pr20 pl20 pt20">
+            <span class="font-bold"
+              >{{ listIndex + 1 }}、{{list[listIndex].issue}}</span
+            >
+          </div>
+          <div v-if="list[listIndex].questionType !== 1" class="mt30">
+            <div
+              v-for="(item, index) in list[listIndex].optsArr"
+              :key="index"
+              class="pl20 text-left font-bold"
+            >
+              <span>{{ switchIndexBySelect(index) }}</span> {{ item }}
+            </div>
+          </div>
+        </div>
+        <div class="w440 h440 bg-driver-exam">
+          <div class="w-full">
+            <div class="flex flex-wrap">
+              <div class="w40 lh40 bg-primary-yellow">题号</div>
+              <div
+                class="w40 lh40 bg-primary-yellow"
+                v-for="(item, index) in 10"
+                :key="index"
+              >
+                {{ index + 1 }}列
+              </div>
+            </div>
+
+            <div class="flex flex-col flex-wrap w-full h400 content-start">
+              <div class="w40 overflow-hidden flex flex-col">
+                <div
+                  class="w40 lh40 bg-primary-yellow"
+                  v-for="(item, index) in 10"
+                  :key="index"
+                >
+                  {{ index + 1 }}行
+                </div>
+              </div>
+              <div class="coll">
+                <!-- 侧边栏列表 -->
+                <table border="0" class="coll-table-topic">
+                  <tr :key="index" v-for="(item, index) in list.length / 10">
+                    <td
+                      v-for="(_item, _index) in 10"
+                      :class="{
+                        collselected: index * 10 + _index == listIndex,
+                      }"
+                      :data-key="index * 10 + _index + 1"
+                      :key="_index"
+                      @click="
+                        () => {
+                          listIndex = index * 10 + _index;
+                        }
+                      "
+                    >
+                      <div
+                        v-if="list[index * 10 + _index].questionType == 1"
+                        style="white-space: nowrap"
+                        :data-key="index * 10 + _index + 1"
+                        class="coll-table-topic-item text-black"
+                        :class="{
+                          'text-red': list[index * 10 + _index].isError,
+                        }"
+                      >
+                        {{ list[index * 10 + _index].userAnswer || "" }}
+                      </div>
+                      <div
+                        v-if="list[index * 10 + _index].questionType != 1"
+                        style="white-space: nowrap"
+                        :data-key="index * 10 + _index + 1"
+                        class="coll-table-topic-item text-black"
+                        :class="{
+                          'text-red': list[index * 10 + _index].isError,
+                        }"
+                      >
+                        {{
+                          switchAnswerBySelect(
+                            list[index * 10 + _index].userAnswer,
+                            index * 10 + _index
+                          )
+                        }}
+                      </div>
+                    </td>
+                  </tr>
+                </table>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="w-full bg-driver-exam h84 pl30 pr450 flex justify-between">
+        <div class="pt15 pb15 flex w500 text-left">
+          <div class="font-bold flex">
+            <div class="inline-block">
+              <div>剩余时间</div>
+              <div class="pl20">{{ countDown }}</div>
+            </div>
+
+            <div
+              v-if="list[listIndex].questionType == 1"
+              class="ml90 font-bold inline-block"
+            >
+              您选择的答案:{{ list[listIndex].userAnswer }}
+            </div>
+            <div
+              v-if="list[listIndex].questionType != 1"
+              class="ml90 font-bold inline-block"
+            >
+              您选择的答案:{{
+                switchAnswerBySelect(list[listIndex].userAnswer, listIndex)
+              }}
+            </div>
+          </div>
+        </div>
+        <div class="flex cursor-pointer mt20">
+          <!-- 答案列表 -->
+          <div
+            @click="list[listIndex].isComplete ? '' : setUserAnswer(_item)"
+            v-for="(_item, _index) in list[listIndex].optsArr"
+            :key="_index"
+            class="w46 lh46 h46 answer-select font20 font-bold mr15 flex-grow-0"
+          >
+            <span v-if="list[listIndex].questionType == 1">{{
+              switchIndexByJudge(_index)
+            }}</span>
+            <span v-if="list[listIndex].questionType !== 1">{{
+              switchIndexBySelect(_index)
+            }}</span>
+          </div>
+          <!-- <div class="w46 lh46 h46 answer-select font20 font-bold flex-grow-0">
+            ×
+          </div> -->
+        </div>
+      </div>
+      <div
+        class="border-b-gray-200 border-b w-full h84 text-left pr30 pl30 flex justify-between"
+      >
+        <div class="text-red-500 pt15 font-bold">
+          操作提示:{{ getProblemTypeName(list[listIndex].questionType) }}
+        </div>
+        <div class="flex h-full w390 items-center justify-between">
+          <div @click="preProblem()" class="w120 lh46 bottom-button">
+            上一题
+          </div>
+          <div @click="nextProblem()" class="w120 lh46 bottom-button">
+            下一题
+          </div>
+          <div
+            @click="
+              () => {
+                dialogVisible = true;
+              }
+            "
+            class="w120 lh46 bottom-button"
+          >
+            交卷
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="w-full pt15 h280 pb15 flex-1">
+      <div class="h-full">
+        <img
+          class="h-full mr-auto ml-auto"
+          v-if="list[listIndex].image"
+          :src="list[listIndex].image"
+        />
+      </div>
+    </div>
+
+    <mProblemAlert
+      v-model:visible="alertVisible"
+      title="开启"
+      content="禁止重复"
+    ></mProblemAlert>
+    <mProblemDialog
+      v-model:visible="dialogVisible"
+      title="提示"
+      content="是否真的要交卷(按确定键交卷,按取消键继续答题)"
+    ></mProblemDialog>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, ref, onMounted, watch } from "vue";
+import mProblemAlert from "@/components/mProblemAlert/index.vue";
+import mProblemDialog from "@/components/mProblemDialog/index.vue";
+import api from "@/api";
+import { openApi } from "@/api/open/type";
+import { useDriverExam } from "@/hooks/exam/driverExam";
+import { useRoute } from "vue-router";
+export default defineComponent({
+  name: "driverExam",
+  setup() {
+    const route = useRoute();
+    return {
+      alertVisible: ref(false),
+      dialogVisible: ref(false),
+      ...useDriverExam(
+        api.open.questionInfoSelectTestK14QuestionInfoList({
+          subject: Number(route.query.subject),
+          gs: route.query.gs as string,
+        })
+      ),
+    };
+  },
+
+  components: {
+    mProblemAlert,
+    mProblemDialog,
+  },
+});
+</script>
+
+<style lang="scss" scoped>
+.text-red {
+  color: red;
+}
+.pr23vw {
+  padding-right: 23vw;
+}
+.bottom-button {
+  text-align: center;
+  border: 1px solid #f9de5b;
+  cursor: pointer;
+}
+.bottom-button:hover {
+  background: #fff7cc;
+}
+
+.answer-select {
+  background: #fffdf2;
+
+  border: 1px solid #f9de5b;
+}
+.answer-select:hover {
+  background: #fff7cc;
+}
+.bg-driver-exam {
+  background: #f5f5f3;
+}
+.h100vh {
+  height: 100vh;
+}
+.w1196 {
+  width: 1196px;
+}
+.bg-primary-yellow {
+  background-color: #f9de5b;
+}
+
+.coll {
+  position: relative;
+  display: flex;
+  cursor: pointer;
+
+  .coll-header1 {
+    width: 231px;
+    height: 21px;
+    border-spacing: 0;
+    border-right: 1px solid #b8c0cc;
+    div {
+      box-sizing: border-box;
+    }
+    .coll-header1-row {
+      width: 21px;
+      height: 21px;
+      line-height: 21px;
+      background: #498ef5;
+      border-right: 1px solid #b8c0cc;
+      font-size: 10px;
+      white-space: nowrap;
+    }
+    // .coll-header1-row_border{
+    //   border-bottom: 1px solid #fff;
+    // }
+  }
+  .coll-header2 {
+    // position: absolute;
+    // top: 0px;
+    display: flex;
+    flex-direction: column;
+    flex-wrap: nowrap;
+    border-spacing: 0;
+    height: 237px;
+    width: 21px;
+
+    .coll-header2-col {
+      width: 23px;
+      height: 25px;
+      border-top: 1px solid #b8c0cc;
+      font-size: 10px;
+      line-height: 21px;
+      background: #498ef5;
+      white-space: nowrap;
+    }
+  }
+
+  .coll-table-topic {
+    background: #f2f3f5;
+    border-spacing: 0;
+    border-left: 1px solid #d2d1cf;
+    border-top: 1px solid #d2d1cf;
+    display: table;
+    td {
+      border-bottom: 1px solid #d2d1cf;
+      border-right: 1px solid #d2d1cf;
+
+      div {
+        font-size: 8px;
+        width: 39px;
+        height: 39px;
+        line-height: 39px;
+      }
+      // font-size: 12px;
+      .coll-table-topic-item {
+        border: none;
+
+        white-space: nowrap;
+        div {
+          white-space: nowrap;
+        }
+      }
+    }
+    .collselected {
+      background: #f9de5b;
+      color: #fff;
+    }
+  }
+}
+</style>

+ 1 - 0
tsconfig.json

@@ -7,6 +7,7 @@
     "moduleResolution": "node",
     "skipLibCheck": true,
     "esModuleInterop": true,
+    "noImplicitAny": false,
     "allowSyntheticDefaultImports": true,
     "forceConsistentCasingInFileNames": true,
     "useDefineForClassFields": true,