Browse Source

初次上传

wyling 3 years ago
commit
4f8d26f20e
81 changed files with 8562 additions and 0 deletions
  1. 5 0
      .gitignore
  2. 27 0
      README.md
  3. BIN
      dist.zip
  4. 16 0
      index.html
  5. 1537 0
      package-lock.json
  6. 32 0
      package.json
  7. 9 0
      postcss.config.js
  8. BIN
      public/favicon.ico
  9. BIN
      public/img/empty.png
  10. BIN
      public/img/考试合格.png
  11. 73 0
      public/markdown/README.md
  12. 173 0
      public/markdown/学车必看.json
  13. 156 0
      public/markdown/学车必看.md
  14. 397 0
      public/markdown/考前须知.json
  15. 93 0
      public/markdown/考前须知.md
  16. 48 0
      public/svg/分类练习.svg
  17. 61 0
      public/svg/地方专题.svg
  18. 59 0
      public/svg/学车必看.svg
  19. 54 0
      public/svg/模拟成绩.svg
  20. 31 0
      public/svg/模拟考试仿真题目.svg
  21. 44 0
      public/svg/真实考场模拟.svg
  22. 31 0
      public/svg/精选考题.svg
  23. 63 0
      public/svg/考前须知.svg
  24. 44 0
      public/svg/错题收藏.svg
  25. 44 0
      public/svg/顺序练习.svg
  26. 44 0
      src/App.vue
  27. 3 0
      src/api/index.ts
  28. 16 0
      src/api/modules/auth.ts
  29. 5 0
      src/api/modules/home.ts
  30. 63 0
      src/api/modules/test.ts
  31. 7 0
      src/api/request.ts
  32. BIN
      src/assets/img/bg.png
  33. BIN
      src/assets/img/car.png
  34. BIN
      src/assets/img/empty.png
  35. BIN
      src/assets/img/lx.png
  36. BIN
      src/assets/img/mb.png
  37. BIN
      src/assets/img/考试不合格.png
  38. BIN
      src/assets/img/考试合格.png
  39. BIN
      src/assets/logo.png
  40. 17 0
      src/components/index.ts
  41. 27 0
      src/components/m-button/index.vue
  42. 29 0
      src/components/m-empty/index.vue
  43. 539 0
      src/components/m-icon/demo.css
  44. 1178 0
      src/components/m-icon/demo_index.html
  45. 187 0
      src/components/m-icon/iconfont.css
  46. 0 0
      src/components/m-icon/iconfont.js
  47. 310 0
      src/components/m-icon/iconfont.json
  48. BIN
      src/components/m-icon/iconfont.ttf
  49. 32 0
      src/components/m-icon/index.vue
  50. 32 0
      src/components/m-nav-bar/index.vue
  51. 15 0
      src/components/m-user-avatar/index.vue
  52. 10 0
      src/components/m-user-name/index.vue
  53. 20 0
      src/main.ts
  54. 69 0
      src/route/index.ts
  55. 6 0
      src/shims-vue.d.ts
  56. 14 0
      src/store/index.ts
  57. 11 0
      src/utils/rem.ts
  58. 48 0
      src/views/classify/index.vue
  59. 206 0
      src/views/collection/index.vue
  60. 210 0
      src/views/exercise/hooks.ts
  61. 526 0
      src/views/exercise/index.vue
  62. 29 0
      src/views/home/children/find/children/find1/index.vue
  63. 29 0
      src/views/home/children/find/index.vue
  64. 160 0
      src/views/home/children/test/components/sujectOne.vue
  65. 25 0
      src/views/home/children/test/components/swiper.vue
  66. 36 0
      src/views/home/children/test/components/userData.vue
  67. 131 0
      src/views/home/children/test/index.vue
  68. 72 0
      src/views/home/children/user/index.vue
  69. 36 0
      src/views/home/index.vue
  70. 40 0
      src/views/login/index.vue
  71. 33 0
      src/views/marked/index copy.vue
  72. 158 0
      src/views/marked/index.vue
  73. 137 0
      src/views/mockTest/components/initMockTest.vue
  74. 101 0
      src/views/mockTest/components/mockTestEnd.vue
  75. 680 0
      src/views/mockTest/components/startTest.vue
  76. 29 0
      src/views/mockTest/index.vue
  77. 152 0
      src/views/testScores/index.vue
  78. 58 0
      src/views/topicType/index.vue
  79. 1 0
      src/vite-env.d.ts
  80. 18 0
      tsconfig.json
  81. 16 0
      vite.config.ts

+ 5 - 0
.gitignore

@@ -0,0 +1,5 @@
+node_modules
+.DS_Store
+dist
+dist-ssr
+*.local

+ 27 - 0
README.md

@@ -0,0 +1,27 @@
+# Vue 3 + Typescript + Vite
+
+This template should help get you started developing with Vue 3 and Typescript in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur). Make sure to enable `vetur.experimental.templateInterpolationService` in settings!
+
+### If Using `<script setup>`
+
+[`<script setup>`](https://github.com/vuejs/rfcs/pull/227) is a feature that is currently in RFC stage. To get proper IDE support for the syntax, use [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) instead of Vetur (and disable Vetur).
+
+## Type Support For `.vue` Imports in TS
+
+Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can use the following:
+
+### If Using Volar
+
+Run `Volar: Switch TS Plugin on/off` from VSCode command palette.
+
+### If Using Vetur
+
+1. Install and add `@vuedx/typescript-plugin-vue` to the [plugins section](https://www.typescriptlang.org/tsconfig#plugins) in `tsconfig.json`
+2. Delete `src/shims-vue.d.ts` as it is no longer needed to provide module info to Typescript
+3. Open `src/main.ts` in VSCode
+4. Open the VSCode command palette
+5. Search and run "Select TypeScript version" -> "Use workspace version"

BIN
dist.zip


+ 16 - 0
index.html

@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <link rel="icon" href="/favicon.ico" />
+    <meta
+      name="viewport"
+      content="width=device-width, initial-scale=1.0,maximum-scale=1.0,user-scalable=0"
+    />
+    <title>头文字D</title>
+  </head>
+  <body ontouchstart>
+    <div id="app"></div>
+    <script type="module" src="/src/main.ts"></script>
+  </body>
+</html>

+ 1537 - 0
package-lock.json

@@ -0,0 +1,1537 @@
+{
+  "name": "vue3-ts",
+  "version": "0.0.0",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "@babel/helper-validator-identifier": {
+      "version": "7.14.9",
+      "resolved": "https://registry.nlark.com/@babel/helper-validator-identifier/download/@babel/helper-validator-identifier-7.14.9.tgz?cache=0&sync_timestamp=1627804430461&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-validator-identifier%2Fdownload%2F%40babel%2Fhelper-validator-identifier-7.14.9.tgz",
+      "integrity": "sha1-ZlTRcbICT22O4VG/JQlpmRkTHUg="
+    },
+    "@babel/parser": {
+      "version": "7.15.0",
+      "resolved": "https://registry.nlark.com/@babel/parser/download/@babel/parser-7.15.0.tgz",
+      "integrity": "sha1-ttbikFjKNpEnsO7KKhxLV5Txtrk="
+    },
+    "@babel/types": {
+      "version": "7.15.0",
+      "resolved": "https://registry.nlark.com/@babel/types/download/@babel/types-7.15.0.tgz?cache=0&sync_timestamp=1628111608723&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.15.0.tgz",
+      "integrity": "sha1-Ya8R8ihsTpxpyo3rX0N1pzxy3L0=",
+      "requires": {
+        "@babel/helper-validator-identifier": "^7.14.9",
+        "to-fast-properties": "^2.0.0"
+      }
+    },
+    "@emmetio/abbreviation": {
+      "version": "2.2.2",
+      "resolved": "https://registry.nlark.com/@emmetio/abbreviation/download/@emmetio/abbreviation-2.2.2.tgz",
+      "integrity": "sha1-dGdi/Z56jC6mBPWAxi48/iUOaYk=",
+      "dev": true,
+      "requires": {
+        "@emmetio/scanner": "^1.0.0"
+      }
+    },
+    "@emmetio/css-abbreviation": {
+      "version": "2.1.4",
+      "resolved": "https://registry.nlark.com/@emmetio/css-abbreviation/download/@emmetio/css-abbreviation-2.1.4.tgz",
+      "integrity": "sha1-kDYuihEizjt29sMVeQfTAYL1P1Q=",
+      "dev": true,
+      "requires": {
+        "@emmetio/scanner": "^1.0.0"
+      }
+    },
+    "@emmetio/scanner": {
+      "version": "1.0.0",
+      "resolved": "https://registry.nlark.com/@emmetio/scanner/download/@emmetio/scanner-1.0.0.tgz",
+      "integrity": "sha1-Blsq9iM/50dNRII+PeuJckr0K18=",
+      "dev": true
+    },
+    "@fortawesome/fontawesome-common-types": {
+      "version": "0.2.36",
+      "resolved": "https://registry.nlark.com/@fortawesome/fontawesome-common-types/download/@fortawesome/fontawesome-common-types-0.2.36.tgz",
+      "integrity": "sha1-tE5S2ztrIFI+DFfvjELTFVMsuQM="
+    },
+    "@fortawesome/free-solid-svg-icons": {
+      "version": "5.15.4",
+      "resolved": "https://registry.nlark.com/@fortawesome/free-solid-svg-icons/download/@fortawesome/free-solid-svg-icons-5.15.4.tgz",
+      "integrity": "sha1-Kmjz/D3doS5SZFZUFCueTo+7bMU=",
+      "requires": {
+        "@fortawesome/fontawesome-common-types": "^0.2.36"
+      }
+    },
+    "@popperjs/core": {
+      "version": "2.9.3",
+      "resolved": "https://registry.nlark.com/@popperjs/core/download/@popperjs/core-2.9.3.tgz?cache=0&sync_timestamp=1628004507787&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40popperjs%2Fcore%2Fdownload%2F%40popperjs%2Fcore-2.9.3.tgz",
+      "integrity": "sha1-i2jaHr1/xgOZnPbr7jSkiZoUuI4="
+    },
+    "@types/createjs-lib": {
+      "version": "0.0.29",
+      "resolved": "https://registry.nlark.com/@types/createjs-lib/download/@types/createjs-lib-0.0.29.tgz",
+      "integrity": "sha1-+uguO6hgZmOxkOeJzsfZxyj8Qdc=",
+      "dev": true
+    },
+    "@types/estree": {
+      "version": "0.0.48",
+      "resolved": "https://registry.nlark.com/@types/estree/download/@types/estree-0.0.48.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Festree%2Fdownload%2F%40types%2Festree-0.0.48.tgz",
+      "integrity": "sha1-GNyAkbKF35DbLyWqfZBs/DlLf3Q=",
+      "dev": true
+    },
+    "@types/marked": {
+      "version": "3.0.1",
+      "resolved": "https://registry.nlark.com/@types/marked/download/@types/marked-3.0.1.tgz?cache=0&sync_timestamp=1631543903416&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fmarked%2Fdownload%2F%40types%2Fmarked-3.0.1.tgz",
+      "integrity": "sha1-dIZF7N4w2M94YcPhw2DG9pQXL5I=",
+      "dev": true
+    },
+    "@types/mockjs": {
+      "version": "1.0.4",
+      "resolved": "https://registry.nlark.com/@types/mockjs/download/@types/mockjs-1.0.4.tgz",
+      "integrity": "sha1-5waVHV4ztPCku3Ox+LEk4m8IHeA=",
+      "dev": true
+    },
+    "@types/preloadjs": {
+      "version": "0.6.32",
+      "resolved": "https://registry.nlark.com/@types/preloadjs/download/@types/preloadjs-0.6.32.tgz",
+      "integrity": "sha1-Es/3x/kuODingNQ4zknIzsmBgw0=",
+      "dev": true,
+      "requires": {
+        "@types/createjs-lib": "*"
+      }
+    },
+    "@types/soundjs": {
+      "version": "0.6.28",
+      "resolved": "https://registry.nlark.com/@types/soundjs/download/@types/soundjs-0.6.28.tgz",
+      "integrity": "sha1-z3SOkN149mw/VPq0FTb2CkLIwAI=",
+      "dev": true,
+      "requires": {
+        "@types/createjs-lib": "*",
+        "@types/preloadjs": "*"
+      }
+    },
+    "@vant/icons": {
+      "version": "1.7.0",
+      "resolved": "https://registry.nlark.com/@vant/icons/download/@vant/icons-1.7.0.tgz?cache=0&sync_timestamp=1626958553251&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40vant%2Ficons%2Fdownload%2F%40vant%2Ficons-1.7.0.tgz",
+      "integrity": "sha1-AtQnUyqBQsNdsVnanDZP5okMOsk="
+    },
+    "@vant/lazyload": {
+      "version": "1.2.0",
+      "resolved": "https://registry.nlark.com/@vant/lazyload/download/@vant/lazyload-1.2.0.tgz",
+      "integrity": "sha1-Yul3m9eEStj3HCyiv4UuYUfHqG0="
+    },
+    "@vant/popperjs": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/@vant/popperjs/download/@vant/popperjs-1.1.0.tgz",
+      "integrity": "sha1-tO3uW7+m+xhwWYbjE9T9XxeUKg8=",
+      "requires": {
+        "@popperjs/core": "^2.9.2"
+      }
+    },
+    "@vant/use": {
+      "version": "1.2.2",
+      "resolved": "https://registry.nlark.com/@vant/use/download/@vant/use-1.2.2.tgz",
+      "integrity": "sha1-ABzRZbgxya+bBSKS7Q2cuK9OBoI="
+    },
+    "@vitejs/plugin-vue": {
+      "version": "1.3.0",
+      "resolved": "https://registry.nlark.com/@vitejs/plugin-vue/download/@vitejs/plugin-vue-1.3.0.tgz?cache=0&sync_timestamp=1627380102462&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40vitejs%2Fplugin-vue%2Fdownload%2F%40vitejs%2Fplugin-vue-1.3.0.tgz",
+      "integrity": "sha1-/ImmybWlFXkWr+zk7cj7Vb8bvEI=",
+      "dev": true
+    },
+    "@volar/code-gen": {
+      "version": "0.26.11",
+      "resolved": "https://registry.nlark.com/@volar/code-gen/download/@volar/code-gen-0.26.11.tgz",
+      "integrity": "sha1-Q6qzVqMGW+zvScBxyy7HwusOQa8=",
+      "dev": true,
+      "requires": {
+        "@volar/shared": "^0.26.11",
+        "@volar/source-map": "^0.26.11"
+      }
+    },
+    "@volar/html2pug": {
+      "version": "0.26.11",
+      "resolved": "https://registry.nlark.com/@volar/html2pug/download/@volar/html2pug-0.26.11.tgz",
+      "integrity": "sha1-NAVmh2gqOreCHPFQqvpmyDkujp0=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "^2.2.0",
+        "domhandler": "^4.2.0",
+        "htmlparser2": "^6.1.0",
+        "pug": "^3.0.2"
+      }
+    },
+    "@volar/shared": {
+      "version": "0.26.11",
+      "resolved": "https://registry.nlark.com/@volar/shared/download/@volar/shared-0.26.11.tgz",
+      "integrity": "sha1-puVzRPAVEtjPK1rZ6W0k1D4DpEc=",
+      "dev": true,
+      "requires": {
+        "upath": "^2.0.1",
+        "vscode-jsonrpc": "^8.0.0-next.1"
+      }
+    },
+    "@volar/source-map": {
+      "version": "0.26.11",
+      "resolved": "https://registry.nlark.com/@volar/source-map/download/@volar/source-map-0.26.11.tgz",
+      "integrity": "sha1-zncl6Xvy93Q6tndbcDH0KYkZmAo=",
+      "dev": true,
+      "requires": {
+        "@volar/shared": "^0.26.11"
+      }
+    },
+    "@volar/transforms": {
+      "version": "0.26.11",
+      "resolved": "https://registry.nlark.com/@volar/transforms/download/@volar/transforms-0.26.11.tgz",
+      "integrity": "sha1-XfL/9LKg50HCcKs4hdE5rXTGtpk=",
+      "dev": true,
+      "requires": {
+        "@volar/shared": "^0.26.11"
+      }
+    },
+    "@vue/compiler-core": {
+      "version": "3.1.5",
+      "resolved": "https://registry.nlark.com/@vue/compiler-core/download/@vue/compiler-core-3.1.5.tgz",
+      "integrity": "sha1-KY+QW2Bl1tgf9jdW+Yxgh2s5PIc=",
+      "requires": {
+        "@babel/parser": "^7.12.0",
+        "@babel/types": "^7.12.0",
+        "@vue/shared": "3.1.5",
+        "estree-walker": "^2.0.1",
+        "source-map": "^0.6.1"
+      }
+    },
+    "@vue/compiler-dom": {
+      "version": "3.1.5",
+      "resolved": "https://registry.nlark.com/@vue/compiler-dom/download/@vue/compiler-dom-3.1.5.tgz",
+      "integrity": "sha1-y7lwIMYqX6o/vCqXkWvZgEGsmFY=",
+      "requires": {
+        "@vue/compiler-core": "3.1.5",
+        "@vue/shared": "3.1.5"
+      }
+    },
+    "@vue/compiler-sfc": {
+      "version": "3.1.5",
+      "resolved": "https://registry.nlark.com/@vue/compiler-sfc/download/@vue/compiler-sfc-3.1.5.tgz",
+      "integrity": "sha1-5h5U86ljsPSo5SP7uGMjkNxSsNY=",
+      "dev": true,
+      "requires": {
+        "@babel/parser": "^7.13.9",
+        "@babel/types": "^7.13.0",
+        "@types/estree": "^0.0.48",
+        "@vue/compiler-core": "3.1.5",
+        "@vue/compiler-dom": "3.1.5",
+        "@vue/compiler-ssr": "3.1.5",
+        "@vue/shared": "3.1.5",
+        "consolidate": "^0.16.0",
+        "estree-walker": "^2.0.1",
+        "hash-sum": "^2.0.0",
+        "lru-cache": "^5.1.1",
+        "magic-string": "^0.25.7",
+        "merge-source-map": "^1.1.0",
+        "postcss": "^8.1.10",
+        "postcss-modules": "^4.0.0",
+        "postcss-selector-parser": "^6.0.4",
+        "source-map": "^0.6.1"
+      }
+    },
+    "@vue/compiler-ssr": {
+      "version": "3.1.5",
+      "resolved": "https://registry.nlark.com/@vue/compiler-ssr/download/@vue/compiler-ssr-3.1.5.tgz",
+      "integrity": "sha1-8GhlJ3QpMlah5TCEvtSKZ2gt+dI=",
+      "dev": true,
+      "requires": {
+        "@vue/compiler-dom": "3.1.5",
+        "@vue/shared": "3.1.5"
+      }
+    },
+    "@vue/devtools-api": {
+      "version": "6.0.0-beta.15",
+      "resolved": "https://registry.nlark.com/@vue/devtools-api/download/@vue/devtools-api-6.0.0-beta.15.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40vue%2Fdevtools-api%2Fdownload%2F%40vue%2Fdevtools-api-6.0.0-beta.15.tgz",
+      "integrity": "sha1-rXyzhOBi8WW8+cg3MhJb/7wq2D0="
+    },
+    "@vue/reactivity": {
+      "version": "3.1.5",
+      "resolved": "https://registry.nlark.com/@vue/reactivity/download/@vue/reactivity-3.1.5.tgz",
+      "integrity": "sha1-2+xNlVf3yPJcJjXbHiOninKeuZE=",
+      "requires": {
+        "@vue/shared": "3.1.5"
+      }
+    },
+    "@vue/runtime-core": {
+      "version": "3.1.5",
+      "resolved": "https://registry.nlark.com/@vue/runtime-core/download/@vue/runtime-core-3.1.5.tgz",
+      "integrity": "sha1-pUW38UYJKSnLXoM+hUORUPF6yHs=",
+      "requires": {
+        "@vue/reactivity": "3.1.5",
+        "@vue/shared": "3.1.5"
+      }
+    },
+    "@vue/runtime-dom": {
+      "version": "3.1.5",
+      "resolved": "https://registry.nlark.com/@vue/runtime-dom/download/@vue/runtime-dom-3.1.5.tgz",
+      "integrity": "sha1-T6KJR9QIqjaPoX6g7cG+ua8UcqE=",
+      "requires": {
+        "@vue/runtime-core": "3.1.5",
+        "@vue/shared": "3.1.5",
+        "csstype": "^2.6.8"
+      }
+    },
+    "@vue/shared": {
+      "version": "3.1.5",
+      "resolved": "https://registry.nlark.com/@vue/shared/download/@vue/shared-3.1.5.tgz",
+      "integrity": "sha1-dO46rZldCjmWpruVM9TSgFFO3gM="
+    },
+    "acorn": {
+      "version": "7.4.1",
+      "resolved": "https://registry.nlark.com/acorn/download/acorn-7.4.1.tgz",
+      "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=",
+      "dev": true
+    },
+    "anymatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.nlark.com/anymatch/download/anymatch-3.1.2.tgz",
+      "integrity": "sha1-wFV8CWrzLxBhmPT04qODU343hxY=",
+      "dev": true,
+      "requires": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      }
+    },
+    "asap": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npm.taobao.org/asap/download/asap-2.0.6.tgz",
+      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
+      "dev": true
+    },
+    "assert-never": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npm.taobao.org/assert-never/download/assert-never-1.2.1.tgz",
+      "integrity": "sha1-EfDjY78UYgX7CBk7XHuQ9NHPRP4=",
+      "dev": true
+    },
+    "axios": {
+      "version": "0.21.1",
+      "resolved": "https://registry.npm.taobao.org/axios/download/axios-0.21.1.tgz?cache=0&sync_timestamp=1608609215811&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.21.1.tgz",
+      "integrity": "sha1-IlY0gZYvTWvemnbVFu8OXTwJsrg=",
+      "requires": {
+        "follow-redirects": "^1.10.0"
+      }
+    },
+    "babel-walk": {
+      "version": "3.0.0-canary-5",
+      "resolved": "https://registry.npm.taobao.org/babel-walk/download/babel-walk-3.0.0-canary-5.tgz",
+      "integrity": "sha1-9m7Ncpg1eu5ElV8jWm71QhkQSxE=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.9.6"
+      }
+    },
+    "big.js": {
+      "version": "5.2.2",
+      "resolved": "https://registry.nlark.com/big.js/download/big.js-5.2.2.tgz?cache=0&sync_timestamp=1620132748267&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fbig.js%2Fdownload%2Fbig.js-5.2.2.tgz",
+      "integrity": "sha1-ZfCvOC9Xi83HQr2cKB6cstd2gyg=",
+      "dev": true
+    },
+    "binary-extensions": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npm.taobao.org/binary-extensions/download/binary-extensions-2.2.0.tgz?cache=0&sync_timestamp=1610299308660&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbinary-extensions%2Fdownload%2Fbinary-extensions-2.2.0.tgz",
+      "integrity": "sha1-dfUC7q+f/eQvyYgpZFvk6na9ni0=",
+      "dev": true
+    },
+    "bluebird": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npm.taobao.org/bluebird/download/bluebird-3.7.2.tgz",
+      "integrity": "sha1-nyKcFb4nJFT/qXOs4NvueaGww28=",
+      "dev": true
+    },
+    "braces": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npm.taobao.org/braces/download/braces-3.0.2.tgz",
+      "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=",
+      "dev": true,
+      "requires": {
+        "fill-range": "^7.0.1"
+      }
+    },
+    "call-bind": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/call-bind/download/call-bind-1.0.2.tgz",
+      "integrity": "sha1-sdTonmiBGcPJqQOtMKuy9qkZvjw=",
+      "dev": true,
+      "requires": {
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.2"
+      }
+    },
+    "character-parser": {
+      "version": "2.2.0",
+      "resolved": "https://registry.nlark.com/character-parser/download/character-parser-2.2.0.tgz",
+      "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=",
+      "dev": true,
+      "requires": {
+        "is-regex": "^1.0.3"
+      }
+    },
+    "chokidar": {
+      "version": "3.5.2",
+      "resolved": "https://registry.nlark.com/chokidar/download/chokidar-3.5.2.tgz",
+      "integrity": "sha1-26OXb8rbAW9m/TZQIdkWANAcHnU=",
+      "dev": true,
+      "requires": {
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "fsevents": "~2.3.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
+      }
+    },
+    "colorette": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npm.taobao.org/colorette/download/colorette-1.2.2.tgz?cache=0&sync_timestamp=1614259623635&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcolorette%2Fdownload%2Fcolorette-1.2.2.tgz",
+      "integrity": "sha1-y8x51emcrqLb8Q6zom/Ys+as+pQ=",
+      "dev": true
+    },
+    "commander": {
+      "version": "8.1.0",
+      "resolved": "https://registry.nlark.com/commander/download/commander-8.1.0.tgz?cache=0&sync_timestamp=1627358254258&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcommander%2Fdownload%2Fcommander-8.1.0.tgz",
+      "integrity": "sha1-2zbj5m7fJP9ZHWOYYsarLFJmQ2I="
+    },
+    "consolidate": {
+      "version": "0.16.0",
+      "resolved": "https://registry.npm.taobao.org/consolidate/download/consolidate-0.16.0.tgz?cache=0&sync_timestamp=1599596647062&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconsolidate%2Fdownload%2Fconsolidate-0.16.0.tgz",
+      "integrity": "sha1-oRhkdokw8vGUMWYKZZBmaPX73BY=",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.7.2"
+      }
+    },
+    "constantinople": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npm.taobao.org/constantinople/download/constantinople-4.0.1.tgz",
+      "integrity": "sha1-De8RP6Dk3I3oMzGlz3nIsyUhMVE=",
+      "dev": true,
+      "requires": {
+        "@babel/parser": "^7.6.0",
+        "@babel/types": "^7.6.1"
+      }
+    },
+    "cookie-storage": {
+      "version": "6.1.0",
+      "resolved": "https://registry.nlark.com/cookie-storage/download/cookie-storage-6.1.0.tgz",
+      "integrity": "sha1-KRsvZi2WG+RPmZYmWTQhy/zyN5A="
+    },
+    "copy-text-to-clipboard": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npm.taobao.org/copy-text-to-clipboard/download/copy-text-to-clipboard-3.0.1.tgz",
+      "integrity": "sha1-jL+PkOCkfxLkokdDc2Jl0Ve85pw="
+    },
+    "core-js": {
+      "version": "3.16.1",
+      "resolved": "https://registry.nlark.com/core-js/download/core-js-3.16.1.tgz",
+      "integrity": "sha1-9Ehc5cnzxqfLGPqASI4I02IJckk="
+    },
+    "cssesc": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/cssesc/download/cssesc-3.0.0.tgz",
+      "integrity": "sha1-N3QZGZA7hoVl4cCep0dEXNGJg+4=",
+      "dev": true
+    },
+    "csstype": {
+      "version": "2.6.17",
+      "resolved": "https://registry.nlark.com/csstype/download/csstype-2.6.17.tgz",
+      "integrity": "sha1-TPMOuH4dGgBdi2UQ+VKSQT9qHA4="
+    },
+    "doctypes": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/doctypes/download/doctypes-1.1.0.tgz",
+      "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=",
+      "dev": true
+    },
+    "dom-serializer": {
+      "version": "1.3.2",
+      "resolved": "https://registry.nlark.com/dom-serializer/download/dom-serializer-1.3.2.tgz?cache=0&sync_timestamp=1621256918158&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdom-serializer%2Fdownload%2Fdom-serializer-1.3.2.tgz",
+      "integrity": "sha1-YgZDfTLO767HFhgDIwx6ILwbTZE=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "^2.0.1",
+        "domhandler": "^4.2.0",
+        "entities": "^2.0.0"
+      }
+    },
+    "domelementtype": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npm.taobao.org/domelementtype/download/domelementtype-2.2.0.tgz",
+      "integrity": "sha1-mgtsJ4LtahxzI9QiZxg9+b2LHVc=",
+      "dev": true
+    },
+    "domhandler": {
+      "version": "4.2.0",
+      "resolved": "https://registry.nlark.com/domhandler/download/domhandler-4.2.0.tgz",
+      "integrity": "sha1-+XaKXwNL5gqJonwuTQ9066DYsFk=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "^2.2.0"
+      }
+    },
+    "domutils": {
+      "version": "2.7.0",
+      "resolved": "https://registry.nlark.com/domutils/download/domutils-2.7.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdomutils%2Fdownload%2Fdomutils-2.7.0.tgz",
+      "integrity": "sha1-jrrwxB66/PVbC3LsMcVjI3EsVEI=",
+      "dev": true,
+      "requires": {
+        "dom-serializer": "^1.0.1",
+        "domelementtype": "^2.2.0",
+        "domhandler": "^4.2.0"
+      }
+    },
+    "emmet": {
+      "version": "2.3.4",
+      "resolved": "https://registry.nlark.com/emmet/download/emmet-2.3.4.tgz",
+      "integrity": "sha1-W6DXpVaaaMdpffqJDHcuTzF50SM=",
+      "dev": true,
+      "requires": {
+        "@emmetio/abbreviation": "^2.2.2",
+        "@emmetio/css-abbreviation": "^2.1.4"
+      }
+    },
+    "emojis-list": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/emojis-list/download/emojis-list-3.0.0.tgz",
+      "integrity": "sha1-VXBmIEatKeLpFucariYKvf9Pang=",
+      "dev": true
+    },
+    "entities": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npm.taobao.org/entities/download/entities-2.2.0.tgz?cache=0&sync_timestamp=1611535711703&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fentities%2Fdownload%2Fentities-2.2.0.tgz",
+      "integrity": "sha1-CY3JDruD2N/6CJ1VJWs1HTTE2lU=",
+      "dev": true
+    },
+    "esbuild": {
+      "version": "0.12.17",
+      "resolved": "https://registry.nlark.com/esbuild/download/esbuild-0.12.17.tgz",
+      "integrity": "sha1-WBb5BcKQXeDrvGWIYN97W0ivvNM=",
+      "dev": true
+    },
+    "estree-walker": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npm.taobao.org/estree-walker/download/estree-walker-2.0.2.tgz",
+      "integrity": "sha1-UvAQF4wqTBF6d1fP6UKtt9LaTKw="
+    },
+    "fill-range": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-7.0.1.tgz",
+      "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=",
+      "dev": true,
+      "requires": {
+        "to-regex-range": "^5.0.1"
+      }
+    },
+    "follow-redirects": {
+      "version": "1.14.1",
+      "resolved": "https://registry.nlark.com/follow-redirects/download/follow-redirects-1.14.1.tgz?cache=0&sync_timestamp=1620555292056&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.14.1.tgz",
+      "integrity": "sha1-2RFN7Qoc/dM04WTmZirQK/2R/0M="
+    },
+    "fsevents": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npm.taobao.org/fsevents/download/fsevents-2.3.2.tgz?cache=0&sync_timestamp=1612537044236&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffsevents%2Fdownload%2Ffsevents-2.3.2.tgz",
+      "integrity": "sha1-ilJveLj99GI7cJ4Ll1xSwkwC/Ro=",
+      "dev": true,
+      "optional": true
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/function-bind/download/function-bind-1.1.1.tgz",
+      "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=",
+      "dev": true
+    },
+    "generic-names": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npm.taobao.org/generic-names/download/generic-names-2.0.1.tgz?cache=0&sync_timestamp=1603542764418&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fgeneric-names%2Fdownload%2Fgeneric-names-2.0.1.tgz",
+      "integrity": "sha1-+KN46tLMqno08DF7BVVIMq5BuHI=",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0"
+      }
+    },
+    "get-intrinsic": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/get-intrinsic/download/get-intrinsic-1.1.1.tgz",
+      "integrity": "sha1-FfWfN2+FXERpY5SPDSTNNje0q8Y=",
+      "dev": true,
+      "requires": {
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1"
+      }
+    },
+    "glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.nlark.com/glob-parent/download/glob-parent-5.1.2.tgz?cache=0&sync_timestamp=1626760165717&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fglob-parent%2Fdownload%2Fglob-parent-5.1.2.tgz",
+      "integrity": "sha1-hpgyxYA0/mikCTwX3BXoNA2EAcQ=",
+      "dev": true,
+      "requires": {
+        "is-glob": "^4.0.1"
+      }
+    },
+    "has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npm.taobao.org/has/download/has-1.0.3.tgz",
+      "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=",
+      "dev": true,
+      "requires": {
+        "function-bind": "^1.1.1"
+      }
+    },
+    "has-symbols": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/has-symbols/download/has-symbols-1.0.2.tgz?cache=0&sync_timestamp=1614443557459&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-symbols%2Fdownload%2Fhas-symbols-1.0.2.tgz",
+      "integrity": "sha1-Fl0wcMADCXUqEjakeTMeOsVvFCM=",
+      "dev": true
+    },
+    "hash-sum": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/hash-sum/download/hash-sum-2.0.0.tgz",
+      "integrity": "sha1-gdAbtd6OpKIUrV1urRtSNGCwtFo=",
+      "dev": true
+    },
+    "htmlparser2": {
+      "version": "6.1.0",
+      "resolved": "https://registry.nlark.com/htmlparser2/download/htmlparser2-6.1.0.tgz",
+      "integrity": "sha1-xNditsM3GgXb5l6UrkOp+EX7j7c=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "^2.0.1",
+        "domhandler": "^4.0.0",
+        "domutils": "^2.5.2",
+        "entities": "^2.0.0"
+      }
+    },
+    "icss-replace-symbols": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/icss-replace-symbols/download/icss-replace-symbols-1.1.0.tgz",
+      "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=",
+      "dev": true
+    },
+    "icss-utils": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npm.taobao.org/icss-utils/download/icss-utils-5.1.0.tgz?cache=0&sync_timestamp=1605801291394&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ficss-utils%2Fdownload%2Ficss-utils-5.1.0.tgz",
+      "integrity": "sha1-xr5oWKvQE9do6YNmrkfiXViHsa4=",
+      "dev": true
+    },
+    "is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npm.taobao.org/is-binary-path/download/is-binary-path-2.1.0.tgz",
+      "integrity": "sha1-6h9/O4DwZCNug0cPhsCcJU+0Wwk=",
+      "dev": true,
+      "requires": {
+        "binary-extensions": "^2.0.0"
+      }
+    },
+    "is-core-module": {
+      "version": "2.5.0",
+      "resolved": "https://registry.nlark.com/is-core-module/download/is-core-module-2.5.0.tgz",
+      "integrity": "sha1-91SENhfHC/0pt72HMnQAzaXBhJE=",
+      "dev": true,
+      "requires": {
+        "has": "^1.0.3"
+      }
+    },
+    "is-expression": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npm.taobao.org/is-expression/download/is-expression-4.0.0.tgz",
+      "integrity": "sha1-wzFVliq/IdCv0lUlFNZ9LsFv0qs=",
+      "dev": true,
+      "requires": {
+        "acorn": "^7.1.1",
+        "object-assign": "^4.1.1"
+      }
+    },
+    "is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npm.taobao.org/is-extglob/download/is-extglob-2.1.1.tgz",
+      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "dev": true
+    },
+    "is-glob": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npm.taobao.org/is-glob/download/is-glob-4.0.1.tgz",
+      "integrity": "sha1-dWfb6fL14kZ7x3q4PEopSCQHpdw=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "^2.1.1"
+      }
+    },
+    "is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz",
+      "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=",
+      "dev": true
+    },
+    "is-promise": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npm.taobao.org/is-promise/download/is-promise-2.2.2.tgz",
+      "integrity": "sha1-OauVnMv5p3TPB597QMeib3YxNfE=",
+      "dev": true
+    },
+    "is-regex": {
+      "version": "1.1.3",
+      "resolved": "https://registry.nlark.com/is-regex/download/is-regex-1.1.3.tgz?cache=0&sync_timestamp=1620452285370&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fis-regex%2Fdownload%2Fis-regex-1.1.3.tgz",
+      "integrity": "sha1-0Cn5r/ZEi5Prvj8z2scVEf3L758=",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.2",
+        "has-symbols": "^1.0.2"
+      }
+    },
+    "js-stringify": {
+      "version": "1.0.2",
+      "resolved": "https://registry.nlark.com/js-stringify/download/js-stringify-1.0.2.tgz",
+      "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=",
+      "dev": true
+    },
+    "json5": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/json5/download/json5-1.0.1.tgz?cache=0&sync_timestamp=1612146215945&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-1.0.1.tgz",
+      "integrity": "sha1-d5+wAYYE+oVOrL9iUhgNg1Q+Pb4=",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.2.0"
+      }
+    },
+    "jsonc-parser": {
+      "version": "3.0.0",
+      "resolved": "https://registry.nlark.com/jsonc-parser/download/jsonc-parser-3.0.0.tgz",
+      "integrity": "sha1-q914VwHH5+rKip7IzwcMpRp0WiI=",
+      "dev": true
+    },
+    "jstransformer": {
+      "version": "1.0.0",
+      "resolved": "https://registry.nlark.com/jstransformer/download/jstransformer-1.0.0.tgz",
+      "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=",
+      "dev": true,
+      "requires": {
+        "is-promise": "^2.0.0",
+        "promise": "^7.0.1"
+      }
+    },
+    "loader-utils": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-1.4.0.tgz",
+      "integrity": "sha1-xXm140yzSxp07cbB+za/o3HVphM=",
+      "dev": true,
+      "requires": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^3.0.0",
+        "json5": "^1.0.1"
+      }
+    },
+    "lodash.camelcase": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npm.taobao.org/lodash.camelcase/download/lodash.camelcase-4.3.0.tgz",
+      "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
+      "dev": true
+    },
+    "lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npm.taobao.org/lru-cache/download/lru-cache-5.1.1.tgz?cache=0&sync_timestamp=1599054167787&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flru-cache%2Fdownload%2Flru-cache-5.1.1.tgz",
+      "integrity": "sha1-HaJ+ZxAnGUdpXa9oSOhH8B2EuSA=",
+      "dev": true,
+      "requires": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "magic-string": {
+      "version": "0.25.7",
+      "resolved": "https://registry.npm.taobao.org/magic-string/download/magic-string-0.25.7.tgz",
+      "integrity": "sha1-P0l9b9NMZpxnmNy4IfLvMfVEUFE=",
+      "dev": true,
+      "requires": {
+        "sourcemap-codec": "^1.4.4"
+      }
+    },
+    "marked": {
+      "version": "3.0.4",
+      "resolved": "https://registry.nlark.com/marked/download/marked-3.0.4.tgz?cache=0&sync_timestamp=1631641917711&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fmarked%2Fdownload%2Fmarked-3.0.4.tgz",
+      "integrity": "sha1-uKFTnl4Fxuqek/FcC60dVM6JBAY="
+    },
+    "merge-source-map": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/merge-source-map/download/merge-source-map-1.1.0.tgz",
+      "integrity": "sha1-L93n5gIJOfcJBqaPLXrmheTIxkY=",
+      "dev": true,
+      "requires": {
+        "source-map": "^0.6.1"
+      }
+    },
+    "minimist": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npm.taobao.org/minimist/download/minimist-1.2.5.tgz",
+      "integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI=",
+      "dev": true
+    },
+    "mockjs": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/mockjs/download/mockjs-1.1.0.tgz",
+      "integrity": "sha1-5qDDeOkZBtuv8gkRzAJzs8fXWwY=",
+      "requires": {
+        "commander": "*"
+      }
+    },
+    "mutation-observer": {
+      "version": "1.0.3",
+      "resolved": "https://registry.nlark.com/mutation-observer/download/mutation-observer-1.0.3.tgz",
+      "integrity": "sha1-QukiKxAbyoLlup1aes9KFMDyY9A="
+    },
+    "nanoid": {
+      "version": "3.1.23",
+      "resolved": "https://registry.nlark.com/nanoid/download/nanoid-3.1.23.tgz?cache=0&sync_timestamp=1620673983269&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fnanoid%2Fdownload%2Fnanoid-3.1.23.tgz",
+      "integrity": "sha1-90QIbOfCvEfuCoRyV01ceOQYOoE=",
+      "dev": true
+    },
+    "normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/normalize-path/download/normalize-path-3.0.0.tgz",
+      "integrity": "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU=",
+      "dev": true
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "dev": true
+    },
+    "path-parse": {
+      "version": "1.0.7",
+      "resolved": "https://registry.nlark.com/path-parse/download/path-parse-1.0.7.tgz",
+      "integrity": "sha1-+8EUtgykKzDZ2vWFjkvWi77bZzU=",
+      "dev": true
+    },
+    "picomatch": {
+      "version": "2.3.0",
+      "resolved": "https://registry.nlark.com/picomatch/download/picomatch-2.3.0.tgz?cache=0&sync_timestamp=1621648246651&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fpicomatch%2Fdownload%2Fpicomatch-2.3.0.tgz",
+      "integrity": "sha1-8fBh3o9qS/AiiS4tEoI0+5gwKXI=",
+      "dev": true
+    },
+    "postcss": {
+      "version": "8.3.6",
+      "resolved": "https://registry.nlark.com/postcss/download/postcss-8.3.6.tgz?cache=0&sync_timestamp=1626882933935&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fpostcss%2Fdownload%2Fpostcss-8.3.6.tgz",
+      "integrity": "sha1-JzDddql5afN/U7mmCWGXvjEcxOo=",
+      "dev": true,
+      "requires": {
+        "colorette": "^1.2.2",
+        "nanoid": "^3.1.23",
+        "source-map-js": "^0.6.2"
+      }
+    },
+    "postcss-modules": {
+      "version": "4.2.2",
+      "resolved": "https://registry.nlark.com/postcss-modules/download/postcss-modules-4.2.2.tgz?cache=0&sync_timestamp=1627039460598&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fpostcss-modules%2Fdownload%2Fpostcss-modules-4.2.2.tgz",
+      "integrity": "sha1-Xnd3xaiWTqF2kZ2QsuVO+JEyHOU=",
+      "dev": true,
+      "requires": {
+        "generic-names": "^2.0.1",
+        "icss-replace-symbols": "^1.1.0",
+        "lodash.camelcase": "^4.3.0",
+        "postcss-modules-extract-imports": "^3.0.0",
+        "postcss-modules-local-by-default": "^4.0.0",
+        "postcss-modules-scope": "^3.0.0",
+        "postcss-modules-values": "^4.0.0",
+        "string-hash": "^1.1.1"
+      }
+    },
+    "postcss-modules-extract-imports": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/postcss-modules-extract-imports/download/postcss-modules-extract-imports-3.0.0.tgz?cache=0&sync_timestamp=1602588245463&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-extract-imports%2Fdownload%2Fpostcss-modules-extract-imports-3.0.0.tgz",
+      "integrity": "sha1-zaHwR8CugMl9vijD52pDuIAldB0=",
+      "dev": true
+    },
+    "postcss-modules-local-by-default": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npm.taobao.org/postcss-modules-local-by-default/download/postcss-modules-local-by-default-4.0.0.tgz?cache=0&sync_timestamp=1602587568476&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-local-by-default%2Fdownload%2Fpostcss-modules-local-by-default-4.0.0.tgz",
+      "integrity": "sha1-67tU+uFZjuz99pGgKz/zs5ClpRw=",
+      "dev": true,
+      "requires": {
+        "icss-utils": "^5.0.0",
+        "postcss-selector-parser": "^6.0.2",
+        "postcss-value-parser": "^4.1.0"
+      }
+    },
+    "postcss-modules-scope": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/postcss-modules-scope/download/postcss-modules-scope-3.0.0.tgz?cache=0&sync_timestamp=1602593260387&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-scope%2Fdownload%2Fpostcss-modules-scope-3.0.0.tgz",
+      "integrity": "sha1-nvMVFFbTu/oSDKRImN/Kby+gHwY=",
+      "dev": true,
+      "requires": {
+        "postcss-selector-parser": "^6.0.4"
+      }
+    },
+    "postcss-modules-values": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npm.taobao.org/postcss-modules-values/download/postcss-modules-values-4.0.0.tgz?cache=0&sync_timestamp=1602586230505&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-values%2Fdownload%2Fpostcss-modules-values-4.0.0.tgz",
+      "integrity": "sha1-18Xn5ow7s8myfL9Iyguz/7RgLJw=",
+      "dev": true,
+      "requires": {
+        "icss-utils": "^5.0.0"
+      }
+    },
+    "postcss-pxtorem": {
+      "version": "6.0.0",
+      "resolved": "https://registry.nlark.com/postcss-pxtorem/download/postcss-pxtorem-6.0.0.tgz",
+      "integrity": "sha1-8iik0F2Kc/BkLquulQ4rGYNjZtc=",
+      "dev": true
+    },
+    "postcss-selector-parser": {
+      "version": "6.0.6",
+      "resolved": "https://registry.nlark.com/postcss-selector-parser/download/postcss-selector-parser-6.0.6.tgz?cache=0&sync_timestamp=1620752924836&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fpostcss-selector-parser%2Fdownload%2Fpostcss-selector-parser-6.0.6.tgz",
+      "integrity": "sha1-LFu6gXSsL2mBq2MaQqsO5UrzMuo=",
+      "dev": true,
+      "requires": {
+        "cssesc": "^3.0.0",
+        "util-deprecate": "^1.0.2"
+      }
+    },
+    "postcss-value-parser": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-4.1.0.tgz",
+      "integrity": "sha1-RD9qIM7WSBor2k+oUypuVdeJoss=",
+      "dev": true
+    },
+    "promise": {
+      "version": "7.3.1",
+      "resolved": "https://registry.npm.taobao.org/promise/download/promise-7.3.1.tgz",
+      "integrity": "sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078=",
+      "dev": true,
+      "requires": {
+        "asap": "~2.0.3"
+      }
+    },
+    "pug": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npm.taobao.org/pug/download/pug-3.0.2.tgz",
+      "integrity": "sha1-81xxBzQ0VOQ7wnrg/3bHMbeOpTU=",
+      "dev": true,
+      "requires": {
+        "pug-code-gen": "^3.0.2",
+        "pug-filters": "^4.0.0",
+        "pug-lexer": "^5.0.1",
+        "pug-linker": "^4.0.0",
+        "pug-load": "^3.0.0",
+        "pug-parser": "^6.0.0",
+        "pug-runtime": "^3.0.1",
+        "pug-strip-comments": "^2.0.0"
+      }
+    },
+    "pug-attrs": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/pug-attrs/download/pug-attrs-3.0.0.tgz",
+      "integrity": "sha1-sQRR4DSBZeMfrRzCPr3dncc0fEE=",
+      "dev": true,
+      "requires": {
+        "constantinople": "^4.0.1",
+        "js-stringify": "^1.0.2",
+        "pug-runtime": "^3.0.0"
+      }
+    },
+    "pug-code-gen": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npm.taobao.org/pug-code-gen/download/pug-code-gen-3.0.2.tgz",
+      "integrity": "sha1-rRkPSUMTO/GGtguA3kgxAOEy4s4=",
+      "dev": true,
+      "requires": {
+        "constantinople": "^4.0.1",
+        "doctypes": "^1.1.0",
+        "js-stringify": "^1.0.2",
+        "pug-attrs": "^3.0.0",
+        "pug-error": "^2.0.0",
+        "pug-runtime": "^3.0.0",
+        "void-elements": "^3.1.0",
+        "with": "^7.0.0"
+      }
+    },
+    "pug-error": {
+      "version": "2.0.0",
+      "resolved": "https://registry.nlark.com/pug-error/download/pug-error-2.0.0.tgz",
+      "integrity": "sha1-XGIXPLCcNN4qLOBPF7it/sdNjKU=",
+      "dev": true
+    },
+    "pug-filters": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npm.taobao.org/pug-filters/download/pug-filters-4.0.0.tgz",
+      "integrity": "sha1-0+Sa9bqEcum3pm2YDnB86dLMm14=",
+      "dev": true,
+      "requires": {
+        "constantinople": "^4.0.1",
+        "jstransformer": "1.0.0",
+        "pug-error": "^2.0.0",
+        "pug-walk": "^2.0.0",
+        "resolve": "^1.15.1"
+      }
+    },
+    "pug-lexer": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npm.taobao.org/pug-lexer/download/pug-lexer-5.0.1.tgz",
+      "integrity": "sha1-rkRijFvvmxkLZlaDsojKkCS4sNU=",
+      "dev": true,
+      "requires": {
+        "character-parser": "^2.2.0",
+        "is-expression": "^4.0.0",
+        "pug-error": "^2.0.0"
+      }
+    },
+    "pug-linker": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npm.taobao.org/pug-linker/download/pug-linker-4.0.0.tgz",
+      "integrity": "sha1-EsvAWU/Fo+Brn8Web5PBRpYqdwg=",
+      "dev": true,
+      "requires": {
+        "pug-error": "^2.0.0",
+        "pug-walk": "^2.0.0"
+      }
+    },
+    "pug-load": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/pug-load/download/pug-load-3.0.0.tgz",
+      "integrity": "sha1-n9nNpSICsIrbEdJWgfufNL1BtmI=",
+      "dev": true,
+      "requires": {
+        "object-assign": "^4.1.1",
+        "pug-walk": "^2.0.0"
+      }
+    },
+    "pug-parser": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npm.taobao.org/pug-parser/download/pug-parser-6.0.0.tgz",
+      "integrity": "sha1-qP3ANYY6lbLB3F6/Ts+AtOdqEmA=",
+      "dev": true,
+      "requires": {
+        "pug-error": "^2.0.0",
+        "token-stream": "1.0.0"
+      }
+    },
+    "pug-runtime": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npm.taobao.org/pug-runtime/download/pug-runtime-3.0.1.tgz",
+      "integrity": "sha1-9jaXYgRyPzWoxfb61qzaKhkbg9c=",
+      "dev": true
+    },
+    "pug-strip-comments": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/pug-strip-comments/download/pug-strip-comments-2.0.0.tgz",
+      "integrity": "sha1-+UsH/WtJVSMzD0kKf1VLT/h2MD4=",
+      "dev": true,
+      "requires": {
+        "pug-error": "^2.0.0"
+      }
+    },
+    "pug-walk": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/pug-walk/download/pug-walk-2.0.0.tgz",
+      "integrity": "sha1-QXqrwpIyu0SZtbUGmistKiTV9f4=",
+      "dev": true
+    },
+    "readdirp": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npm.taobao.org/readdirp/download/readdirp-3.6.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freaddirp%2Fdownload%2Freaddirp-3.6.0.tgz",
+      "integrity": "sha1-dKNwvYVxFuJFspzJc0DNQxoCpsc=",
+      "dev": true,
+      "requires": {
+        "picomatch": "^2.2.1"
+      }
+    },
+    "request-light": {
+      "version": "0.5.4",
+      "resolved": "https://registry.nlark.com/request-light/download/request-light-0.5.4.tgz",
+      "integrity": "sha1-SXqYxtiuSVNkF6Xi1/ODuTTz44w=",
+      "dev": true
+    },
+    "resolve": {
+      "version": "1.20.0",
+      "resolved": "https://registry.npm.taobao.org/resolve/download/resolve-1.20.0.tgz",
+      "integrity": "sha1-YpoBP7P3B1XW8LeTXMHCxTeLGXU=",
+      "dev": true,
+      "requires": {
+        "is-core-module": "^2.2.0",
+        "path-parse": "^1.0.6"
+      }
+    },
+    "rollup": {
+      "version": "2.55.1",
+      "resolved": "https://registry.nlark.com/rollup/download/rollup-2.55.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Frollup%2Fdownload%2Frollup-2.55.1.tgz",
+      "integrity": "sha1-ZqREZI4vtgPY4ynnemHGCKZRD9o=",
+      "dev": true,
+      "requires": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "sass": {
+      "version": "1.37.5",
+      "resolved": "https://registry.nlark.com/sass/download/sass-1.37.5.tgz",
+      "integrity": "sha1-9oODUffMgUxPz+HZog4Mq70eezw=",
+      "dev": true,
+      "requires": {
+        "chokidar": ">=3.0.0 <4.0.0"
+      }
+    },
+    "soundjs": {
+      "version": "1.0.1",
+      "resolved": "https://registry.nlark.com/soundjs/download/soundjs-1.0.1.tgz",
+      "integrity": "sha1-mZcFQtKNDfKh69BhrnXJYamMgYA="
+    },
+    "source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
+      "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM="
+    },
+    "source-map-js": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npm.taobao.org/source-map-js/download/source-map-js-0.6.2.tgz",
+      "integrity": "sha1-C7XeYxtBz72mz7qL0FqA79/SOF4=",
+      "dev": true
+    },
+    "sourcemap-codec": {
+      "version": "1.4.8",
+      "resolved": "https://registry.npm.taobao.org/sourcemap-codec/download/sourcemap-codec-1.4.8.tgz",
+      "integrity": "sha1-6oBL2UhXQC5pktBaOO8a41qatMQ=",
+      "dev": true
+    },
+    "string-hash": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npm.taobao.org/string-hash/download/string-hash-1.1.3.tgz",
+      "integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=",
+      "dev": true
+    },
+    "svelte-fa": {
+      "version": "2.2.1",
+      "resolved": "https://registry.nlark.com/svelte-fa/download/svelte-fa-2.2.1.tgz?cache=0&sync_timestamp=1626420512203&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsvelte-fa%2Fdownload%2Fsvelte-fa-2.2.1.tgz",
+      "integrity": "sha1-dDtWYs5ZRwW8jxbZnYTr+iPzJt0="
+    },
+    "to-fast-properties": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/to-fast-properties/download/to-fast-properties-2.0.0.tgz",
+      "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
+    },
+    "to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-5.0.1.tgz",
+      "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=",
+      "dev": true,
+      "requires": {
+        "is-number": "^7.0.0"
+      }
+    },
+    "token-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/token-stream/download/token-stream-1.0.0.tgz",
+      "integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=",
+      "dev": true
+    },
+    "typescript": {
+      "version": "4.3.5",
+      "resolved": "https://registry.nlark.com/typescript/download/typescript-4.3.5.tgz?cache=0&sync_timestamp=1628061383668&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ftypescript%2Fdownload%2Ftypescript-4.3.5.tgz",
+      "integrity": "sha1-TRw3zBbok5c8RaBohrcRMjTxGfQ=",
+      "dev": true
+    },
+    "upath": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npm.taobao.org/upath/download/upath-2.0.1.tgz",
+      "integrity": "sha1-UMc96mjW9rmQ9R0nnOYIFmXWGos=",
+      "dev": true
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "dev": true
+    },
+    "vant": {
+      "version": "3.1.5",
+      "resolved": "https://registry.nlark.com/vant/download/vant-3.1.5.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fvant%2Fdownload%2Fvant-3.1.5.tgz",
+      "integrity": "sha1-PoC1uKhDHQwiIRKf6onEzCGm8rI=",
+      "requires": {
+        "@vant/icons": "^1.7.0",
+        "@vant/lazyload": "^1.2.0",
+        "@vant/popperjs": "^1.1.0",
+        "@vant/use": "^1.2.2"
+      }
+    },
+    "vconsole": {
+      "version": "3.9.1",
+      "resolved": "https://registry.nlark.com/vconsole/download/vconsole-3.9.1.tgz",
+      "integrity": "sha1-QcnTEeFKGmhWahvlJDqGZ/TDRdM=",
+      "requires": {
+        "@fortawesome/free-solid-svg-icons": "^5.15.3",
+        "cookie-storage": "^6.1.0",
+        "copy-text-to-clipboard": "^3.0.1",
+        "core-js": "^3.11.0",
+        "mutation-observer": "^1.0.3",
+        "svelte-fa": "^2.2.1"
+      }
+    },
+    "vite": {
+      "version": "2.4.4",
+      "resolved": "https://registry.nlark.com/vite/download/vite-2.4.4.tgz",
+      "integrity": "sha1-jEAqB61F8Wj261Qovq048+Q2Pkc=",
+      "dev": true,
+      "requires": {
+        "esbuild": "^0.12.8",
+        "fsevents": "~2.3.2",
+        "postcss": "^8.3.6",
+        "resolve": "^1.20.0",
+        "rollup": "^2.38.5"
+      }
+    },
+    "void-elements": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npm.taobao.org/void-elements/download/void-elements-3.1.0.tgz",
+      "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=",
+      "dev": true
+    },
+    "vscode-css-languageservice": {
+      "version": "5.1.4",
+      "resolved": "https://registry.nlark.com/vscode-css-languageservice/download/vscode-css-languageservice-5.1.4.tgz",
+      "integrity": "sha1-B+TGPxw7sG5vPzKcMrSQ0gpgG6s=",
+      "dev": true,
+      "requires": {
+        "vscode-languageserver-textdocument": "^1.0.1",
+        "vscode-languageserver-types": "^3.16.0",
+        "vscode-nls": "^5.0.0",
+        "vscode-uri": "^3.0.2"
+      }
+    },
+    "vscode-emmet-helper": {
+      "version": "2.6.4",
+      "resolved": "https://registry.nlark.com/vscode-emmet-helper/download/vscode-emmet-helper-2.6.4.tgz",
+      "integrity": "sha1-vqR/F2Sbuia0EvPR+sGKruQ+uiU=",
+      "dev": true,
+      "requires": {
+        "emmet": "^2.3.0",
+        "jsonc-parser": "^2.3.0",
+        "vscode-languageserver-textdocument": "^1.0.1",
+        "vscode-languageserver-types": "^3.15.1",
+        "vscode-nls": "^5.0.0",
+        "vscode-uri": "^2.1.2"
+      },
+      "dependencies": {
+        "jsonc-parser": {
+          "version": "2.3.1",
+          "resolved": "https://registry.nlark.com/jsonc-parser/download/jsonc-parser-2.3.1.tgz",
+          "integrity": "sha1-WVSRULEz8u+sykj+nOHsBlmvI0I=",
+          "dev": true
+        },
+        "vscode-uri": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npm.taobao.org/vscode-uri/download/vscode-uri-2.1.2.tgz",
+          "integrity": "sha1-yNQN6T61evMfPHFd1lDiyiwJbxw=",
+          "dev": true
+        }
+      }
+    },
+    "vscode-html-languageservice": {
+      "version": "4.0.7",
+      "resolved": "https://registry.nlark.com/vscode-html-languageservice/download/vscode-html-languageservice-4.0.7.tgz",
+      "integrity": "sha1-lPLtIsghll+CgiLRO1qlQbNY2ZI=",
+      "dev": true,
+      "requires": {
+        "vscode-languageserver-textdocument": "^1.0.1",
+        "vscode-languageserver-types": "^3.16.0",
+        "vscode-nls": "^5.0.0",
+        "vscode-uri": "^3.0.2"
+      }
+    },
+    "vscode-json-languageservice": {
+      "version": "4.1.6",
+      "resolved": "https://registry.nlark.com/vscode-json-languageservice/download/vscode-json-languageservice-4.1.6.tgz",
+      "integrity": "sha1-QnXo2vHLqAJzwxjzP796Lt4wcFM=",
+      "dev": true,
+      "requires": {
+        "jsonc-parser": "^3.0.0",
+        "vscode-languageserver-textdocument": "^1.0.1",
+        "vscode-languageserver-types": "^3.16.0",
+        "vscode-nls": "^5.0.0",
+        "vscode-uri": "^3.0.2"
+      }
+    },
+    "vscode-jsonrpc": {
+      "version": "8.0.0-next.1",
+      "resolved": "https://registry.nlark.com/vscode-jsonrpc/download/vscode-jsonrpc-8.0.0-next.1.tgz",
+      "integrity": "sha1-GWRoiphR+GkAxV4piTmhV7LiJK0=",
+      "dev": true
+    },
+    "vscode-languageserver": {
+      "version": "8.0.0-next.1",
+      "resolved": "https://registry.nlark.com/vscode-languageserver/download/vscode-languageserver-8.0.0-next.1.tgz",
+      "integrity": "sha1-tYRFhaz4Yqe9qrItKMnaDxUn15A=",
+      "dev": true,
+      "requires": {
+        "vscode-languageserver-protocol": "3.17.0-next.7"
+      }
+    },
+    "vscode-languageserver-protocol": {
+      "version": "3.17.0-next.7",
+      "resolved": "https://registry.nlark.com/vscode-languageserver-protocol/download/vscode-languageserver-protocol-3.17.0-next.7.tgz",
+      "integrity": "sha1-IVDtuGtqUcMlADtDelIvDc/GBLQ=",
+      "dev": true,
+      "requires": {
+        "vscode-jsonrpc": "8.0.0-next.1",
+        "vscode-languageserver-types": "3.17.0-next.3"
+      },
+      "dependencies": {
+        "vscode-languageserver-types": {
+          "version": "3.17.0-next.3",
+          "resolved": "https://registry.nlark.com/vscode-languageserver-types/download/vscode-languageserver-types-3.17.0-next.3.tgz?cache=0&sync_timestamp=1625834451077&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fvscode-languageserver-types%2Fdownload%2Fvscode-languageserver-types-3.17.0-next.3.tgz",
+          "integrity": "sha1-4fQxHgjqMZPoESYVS2o0L8HD26M=",
+          "dev": true
+        }
+      }
+    },
+    "vscode-languageserver-textdocument": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/vscode-languageserver-textdocument/download/vscode-languageserver-textdocument-1.0.1.tgz",
+      "integrity": "sha1-F4Fo6H761hcbNyrdHeo09T5dMw8=",
+      "dev": true
+    },
+    "vscode-languageserver-types": {
+      "version": "3.16.0",
+      "resolved": "https://registry.nlark.com/vscode-languageserver-types/download/vscode-languageserver-types-3.16.0.tgz?cache=0&sync_timestamp=1625834451077&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fvscode-languageserver-types%2Fdownload%2Fvscode-languageserver-types-3.16.0.tgz",
+      "integrity": "sha1-7POT/BIexpdLLaPvsxVWRMUU4kc=",
+      "dev": true
+    },
+    "vscode-nls": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npm.taobao.org/vscode-nls/download/vscode-nls-5.0.0.tgz",
+      "integrity": "sha1-mfDaC9nqfNpE5WWnTFSx8rwleEA=",
+      "dev": true
+    },
+    "vscode-pug-languageservice": {
+      "version": "0.26.11",
+      "resolved": "https://registry.nlark.com/vscode-pug-languageservice/download/vscode-pug-languageservice-0.26.11.tgz",
+      "integrity": "sha1-vUVAbVnBaY2oVfJjvB6f4PQ54nM=",
+      "dev": true,
+      "requires": {
+        "@volar/code-gen": "^0.26.11",
+        "@volar/shared": "^0.26.11",
+        "@volar/source-map": "^0.26.11",
+        "@volar/transforms": "^0.26.11",
+        "pug-lexer": "^5.0.1",
+        "pug-parser": "^6.0.0",
+        "vscode-languageserver": "^8.0.0-next.1"
+      }
+    },
+    "vscode-typescript-languageservice": {
+      "version": "0.26.11",
+      "resolved": "https://registry.nlark.com/vscode-typescript-languageservice/download/vscode-typescript-languageservice-0.26.11.tgz",
+      "integrity": "sha1-ziyxWtTdp3lzHixHf0c95EQn/uc=",
+      "dev": true,
+      "requires": {
+        "@volar/shared": "^0.26.11",
+        "upath": "^2.0.1",
+        "vscode-languageserver": "^8.0.0-next.1",
+        "vscode-languageserver-textdocument": "^1.0.1"
+      }
+    },
+    "vscode-uri": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npm.taobao.org/vscode-uri/download/vscode-uri-3.0.2.tgz",
+      "integrity": "sha1-7P0dBmy470w6II3s26uajCPQVdA=",
+      "dev": true
+    },
+    "vscode-vue-languageservice": {
+      "version": "0.26.11",
+      "resolved": "https://registry.nlark.com/vscode-vue-languageservice/download/vscode-vue-languageservice-0.26.11.tgz",
+      "integrity": "sha1-uUAHMne+F5srcGUsJOtU9XL5dh0=",
+      "dev": true,
+      "requires": {
+        "@volar/code-gen": "^0.26.11",
+        "@volar/html2pug": "^0.26.11",
+        "@volar/shared": "^0.26.11",
+        "@volar/source-map": "^0.26.11",
+        "@volar/transforms": "^0.26.11",
+        "@vue/compiler-dom": "^3.2.0-beta.5",
+        "@vue/compiler-sfc": "^3.2.0-beta.5",
+        "@vue/reactivity": "^3.2.0-beta.5",
+        "@vue/shared": "^3.2.0-beta.5",
+        "jsonc-parser": "^3.0.0",
+        "request-light": "^0.5.4",
+        "upath": "^2.0.1",
+        "vscode-css-languageservice": "^5.1.4",
+        "vscode-emmet-helper": "^2.6.4",
+        "vscode-html-languageservice": "^4.0.7",
+        "vscode-json-languageservice": "^4.1.5",
+        "vscode-languageserver": "^8.0.0-next.1",
+        "vscode-languageserver-textdocument": "^1.0.1",
+        "vscode-pug-languageservice": "^0.26.11",
+        "vscode-typescript-languageservice": "^0.26.11"
+      },
+      "dependencies": {
+        "@vue/compiler-core": {
+          "version": "3.2.0-beta.7",
+          "resolved": "https://registry.nlark.com/@vue/compiler-core/download/@vue/compiler-core-3.2.0-beta.7.tgz",
+          "integrity": "sha1-u1UemeIHw+aUvWsoPLWioqrn9SE=",
+          "dev": true,
+          "requires": {
+            "@babel/parser": "^7.12.0",
+            "@babel/types": "^7.12.0",
+            "@vue/shared": "3.2.0-beta.7",
+            "estree-walker": "^2.0.1",
+            "source-map": "^0.6.1"
+          },
+          "dependencies": {
+            "@vue/shared": {
+              "version": "3.2.0-beta.7",
+              "resolved": "https://registry.nlark.com/@vue/shared/download/@vue/shared-3.2.0-beta.7.tgz",
+              "integrity": "sha1-C853YnHzKeZYL82gDWHUvPHGC1I=",
+              "dev": true
+            }
+          }
+        },
+        "@vue/compiler-dom": {
+          "version": "3.2.0-beta.7",
+          "resolved": "https://registry.nlark.com/@vue/compiler-dom/download/@vue/compiler-dom-3.2.0-beta.7.tgz",
+          "integrity": "sha1-IJl5cga193PpSYAd0dajvXPRdM4=",
+          "dev": true,
+          "requires": {
+            "@vue/compiler-core": "3.2.0-beta.7",
+            "@vue/shared": "3.2.0-beta.7"
+          },
+          "dependencies": {
+            "@vue/shared": {
+              "version": "3.2.0-beta.7",
+              "resolved": "https://registry.nlark.com/@vue/shared/download/@vue/shared-3.2.0-beta.7.tgz",
+              "integrity": "sha1-C853YnHzKeZYL82gDWHUvPHGC1I=",
+              "dev": true
+            }
+          }
+        },
+        "@vue/compiler-sfc": {
+          "version": "3.2.0-beta.7",
+          "resolved": "https://registry.nlark.com/@vue/compiler-sfc/download/@vue/compiler-sfc-3.2.0-beta.7.tgz",
+          "integrity": "sha1-bwSis341ivzXeRto767/0L8Zjd0=",
+          "dev": true,
+          "requires": {
+            "@babel/parser": "^7.13.9",
+            "@babel/types": "^7.13.0",
+            "@types/estree": "^0.0.48",
+            "@vue/compiler-core": "3.2.0-beta.7",
+            "@vue/compiler-dom": "3.2.0-beta.7",
+            "@vue/compiler-ssr": "3.2.0-beta.7",
+            "@vue/shared": "3.2.0-beta.7",
+            "consolidate": "^0.16.0",
+            "estree-walker": "^2.0.1",
+            "hash-sum": "^2.0.0",
+            "lru-cache": "^5.1.1",
+            "magic-string": "^0.25.7",
+            "merge-source-map": "^1.1.0",
+            "postcss": "^8.1.10",
+            "postcss-modules": "^4.0.0",
+            "postcss-selector-parser": "^6.0.4",
+            "source-map": "^0.6.1"
+          },
+          "dependencies": {
+            "@vue/shared": {
+              "version": "3.2.0-beta.7",
+              "resolved": "https://registry.nlark.com/@vue/shared/download/@vue/shared-3.2.0-beta.7.tgz",
+              "integrity": "sha1-C853YnHzKeZYL82gDWHUvPHGC1I=",
+              "dev": true
+            }
+          }
+        },
+        "@vue/compiler-ssr": {
+          "version": "3.2.0-beta.7",
+          "resolved": "https://registry.nlark.com/@vue/compiler-ssr/download/@vue/compiler-ssr-3.2.0-beta.7.tgz",
+          "integrity": "sha1-Gkar+LzTGWwsmtFJBjwAxGGfHiQ=",
+          "dev": true,
+          "requires": {
+            "@vue/compiler-dom": "3.2.0-beta.7",
+            "@vue/shared": "3.2.0-beta.7"
+          },
+          "dependencies": {
+            "@vue/shared": {
+              "version": "3.2.0-beta.7",
+              "resolved": "https://registry.nlark.com/@vue/shared/download/@vue/shared-3.2.0-beta.7.tgz",
+              "integrity": "sha1-C853YnHzKeZYL82gDWHUvPHGC1I=",
+              "dev": true
+            }
+          }
+        },
+        "@vue/reactivity": {
+          "version": "3.2.0-beta.7",
+          "resolved": "https://registry.nlark.com/@vue/reactivity/download/@vue/reactivity-3.2.0-beta.7.tgz",
+          "integrity": "sha1-BskWMV87dK5kAEDdt1ly2ilGf4Q=",
+          "dev": true,
+          "requires": {
+            "@vue/shared": "3.2.0-beta.7"
+          },
+          "dependencies": {
+            "@vue/shared": {
+              "version": "3.2.0-beta.7",
+              "resolved": "https://registry.nlark.com/@vue/shared/download/@vue/shared-3.2.0-beta.7.tgz",
+              "integrity": "sha1-C853YnHzKeZYL82gDWHUvPHGC1I=",
+              "dev": true
+            }
+          }
+        },
+        "@vue/shared": {
+          "version": "3.2.0-beta.5",
+          "resolved": "https://registry.nlark.com/@vue/shared/download/@vue/shared-3.2.0-beta.5.tgz",
+          "integrity": "sha1-wnUrrFFHa/2cYFD0pel8KOtm8no=",
+          "dev": true
+        }
+      }
+    },
+    "vue": {
+      "version": "3.1.5",
+      "resolved": "https://registry.nlark.com/vue/download/vue-3.1.5.tgz",
+      "integrity": "sha1-EoebEdBoXuRHjIhpVReZYwpS+f4=",
+      "requires": {
+        "@vue/compiler-dom": "3.1.5",
+        "@vue/runtime-dom": "3.1.5",
+        "@vue/shared": "3.1.5"
+      }
+    },
+    "vue-router": {
+      "version": "4.0.10",
+      "resolved": "https://registry.nlark.com/vue-router/download/vue-router-4.0.10.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fvue-router%2Fdownload%2Fvue-router-4.0.10.tgz",
+      "integrity": "sha1-7I/aAylJsqMdMnMXD483bobrUqw=",
+      "requires": {
+        "@vue/devtools-api": "^6.0.0-beta.14"
+      }
+    },
+    "vue-tsc": {
+      "version": "0.2.2",
+      "resolved": "https://registry.nlark.com/vue-tsc/download/vue-tsc-0.2.2.tgz?cache=0&sync_timestamp=1626837750289&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fvue-tsc%2Fdownload%2Fvue-tsc-0.2.2.tgz",
+      "integrity": "sha1-5/1eXHib6zGECtJggs/Iu2NW5zM=",
+      "dev": true,
+      "requires": {
+        "vscode-vue-languageservice": "^0.26.6"
+      }
+    },
+    "vuex": {
+      "version": "4.0.2",
+      "resolved": "https://registry.nlark.com/vuex/download/vuex-4.0.2.tgz?cache=0&sync_timestamp=1623945218026&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fvuex%2Fdownload%2Fvuex-4.0.2.tgz",
+      "integrity": "sha1-+Jbb1b8qDpY/AMZ+m2EN50nMrMk=",
+      "requires": {
+        "@vue/devtools-api": "^6.0.0-beta.11"
+      }
+    },
+    "with": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npm.taobao.org/with/download/with-7.0.2.tgz",
+      "integrity": "sha1-zO461ULSVTinp6gKrSErmChJW6w=",
+      "dev": true,
+      "requires": {
+        "@babel/parser": "^7.9.6",
+        "@babel/types": "^7.9.6",
+        "assert-never": "^1.2.1",
+        "babel-walk": "3.0.0-canary-5"
+      }
+    },
+    "yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-3.1.1.tgz",
+      "integrity": "sha1-27fa+b/YusmrRev2ArjLrQ1dCP0=",
+      "dev": true
+    }
+  }
+}

+ 32 - 0
package.json

@@ -0,0 +1,32 @@
+{
+  "name": "vue3-ts",
+  "version": "0.0.0",
+  "scripts": {
+    "dev": "vite",
+    "build": "vue-tsc --noEmit && vite build",
+    "serve": "vite preview"
+  },
+  "dependencies": {
+    "marked": "^3.0.4",
+    "mockjs": "^1.1.0",
+    "soundjs": "^1.0.1",
+    "vant": "^3.1.5",
+    "vconsole": "^3.9.1",
+    "vue": "^3.0.5",
+    "vue-router": "^4.0.10",
+    "axios": "^0.21.1",
+    "vuex": "^4.0.2"
+  },
+  "devDependencies": {
+    "@types/marked": "^3.0.1",
+    "@types/mockjs": "^1.0.4",
+    "@types/soundjs": "^0.6.28",
+    "@vitejs/plugin-vue": "^1.3.0",
+    "@vue/compiler-sfc": "^3.0.5",
+    "postcss-pxtorem": "^6.0.0",
+    "sass": "^1.37.5",
+    "typescript": "^4.3.2",
+    "vite": "^2.4.4",
+    "vue-tsc": "^0.2.2"
+  }
+}

+ 9 - 0
postcss.config.js

@@ -0,0 +1,9 @@
+module.exports = {
+  plugins: {
+    "postcss-pxtorem": {
+      rootValue: 37.5, // Vant 官方根字体大小是 37.5
+      propList: ["*"],
+      selectorBlackList: [".norem"], // 过滤掉.norem-开头的class,不进行rem转换
+    },
+  },
+};

BIN
public/favicon.ico


BIN
public/img/empty.png


BIN
public/img/考试合格.png


+ 73 - 0
public/markdown/README.md

@@ -0,0 +1,73 @@
+<p align="center">
+  <a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo_text.svg" width="320" alt="Nest Logo" /></a>
+</p>
+
+[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
+[circleci-url]: https://circleci.com/gh/nestjs/nest
+
+  <p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
+    <p align="center">
+<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
+<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
+<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
+<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
+<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
+<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
+<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
+<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
+  <a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
+    <a href="https://opencollective.com/nest#sponsor"  target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
+  <a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
+</p>
+  <!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
+  [![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
+
+## Description
+
+[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
+
+## Installation
+
+```bash
+$ npm install
+```
+
+## Running the app
+
+```bash
+# development
+$ npm run start
+
+# watch mode
+$ npm run start:dev
+
+# production mode
+$ npm run start:prod
+```
+
+## Test
+
+```bash
+# unit tests
+$ npm run test
+
+# e2e tests
+$ npm run test:e2e
+
+# test coverage
+$ npm run test:cov
+```
+
+## Support
+
+Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
+
+## Stay in touch
+
+- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
+- Website - [https://nestjs.com](https://nestjs.com/)
+- Twitter - [@nestframework](https://twitter.com/nestframework)
+
+## License
+
+Nest is [MIT licensed](LICENSE).

+ 173 - 0
public/markdown/学车必看.json

@@ -0,0 +1,173 @@
+{
+  "data": [
+    {
+      "title": "报名",
+      "explain": "首先第一步,带齐身份证等材料到驾校报名学车,本地学员准备身份证原件和复印件和一寸免冠照片。需要注意:报名后十天才可以预约科目一。"
+    },
+    {
+      "title": "科目一",
+      "explain": "待科目一学的差不多了,学时也满了,学员就可以在车管所网站上预约科目一考试,考场和考试时间都可以自主选择,科目一考试是电脑无纸化考试形式,主要考核交通法律、法规的基本知识。考试当天必须携带身份证原件。考试当天共有2次考试机会,2次都没有通过则必须重新预约考试。科目一考试时长45分钟,每题1分,90-100分为合格。成绩合格的考生,须持本人身份证在考场内出口位置刷身份证,用签名笔签名,并点击确认签名(考生无须取纸质成绩单)"
+    },
+    {
+      "title": "科目二",
+      "explain": "科目二的具体考试项目包括:直角转弯、曲线行驶、坡道定点停车、侧方停车、倒车入库(部分地区有增加项目)。总分为100分,考试大型客车、牵引车、城市公交车、中型客车、大型货车准驾车型的,成绩达到90分的为合格,其他准驾车型的成绩达到80分的为合格。学员学车时必须严格记录学时,学时满后才有资格预约考科目二,考试当天共有2次考试机会,2次都没有通过则必须重新预约考试。",
+      "twoLevel": [
+        {
+          "title": "科目二扣分标准",
+          "explain": "不同地方评判标准和扣分标准不同,仅供参考",
+          "threeLevel": [
+            {
+              "title": "通用扣分标准",
+              "list": [
+                "未系安全带:扣100分",
+                "未关好车门:扣100分",
+                "启动发动机时档位未在空档:扣100分",
+                "未打转向灯(包括起步、变道、超车、转弯、靠边停车);转向灯打开未超三秒;忘记关转向灯或转向灯使用错误:扣10分",
+                "熄火一次:扣10分"
+              ]
+            },
+            {
+              "title": "侧方位停车扣分标准",
+              "list": [
+                "车辆入库停止后车身出线:扣100分",
+                "出库时不使用或错误使用转向灯:扣10分",
+                "项目完成时间超过90秒:扣100分",
+                "行驶中车身触碰库位边线:扣10分/次",
+                "行驶中车轮触轧车道边线:扣10分/次",
+                "中途停车超过2秒:扣5分/次"
+              ]
+            },
+            {
+              "title": "侧方停车扣分标准",
+              "list": [
+                "项目完成时间超过210秒:扣100分(扣分重点)",
+                "不按规定路线、顺序行驶:扣100分",
+                "倒车前未将前轮均触点均驶过控制线:100分",
+                "中途停车超2秒:扣5分/次",
+                "倒库不入:扣100分",
+                "车身出线:扣100分"
+              ]
+            },
+            {
+              "title": "曲线行驶扣分标准",
+              "list": [
+                "车轮压到边缘线:扣100分(原先为扣20分,新标准调整)",
+                "中途停车超2秒:扣100分"
+              ]
+            },
+            {
+              "title": "直角转弯扣分标准",
+              "list": [
+                "车轮压到边缘线:扣100分(原先为扣20分,新标准调整)",
+                "中途停车超2s:扣5分/次"
+              ]
+            },
+            {
+              "title": "坡道定点停车扣分标准",
+              "list": [
+                "起步未开左转向灯:扣10分",
+                "起步时间超30秒:扣100分(扣分重点)",
+                "行驶过程中车轮轧到边线:扣100分",
+                "车辆停止后,车辆前保险杠或摩托车前轴未定于桩杆线上,前后未超过50cm:扣10分",
+                "车辆停止后,车辆前保险杠或摩托车前轴未定于桩杆线上,前后超过50cm:扣100分",
+                "车辆停止后,车身至车道边缘线超过30cm未超50cm:扣10分",
+                "车辆停止后,车身至车道边缘线超过50cm:扣100分",
+                "起步时,溜车距离未超30cm:扣10分",
+                "起步时,溜车距离超过50cm:扣100分"
+              ]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "title": "科目三",
+      "explain": "科目二考试合格后,学员就便可进行科目三路考的训练啦,科目三训练里程最低不得少于300公里,科目三考试项目至少包含:夜间灯光模拟操作、上车准备、直线行驶、百米加减档等16个考试。总分为100分,成绩达到90分的为合格,当天共有2次考试机会,2次都没有通过则必须重新预约考试。",
+      "twoLevel": [
+        {
+          "title": "科目三扣分标准",
+          "explain": "不同地方评判标准和扣分标准不同,仅供参考",
+          "threeLevel": [
+            {
+              "title": "直接判定为不合格情况",
+              "list": [
+                "不按规定使用安全带",
+                "遮挡、关闭车内音视频监控设备",
+                "不按考试员指令驾驶",
+                "起步时车辆后溜距离大于30cm",
+                "使用挡位与车速长时间不匹配,造成车辆发动机转速过高或过低",
+                "车辆在行驶中连续2次挂挡不进",
+                "行驶中空挡滑行",
+                "不按交通信号灯、标志、标线行驶",
+                "不按规定速度行驶",
+                "车辆行驶中骑轧道路中心实线或者车道边缘实线",
+                "长时间骑轧车道分界线行驶(时间大于15秒)",
+                "连续变更两条或两条以上车道",
+                "将车辆停在人行横道、网状线内等禁止停车区域",
+                "考生未按照预约时间参加考试"
+              ]
+            },
+            {
+              "title": "出现以下情况扣10分",
+              "list": [
+                "起步时车辆后溜,但后溜距离小于30cm",
+                "起步或行驶中挂错挡",
+                "起步、转向、变更车道、超车、停车前不使用或错误使用转向灯",
+                "起步、转向、变更车道、超车、停车前,开转向灯少于3秒即转向",
+                "因操作不当造成发动机熄火一次"
+              ]
+            },
+            {
+              "title": "上车准备扣分标准",
+              "list": ["未按逆时针方向绕车一圈检查车辆外观及周围环境,不合格。"]
+            },
+            {
+              "title": "起步扣分标准",
+              "list": [
+                "制动气压不足起步,不合格",
+                "车门未完全关闭起步,不合格",
+                "启动发动机时,变速器操纵杆未置于空挡,不合格",
+                "不松驻车制动器起步,未及时纠正,不合格",
+                "不松驻车制动器起步,但及时纠正,扣10分",
+                "发动机启动后,不及时松开启动开关,扣10分"
+              ]
+            },
+            {
+              "title": "加减档扣分标准",
+              "list": [
+                "未按指令平稳加、减挡,不合格",
+                "车辆运行速度与挡位不匹配,扣10分"
+              ]
+            },
+            {
+              "title": "靠边停车扣分标准",
+              "list": [
+                "停车后,车身超过道路右侧边缘线或者人行横道线,不合格",
+                "下车后不关闭车门,不合格",
+                "停车后,车身距离道路右侧边缘线或者人行道边缘大于30cm,扣10分",
+                "停车后,未拉紧驻车制动器,扣10分",
+                "拉紧驻车制动器前放松行车制动踏板,扣10分",
+                "下车前不将发动机熄火,扣5分"
+              ]
+            },
+            {
+              "title": "其他扣分标准",
+              "list": [
+                "直行通过路口、路口左转弯、路口右转弯,不按规定减速或停车瞭望,不合格。",
+                "通过人行横道、学校区域、公共汽车站,不按规定减速慢行,不合格。"
+              ]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "title": "科目四",
+      "explain": "科目四考试主要考核安全文明驾驶常识,和科目一一样,也是电脑无纸化考试形式,比科目一多了多选择,动画题,案例分析题的题型。科目四考试时长45分钟,每题2分,90-100分为合格。成绩合格的考生,须持本人身份证在考场内出口位置刷身份证,用签名笔签名,并点击确认签名(考生无须取纸质成绩单)"
+    },
+    {
+      "title": "领取驾驶证",
+      "explain": "当科目四考试合格后,就可以等着车管所制证,当驾校通知驾驶证完成,学员持身份证到驾校报名点领取驾驶证即可。"
+    }
+  ]
+}

+ 156 - 0
public/markdown/学车必看.md

@@ -0,0 +1,156 @@
+## <center> 报名
+``1.首先第一步,带齐身份证等材料到驾校报名学车,本地学员准备身份证原件和复印件和一寸免冠照片。
+需要注意:报名后十天才可以预约科目一。``
+# <center> 科目一
+``1.待科目一学的差不多了,学时也满了,学员就可以在车管所网站上预约科目一考试,考场和考试时间都可以自主选择,科目一考试是电脑无纸化考试形式,主要考核交通法律、法规的基本知识。
+2.考试当天必须携带身份证原件。考试当天共有2次考试机会,2次都没有通过则必须重新预约考试。
+3.科目一考试时长45分钟,每题1分,90-100分为合格。成绩合格的考生,须持本人身份证在考场内出口位置刷身份证,用签名笔签名,并点击确认签名(考生无须取纸质成绩单)``
+# <center> 科目二
+``1.科目二的具体考试项目包括:直角转弯、曲线行驶、坡道定点停车、侧方停车、倒车入库(部分地区有增加项目)。总分为100分,考试大型客车、牵引车、城市公交车、中型客车、大型货车准驾车型的,成绩达到90分的为合格,其他准驾车型的成绩达到80分的为合格。
+2.学员学车时必须严格记录学时,学时满后才有资格预约考科目二,考试当天共有2次考试机会,2次都没有通过则必须重新预约考试。``
+## <center> 科目二扣分标准
+### 通用扣分标准
+1、未系安全带:扣100分
+
+2、未关好车门:扣100分
+
+3、启动发动机时档位未在空档:扣100分
+
+4、未打转向灯(包括起步、变道、超车、转弯、靠边停车);转向灯打开未超三秒;忘记关转向灯或转向灯使用错误:扣10分
+
+5、熄火一次:扣10分
+### 侧方位停车扣分标准
+1、车辆入库停止后车身出线:扣100分
+
+2、出库时不使用或错误使用转向灯:扣10分
+
+3、项目完成时间超过90秒:扣100分
+
+4、行驶中车身触碰库位边线:扣10分/次
+
+5、行驶中车轮触轧车道边线:扣10分/次
+
+6、中途停车超过2秒:扣5分/次
+### 侧方停车扣分标准
+1、项目完成时间超过210秒:扣100分(扣分重点)
+
+2、不按规定路线、顺序行驶:扣100分
+
+3、倒车前未将前轮均触点均驶过控制线:100分
+
+4、中途停车超2秒:扣5分/次
+
+5、倒库不入:扣100分
+
+6、车身出线:扣100分
+### 曲线行驶扣分标准
+1、车轮压到边缘线:扣100分(原先为扣20分,新标准调整)
+
+2、中途停车超2秒:扣100分
+### 直角转弯扣分标准
+1、车轮压到边缘线:扣100分(原先为扣20分,新标准调整)
+
+2、中途停车超2s:扣5分/次
+### 坡道定点停车扣分标准
+1、起步未开左转向灯:扣10分
+
+2、起步时间超30秒:扣100分(扣分重点)
+
+3、行驶过程中车轮轧到边线:扣100分
+
+4、车辆停止后,车辆前保险杠或摩托车前轴未定于桩杆线上,前后未超过50cm:扣10分
+
+5、车辆停止后,车辆前保险杠或摩托车前轴未定于桩杆线上,前后超过50cm:扣100分
+
+6、车辆停止后,车身至车道边缘线超过30cm未超50cm:扣10分
+
+7、车辆停止后,车身至车道边缘线超过50cm:扣100分
+
+8、起步时,溜车距离未超30cm:扣10分
+
+9、起步时,溜车距离超过50cm:扣100分
+# <center> 科目三
+``科目二考试合格后,学员就便可进行科目三路考的训练啦,科目三训练里程最低不得少于300公里,科目三考试项目至少包含:夜间灯光模拟操作、上车准备、直线行驶、百米加减档等16个考试。总分为100分,成绩达到90分的为合格,当天共有2次考试机会,2次都没有通过则必须重新预约考试。``
+## <center> 科目三扣分标准
+### 通用扣分标准
+出现以下情况直接判定为不合格:
+
+1、不按规定使用安全带;
+
+2、遮挡、关闭车内音视频监控设备;
+
+3、不按考试员指令驾驶;
+
+4、起步时车辆后溜距离大于30cm;
+
+5、使用挡位与车速长时间不匹配,造成车辆发动机转速过高或过低;
+
+6、车辆在行驶中连续2次挂挡不进;
+
+7、行驶中空挡滑行;
+
+8、不按交通信号灯、标志、标线行驶;
+
+9、不按规定速度行驶;
+
+10、车辆行驶中骑轧道路中心实线或者车道边缘实线;
+
+11、长时间骑轧车道分界线行驶(时间大于15秒);
+
+12、连续变更两条或两条以上车道;
+
+13、将车辆停在人行横道、网状线内等禁止停车区域;
+
+14、考生未按照预约时间参加考试;
+### 出现以下情况扣10分
+1、起步时车辆后溜,但后溜距离小于30cm;
+
+2、起步或行驶中挂错挡;
+
+3、起步、转向、变更车道、超车、停车前不使用或错误使用转向灯;
+
+4、起步、转向、变更车道、超车、停车前,开转向灯少于3秒即转向;
+
+5、因操作不当造成发动机熄火一次。
+### 上车准备扣分标准
+未按逆时针方向绕车一圈检查车辆外观及周围环境,不合格。
+### 起步扣分标准
+出现以下情况直接判定为不合格:
+
+1、制动气压不足起步;
+
+2、车门未完全关闭起步;
+
+3、启动发动机时,变速器操纵杆未置于空挡;
+
+4、不松驻车制动器起步,未及时纠正;
+
+出现以下情况扣10分:
+
+1、不松驻车制动器起步,但及时纠正;
+
+2、发动机启动后,不及时松开启动开关。
+### 加减档扣分标准
+1、未按指令平稳加、减挡,不合格;
+
+2、车辆运行速度与挡位不匹配,扣10分。
+### 靠边停车扣分标准
+1、停车后,车身超过道路右侧边缘线或者人行横道线,不合格;
+
+2、下车后不关闭车门,不合格;
+
+3、停车后,车身距离道路右侧边缘线或者人行道边缘大于30cm,扣10分;
+
+4、停车后,未拉紧驻车制动器,扣10分;
+
+5、拉紧驻车制动器前放松行车制动踏板,扣10分;
+
+6、下车前不将发动机熄火,扣5分。
+### 其他扣分标准
+1、直行通过路口、路口左转弯、路口右转弯,不按规定减速或停车瞭望,不合格。
+
+2、通过人行横道、学校区域、公共汽车站,不按规定减速慢行,不合格。
+# <center> 科目四
+``科目四考试主要考核安全文明驾驶常识,和科目一一样,也是电脑无纸化考试形式,比科目一多了多选择,动画题,案例分析题的题型。科目四考试时长45分钟,每题2分,90-100分为合格。成绩合格的考生,须持本人身份证在考场内出口位置刷身份证,用签名笔签名,并点击确认签名(考生无须取纸质成绩单)``
+# <center> 领取驾驶证
+``当科目四考试合格后,就可以等着车管所制证,当驾校通知驾驶证完成,学员持身份证到驾校报名点领取驾驶证即可。``

+ 397 - 0
public/markdown/考前须知.json

@@ -0,0 +1,397 @@
+{
+  "data": [
+    {
+      "title": "科目一",
+      "twoLevel": [
+        {
+          "title": "科目一考试流程",
+          "threeLevel": [
+            {
+              "title": "入场",
+              "list": [
+                "候考厅,进候考厅领取小票排号。001-1000",
+                "待考区.考试按票号排队,待考区一次50个排号。进入待考区不能携 带任何与考试无关的物品:水、烟、打火机、眼镜盒、智能设备、电子仪器等入场",
+                "理论考试不分科目一和安全文明,按照先来后到依次入场。考试电脑 自动分配所考科目"
+              ]
+            },
+            {
+              "title": "准备考试",
+              "list": [
+                "考试过程:使用身份证在读卡器上获取信息验证成功后,在【考台分配】处使用身份证在读卡器上获取信息分配指定的考试座位(座位为随机分配1-120号其一),听到分配的座位后前往身后的考试区域,自行寻找分配的对应台号考试(考台桌左上角和正面分别贴有座位号)座位上,检查自己的身份证号和名字是否无误。确定无误后,再开始考试。做题过程中,保持安静,不念题,不站立,不左顾右,禁止相互交流。有操作问题,坐在座位举手示意即可。违反考试纪律按照作弊停考一年处理"
+              ]
+            },
+            {
+              "title": "考试结束",
+              "list": [
+                "考试满分100分,90分合格。",
+                "第一次考试结束,需点击【确定交卷】如等于或大于90分,前往【成绩打印】处,签字盖章即可离场",
+                "如成绩不够90分,点击【确定交卷】后,再次在【配考试】处排队,言明:“考第二次”,即再次分配考试,然后前往分配指定的考试座位。"
+              ]
+            },
+            {
+              "title": "成绩打印",
+              "list": [
+                "考试合格的在【成绩打印】处,打印成绩单,不合格的不打印成绩单。在成绩单考生签名处工整签字,统一盖章即可离场",
+                "科目三安全文明需要再在候考厅【电子签名】处,签字,不合格不需要签字"
+              ]
+            },
+            {
+              "title": "参考信息",
+              "list": [
+                "【123号令】第六章法律责任规定:申请人在考试过程中有赂、舞弊行为的,取消考试资格,已经通过考试的其他科目成绩无效:申请人在一年内不得再次申领机动车驾驶证"
+              ]
+            }
+          ]
+        },
+        {
+          "title": "科目一考试题库答案",
+          "threeLevel": [
+            {
+              "title": "责任判定",
+              "list": [
+                "判断题:最后两个字“拘役”√,“徒刑”×;选择题:选项中找“拘役”",
+                "三短一长选择最长",
+                "三下一上,直接选上"
+              ]
+            },
+            {
+              "title": "速度题",
+              "list": [
+                "选择题:选项中直接选“30”(城市和公路除外)",
+                "判断题:“30公里”和“80公里”答√,其他都答×",
+                "城3/5公4/7,城市道路有中心线50,无线30;公路有中心线70,无线40",
+                "高速路两条路:左侧路速度区间100-120,右侧路区间60-100;三条路:左侧路速度区间110-120,中间路区间90-110,右侧路区间60-90"
+              ]
+            },
+            {
+              "title": "米数题",
+              "list": [
+                "261、145、520(离)(分别对应能见度、速度、车距)",
+                "有“150”直接选,没有“150”选最大的"
+              ]
+            },
+            {
+              "title": "标志题",
+              "list": [
+                "警示标志:选择题找“注意”,判断题:图片中“人”“山”“洞”“自行车”×",
+                "公路速度标志:红牌最高速度,蓝牌最低速度,黄色建议速度"
+              ]
+            },
+            {
+              "title": "扣分罚款",
+              "list": [
+                "看到“几分”答案选择“12分”,(两题例外:未带行驶证记1分,为系安全带记2分)",
+                "判断题12分答√,同时出现“20%”或“应急车道”答错;见6分答√,同时出现“、”或“50%”×",
+                "选择题中见12分找“号牌”或“不符”;见6分找“违”",
+                "图片题:题目说“这种违法行为”答案几辆车选几分",
+                "扣1分:关键词“会车”、“灯光”、“未带行驶证”",
+                "扣2分:关键词“打电话”、“安全带”、“停车”",
+                "扣3分:关键词“禁令标志”、“年检”“超速10%-20%”、“普通道路逆行”",
+                "扣12分的行为有:逃逸,不符,号牌,酒驾,伪造,超速50%,高速逆行等",
+                "扣6分的行为有:违反信号灯,超速20%-50%,占用应急车道,不避让校车,高速路低能见度不按规定行驶",
+                "罚款题:有“罚”找“罚”;有“200元以上2000元以下”直接选,出现“还应当”选“20元以上200以下”"
+              ]
+            },
+            {
+              "title": "仪表灯光题",
+              "list": [
+                "好事成双,两个灯亮√,一个灯亮×,两个车门开√,一个车门开×",
+                "圆形仪表×,方形仪表对。图中见“8”找“发”;多个数找“速度”;见温度计找“水温表”;见加油机找“燃油表”",
+                "灯光杆:红色圆圈套在杆子中间答√,没有套上或没有圆圈答×",
+                "点火开关:钥匙对准中间位置答×,对准两头位置答√",
+                "ABS题:判断题中见“缩短”答错,没有“缩短”答√。选择题选项中找“急”或“死”"
+              ]
+            },
+            {
+              "title": "标线题",
+              "list": ["虚线先找“可”后找“分”两个分看箭头", "实线找“禁止”"]
+            },
+            {
+              "title": "道路信号灯题",
+              "list": [
+                "三颗灯架横×,竖√(横着题中有“确认安全”或“可以左转”√)",
+                "两个灯架,两个灯亮√,一个灯亮×"
+              ]
+            },
+            {
+              "title": "文明驾驶及安全行车题",
+              "list": [
+                "题中有:不能、不得、不要、不准√",
+                "题中有:减速、低速、慢√",
+                "题中有:不减速× 无需减速× 紧急减速×",
+                "题中有:让行、注意、观察、依次、主动、避兔、等、安全、易、报警√",
+                "题中有:迅速、快速、尽快、加速、立即×"
+              ]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "title": "科目二",
+      "twoLevel": [
+        {
+          "title": "科目二考试流程及注意事项",
+          "threeLevel": [
+            {
+              "title": "考前准备",
+              "list": [
+                "身份证",
+                "补考的学员,提前把补考费交好",
+                "平底鞋",
+                "浅色衣服"
+              ]
+            },
+            {
+              "title": "考试当天进考场",
+              "list": [
+                "准备好身份证,排队进考试大厅。进入大厅后大屏幕会显示学员与考试车辆对应的信息。记住自己的考试车号码,进考场等待上车即可。",
+                "手机正常是不允许带进考场的,有的地区可以带但是不能开机。"
+              ]
+            },
+            {
+              "title": "上车考试",
+              "list": [
+                "上车后先调整座位,靠背",
+                "调整后视镜",
+                "系安全带",
+                "人脸识别或者输指纹开始正式考试",
+                "切记不要先挂档。先观察车辆是否打火,没打火的话先打着火再挂档(一般是打火状态)",
+                "起步时,先踩离合,踩刹车,然后挂一档,再放手刹,慢松离合起步即可。"
+              ]
+            },
+            {
+              "title": "半坡前后点停车方法",
+              "list": [
+                "观察左后视镜底边盖章中间黄线 半坡起步看准点以后,停车时。先把离合踩到底,紧接着踩死刹车。或者离合刹车一起踩死也可以。停车后拉起手刹,半坡起步停车完成,30秒之内完成起步。"
+              ]
+            },
+            {
+              "title": "脚刹起步",
+              "list": [
+                "先把手刹放下",
+                "离合慢松至车身抖动,当车身抖动后,此时左脚不动。",
+                "右脚刹车慢慢全部松开,即可完成起步。"
+              ]
+            },
+            {
+              "title": "手刹起步",
+              "list": [
+                "手刹先不放,先松开脚刹。",
+                "离合慢松至车身抖动,当车身抖动后,此时左脚不动。",
+                "手刹全部放下,即可完成起步。"
+              ]
+            },
+            {
+              "title": "脚刹+油门,起步方法",
+              "list": [
+                "先把手刹放下",
+                "离合慢松至车身抖动,当车身抖动后,此时左脚不动。",
+                "右脚刹车全部松开后紧接着踩油门",
+                "此时如果车会起步,左脚则不需要动。如果车不走或者只走一点点,此时"
+              ]
+            },
+            {
+              "title": "手刹+油门,起步方法",
+              "list": [
+                "手刹先不放",
+                "先把右脚刹车全部松开后紧跟着踩油门,踩着油门脚不松",
+                "慢松离合,松离合的过程中车会起步,当车身开始起步时",
+                "手刹全部放下,即可完成起步"
+              ]
+            },
+            {
+              "title": "半坡起步时熄火溜车的原因",
+              "list": [
+                "熄火→离合松的太快,太多(半联动掌握不好)",
+                "溜车→离合松的太少"
+              ]
+            },
+            {
+              "title": "半坡起步下坡的方法",
+              "list": [
+                "三不踩(车速适中)",
+                "踩死离合+轻踩刹车(车速慢)"
+              ]
+            },
+            {
+              "title": "直角转弯时压角原因",
+              "list": [
+                "车太靠左,距离右边线大于50厘米。",
+                "打轮太早,车没开到位置就提前打轮。"
+              ]
+            },
+            {
+              "title": "直角转弯压前边线原因",
+              "list": [
+                "打轮太晚造成。"
+              ]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "title": "科目三",
+      "twoLevel": [
+        {
+          "title": "科目三考试细节及标准",
+          "threeLevel": [
+            {
+              "title": "上车准备",
+              "list": [
+                "上车进行指纹验证后,下车绕车一周确认安全,上车。",
+                "评判:不绕车一周检查车辆外观及周围环境扣 100 分。"
+              ]
+            },
+            {
+              "title": "起步语音",
+              "list": [
+                "提示“请起步”后,挂入一档,打左转向灯,观察后视镜,确认安全,鸣笛, 放手刹,起步。",
+                "评判:起步挡位不正确,起步或行驶中挂错档扣 100 分; 在起步时后溜小于 30cm 扣 10 分,大于 30cm 扣 100 分; 开灯错误、起步、转向、并更车道、超车、停车前不使用或错误使用转向灯,扣 100 分;"
+              ]
+            },
+            {
+              "title": "直线行驶",
+              "list": [
+                "语音提示“请保持直线行驶”,控制好方向,选择合适挡位,保持车辆直线 行驶。",
+                "评判:方向控制不稳,不能保持车辆直线运行,扣 100 分。"
+              ]
+            },
+            {
+              "title": "加减挡操作",
+              "list": [
+                "语音提示“请完成加减档动作”时,挡位归至最低档或 2 档,从低档依次升 至最高档,一般可由 2 档至 4 档,最高挡位时时速需大于 40km/h,并且保 持 3 秒以上,再将挡位依次降至最低档。",
+                "评判:未按指令平稳加、减挡,扣分 100。速度与档位不匹配 扣 10 分。"
+              ]
+            },
+            {
+              "title": "变更车道",
+              "list": [
+                "语音提示“请变更车道”,打转向灯保持三秒钟,观察后视镜,确认安全, 变更车道。不具备变更条件时,减速慢行,条件允许后进行考试科目。",
+                "评判:转向灯使用不正确扣 100 分,连续变更车道扣 100 分。未完成变更车 道科目则为不按考试员指令驾驶扣 100 分。"
+              ]
+            },
+            {
+              "title": "直行通过路口",
+              "list": [
+                "语音提示“前方通过路口”,应减速在进入路口前车速低于 30km/h,观察 交通情况,安全通过,有信号灯按指示行驶。交通阻塞无法行驶时,将车停在安全线以外,停车等待,路口内禁止停车。",
+                "评判:车速大于 30km/h 扣 100 分,不按照红绿灯或导向车道行驶扣 100 分。"
+              ]
+            },
+            {
+              "title": "前方通过人行横道",
+              "list": [
+                "语音提示“前方通过人行横道”,减速在进入该区域前车速低于 30km/h,有 行人通过,把车辆停在安全线外等候,在行人通过后方可通过。",
+                "评判:车速大于 30km/h 扣 100 分。"
+              ]
+            },
+            {
+              "title": "通过学校区域",
+              "list": [
+                "语音提示“前方通过学校”,减速或在进入该区域前车速低于 30km/h,观察 交通情况,避让学生,确认安全后通过。",
+                "评判:车速大于 30km/h 扣 100 分。"
+              ]
+            },
+            {
+              "title": "通过公交车站",
+              "list": [
+                "语音提示“通过公交车站”,减速或在进入该区域前车速低于 30km/h,观察 交通情况,避让公交车,确认安全后通过。",
+                "评判:车速大于 30km/h 扣 100 分。"
+              ]
+            },
+            {
+              "title": "路口左转弯",
+              "list": [
+                "语音提示“前方路口左转弯”,提前 3 秒开转向灯,按导向箭头车道左转至 行车道。出弯的过程需要按照道路标志标线。",
+                "评判:转向灯使用不正确扣 100 分,不按照红绿灯或导向车道行驶扣 100 分。"
+              ]
+            },
+            {
+              "title": "路口右转弯",
+              "list": [
+                "语音提示“前方路口右转弯”,提前 3 秒开转向灯,按导向箭头车道右转至 行车道。出弯的过程需要按照道路标志标线。",
+                "评判:转向灯使用不正确扣 100 分,不按照红绿灯或导向车道行驶扣 100 分。"
+              ]
+            },
+            {
+              "title": "会车",
+              "list": [
+                "语音提示“前方会车”,注意前方来车,靠行车道右侧行驶,车身右侧距离 车道分界线不大于 30 厘米,行驶距离 30 米以上。不能压实线或长时间骑压车道分界线。",
+                "评判:碾压实线或长时间骑压分界线,扣100分。"
+              ]
+            },
+            {
+              "title": "超车",
+              "list": [
+                "语音提示“请完成超车动作”,打左转向灯保持三秒,观察后视镜,确认安 全,驶入左侧车道进行超车,超车完成打右转向灯保持三秒,同时观察右后方, 确认安全后驶入原车道正常行驶,项目完成。当不具备超车动作条件时,请耐心 等待,禁止右侧超车。",
+                "评判:未超车或超车后未返回原车道,系统评判‘未按考试员指令驾驶’扣 100 分。"
+              ]
+            },
+            {
+              "title": "掉头",
+              "list": [
+                "语音提示“前方请掉头”,打左转向灯保持三秒,观察后方交通情况,确认 安全后低速驶入掉头区,观察确认安全,入弯道后驶入新车道正常行驶,关闭转 向灯。掉头过程需要按照道路标志标线进行,需由标示箭头车道掉头进入。",
+                "评判:不按道路交通标志标线行驶,扣 100 分。"
+              ]
+            },
+            {
+              "title": "靠边停车",
+              "list": [
+                "语音提示“请靠边停车”,考生打右转向灯保持三秒,观察后方交通情况, 确认安全,将车辆平行停放距路边石 30cm 以内。",
+                "评判:车辆停车距离边缘线超出 50cm,扣 100 分, 车辆停车距离边缘线 30cm-50cm,扣 10 分。"
+              ]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "title": "科目四",
+      "twoLevel": [
+        {
+          "title": "科四考试题库答案",
+          "threeLevel": [
+            {
+              "title": "交警与信号灯试题",
+              "list": [
+                "看见交警找四个字,没有四个字找转弯,手指的方向即转弯方向",
+                "交警不看你× 看你√ 手势重影√ 站直√",
+                "红绿灯横× 竖√",
+                "黄灯找安全;黄灯放大√;红灯找禁止",
+                "两个标志牌√",
+                "例外,图里有感叹号!×",
+                "车轮扭着√",
+                "下坡塞前轮√ 上坡塞前轮×",
+                "有图看图"
+              ]
+            },
+            {
+              "title": "标线",
+              "list": [
+                "蓝色压虚线对。压实线错",
+                "红色压实线对,压虚线错",
+                "错(有框)",
+                "注意缓慢转向(对)",
+                "虚线可以超车",
+                "两个停不一样是错",
+                "无人无框是对",
+                "指框错",
+                "实景图三可一不找不"
+              ]
+            },
+            {
+              "title": "安全文明",
+              "list": [
+                "开车之前先观察",
+                "下车先看后面再开门(先观察后开门)",
+                "不利于是错",
+                "无影响是错"
+              ]
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}

+ 93 - 0
public/markdown/考前须知.md

@@ -0,0 +1,93 @@
+## <center> 科目一考试流程
+### 一、入场
+1.候考厅,进候考厅领取小票排号。001-1000
+
+2.待考区.考试按票号排队,待考区一次 50 个排号。进入待考区不能携 带任何与考试无关的物品:水、烟、打火机、眼镜盒、智能设备、电 子仪器等入场
+
+3.理论考试不分科目一和安全文明,按照先来后到依次入场。考试电脑 自动分配所考科目
+### 二、准备考试
+考试过程:使用身份证在读卡器上获取信息验证成功后,在【考台分配】 处使用身份证在读卡器上获取信息分配指定的考试座位(座位为随机 分配 1-120 号其一),听到分配的座位后前往身后的考试区域,自行寻找 分配的对应台号考试(考台桌左上角和正面分别贴有座位号)座位上, 检查自己的身份证号和名字是否无误。确定无误后,再开始考试。做题过程中,保持安静,不念题,不站立,不左顾右,禁止相互交流。有操 作问题,坐在座位举手示意即可。违反考试纪律按照作弊停考一年处理
+### 三、考试结束
+考试满分 100 分,90 分合格。
+
+第一次考试结束,需点击【确定交卷】如等于或大于 90 分,前往【成绩打印】处,签字盖章即可离场
+
+如成绩不够 90 分,点击【确定交卷】后,再次在【配考试】处排队,言 明:“考第二次”,即再次分配考试,然后前往分配指定的考试座位。
+### 四、成绩打印
+考试合格的在【成绩打印】处,打印成绩单,不合格的不打印成绩单。 在成绩单考生签名处工整签字,统一盖章即可离场
+
+科目三安全文明需要再在候考厅【电子签名】处,签字,不合格不需要签字
+### 五、参考信息
+【123 号令】第六章法律责任规定:申请人在考试过程中有赂、舞弊行为的,取消考试资格,已经通过考试的其他科目成绩无效:申请人在一年内不得再次申领机动车驾驶证
+
+## <center> 科目一考试题库答案
+### 责任判定
+1、判断题:最后两个字“拘役”√,“徒刑”×;选择题:选项中找“拘役”
+
+2、三短一长选择最长
+
+3、三下一上,直接选上
+### 速度题
+1、选择题:选项中直接选“30”(城市和公路除外)
+
+2、判断题:“30公里”和“80公里”答√,其他都答×
+
+3、城3/5公4/7,城市道路有中心线50,无线30;公路有中心线70,无线40
+
+4、高速路两条路:左侧路速度区间100-120,右侧路区间60-100;三条路:左侧路速度区间110-120,中间路区间90-110,右侧路区间60-90
+### 米数题
+1、261、145、520(离)(分别对应能见度、速度、车距)
+
+2、有“150”直接选,没有“150”选最大的
+### 标志题
+1、警示标志:选择题找“注意”,判断题:图片中“人”“山”“洞”“自行车”×
+
+2、公路速度标志:红牌最高速度,蓝牌最低速度,黄色建议速度
+### 扣分罚款
+1、看到“几分”答案选择“12分”,(两题例外:未带行驶证记1分,为系安全带记2分)
+
+2、判断题12分答√,同时出现“20%”或“应急车道”答错;见6分答√,同时出现“、”或“50%”×
+
+3、选择题中见12分找“号牌”或“不符”;见6分找“违”;
+
+4、图片题:题目说“这种违法行为”答案几辆车选几分
+
+5、扣1分:关键词“会车”、“灯光”、“未带行驶证”
+
+6、扣2分:关键词“打电话”、“安全带”、“停车”
+
+7、扣3分:关键词“禁令标志”、“年检”“超速10%-20%”、“普通道路逆行”
+
+8、扣12分的行为有:逃逸,不符,号牌,酒驾,伪造,超速50%,高速逆行等
+
+9、扣6分的行为有:违反信号灯,超速20%-50%,占用应急车道,不避让校车,高速路低能见度不按规定行驶
+
+10、罚款题:有“罚”找“罚”;有“200元以上2000元以下”直接选,出现“还应当”选“20元以上200以下”
+### 仪表灯光题
+1、好事成双,两个灯亮√,一个灯亮×,两个车门开√,一个车门开×
+
+2、圆形仪表×,方形仪表对。图中见“8”找“发”;多个数找“速度”;见温度计找“水温表”;见加油机找“燃油表”
+
+3、灯光杆:红色圆圈套在杆子中间答√,没有套上或没有圆圈答×
+
+4、点火开关:钥匙对准中间位置答×,对准两头位置答√
+
+5、ABS题:判断题中见“缩短”答错,没有“缩短”答√。选择题选项中找“急”或“死”
+### 标线题
+1、虚线先找“可”后找“分”两个分看箭头
+
+2、实线找“禁止”
+### 道路信号灯题
+1、三颗灯架横×,竖√(横着题中有“确认安全”或“可以左转”√)
+
+2、两个灯架,两个灯亮√,一个灯亮×
+### 文明驾驶及安全行车题
+1、题中有:不能、不得、不要、不准√
+
+2、题中有:减速、低速、慢√
+
+3、题中有:不减速× 无需减速× 紧急减速×
+
+4、题中有:让行、注意、观察、依次、主动、避兔、等、安全、易、报警√
+
+5、题中有:迅速、快速、尽快、加速、立即×

+ 48 - 0
public/svg/分类练习.svg

@@ -0,0 +1,48 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="51" height="51" viewBox="0 0 51 51">
+  <defs>
+    <style>
+      .cls-1 {
+        fill: #09b379;
+      }
+
+      .cls-2 {
+        fill: #02c38e;
+      }
+
+      .cls-3 {
+        fill: #fff;
+        stroke: rgba(0,0,0,0);
+        stroke-miterlimit: 10;
+      }
+
+      .cls-4 {
+        fill: url(#linear-gradient);
+      }
+
+      .cls-5 {
+        filter: url(#减去_3);
+      }
+    </style>
+    <filter id="减去_3" x="6.5" y="6.5" width="37.744" height="37.744" filterUnits="userSpaceOnUse">
+      <feOffset input="SourceAlpha"/>
+      <feGaussianBlur stdDeviation="3" result="blur"/>
+      <feFlood flood-color="#069b7a" flood-opacity="0.89"/>
+      <feComposite operator="in" in2="blur"/>
+      <feComposite in="SourceGraphic"/>
+    </filter>
+    <linearGradient id="linear-gradient" x1="1.175" y1="-0.112" x2="0.177" y2="0.829" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#01c18d" stop-opacity="0.878"/>
+      <stop offset="1" stop-color="#01c18c" stop-opacity="0.161"/>
+    </linearGradient>
+  </defs>
+  <g id="分类练习" transform="translate(-28 -333)">
+    <rect id="矩形_25" data-name="矩形 25" class="cls-1" width="27" height="27" rx="10" transform="translate(40 345)"/>
+    <rect id="矩形_24" data-name="矩形 24" class="cls-2" width="31" height="31" rx="10" transform="translate(38 343)"/>
+    <g id="组_1164" data-name="组 1164" transform="translate(0 0)">
+      <g class="cls-5" transform="matrix(1, 0, 0, 1, 28, 333)">
+        <path id="减去_3-2" data-name="减去 3" class="cls-3" d="M17.392-53.256H1.426A1.465,1.465,0,0,1,0-54.648V-70.613A1.463,1.463,0,0,1,1.426-72H14.775l3.969,4v13.35A1.409,1.409,0,0,1,17.392-53.256ZM7.5-60a.751.751,0,0,0-.75.75.751.751,0,0,0,.75.75h6a.751.751,0,0,0,.75-.75A.751.751,0,0,0,13.5-60Zm-2.75,0a.751.751,0,0,0-.75.75.751.751,0,0,0,.75.75.751.751,0,0,0,.751-.75A.751.751,0,0,0,4.749-60ZM7.5-63a.751.751,0,0,0-.75.751.751.751,0,0,0,.75.75h6a.751.751,0,0,0,.75-.75A.751.751,0,0,0,13.5-63Zm-2.75,0a.751.751,0,0,0-.75.751.751.751,0,0,0,.75.75.751.751,0,0,0,.751-.75A.751.751,0,0,0,4.749-63ZM7.5-66a.751.751,0,0,0-.75.75.751.751,0,0,0,.75.751h6a.751.751,0,0,0,.75-.751A.751.751,0,0,0,13.5-66Zm-2.75,0a.751.751,0,0,0-.75.75.751.751,0,0,0,.75.751A.751.751,0,0,0,5.5-65.25.751.751,0,0,0,4.749-66Z" transform="translate(16 88)"/>
+      </g>
+      <path id="路径_4387" data-name="路径 4387" class="cls-4" d="M192.336,113.967h2.631L191,110v2.6A1.38,1.38,0,0,0,192.336,113.967Z" transform="translate(-132.223 239)"/>
+    </g>
+  </g>
+</svg>

+ 61 - 0
public/svg/地方专题.svg

@@ -0,0 +1,61 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="51" height="51" viewBox="0 0 51 51">
+  <defs>
+    <style>
+      .cls-1 {
+        fill: #f0cb49;
+      }
+
+      .cls-2 {
+        fill: #ffd54c;
+      }
+
+      .cls-3 {
+        fill: #fff;
+      }
+
+      .cls-4 {
+        fill: url(#linear-gradient);
+      }
+
+      .cls-5 {
+        filter: url(#椭圆_77);
+      }
+
+      .cls-6 {
+        filter: url(#路径_4392);
+      }
+    </style>
+    <filter id="路径_4392" x="11" y="8" width="29.964" height="31.986" filterUnits="userSpaceOnUse">
+      <feOffset input="SourceAlpha"/>
+      <feGaussianBlur stdDeviation="3" result="blur"/>
+      <feFlood flood-color="#f5c21c" flood-opacity="0.831"/>
+      <feComposite operator="in" in2="blur"/>
+      <feComposite in="SourceGraphic"/>
+    </filter>
+    <linearGradient id="linear-gradient" x1="0.533" y1="1" x2="0.526" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#fef9e8"/>
+      <stop offset="1" stop-color="#fcf0c9" stop-opacity="0.302"/>
+    </linearGradient>
+    <filter id="椭圆_77" x="7" y="19.924" width="37" height="24" filterUnits="userSpaceOnUse">
+      <feOffset input="SourceAlpha"/>
+      <feGaussianBlur stdDeviation="3" result="blur-2"/>
+      <feFlood flood-color="#f9c92d" flood-opacity="0.812"/>
+      <feComposite operator="in" in2="blur-2"/>
+      <feComposite in="SourceGraphic"/>
+    </filter>
+  </defs>
+  <g id="地方专题" transform="translate(-298 -346)">
+    <g id="分类" transform="translate(270 13)">
+      <rect id="矩形_25" data-name="矩形 25" class="cls-1" width="27" height="27" rx="10" transform="translate(40 345)"/>
+      <path id="路径_4391" data-name="路径 4391" class="cls-2" d="M10,0H21A10,10,0,0,1,31,10V21A10,10,0,0,1,21,31H10A10,10,0,0,1,0,21V10A10,10,0,0,1,10,0Z" transform="translate(38 343)"/>
+    </g>
+    <g id="组_1165" data-name="组 1165" transform="translate(0 9.924)">
+      <g class="cls-6" transform="matrix(1, 0, 0, 1, 298, 336.08)">
+        <path id="路径_4392-2" data-name="路径 4392" class="cls-3" d="M72.021,0A5.958,5.958,0,0,1,78,5.917a5.708,5.708,0,0,1-1.428,3.832L72.5,13.783a.66.66,0,0,1-.951,0C67.722,10,67.483,9.765,67.468,9.7V9.684A6.076,6.076,0,0,1,66.04,5.851,5.9,5.9,0,0,1,72.02,0Zm0,3.7a2.009,2.009,0,0,0-1.5.606,2.12,2.12,0,1,0,1.5-.606Z" transform="translate(-46.04 17)"/>
+      </g>
+      <g class="cls-5" transform="matrix(1, 0, 0, 1, 298, 336.08)">
+        <ellipse id="椭圆_77-2" data-name="椭圆 77" class="cls-4" cx="9.5" cy="3" rx="9.5" ry="3" transform="translate(16 28.92)"/>
+      </g>
+    </g>
+  </g>
+</svg>

+ 59 - 0
public/svg/学车必看.svg

@@ -0,0 +1,59 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="51" height="51" viewBox="0 0 51 51">
+  <defs>
+    <style>
+      .cls-1 {
+        fill: #09b379;
+      }
+
+      .cls-2 {
+        fill: #02c38e;
+      }
+
+      .cls-3 {
+        fill: url(#linear-gradient);
+      }
+
+      .cls-4 {
+        fill: #fff;
+      }
+
+      .cls-5 {
+        filter: url(#路径_4402);
+      }
+
+      .cls-6 {
+        filter: url(#路径_4401);
+      }
+    </style>
+    <linearGradient id="linear-gradient" x1="0.638" y1="1" x2="0.643" y2="0.268" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#fff" stop-opacity="0.89"/>
+      <stop offset="1" stop-color="#cafbeb" stop-opacity="0.98"/>
+    </linearGradient>
+    <filter id="路径_4401" x="12.846" y="26.922" width="29.537" height="21.078" filterUnits="userSpaceOnUse">
+      <feOffset dy="3" input="SourceAlpha"/>
+      <feGaussianBlur stdDeviation="3" result="blur"/>
+      <feFlood flood-color="#069b7a" flood-opacity="0.89"/>
+      <feComposite operator="in" in2="blur"/>
+      <feComposite in="SourceGraphic"/>
+    </filter>
+    <filter id="路径_4402" x="9" y="7" width="33.383" height="37.228" filterUnits="userSpaceOnUse">
+      <feOffset input="SourceAlpha"/>
+      <feGaussianBlur stdDeviation="3" result="blur-2"/>
+      <feFlood flood-color="#069b7a" flood-opacity="0.89"/>
+      <feComposite operator="in" in2="blur-2"/>
+      <feComposite in="SourceGraphic"/>
+    </filter>
+  </defs>
+  <g id="学车必看" transform="translate(-298 -575)">
+    <rect id="矩形_38" data-name="矩形 38" class="cls-1" width="27" height="27" rx="10" transform="translate(310 587)"/>
+    <rect id="矩形_39" data-name="矩形 39" class="cls-2" width="31" height="31" rx="10" transform="translate(308 585)"/>
+    <g id="组_1177" data-name="组 1177" transform="translate(100.014 467.761)">
+      <g class="cls-6" transform="matrix(1, 0, 0, 1, 197.99, 107.24)">
+        <path id="路径_4401-2" data-name="路径 4401" class="cls-3" d="M368.121,784.176l-.534-.271a1.235,1.235,0,0,0-1.114,0l-.534.271a.307.307,0,0,1-.446-.274v-2.46a.309.309,0,0,1,.309-.309h2.46a.309.309,0,0,1,.309.309v2.46A.307.307,0,0,1,368.121,784.176Zm8.294-2.266h-6.768a.309.309,0,0,0-.309.309v.917a.309.309,0,0,0,.309.309h6.768a.613.613,0,0,0,.614-.614v-.306A.613.613,0,0,0,376.415,781.911Z" transform="translate(-343.65 -748.21)"/>
+      </g>
+      <g class="cls-5" transform="matrix(1, 0, 0, 1, 197.99, 107.24)">
+        <path id="路径_4402-2" data-name="路径 4402" class="cls-4" d="M229.523,123.239H217.831a1.845,1.845,0,0,0-1.846,1.846v15.537a1.845,1.845,0,0,0,1.846,1.846h.923a.309.309,0,0,0,.309-.309v-.917a.309.309,0,0,0-.309-.309H218.3a.771.771,0,1,1,0-1.543h12.457a.613.613,0,0,0,.614-.614V125.084a1.845,1.845,0,0,0-1.846-1.846Zm-1.666,11.891a.665.665,0,0,1-.666.666h-6.874a.665.665,0,0,1-.666-.666v-.2a.665.665,0,0,1,.666-.666h6.871a.665.665,0,0,1,.666.666v.2Zm0-3.714a.665.665,0,0,1-.666.666h-6.874a.665.665,0,0,1-.666-.666v-.2a.665.665,0,0,1,.666-.666h6.871a.665.665,0,0,1,.666.666v.2Zm0-3.717a.665.665,0,0,1-.666.666h-6.874a.665.665,0,0,1-.666-.666v-.2a.665.665,0,0,1,.666-.666h6.871a.665.665,0,0,1,.666.666v.2Z" transform="translate(-197.99 -107.24)"/>
+      </g>
+    </g>
+  </g>
+</svg>

File diff suppressed because it is too large
+ 54 - 0
public/svg/模拟成绩.svg


+ 31 - 0
public/svg/模拟考试仿真题目.svg

@@ -0,0 +1,31 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="125" height="125" viewBox="0 0 125 125">
+  <defs>
+    <style>
+      .cls-1 {
+        fill: #01c18d;
+      }
+
+      .cls-2, .cls-4 {
+        fill: none;
+      }
+
+      .cls-2 {
+        stroke: #b8cae6;
+        stroke-width: 2px;
+        stroke-dasharray: 6;
+      }
+
+      .cls-3 {
+        stroke: none;
+      }
+    </style>
+  </defs>
+  <g id="模拟考试仿真题目" transform="translate(-132 -335)">
+    <circle id="椭圆_72" data-name="椭圆 72" class="cls-1" cx="47.5" cy="47.5" r="47.5" transform="translate(147 350)"/>
+    <path id="路径_4397" data-name="路径 4397" class="cls-1" d="M51.5,0A51.5,51.5,0,1,1,0,51.5,51.5,51.5,0,0,1,51.5,0Z" transform="translate(142 345)"/>
+    <g id="椭圆_78" data-name="椭圆 78" class="cls-2" transform="translate(138 341)">
+      <circle class="cls-3" cx="55.5" cy="55.5" r="55.5"/>
+      <circle class="cls-4" cx="55.5" cy="55.5" r="54.5"/>
+    </g>
+  </g>
+</svg>

+ 44 - 0
public/svg/真实考场模拟.svg

@@ -0,0 +1,44 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="51" height="51" viewBox="0 0 51 51">
+  <defs>
+    <style>
+      .cls-1 {
+        fill: #498ef5;
+      }
+
+      .cls-2 {
+        fill: #fff;
+      }
+
+      .cls-3 {
+        fill: url(#linear-gradient);
+      }
+
+      .cls-4 {
+        filter: url(#减去_5);
+      }
+    </style>
+    <filter id="减去_5" x="8" y="8" width="35.692" height="31.494" filterUnits="userSpaceOnUse">
+      <feOffset input="SourceAlpha"/>
+      <feGaussianBlur stdDeviation="3" result="blur"/>
+      <feFlood flood-color="#1c6ae1"/>
+      <feComposite operator="in" in2="blur"/>
+      <feComposite in="SourceGraphic"/>
+    </filter>
+    <linearGradient id="linear-gradient" x1="0.5" y1="1" x2="0.5" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#e0ebfc" stop-opacity="0.929"/>
+      <stop offset="1" stop-color="#70a9fe" stop-opacity="0.929"/>
+    </linearGradient>
+  </defs>
+  <g id="真实考场模拟" transform="translate(-28 -506)">
+    <g id="组_1162" data-name="组 1162" transform="translate(0 173)">
+      <rect id="矩形_25" data-name="矩形 25" class="cls-1" width="27" height="27" rx="10" transform="translate(40 345)"/>
+      <rect id="矩形_24" data-name="矩形 24" class="cls-1" width="31" height="31" rx="10" transform="translate(38 343)"/>
+    </g>
+    <g id="组_1172" data-name="组 1172" transform="translate(2.121 19)">
+      <g class="cls-4" transform="matrix(1, 0, 0, 1, 25.88, 487)">
+        <path id="减去_5-2" data-name="减去 5" class="cls-2" d="M14.381,14.494H-.931a1.187,1.187,0,0,1-.844-.351,1.194,1.194,0,0,1-.347-.844V2.2a1.186,1.186,0,0,1,.347-.843A1.2,1.2,0,0,1-.931,1H14.381a1.183,1.183,0,0,1,.843.352,1.209,1.209,0,0,1,.346.843V13.3a1.191,1.191,0,0,1-1.19,1.2ZM3.56,7.413a.5.5,0,1,0,0,1H9.679a.5.5,0,0,0,0-1Z" transform="translate(19.12 16)"/>
+      </g>
+      <path id="联合_4" data-name="联合 4" class="cls-3" d="M0,3.5V2.225H2.04V0h8.5V2.225h1.7V3.5Z" transform="translate(45.501 518.342)"/>
+    </g>
+  </g>
+</svg>

+ 31 - 0
public/svg/精选考题.svg

@@ -0,0 +1,31 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="125" height="125" viewBox="0 0 125 125">
+  <defs>
+    <style>
+      .cls-1 {
+        fill: #498ef5;
+      }
+
+      .cls-2, .cls-4 {
+        fill: none;
+      }
+
+      .cls-2 {
+        stroke: #b8cae6;
+        stroke-width: 2px;
+        stroke-dasharray: 6;
+      }
+
+      .cls-3 {
+        stroke: none;
+      }
+    </style>
+  </defs>
+  <g id="精选考题" transform="translate(-132 -335)">
+    <circle id="椭圆_72" data-name="椭圆 72" class="cls-1" cx="47.5" cy="47.5" r="47.5" transform="translate(147 350)"/>
+    <path id="路径_4466" data-name="路径 4466" class="cls-1" d="M51.5,0A51.5,51.5,0,1,1,0,51.5,51.5,51.5,0,0,1,51.5,0Z" transform="translate(142 345)"/>
+    <g id="椭圆_78" data-name="椭圆 78" class="cls-2" transform="translate(138 341)">
+      <circle class="cls-3" cx="55.5" cy="55.5" r="55.5"/>
+      <circle class="cls-4" cx="55.5" cy="55.5" r="54.5"/>
+    </g>
+  </g>
+</svg>

+ 63 - 0
public/svg/考前须知.svg

@@ -0,0 +1,63 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="51" height="51" viewBox="0 0 51 51">
+  <defs>
+    <style>
+      .cls-1 {
+        fill: #f0cb49;
+      }
+
+      .cls-2 {
+        fill: #ffd54c;
+      }
+
+      .cls-3 {
+        fill: #fff;
+      }
+
+      .cls-4 {
+        fill: url(#linear-gradient);
+      }
+
+      .cls-5 {
+        filter: url(#矩形_33);
+      }
+
+      .cls-6 {
+        filter: url(#减去_8);
+      }
+    </style>
+    <filter id="减去_8" x="7" y="9" width="37" height="35" filterUnits="userSpaceOnUse">
+      <feOffset input="SourceAlpha"/>
+      <feGaussianBlur stdDeviation="3" result="blur"/>
+      <feFlood flood-color="#f5c21c" flood-opacity="0.89"/>
+      <feComposite operator="in" in2="blur"/>
+      <feComposite in="SourceGraphic"/>
+    </filter>
+    <linearGradient id="linear-gradient" x1="0.5" y1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#fef9e8"/>
+      <stop offset="1" stop-color="#fcf0c9" stop-opacity="0.302"/>
+    </linearGradient>
+    <filter id="矩形_33" x="13" y="6" width="25" height="21" filterUnits="userSpaceOnUse">
+      <feOffset input="SourceAlpha"/>
+      <feGaussianBlur stdDeviation="3" result="blur-2"/>
+      <feFlood flood-color="#f5c21c" flood-opacity="0.878"/>
+      <feComposite operator="in" in2="blur-2"/>
+      <feComposite in="SourceGraphic"/>
+    </filter>
+  </defs>
+  <g id="考前须知" transform="translate(-298 -506)">
+    <g id="分类" transform="translate(270 173)">
+      <rect id="矩形_25" data-name="矩形 25" class="cls-1" width="27" height="27" rx="10" transform="translate(40 345)"/>
+      <path id="路径_4391" data-name="路径 4391" class="cls-2" d="M10,0H21A10,10,0,0,1,31,10V21A10,10,0,0,1,21,31H10A10,10,0,0,1,0,21V10A10,10,0,0,1,10,0Z" transform="translate(38 343)"/>
+    </g>
+    <g id="组_1178" data-name="组 1178" transform="translate(0 19)">
+      <g class="cls-6" transform="matrix(1, 0, 0, 1, 298, 487)">
+        <path id="减去_8-2" data-name="减去 8" class="cls-3" d="M17,17H2a2,2,0,0,1-2-2V2A2,2,0,0,1,2,0H5.674A1.5,1.5,0,0,0,7.088,1h4.823a1.5,1.5,0,0,0,1.415-1H17a2,2,0,0,1,2,2V15A2,2,0,0,1,17,17ZM6,11a1,1,0,0,0,0,2h7a1,1,0,1,0,0-2ZM6,8a1,1,0,0,0,0,2h7a1,1,0,1,0,0-2ZM6,5A1,1,0,0,0,6,7h7a1,1,0,0,0,0-2Z" transform="translate(16 18)"/>
+      </g>
+      <g id="组_1174" data-name="组 1174" transform="translate(270 153)">
+        <g class="cls-5" transform="matrix(1, 0, 0, 1, 28, 334)">
+          <rect id="矩形_33-2" data-name="矩形 33" class="cls-4" width="7" height="3" rx="1.5" transform="translate(22 15)"/>
+        </g>
+      </g>
+    </g>
+  </g>
+</svg>

+ 44 - 0
public/svg/错题收藏.svg

@@ -0,0 +1,44 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="51" height="51" viewBox="0 0 51 51">
+  <defs>
+    <style>
+      .cls-1 {
+        fill: #ff4c52;
+      }
+
+      .cls-2 {
+        fill: url(#linear-gradient);
+      }
+
+      .cls-3 {
+        fill: #fff;
+      }
+
+      .cls-4 {
+        filter: url(#减去_4);
+      }
+    </style>
+    <linearGradient id="linear-gradient" x1="0.652" y1="0.303" x2="0.623" y2="1.555" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#fff1f1"/>
+      <stop offset="1" stop-color="#ff4a50" stop-opacity="0.149"/>
+    </linearGradient>
+    <filter id="减去_4" x="8.607" y="7.189" width="33.786" height="36.622" filterUnits="userSpaceOnUse">
+      <feOffset input="SourceAlpha"/>
+      <feGaussianBlur stdDeviation="3" result="blur"/>
+      <feFlood flood-color="#de1219" flood-opacity="0.851"/>
+      <feComposite operator="in" in2="blur"/>
+      <feComposite in="SourceGraphic"/>
+    </filter>
+  </defs>
+  <g id="错题收藏" transform="translate(-298 -410)">
+    <g id="分类" transform="translate(270 77)">
+      <rect id="矩形_25" data-name="矩形 25" class="cls-1" width="27" height="27" rx="10" transform="translate(40 345)"/>
+      <path id="路径_4391" data-name="路径 4391" class="cls-1" d="M10,0H21A10,10,0,0,1,31,10V21A10,10,0,0,1,21,31H10A10,10,0,0,1,0,21V10A10,10,0,0,1,10,0Z" transform="translate(38 343)"/>
+    </g>
+    <g id="组_1168" data-name="组 1168" transform="translate(185.444 514.19)">
+      <path id="交叉_1" data-name="交叉 1" class="cls-2" d="M-177.53-499.531l7.872-4.038v8Z" transform="translate(315.586 426.189)"/>
+    </g>
+    <g class="cls-4" transform="matrix(1, 0, 0, 1, 298, 410)">
+      <path id="减去_4-2" data-name="减去 4" class="cls-3" d="M0,18.622V1.858A1.859,1.859,0,0,1,1.857,0H13.929a1.859,1.859,0,0,1,1.857,1.858V10.62L7.914,14.658,7.9,14.65,0,18.621Zm7.893-7.966h0l3.157,1.416-.434-3.307L13,6.333,9.576,5.707,7.893,2.786,6.209,5.707l-3.424.626L5.168,8.766l-.432,3.307,3.157-1.416Z" transform="translate(17.61 16.19)"/>
+    </g>
+  </g>
+</svg>

+ 44 - 0
public/svg/顺序练习.svg

@@ -0,0 +1,44 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="51" height="51" viewBox="0 0 51 51">
+  <defs>
+    <style>
+      .cls-1 {
+        fill: #498ef5;
+      }
+
+      .cls-2 {
+        fill: #fff;
+        stroke: rgba(0,0,0,0);
+        stroke-miterlimit: 10;
+      }
+
+      .cls-3 {
+        fill: url(#linear-gradient);
+      }
+
+      .cls-4 {
+        filter: url(#减去_2);
+      }
+    </style>
+    <filter id="减去_2" x="6.989" y="6.383" width="37.744" height="37.744" filterUnits="userSpaceOnUse">
+      <feOffset input="SourceAlpha"/>
+      <feGaussianBlur stdDeviation="3" result="blur"/>
+      <feFlood flood-color="#1c6ae1"/>
+      <feComposite operator="in" in2="blur"/>
+      <feComposite in="SourceGraphic"/>
+    </filter>
+    <linearGradient id="linear-gradient" x1="1.175" y1="-0.112" x2="0.177" y2="0.829" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#498ef5" stop-opacity="0.631"/>
+      <stop offset="1" stop-color="#438bf9" stop-opacity="0.149"/>
+    </linearGradient>
+  </defs>
+  <g id="顺序练习" transform="translate(-28 -333)">
+    <rect id="矩形_25" data-name="矩形 25" class="cls-1" width="27" height="27" rx="10" transform="translate(40 345)"/>
+    <rect id="矩形_24" data-name="矩形 24" class="cls-1" width="31" height="31" rx="10" transform="translate(38 343)"/>
+    <g id="组_1161" data-name="组 1161" transform="translate(44.489 348.883)">
+      <g class="cls-4" transform="matrix(1, 0, 0, 1, -16.49, -15.88)">
+        <path id="减去_2-2" data-name="减去 2" class="cls-2" d="M17.391,18.744H1.426A1.465,1.465,0,0,1,0,17.352V1.387A1.463,1.463,0,0,1,1.426,0H14.775l3.968,4V17.352A1.409,1.409,0,0,1,17.391,18.744ZM6.58,9.376a.693.693,0,0,0-.5.206L3.99,11.676a.7.7,0,0,0-.2.4.688.688,0,0,0-.007.1.7.7,0,0,0,.206.5l2.094,2.094a.7.7,0,0,0,.29.173l.013,0,.006,0,.008,0,.01,0h.006l.011,0h0l.013,0,.017,0,.017,0,.017,0,.017,0h.1a.7.7,0,0,0,.354-.114l0,0,0,0a.722.722,0,0,0,.105-.087.705.705,0,0,0,0-1l-.907-.906h6.693a2.1,2.1,0,0,0,2.094-2.094v-.7a.7.7,0,0,0-.014-.141V9.918a.7.7,0,0,0-1.38.145v.7a.7.7,0,0,1-.7.7H6.168l.907-.893a.7.7,0,0,0-.5-1.191Zm-.7-2.1h6.693l-.907.9a.7.7,0,0,0-.2.4.691.691,0,0,0-.007.1.7.7,0,0,0,1.2.5L14.754,7.07a.7.7,0,0,0,0-.992L12.659,3.984a.7.7,0,0,0-.991.992l.907.9H5.882a2.075,2.075,0,0,0-.838.175A2.093,2.093,0,0,0,3.787,7.97v.7a.7.7,0,1,0,1.4,0v-.7A.7.7,0,0,1,5.882,7.272Z" transform="translate(16.49 15.88)"/>
+      </g>
+      <path id="路径_4387" data-name="路径 4387" class="cls-3" d="M192.336,113.967h2.631L191,110v2.6A1.38,1.38,0,0,0,192.336,113.967Z" transform="translate(-176.223 -110)"/>
+    </g>
+  </g>
+</svg>

+ 44 - 0
src/App.vue

@@ -0,0 +1,44 @@
+<template>
+  <transition name="slide-left">
+    <router-view></router-view>
+  </transition>
+</template>
+
+<script lang="ts">
+import { defineComponent } from "vue";
+
+export default defineComponent({
+  name: "App",
+});
+</script>
+
+<style lang="scss">
+* {
+  margin: 0;
+  padding: 0;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -khtml-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+#app::-webkit-scrollbar {
+  width: 0px;
+  height: 0px;
+}
+/* 可以设置不同的进入和离开动画   */
+/* 设置持续时间和动画函数        */
+.slide-left-enter,
+.slide-right-leave-active {
+  opacity: 0;
+  -webkit-transform: translate(30px, 0);
+  transform: translate(30px, 0);
+}
+.slide-left-leave-active,
+.slide-right-enter {
+  opacity: 0;
+  -webkit-transform: translate(-30px, 0);
+  transform: translate(-30px, 0);
+}
+</style>

+ 3 - 0
src/api/index.ts

@@ -0,0 +1,3 @@
+export * from "./modules/home";
+export * from "./modules/test";
+export * from "./modules/auth"

+ 16 - 0
src/api/modules/auth.ts

@@ -0,0 +1,16 @@
+import request from "../request";
+
+/**
+ *
+ * @param code 微信code
+ * @returns
+ */
+export function login(code: string) {
+  return request({
+    url: "/twzd-admin/login/code/test",
+    method: "post",
+    params: {
+      authorizationCode: code,
+    },
+  });
+}

+ 5 - 0
src/api/modules/home.ts

@@ -0,0 +1,5 @@
+import request from "../request";
+
+export function apitest(){
+    return {}
+}

+ 63 - 0
src/api/modules/test.ts

@@ -0,0 +1,63 @@
+import request from "../request";
+import Mcok from "mockjs";
+
+/**
+ * 获取题目列表
+ * @returns
+ */
+export function getTopicList() {
+  const type = Mcok.Random.natural(0, 2);
+
+  const getOpts = (type: Number) => {
+    switch (type) {
+      case 0:
+        return ["√", "×"];
+      case 1:
+        return ["A", "B", "C", "D"];
+      case 2:
+        return ["多选A", "多选B", "多选C", "多选D"];
+    }
+  };
+
+  const getAnswer = (type: Number) => {
+    switch (type) {
+      case 0:
+        return "√";
+      case 1:
+        return "A";
+      case 2:
+        return ["多选A", "多选B", "多选C"];
+    }
+  };
+
+  const getUserAnswer = (type: Number) => {
+    switch (type) {
+      case 0:
+        return null;
+      case 1:
+        return null;
+      case 2:
+        return [];
+    }
+  };
+
+  const data = Mcok.mock({
+    code: 200,
+    msg: "请求成功",
+    data: {
+      total: 1000,
+      "list|15": [
+        {
+          explain: "@cparagraph(1, 3)",
+          opts: getOpts(type),
+          type,
+          answer: getAnswer(type),
+          userAnswer: getUserAnswer(type),
+          isTrue: null,
+        },
+      ],
+    },
+  });
+
+  return data;
+}

+ 7 - 0
src/api/request.ts

@@ -0,0 +1,7 @@
+import axios from 'axios'
+
+const request=axios.create({
+    baseURL:'http://192.168.8.213:8080'
+})
+
+export default request

BIN
src/assets/img/bg.png


BIN
src/assets/img/car.png


BIN
src/assets/img/empty.png


BIN
src/assets/img/lx.png


BIN
src/assets/img/mb.png


BIN
src/assets/img/考试不合格.png


BIN
src/assets/img/考试合格.png


BIN
src/assets/logo.png


+ 17 - 0
src/components/index.ts

@@ -0,0 +1,17 @@
+// 导入library文件夹下的所有组件
+// 批量导入需要使用一个函数 require.context(dir,deep,matching)
+// 参数:1. 目录  2. 是否加载子目录  3. 加载的正则匹配
+const modules = import.meta.glob("./*/index.vue");
+// 匹配到的文件名数组
+// console.log('查看匹配到的文件名数组', importFn.keys())
+export default {
+  install(app: any) {
+    // 批量注册全局组件
+    // 遍历文件名数组
+    for (const path in modules) {
+      modules[path]().then((mod) => {
+        app.component(path.split('/')[1], mod.default);
+      });
+    }
+  },
+};

+ 27 - 0
src/components/m-button/index.vue

@@ -0,0 +1,27 @@
+<template>
+  <span class="button" :style="{ width, height }">{{ text }}</span>
+</template>
+
+<script setup lang="ts">
+const props = defineProps({
+  text: String,
+  width: String,
+  height: String,
+});
+</script>
+
+<style lang="scss" scoped>
+.button {
+  width: 100px;
+  height: 40px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  font-size: 15px;
+  border-radius: 20px;
+  &:active {
+    background-color: #cccccc;
+    filter: brightness(50%);
+  }
+}
+</style>

+ 29 - 0
src/components/m-empty/index.vue

@@ -0,0 +1,29 @@
+<template>
+  <div class="empty-box">
+    <img src="/img/empty.png" />
+    <span>别急,努力加载中~</span>
+  </div>
+</template>
+
+<script>
+export default {};
+</script>
+
+<style lang="scss" scoped>
+.empty-box {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 30px;
+  img {
+    width: 80%;
+  }
+  span {
+    font-size: 12px;
+    font-family: PingFang SC;
+    font-weight: 400;
+    color: #8a9099;
+    line-height: 46px;
+  }
+}
+</style>

+ 539 - 0
src/components/m-icon/demo.css

@@ -0,0 +1,539 @@
+/* Logo 字体 */
+@font-face {
+  font-family: "iconfont logo";
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+  font-family: "iconfont logo";
+  font-size: 160px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+  position: relative;
+}
+
+.nav-tabs .nav-more {
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  height: 42px;
+  line-height: 42px;
+  color: #666;
+}
+
+#tabs {
+  border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+  cursor: pointer;
+  width: 100px;
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  font-size: 16px;
+  border-bottom: 2px solid transparent;
+  position: relative;
+  z-index: 1;
+  margin-bottom: -1px;
+  color: #666;
+}
+
+
+#tabs .active {
+  border-bottom-color: #f00;
+  color: #222;
+}
+
+.tab-container .content {
+  display: none;
+}
+
+/* 页面布局 */
+.main {
+  padding: 30px 100px;
+  width: 960px;
+  margin: 0 auto;
+}
+
+.main .logo {
+  color: #333;
+  text-align: left;
+  margin-bottom: 30px;
+  line-height: 1;
+  height: 110px;
+  margin-top: -50px;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.main .logo a {
+  font-size: 160px;
+  color: #333;
+}
+
+.helps {
+  margin-top: 40px;
+}
+
+.helps pre {
+  padding: 20px;
+  margin: 10px 0;
+  border: solid 1px #e7e1cd;
+  background-color: #fffdef;
+  overflow: auto;
+}
+
+.icon_lists {
+  width: 100% !important;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.icon_lists li {
+  width: 100px;
+  margin-bottom: 10px;
+  margin-right: 20px;
+  text-align: center;
+  list-style: none !important;
+  cursor: default;
+}
+
+.icon_lists li .code-name {
+  line-height: 1.2;
+}
+
+.icon_lists .icon {
+  display: block;
+  height: 100px;
+  line-height: 100px;
+  font-size: 42px;
+  margin: 10px auto;
+  color: #333;
+  -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+  -moz-transition: font-size 0.25s linear, width 0.25s linear;
+  transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+  font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+  /* 通过设置 font-size 来改变图标大小 */
+  width: 1em;
+  /* 图标和文字相邻时,垂直对齐 */
+  vertical-align: -0.15em;
+  /* 通过设置 color 来改变 SVG 的颜色/fill */
+  fill: currentColor;
+  /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+      normalize.css 中也包含这行 */
+  overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+  color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+  color: #666;
+  font-size: 14px;
+  line-height: 1.8;
+}
+
+.highlight {
+  line-height: 1.5;
+}
+
+.markdown img {
+  vertical-align: middle;
+  max-width: 100%;
+}
+
+.markdown h1 {
+  color: #404040;
+  font-weight: 500;
+  line-height: 40px;
+  margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+  color: #404040;
+  margin: 1.6em 0 0.6em 0;
+  font-weight: 500;
+  clear: both;
+}
+
+.markdown h1 {
+  font-size: 28px;
+}
+
+.markdown h2 {
+  font-size: 22px;
+}
+
+.markdown h3 {
+  font-size: 16px;
+}
+
+.markdown h4 {
+  font-size: 14px;
+}
+
+.markdown h5 {
+  font-size: 12px;
+}
+
+.markdown h6 {
+  font-size: 12px;
+}
+
+.markdown hr {
+  height: 1px;
+  border: 0;
+  background: #e9e9e9;
+  margin: 16px 0;
+  clear: both;
+}
+
+.markdown p {
+  margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+  width: 80%;
+}
+
+.markdown ul>li {
+  list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+  margin: 0.6em 0;
+}
+
+.markdown ol>li {
+  list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown code {
+  margin: 0 3px;
+  padding: 0 5px;
+  background: #eee;
+  border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+  font-weight: 600;
+}
+
+.markdown>table {
+  border-collapse: collapse;
+  border-spacing: 0px;
+  empty-cells: show;
+  border: 1px solid #e9e9e9;
+  width: 95%;
+  margin-bottom: 24px;
+}
+
+.markdown>table th {
+  white-space: nowrap;
+  color: #333;
+  font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+  border: 1px solid #e9e9e9;
+  padding: 8px 16px;
+  text-align: left;
+}
+
+.markdown>table th {
+  background: #F7F7F7;
+}
+
+.markdown blockquote {
+  font-size: 90%;
+  color: #999;
+  border-left: 4px solid #e9e9e9;
+  padding-left: 0.8em;
+  margin: 1em 0;
+}
+
+.markdown blockquote p {
+  margin: 0;
+}
+
+.markdown .anchor {
+  opacity: 0;
+  transition: opacity 0.3s ease;
+  margin-left: 8px;
+}
+
+.markdown .waiting {
+  color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+  opacity: 1;
+  display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+  clear: both;
+}
+
+
+.hljs {
+  display: block;
+  background: white;
+  padding: 0.5em;
+  color: #333333;
+  overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+  color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+  color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+  color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+  color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+  color: #63a35c;
+}
+
+.hljs-tag {
+  color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+  color: #795da3;
+}
+
+.hljs-addition {
+  color: #55a532;
+  background-color: #eaffea;
+}
+
+.hljs-deletion {
+  color: #bd2c00;
+  background-color: #ffecec;
+}
+
+.hljs-link {
+  text-decoration: underline;
+}
+
+/* 代码高亮 */
+/* PrismJS 1.15.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+  color: black;
+  background: none;
+  text-shadow: 0 1px white;
+  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  line-height: 1.5;
+
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+@media print {
+
+  code[class*="language-"],
+  pre[class*="language-"] {
+    text-shadow: none;
+  }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+  padding: 1em;
+  margin: .5em 0;
+  overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+  background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+  padding: .1em;
+  border-radius: .3em;
+  white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+  color: slategray;
+}
+
+.token.punctuation {
+  color: #999;
+}
+
+.namespace {
+  opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+  color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+  color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+  color: #9a6e3a;
+  background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+  color: #07a;
+}
+
+.token.function,
+.token.class-name {
+  color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+  color: #e90;
+}
+
+.token.important,
+.token.bold {
+  font-weight: bold;
+}
+
+.token.italic {
+  font-style: italic;
+}
+
+.token.entity {
+  cursor: help;
+}

+ 1178 - 0
src/components/m-icon/demo_index.html

@@ -0,0 +1,1178 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8"/>
+  <title>iconfont Demo</title>
+  <link rel="shortcut icon" href="//img.alicdn.com/imgextra/i2/O1CN01ZyAlrn1MwaMhqz36G_!!6000000001499-73-tps-64-64.ico" type="image/x-icon"/>
+  <link rel="icon" type="image/svg+xml" href="//img.alicdn.com/imgextra/i4/O1CN01EYTRnJ297D6vehehJ_!!6000000008020-55-tps-64-64.svg"/>
+  <link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
+  <link rel="stylesheet" href="demo.css">
+  <link rel="stylesheet" href="iconfont.css">
+  <script src="iconfont.js"></script>
+  <!-- jQuery -->
+  <script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
+  <!-- 代码高亮 -->
+  <script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
+  <style>
+    .main .logo {
+      margin-top: 0;
+      height: auto;
+    }
+
+    .main .logo a {
+      display: flex;
+      align-items: center;
+    }
+
+    .main .logo .sub-title {
+      margin-left: 0.5em;
+      font-size: 22px;
+      color: #fff;
+      background: linear-gradient(-45deg, #3967FF, #B500FE);
+      -webkit-background-clip: text;
+      -webkit-text-fill-color: transparent;
+    }
+  </style>
+</head>
+<body>
+  <div class="main">
+    <h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank">
+      <img width="200" src="https://img.alicdn.com/imgextra/i3/O1CN01Mn65HV1FfSEzR6DKv_!!6000000000514-55-tps-228-59.svg">
+      
+        <span class="sub-title">彩色字体</span>
+      
+    </a></h1>
+    <div class="nav-tabs">
+      <ul id="tabs" class="dib-box">
+        <li class="dib active"><span>Unicode</span></li>
+        <li class="dib"><span>Font class</span></li>
+        <li class="dib"><span>Symbol</span></li>
+      </ul>
+      
+      <a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=2734764" target="_blank" class="nav-more">查看项目</a>
+      
+    </div>
+    <div class="tab-container">
+      <div class="content unicode" style="display: block;">
+          <ul class="icon_lists dib-box">
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe607;</span>
+                <div class="name">一级标题装饰</div>
+                <div class="code-name">&amp;#xe607;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe606;</span>
+                <div class="name">二级标题装饰</div>
+                <div class="code-name">&amp;#xe606;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe645;</span>
+                <div class="name">交卷</div>
+                <div class="code-name">&amp;#xe645;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe644;</span>
+                <div class="name">关闭</div>
+                <div class="code-name">&amp;#xe644;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe605;</span>
+                <div class="name">驾考灰</div>
+                <div class="code-name">&amp;#xe605;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe604;</span>
+                <div class="name">发现灰 </div>
+                <div class="code-name">&amp;#xe604;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe603;</span>
+                <div class="name">我的灰</div>
+                <div class="code-name">&amp;#xe603;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe643;</span>
+                <div class="name">暂停</div>
+                <div class="code-name">&amp;#xe643;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe642;</span>
+                <div class="name">更新摘要</div>
+                <div class="code-name">&amp;#xe642;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe641;</span>
+                <div class="name">微信</div>
+                <div class="code-name">&amp;#xe641;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe640;</span>
+                <div class="name">反馈帮助</div>
+                <div class="code-name">&amp;#xe640;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe63f;</span>
+                <div class="name">版本更新</div>
+                <div class="code-name">&amp;#xe63f;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe63e;</span>
+                <div class="name">专属老师</div>
+                <div class="code-name">&amp;#xe63e;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe63d;</span>
+                <div class="name">激活码</div>
+                <div class="code-name">&amp;#xe63d;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe63c;</span>
+                <div class="name">会员有效期</div>
+                <div class="code-name">&amp;#xe63c;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe63b;</span>
+                <div class="name">答题剩余时间</div>
+                <div class="code-name">&amp;#xe63b;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe63a;</span>
+                <div class="name">选中</div>
+                <div class="code-name">&amp;#xe63a;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe639;</span>
+                <div class="name">未选中</div>
+                <div class="code-name">&amp;#xe639;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe638;</span>
+                <div class="name">收藏黄</div>
+                <div class="code-name">&amp;#xe638;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe637;</span>
+                <div class="name">错</div>
+                <div class="code-name">&amp;#xe637;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe636;</span>
+                <div class="name">对</div>
+                <div class="code-name">&amp;#xe636;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe635;</span>
+                <div class="name">官方解释</div>
+                <div class="code-name">&amp;#xe635;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe634;</span>
+                <div class="name">总题数</div>
+                <div class="code-name">&amp;#xe634;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe633;</span>
+                <div class="name">下一题</div>
+                <div class="code-name">&amp;#xe633;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe632;</span>
+                <div class="name">上一题</div>
+                <div class="code-name">&amp;#xe632;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe631;</span>
+                <div class="name">技巧讲解</div>
+                <div class="code-name">&amp;#xe631;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe630;</span>
+                <div class="name">读题</div>
+                <div class="code-name">&amp;#xe630;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe62f;</span>
+                <div class="name">读题+答案</div>
+                <div class="code-name">&amp;#xe62f;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe62e;</span>
+                <div class="name">收藏灰</div>
+                <div class="code-name">&amp;#xe62e;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe62d;</span>
+                <div class="name">自动读题</div>
+                <div class="code-name">&amp;#xe62d;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe62c;</span>
+                <div class="name">设置</div>
+                <div class="code-name">&amp;#xe62c;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe62b;</span>
+                <div class="name">返回</div>
+                <div class="code-name">&amp;#xe62b;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe62a;</span>
+                <div class="name">单项选择</div>
+                <div class="code-name">&amp;#xe62a;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe629;</span>
+                <div class="name">语音讲解</div>
+                <div class="code-name">&amp;#xe629;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe627;</span>
+                <div class="name">我的蓝</div>
+                <div class="code-name">&amp;#xe627;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe626;</span>
+                <div class="name">发现蓝</div>
+                <div class="code-name">&amp;#xe626;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe625;</span>
+                <div class="name">驾考蓝</div>
+                <div class="code-name">&amp;#xe625;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe624;</span>
+                <div class="name">摩托车</div>
+                <div class="code-name">&amp;#xe624;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe623;</span>
+                <div class="name">货车</div>
+                <div class="code-name">&amp;#xe623;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe622;</span>
+                <div class="name">客车</div>
+                <div class="code-name">&amp;#xe622;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe621;</span>
+                <div class="name">轿车</div>
+                <div class="code-name">&amp;#xe621;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe620;</span>
+                <div class="name">会员</div>
+                <div class="code-name">&amp;#xe620;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe61f;</span>
+                <div class="name">会员头像</div>
+                <div class="code-name">&amp;#xe61f;</div>
+              </li>
+          
+          </ul>
+          <div class="article markdown">
+          <h2 id="unicode-">Unicode 引用</h2>
+          <hr>
+
+          <p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
+          <ul>
+            <li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
+            <li>默认情况下不支持多色,直接添加多色图标会自动去色。</li>
+          </ul>
+          <blockquote>
+            <p>注意:新版 iconfont 支持两种方式引用多色图标:SVG symbol 引用方式和彩色字体图标模式。(使用彩色字体图标需要在「编辑项目」中开启「彩色」选项后并重新生成。)</p>
+          </blockquote>
+          <p>Unicode 使用步骤如下:</p>
+          <h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
+<pre><code class="language-css"
+>@font-face {
+  font-family: 'iconfont';
+  src: 
+       url('iconfont.ttf?t=1632279067782') format('truetype');
+}
+</code></pre>
+          <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
+<pre><code class="language-css"
+>.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+</code></pre>
+          <h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
+<pre>
+<code class="language-html"
+>&lt;span class="iconfont"&gt;&amp;#x33;&lt;/span&gt;
+</code></pre>
+          <blockquote>
+            <p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
+          </blockquote>
+          </div>
+      </div>
+      <div class="content font-class">
+        <ul class="icon_lists dib-box">
+          
+          <li class="dib">
+            <span class="icon iconfont icon-biaotizhuangshi3"></span>
+            <div class="name">
+              一级标题装饰
+            </div>
+            <div class="code-name">.icon-biaotizhuangshi3
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-biaotizhuangshi1"></span>
+            <div class="name">
+              二级标题装饰
+            </div>
+            <div class="code-name">.icon-biaotizhuangshi1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jiaojuan"></span>
+            <div class="name">
+              交卷
+            </div>
+            <div class="code-name">.icon-jiaojuan
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-guanbi"></span>
+            <div class="name">
+              关闭
+            </div>
+            <div class="code-name">.icon-guanbi
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jiakaohui"></span>
+            <div class="name">
+              驾考灰
+            </div>
+            <div class="code-name">.icon-jiakaohui
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-faxianhui"></span>
+            <div class="name">
+              发现灰 
+            </div>
+            <div class="code-name">.icon-faxianhui
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-wodehui"></span>
+            <div class="name">
+              我的灰
+            </div>
+            <div class="code-name">.icon-wodehui
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-zanting"></span>
+            <div class="name">
+              暂停
+            </div>
+            <div class="code-name">.icon-zanting
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-gengxinzhaiyao"></span>
+            <div class="name">
+              更新摘要
+            </div>
+            <div class="code-name">.icon-gengxinzhaiyao
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-weixin"></span>
+            <div class="name">
+              微信
+            </div>
+            <div class="code-name">.icon-weixin
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-fkbz"></span>
+            <div class="name">
+              反馈帮助
+            </div>
+            <div class="code-name">.icon-fkbz
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-bbgx"></span>
+            <div class="name">
+              版本更新
+            </div>
+            <div class="code-name">.icon-bbgx
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-zsls"></span>
+            <div class="name">
+              专属老师
+            </div>
+            <div class="code-name">.icon-zsls
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jihuoma"></span>
+            <div class="name">
+              激活码
+            </div>
+            <div class="code-name">.icon-jihuoma
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-hyyxq"></span>
+            <div class="name">
+              会员有效期
+            </div>
+            <div class="code-name">.icon-hyyxq
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-dtsysj"></span>
+            <div class="name">
+              答题剩余时间
+            </div>
+            <div class="code-name">.icon-dtsysj
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-xuanzhong"></span>
+            <div class="name">
+              选中
+            </div>
+            <div class="code-name">.icon-xuanzhong
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-weixuanzhong"></span>
+            <div class="name">
+              未选中
+            </div>
+            <div class="code-name">.icon-weixuanzhong
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-shoucanghuang"></span>
+            <div class="name">
+              收藏黄
+            </div>
+            <div class="code-name">.icon-shoucanghuang
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-cuo"></span>
+            <div class="name">
+              错
+            </div>
+            <div class="code-name">.icon-cuo
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-dui"></span>
+            <div class="name">
+              对
+            </div>
+            <div class="code-name">.icon-dui
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-gfjs"></span>
+            <div class="name">
+              官方解释
+            </div>
+            <div class="code-name">.icon-gfjs
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-zongtishu"></span>
+            <div class="name">
+              总题数
+            </div>
+            <div class="code-name">.icon-zongtishu
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-xiayiti"></span>
+            <div class="name">
+              下一题
+            </div>
+            <div class="code-name">.icon-xiayiti
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-shangyiti"></span>
+            <div class="name">
+              上一题
+            </div>
+            <div class="code-name">.icon-shangyiti
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jqjj"></span>
+            <div class="name">
+              技巧讲解
+            </div>
+            <div class="code-name">.icon-jqjj
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-duti"></span>
+            <div class="name">
+              读题
+            </div>
+            <div class="code-name">.icon-duti
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-a-dtda"></span>
+            <div class="name">
+              读题+答案
+            </div>
+            <div class="code-name">.icon-a-dtda
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-shoucanghui"></span>
+            <div class="name">
+              收藏灰
+            </div>
+            <div class="code-name">.icon-shoucanghui
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-zddt"></span>
+            <div class="name">
+              自动读题
+            </div>
+            <div class="code-name">.icon-zddt
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-shezhi"></span>
+            <div class="name">
+              设置
+            </div>
+            <div class="code-name">.icon-shezhi
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-fanhui"></span>
+            <div class="name">
+              返回
+            </div>
+            <div class="code-name">.icon-fanhui
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-dxxz"></span>
+            <div class="name">
+              单项选择
+            </div>
+            <div class="code-name">.icon-dxxz
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-yyjj"></span>
+            <div class="name">
+              语音讲解
+            </div>
+            <div class="code-name">.icon-yyjj
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-wode"></span>
+            <div class="name">
+              我的蓝
+            </div>
+            <div class="code-name">.icon-wode
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-faxian"></span>
+            <div class="name">
+              发现蓝
+            </div>
+            <div class="code-name">.icon-faxian
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jiakao"></span>
+            <div class="name">
+              驾考蓝
+            </div>
+            <div class="code-name">.icon-jiakao
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-motuoche"></span>
+            <div class="name">
+              摩托车
+            </div>
+            <div class="code-name">.icon-motuoche
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-huoche"></span>
+            <div class="name">
+              货车
+            </div>
+            <div class="code-name">.icon-huoche
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-keche"></span>
+            <div class="name">
+              客车
+            </div>
+            <div class="code-name">.icon-keche
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jiaoche"></span>
+            <div class="name">
+              轿车
+            </div>
+            <div class="code-name">.icon-jiaoche
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-huiyuan"></span>
+            <div class="name">
+              会员
+            </div>
+            <div class="code-name">.icon-huiyuan
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-hytx"></span>
+            <div class="name">
+              会员头像
+            </div>
+            <div class="code-name">.icon-hytx
+            </div>
+          </li>
+          
+        </ul>
+        <div class="article markdown">
+        <h2 id="font-class-">font-class 引用</h2>
+        <hr>
+
+        <p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
+        <p>与 Unicode 使用方式相比,具有如下特点:</p>
+        <ul>
+          <li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
+          <li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
+        </ul>
+        <p>使用步骤如下:</p>
+        <h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
+<pre><code class="language-html">&lt;link rel="stylesheet" href="./iconfont.css"&gt;
+</code></pre>
+        <h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
+<pre><code class="language-html">&lt;span class="iconfont icon-xxx"&gt;&lt;/span&gt;
+</code></pre>
+        <blockquote>
+          <p>"
+            iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
+        </blockquote>
+      </div>
+      </div>
+      <div class="content symbol">
+          <ul class="icon_lists dib-box">
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-biaotizhuangshi3"></use>
+                </svg>
+                <div class="name">一级标题装饰</div>
+                <div class="code-name">#icon-biaotizhuangshi3</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-biaotizhuangshi1"></use>
+                </svg>
+                <div class="name">二级标题装饰</div>
+                <div class="code-name">#icon-biaotizhuangshi1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jiaojuan"></use>
+                </svg>
+                <div class="name">交卷</div>
+                <div class="code-name">#icon-jiaojuan</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-guanbi"></use>
+                </svg>
+                <div class="name">关闭</div>
+                <div class="code-name">#icon-guanbi</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jiakaohui"></use>
+                </svg>
+                <div class="name">驾考灰</div>
+                <div class="code-name">#icon-jiakaohui</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-faxianhui"></use>
+                </svg>
+                <div class="name">发现灰 </div>
+                <div class="code-name">#icon-faxianhui</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-wodehui"></use>
+                </svg>
+                <div class="name">我的灰</div>
+                <div class="code-name">#icon-wodehui</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-zanting"></use>
+                </svg>
+                <div class="name">暂停</div>
+                <div class="code-name">#icon-zanting</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-gengxinzhaiyao"></use>
+                </svg>
+                <div class="name">更新摘要</div>
+                <div class="code-name">#icon-gengxinzhaiyao</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-weixin"></use>
+                </svg>
+                <div class="name">微信</div>
+                <div class="code-name">#icon-weixin</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-fkbz"></use>
+                </svg>
+                <div class="name">反馈帮助</div>
+                <div class="code-name">#icon-fkbz</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-bbgx"></use>
+                </svg>
+                <div class="name">版本更新</div>
+                <div class="code-name">#icon-bbgx</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-zsls"></use>
+                </svg>
+                <div class="name">专属老师</div>
+                <div class="code-name">#icon-zsls</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jihuoma"></use>
+                </svg>
+                <div class="name">激活码</div>
+                <div class="code-name">#icon-jihuoma</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-hyyxq"></use>
+                </svg>
+                <div class="name">会员有效期</div>
+                <div class="code-name">#icon-hyyxq</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-dtsysj"></use>
+                </svg>
+                <div class="name">答题剩余时间</div>
+                <div class="code-name">#icon-dtsysj</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-xuanzhong"></use>
+                </svg>
+                <div class="name">选中</div>
+                <div class="code-name">#icon-xuanzhong</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-weixuanzhong"></use>
+                </svg>
+                <div class="name">未选中</div>
+                <div class="code-name">#icon-weixuanzhong</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-shoucanghuang"></use>
+                </svg>
+                <div class="name">收藏黄</div>
+                <div class="code-name">#icon-shoucanghuang</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-cuo"></use>
+                </svg>
+                <div class="name">错</div>
+                <div class="code-name">#icon-cuo</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-dui"></use>
+                </svg>
+                <div class="name">对</div>
+                <div class="code-name">#icon-dui</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-gfjs"></use>
+                </svg>
+                <div class="name">官方解释</div>
+                <div class="code-name">#icon-gfjs</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-zongtishu"></use>
+                </svg>
+                <div class="name">总题数</div>
+                <div class="code-name">#icon-zongtishu</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-xiayiti"></use>
+                </svg>
+                <div class="name">下一题</div>
+                <div class="code-name">#icon-xiayiti</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-shangyiti"></use>
+                </svg>
+                <div class="name">上一题</div>
+                <div class="code-name">#icon-shangyiti</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jqjj"></use>
+                </svg>
+                <div class="name">技巧讲解</div>
+                <div class="code-name">#icon-jqjj</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-duti"></use>
+                </svg>
+                <div class="name">读题</div>
+                <div class="code-name">#icon-duti</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-a-dtda"></use>
+                </svg>
+                <div class="name">读题+答案</div>
+                <div class="code-name">#icon-a-dtda</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-shoucanghui"></use>
+                </svg>
+                <div class="name">收藏灰</div>
+                <div class="code-name">#icon-shoucanghui</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-zddt"></use>
+                </svg>
+                <div class="name">自动读题</div>
+                <div class="code-name">#icon-zddt</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-shezhi"></use>
+                </svg>
+                <div class="name">设置</div>
+                <div class="code-name">#icon-shezhi</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-fanhui"></use>
+                </svg>
+                <div class="name">返回</div>
+                <div class="code-name">#icon-fanhui</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-dxxz"></use>
+                </svg>
+                <div class="name">单项选择</div>
+                <div class="code-name">#icon-dxxz</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-yyjj"></use>
+                </svg>
+                <div class="name">语音讲解</div>
+                <div class="code-name">#icon-yyjj</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-wode"></use>
+                </svg>
+                <div class="name">我的蓝</div>
+                <div class="code-name">#icon-wode</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-faxian"></use>
+                </svg>
+                <div class="name">发现蓝</div>
+                <div class="code-name">#icon-faxian</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jiakao"></use>
+                </svg>
+                <div class="name">驾考蓝</div>
+                <div class="code-name">#icon-jiakao</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-motuoche"></use>
+                </svg>
+                <div class="name">摩托车</div>
+                <div class="code-name">#icon-motuoche</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-huoche"></use>
+                </svg>
+                <div class="name">货车</div>
+                <div class="code-name">#icon-huoche</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-keche"></use>
+                </svg>
+                <div class="name">客车</div>
+                <div class="code-name">#icon-keche</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jiaoche"></use>
+                </svg>
+                <div class="name">轿车</div>
+                <div class="code-name">#icon-jiaoche</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-huiyuan"></use>
+                </svg>
+                <div class="name">会员</div>
+                <div class="code-name">#icon-huiyuan</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-hytx"></use>
+                </svg>
+                <div class="name">会员头像</div>
+                <div class="code-name">#icon-hytx</div>
+            </li>
+          
+          </ul>
+          <div class="article markdown">
+          <h2 id="symbol-">Symbol 引用</h2>
+          <hr>
+
+          <p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
+            这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
+          <ul>
+            <li>支持多色图标了,不再受单色限制。</li>
+            <li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
+            <li>兼容性较差,支持 IE9+,及现代浏览器。</li>
+            <li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
+          </ul>
+          <p>使用步骤如下:</p>
+          <h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
+<pre><code class="language-html">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;
+</code></pre>
+          <h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
+<pre><code class="language-html">&lt;style&gt;
+.icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+&lt;/style&gt;
+</code></pre>
+          <h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
+<pre><code class="language-html">&lt;svg class="icon" aria-hidden="true"&gt;
+  &lt;use xlink:href="#icon-xxx"&gt;&lt;/use&gt;
+&lt;/svg&gt;
+</code></pre>
+          </div>
+      </div>
+
+    </div>
+  </div>
+  <script>
+  $(document).ready(function () {
+      $('.tab-container .content:first').show()
+
+      $('#tabs li').click(function (e) {
+        var tabContent = $('.tab-container .content')
+        var index = $(this).index()
+
+        if ($(this).hasClass('active')) {
+          return
+        } else {
+          $('#tabs li').removeClass('active')
+          $(this).addClass('active')
+
+          tabContent.hide().eq(index).fadeIn()
+        }
+      })
+    })
+  </script>
+</body>
+</html>

+ 187 - 0
src/components/m-icon/iconfont.css

@@ -0,0 +1,187 @@
+@font-face {
+  font-family: "iconfont"; /* Project id 2734764 */
+  /* Color fonts */
+  src: 
+       url('iconfont.ttf?t=1632279067782') format('truetype');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-biaotizhuangshi3:before {
+  content: "\e607";
+}
+
+.icon-biaotizhuangshi1:before {
+  content: "\e606";
+}
+
+.icon-jiaojuan:before {
+  content: "\e645";
+}
+
+.icon-guanbi:before {
+  content: "\e644";
+}
+
+.icon-jiakaohui:before {
+  content: "\e605";
+}
+
+.icon-faxianhui:before {
+  content: "\e604";
+}
+
+.icon-wodehui:before {
+  content: "\e603";
+}
+
+.icon-zanting:before {
+  content: "\e643";
+}
+
+.icon-gengxinzhaiyao:before {
+  content: "\e642";
+}
+
+.icon-weixin:before {
+  content: "\e641";
+}
+
+.icon-fkbz:before {
+  content: "\e640";
+}
+
+.icon-bbgx:before {
+  content: "\e63f";
+}
+
+.icon-zsls:before {
+  content: "\e63e";
+}
+
+.icon-jihuoma:before {
+  content: "\e63d";
+}
+
+.icon-hyyxq:before {
+  content: "\e63c";
+}
+
+.icon-dtsysj:before {
+  content: "\e63b";
+}
+
+.icon-xuanzhong:before {
+  content: "\e63a";
+}
+
+.icon-weixuanzhong:before {
+  content: "\e639";
+}
+
+.icon-shoucanghuang:before {
+  content: "\e638";
+}
+
+.icon-cuo:before {
+  content: "\e637";
+}
+
+.icon-dui:before {
+  content: "\e636";
+}
+
+.icon-gfjs:before {
+  content: "\e635";
+}
+
+.icon-zongtishu:before {
+  content: "\e634";
+}
+
+.icon-xiayiti:before {
+  content: "\e633";
+}
+
+.icon-shangyiti:before {
+  content: "\e632";
+}
+
+.icon-jqjj:before {
+  content: "\e631";
+}
+
+.icon-duti:before {
+  content: "\e630";
+}
+
+.icon-a-dtda:before {
+  content: "\e62f";
+}
+
+.icon-shoucanghui:before {
+  content: "\e62e";
+}
+
+.icon-zddt:before {
+  content: "\e62d";
+}
+
+.icon-shezhi:before {
+  content: "\e62c";
+}
+
+.icon-fanhui:before {
+  content: "\e62b";
+}
+
+.icon-dxxz:before {
+  content: "\e62a";
+}
+
+.icon-yyjj:before {
+  content: "\e629";
+}
+
+.icon-wode:before {
+  content: "\e627";
+}
+
+.icon-faxian:before {
+  content: "\e626";
+}
+
+.icon-jiakao:before {
+  content: "\e625";
+}
+
+.icon-motuoche:before {
+  content: "\e624";
+}
+
+.icon-huoche:before {
+  content: "\e623";
+}
+
+.icon-keche:before {
+  content: "\e622";
+}
+
+.icon-jiaoche:before {
+  content: "\e621";
+}
+
+.icon-huiyuan:before {
+  content: "\e620";
+}
+
+.icon-hytx:before {
+  content: "\e61f";
+}
+

File diff suppressed because it is too large
+ 0 - 0
src/components/m-icon/iconfont.js


+ 310 - 0
src/components/m-icon/iconfont.json

@@ -0,0 +1,310 @@
+{
+  "id": "2734764",
+  "name": "头文字D",
+  "font_family": "iconfont",
+  "css_prefix_text": "icon-",
+  "description": "公众号H5和APP图标管理",
+  "glyphs": [
+    {
+      "icon_id": "24477933",
+      "name": "一级标题装饰",
+      "font_class": "biaotizhuangshi3",
+      "unicode": "e607",
+      "unicode_decimal": 58887
+    },
+    {
+      "icon_id": "24477901",
+      "name": "二级标题装饰",
+      "font_class": "biaotizhuangshi1",
+      "unicode": "e606",
+      "unicode_decimal": 58886
+    },
+    {
+      "icon_id": "24195264",
+      "name": "交卷",
+      "font_class": "jiaojuan",
+      "unicode": "e645",
+      "unicode_decimal": 58949
+    },
+    {
+      "icon_id": "24157480",
+      "name": "关闭",
+      "font_class": "guanbi",
+      "unicode": "e644",
+      "unicode_decimal": 58948
+    },
+    {
+      "icon_id": "23639243",
+      "name": "驾考灰",
+      "font_class": "jiakaohui",
+      "unicode": "e605",
+      "unicode_decimal": 58885
+    },
+    {
+      "icon_id": "23639232",
+      "name": "发现灰 ",
+      "font_class": "faxianhui",
+      "unicode": "e604",
+      "unicode_decimal": 58884
+    },
+    {
+      "icon_id": "23639223",
+      "name": "我的灰",
+      "font_class": "wodehui",
+      "unicode": "e603",
+      "unicode_decimal": 58883
+    },
+    {
+      "icon_id": "23567522",
+      "name": "暂停",
+      "font_class": "zanting",
+      "unicode": "e643",
+      "unicode_decimal": 58947
+    },
+    {
+      "icon_id": "23476972",
+      "name": "更新摘要",
+      "font_class": "gengxinzhaiyao",
+      "unicode": "e642",
+      "unicode_decimal": 58946
+    },
+    {
+      "icon_id": "23476894",
+      "name": "微信",
+      "font_class": "weixin",
+      "unicode": "e641",
+      "unicode_decimal": 58945
+    },
+    {
+      "icon_id": "23476722",
+      "name": "反馈帮助",
+      "font_class": "fkbz",
+      "unicode": "e640",
+      "unicode_decimal": 58944
+    },
+    {
+      "icon_id": "23476710",
+      "name": "版本更新",
+      "font_class": "bbgx",
+      "unicode": "e63f",
+      "unicode_decimal": 58943
+    },
+    {
+      "icon_id": "23476685",
+      "name": "专属老师",
+      "font_class": "zsls",
+      "unicode": "e63e",
+      "unicode_decimal": 58942
+    },
+    {
+      "icon_id": "23476674",
+      "name": "激活码",
+      "font_class": "jihuoma",
+      "unicode": "e63d",
+      "unicode_decimal": 58941
+    },
+    {
+      "icon_id": "23476642",
+      "name": "会员有效期",
+      "font_class": "hyyxq",
+      "unicode": "e63c",
+      "unicode_decimal": 58940
+    },
+    {
+      "icon_id": "23476487",
+      "name": "答题剩余时间",
+      "font_class": "dtsysj",
+      "unicode": "e63b",
+      "unicode_decimal": 58939
+    },
+    {
+      "icon_id": "23476440",
+      "name": "选中",
+      "font_class": "xuanzhong",
+      "unicode": "e63a",
+      "unicode_decimal": 58938
+    },
+    {
+      "icon_id": "23476434",
+      "name": "未选中",
+      "font_class": "weixuanzhong",
+      "unicode": "e639",
+      "unicode_decimal": 58937
+    },
+    {
+      "icon_id": "23476053",
+      "name": "收藏黄",
+      "font_class": "shoucanghuang",
+      "unicode": "e638",
+      "unicode_decimal": 58936
+    },
+    {
+      "icon_id": "23475952",
+      "name": "错",
+      "font_class": "cuo",
+      "unicode": "e637",
+      "unicode_decimal": 58935
+    },
+    {
+      "icon_id": "23475945",
+      "name": "对",
+      "font_class": "dui",
+      "unicode": "e636",
+      "unicode_decimal": 58934
+    },
+    {
+      "icon_id": "23475226",
+      "name": "官方解释",
+      "font_class": "gfjs",
+      "unicode": "e635",
+      "unicode_decimal": 58933
+    },
+    {
+      "icon_id": "23472634",
+      "name": "总题数",
+      "font_class": "zongtishu",
+      "unicode": "e634",
+      "unicode_decimal": 58932
+    },
+    {
+      "icon_id": "23472617",
+      "name": "下一题",
+      "font_class": "xiayiti",
+      "unicode": "e633",
+      "unicode_decimal": 58931
+    },
+    {
+      "icon_id": "23472589",
+      "name": "上一题",
+      "font_class": "shangyiti",
+      "unicode": "e632",
+      "unicode_decimal": 58930
+    },
+    {
+      "icon_id": "23472576",
+      "name": "技巧讲解",
+      "font_class": "jqjj",
+      "unicode": "e631",
+      "unicode_decimal": 58929
+    },
+    {
+      "icon_id": "23472566",
+      "name": "读题",
+      "font_class": "duti",
+      "unicode": "e630",
+      "unicode_decimal": 58928
+    },
+    {
+      "icon_id": "23472484",
+      "name": "读题+答案",
+      "font_class": "a-dtda",
+      "unicode": "e62f",
+      "unicode_decimal": 58927
+    },
+    {
+      "icon_id": "23472442",
+      "name": "收藏灰",
+      "font_class": "shoucanghui",
+      "unicode": "e62e",
+      "unicode_decimal": 58926
+    },
+    {
+      "icon_id": "23472368",
+      "name": "自动读题",
+      "font_class": "zddt",
+      "unicode": "e62d",
+      "unicode_decimal": 58925
+    },
+    {
+      "icon_id": "23472363",
+      "name": "设置",
+      "font_class": "shezhi",
+      "unicode": "e62c",
+      "unicode_decimal": 58924
+    },
+    {
+      "icon_id": "23472347",
+      "name": "返回",
+      "font_class": "fanhui",
+      "unicode": "e62b",
+      "unicode_decimal": 58923
+    },
+    {
+      "icon_id": "23472288",
+      "name": "单项选择",
+      "font_class": "dxxz",
+      "unicode": "e62a",
+      "unicode_decimal": 58922
+    },
+    {
+      "icon_id": "23469401",
+      "name": "语音讲解",
+      "font_class": "yyjj",
+      "unicode": "e629",
+      "unicode_decimal": 58921
+    },
+    {
+      "icon_id": "23468150",
+      "name": "我的蓝",
+      "font_class": "wode",
+      "unicode": "e627",
+      "unicode_decimal": 58919
+    },
+    {
+      "icon_id": "23468128",
+      "name": "发现蓝",
+      "font_class": "faxian",
+      "unicode": "e626",
+      "unicode_decimal": 58918
+    },
+    {
+      "icon_id": "23468098",
+      "name": "驾考蓝",
+      "font_class": "jiakao",
+      "unicode": "e625",
+      "unicode_decimal": 58917
+    },
+    {
+      "icon_id": "23468073",
+      "name": "摩托车",
+      "font_class": "motuoche",
+      "unicode": "e624",
+      "unicode_decimal": 58916
+    },
+    {
+      "icon_id": "23468067",
+      "name": "货车",
+      "font_class": "huoche",
+      "unicode": "e623",
+      "unicode_decimal": 58915
+    },
+    {
+      "icon_id": "23468059",
+      "name": "客车",
+      "font_class": "keche",
+      "unicode": "e622",
+      "unicode_decimal": 58914
+    },
+    {
+      "icon_id": "23468013",
+      "name": "轿车",
+      "font_class": "jiaoche",
+      "unicode": "e621",
+      "unicode_decimal": 58913
+    },
+    {
+      "icon_id": "23468001",
+      "name": "会员",
+      "font_class": "huiyuan",
+      "unicode": "e620",
+      "unicode_decimal": 58912
+    },
+    {
+      "icon_id": "23467969",
+      "name": "会员头像",
+      "font_class": "hytx",
+      "unicode": "e61f",
+      "unicode_decimal": 58911
+    }
+  ]
+}

BIN
src/components/m-icon/iconfont.ttf


+ 32 - 0
src/components/m-icon/index.vue

@@ -0,0 +1,32 @@
+<template>
+  <svg
+    class="icon"
+    aria-hidden="true"
+    v-if="!isSvg"
+    :style="`font-size:${size}`"
+  >
+    <use :xlink:href="`#icon-${type}`"></use>
+  </svg>
+  <!-- <span v-if="!isSvg" class="iconfont" :class="`icon-${type}`" style="fill:#ffffff"></span> -->
+  <img :src="`/svg/${type}.svg`" v-else />
+</template>
+
+<script lang="ts" setup>
+import "./iconfont";
+const props = defineProps({
+  type: String,
+  isSvg: Boolean,
+  size: String,
+});
+</script>
+
+<style>
+@import url("./iconfont.css");
+.icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+</style>

+ 32 - 0
src/components/m-nav-bar/index.vue

@@ -0,0 +1,32 @@
+<template>
+  <div class="header">
+    <m-icon type="fanhui" @click="onClickLeft" />
+    <span class="title">{{ title }}</span>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { useRouter } from "vue-router";
+const props = defineProps({
+  title: String,
+});
+const router = useRouter();
+const onClickLeft = () => {
+  router.back();
+};
+</script>
+
+<style lang="scss" scoped>
+.header {
+  position: sticky;
+  top: 0;
+  font-size: 15px;
+  padding: 15px;
+  .title {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translate(-50%, -50%);
+  }
+}
+</style>

+ 15 - 0
src/components/m-user-avatar/index.vue

@@ -0,0 +1,15 @@
+<template>
+  <img class="user-avatar" src="https://img.yzcdn.cn/vant/cat.jpeg" />
+</template>
+
+<script>
+export default {};
+</script>
+
+<style scoped>
+.user-avatar{
+    width: 54px;
+    height: 54px;
+    border-radius: 50%;
+}
+</style>

+ 10 - 0
src/components/m-user-name/index.vue

@@ -0,0 +1,10 @@
+<template>
+  <span class="user-name">我有六把刀</span>
+</template>
+
+<script>
+export default {};
+</script>
+
+<style scoped>
+</style>

+ 20 - 0
src/main.ts

@@ -0,0 +1,20 @@
+import { createApp } from "vue";
+import App from "./App.vue";
+import store from "./store";
+import router from "./route";
+import Vant from "vant";
+import "vant/lib/index.css";
+import './utils/rem'
+import components from './components'
+
+import VConsole from "vconsole";
+new VConsole()
+
+const app = createApp(App);
+app.use(store);
+app.use(router);
+app.use(components)
+app.use(Vant);
+app.mount("#app");
+
+

+ 69 - 0
src/route/index.ts

@@ -0,0 +1,69 @@
+import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
+
+// 导入library文件夹下的所有组件
+// 批量导入需要使用一个函数 require.context(dir,deep,matching)
+// 参数:1. 目录  2. 是否加载子目录  3. 加载的正则匹配
+const modules = import.meta.glob("../views/**/index.vue");
+// 匹配到的文件名数组
+let aotuRoutes: any = [];
+//根据名字查找路由项目
+const aotuRoutesFind = (name: String) => {
+  let list: any = [];
+  //递归查询所以路由,子路由;添加至list
+  const recursionPush = (routes: any) => {
+    routes.forEach((item: any) => {
+      list.push(item);
+      recursionPush(item.children);
+    });
+  };
+  recursionPush(aotuRoutes);
+  //返回查找到的路由
+  return list.find((route: any) => route.name == name);
+};
+for (const path in modules) {
+  //提取路由信息
+  let nameArr = path.split("/");
+  //子路由循环时有作用
+  let aotuRoutesItem = aotuRoutes;
+  //子路由层次标识
+  let index = 0;
+  //判断是否是子路由
+  for (let i = 0; i < nameArr.length - 4; i = i + 2) {
+    aotuRoutesItem = aotuRoutesItem.find(
+      (route: any) => route.name == nameArr[i + 2]
+    ).children;
+    index++;
+  }
+  //路径生成
+  let routePath = "";
+  for (let i = 0; i <= index; i++) {
+    routePath += "/" + nameArr[i * 2 + 2];
+  }
+  //设置文件夹名带有-default的子路由为默认路由
+  if (nameArr[index * 2 + 2].includes("-default")) {
+    aotuRoutesFind(nameArr[index * 2]).redirect = routePath;
+  }
+  //添加路由信息
+  aotuRoutesItem.push({
+    name: nameArr[index * 2 + 2],
+    path: routePath,
+    component: modules[path],
+    children: [],
+  });
+}
+
+console.log(aotuRoutesFind("initMockTest-default"));
+
+// 创建路由实例并传递 `routes` 配置
+const router = createRouter({
+  history: createWebHashHistory(),
+  routes: [
+    {
+      path: "/",
+      redirect: "/login",
+    },
+    ...aotuRoutes,
+  ],
+});
+
+export default router;

+ 6 - 0
src/shims-vue.d.ts

@@ -0,0 +1,6 @@
+declare module '*.vue' {
+  import { DefineComponent } from 'vue'
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
+  const component: DefineComponent<{}, {}, any>
+  export default component
+}

+ 14 - 0
src/store/index.ts

@@ -0,0 +1,14 @@
+import { createStore } from "vuex";
+
+const store = createStore({
+  state: () => ({
+    count: 10,
+  }),
+  mutations: {
+    increment(state) {
+      state.count++;
+    },
+  },
+});
+
+export default store;

+ 11 - 0
src/utils/rem.ts

@@ -0,0 +1,11 @@
+const baseSize = 37.5;
+function setRem() {
+  const scale = document.documentElement.clientWidth / 375;
+  document.documentElement.style.fontSize =
+    baseSize * Math.min(scale, 2) + "px";
+}
+setRem();
+window.onresize = function () {
+  console.log("我执行了");
+  setRem();
+};

+ 48 - 0
src/views/classify/index.vue

@@ -0,0 +1,48 @@
+<template>
+  <m-nav-bar title="分类练习" />
+  <div class="cell-box">
+    <van-cell
+      class="cell"
+      title="单元格"
+      is-link
+      center
+      v-for="(item, index) in 11"
+      :key="index"
+      :border="false"
+    >
+      <template #icon>
+        <div class="icon">{{ index + 1 }}</div>
+      </template>
+    </van-cell>
+  </div>
+</template>
+
+<script setup lang="ts"></script>
+
+<style lang="scss" scoped>
+.cell-box {
+  display: flex;
+  padding: 5px 15px;
+  flex-wrap: wrap;
+  justify-content: space-between;
+  .cell {
+    width: 167px;
+    margin-top: 10px;
+    box-shadow: 0px 0px 10px rgba(124, 129, 136, 0.2);
+  }
+  .icon {
+    width: 20px;
+    height: 20px;
+    background: #498ef5;
+    border-radius: 50%;
+    font-weight: 500;
+    font-family: PingFang SC;
+    font-size: 13px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    color: #ffffff;
+    margin-right: 5px;
+  }
+}
+</style>

+ 206 - 0
src/views/collection/index.vue

@@ -0,0 +1,206 @@
+<template>
+  <van-nav-bar left-arrow @click-left="onClickLeft" fixed placeholder>
+    <template #title>
+      <div class="title">
+        <span :class="{ active: isType == 0 }" @click="isType = 0">做错题</span>
+        <span :class="{ active: isType == 1 }" @click="isType = 1">收藏题</span>
+      </div>
+    </template>
+  </van-nav-bar>
+  <div>
+    <van-checkbox-group v-model="checked">
+      <van-cell-group>
+        <van-swipe-cell
+          v-for="(item, index) in list"
+          :key="index"
+          :disabled="isChoose"
+        >
+          <van-cell
+            clickable
+            :title="`${item}. 复选框复选框复选框复选框复选框复选框复选框复选框复选框复选框复选框复选框复选框`"
+            @click="console.log(1231312312)"
+          >
+            <template #icon v-if="isChoose">
+              <van-checkbox :name="item" class="checkbox" />
+            </template>
+          </van-cell>
+          <template #right>
+            <van-button square style="height: 100%" type="danger" text="删除" />
+            <van-button
+              square
+              style="height: 100%"
+              type="primary"
+              text="收藏"
+              v-if="isType == 0"
+            />
+          </template>
+        </van-swipe-cell>
+      </van-cell-group>
+    </van-checkbox-group>
+  </div>
+  <div style="height: 50px"></div>
+  <div class="bottom-cell">
+    <div>
+      <span v-if="!isChoose" @click="isChoose = true">批量选中</span>
+      <div class="choose" v-else>
+        <van-checkbox v-model="isSelectAll">全选</van-checkbox>
+        <span
+          @click="
+            isChoose = false;
+            unSelectAll();
+          "
+          >取消</span
+        >
+      </div>
+    </div>
+    <div>
+      <div class="operate">
+        <van-button
+          round
+          type="danger"
+          size="small"
+          :disabled="checked.length == 0"
+          >删除选中</van-button
+        >
+        <van-button
+          round
+          type="primary"
+          size="small"
+          :disabled="checked.length == 0"
+          >移入收藏夹</van-button
+        >
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { nextTick, ref, watch } from "vue";
+import { useRouter } from "vue-router";
+const router = useRouter();
+const onClickLeft = () => {
+  router.back();
+};
+
+const list = ref([1, 2, 3, 4, 5, 6]); //题目列表
+const isChoose = ref(false); //开启批量选中
+const isSelectAll = ref(false); //是否全选
+const checked = ref([]); //选中内容
+const isType = ref(0); //0错题 1收藏
+//切换数据列表
+watch(isType, (val) => {
+  list.value = [];
+  nextTick(() => {
+    list.value = [7, 8, 9, 10, 11, 12];
+  });
+});
+//选择全选
+watch(isSelectAll, (val) => {
+  if (val) {
+    selectAll();
+  } else {
+    unSelectAll();
+  }
+});
+//全选状态改变
+watch(checked, (val) => {
+  if (val.length == 0) {
+    isSelectAll.value = false;
+  }
+  if (val.length == list.value.length) {
+    isSelectAll.value = true;
+  }
+});
+//全选
+const selectAll = () => {
+  checked.value = <never[]>list.value;
+};
+//取消全选
+const unSelectAll = () => {
+  checked.value = [];
+};
+//单个删除
+//单个收藏
+//批量删除
+//批量收藏
+</script>
+
+<style lang="scss" scoped>
+.title {
+  display: flex;
+  width: 130px;
+  justify-content: space-between;
+  align-items: center;
+  span {
+    font-size: 15px;
+    font-family: PingFang SC;
+    font-weight: 400;
+    line-height: 13px;
+    color: #0a1a33;
+    position: relative;
+    padding: 8px;
+  }
+  .active {
+    &:after {
+      position: absolute;
+      content: "";
+      width: 20px;
+      height: 4px;
+      border-radius: 3px;
+      background-color: #498ef5;
+      bottom: 0;
+      left: 50%;
+      transform: translateX(-50%);
+      z-index: 100;
+    }
+  }
+}
+.checkbox {
+  margin-right: 5px;
+}
+.bottom-cell {
+  position: fixed;
+  bottom: 0;
+  border-top: 1px solid #bdbaba;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  width: 100vw;
+  height: 50px;
+  box-sizing: border-box;
+  font-size: 13px;
+  font-weight: 400;
+  font-family: PingFang SC;
+  background-color: #ffffff;
+  padding: 10px 15px;
+  .choose {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    width: 100px;
+  }
+  .operate {
+    display: flex;
+    justify-content: space-between;
+
+    span {
+      height: 30px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      color: #ffffff;
+      border-radius: 15px;
+
+      &:nth-of-type(1) {
+        background-color: #ff4d53;
+      }
+      &:active {
+        filter: brightness(50%);
+      }
+      &:nth-of-type(2) {
+        background-color: #498ef5;
+      }
+    }
+  }
+}
+</style>

+ 210 - 0
src/views/exercise/hooks.ts

@@ -0,0 +1,210 @@
+import { ref, watch, onBeforeMount, Ref, computed } from "vue";
+import * as API from "@/api";
+
+//答题模式切换
+export function useTopicMode() {
+  const answerTypeList = ref([
+    { name: "顺序练习" },
+    { name: "随机练习" },
+    { name: "背题模式" },
+  ]);
+  const currentType = ref(0);
+  const typeParams = ref({
+    order: true, //顺序练习
+    answerShow: false, //背题模式
+  });
+  watch(currentType, (currentVal) => {
+    switch (currentVal) {
+      case 0:
+        typeParams.value.order = true;
+        typeParams.value.answerShow = false;
+        break;
+      case 1:
+        typeParams.value.order = false;
+        typeParams.value.answerShow = false;
+        break;
+      case 2:
+        typeParams.value.order = true;
+        typeParams.value.answerShow = true;
+        break;
+    }
+  });
+  return {
+    answerTypeList,
+    currentType,
+    typeParams,
+  };
+}
+
+//语音设置
+export function useAudioSet(currentAnswerIndex: Ref<number>) {
+  const aotuPlayFlag = ref(false);
+  //音频模块
+  const audio = ref();
+
+  /**
+   * 读题
+   */
+  const issueAudioPlay = () => {
+    audio.value.src =
+      "https://t1-1305573081.file.myqcloud.com/issue/issue1.mp3";
+    audio.value.play();
+  };
+
+  /**
+   * 读答案
+   */
+  const answerAudioPlay = () => {
+    audio.value.src =
+      "https://t1-1305573081.file.myqcloud.com/answer/answer1.mp3";
+    audio.value.play();
+  };
+
+  /**
+   * 读官方解释
+   */
+  const explainAudioPlay = () => {
+    audio.value.src =
+      "https://t1-1305573081.file.myqcloud.com/explainjs/explainJS1.mp3";
+    audio.value.play();
+  };
+
+  /**
+   * 读技巧解释
+   */
+  const JQexplainAudioPlay = () => {
+    audio.value.src =
+      "https://t1-1305573081.file.myqcloud.com/mp3/explain1.mp3";
+    audio.value.play();
+  };
+
+  /**
+   * 停止播放
+   */
+  const audioPause = () => {
+    audio.value.pause();
+  };
+
+  //音频模块end
+  const aotuPlaySet = () => {
+    aotuPlayFlag.value = !aotuPlayFlag.value;
+    if (aotuPlayFlag.value) issueAudioPlay();
+    if (!aotuPlayFlag.value) audioPause();
+  };
+
+  onBeforeMount(() => {
+    watch(currentAnswerIndex, () => {
+      if (aotuPlayFlag.value) issueAudioPlay(); //自动读题
+    });
+  });
+
+  return {
+    aotuPlayFlag,
+    audio,
+    issueAudioPlay,
+    answerAudioPlay,
+    explainAudioPlay,
+    JQexplainAudioPlay,
+    audioPause,
+    aotuPlaySet,
+  };
+}
+
+//题目展示逻辑
+export function useTopicShow(
+  trueNum: Ref<number>,
+  falseNum: Ref<number>,
+  idIndex: Ref<number>,
+  total: Ref<number>,
+  isJump: Ref<boolean>
+) {
+  const topicList = ref([]);
+
+  //API请求接口数据
+  onBeforeMount(async () => {
+    const topicListApiRes = API.getTopicList();
+    setTimeout(() => {
+      topicList.value = topicListApiRes.data.list;
+      idIndex.value = 200;
+      total.value = 1999;
+    }, 1000);
+  });
+
+  //当前题目数据
+  const currentAnswerIndex = ref(0);
+  onBeforeMount(() => {
+    watch(currentAnswerIndex, () => {
+      idIndex.value = currentAnswerIndex.value;
+    });
+  });
+  const currentAnswer: any = computed(() => {
+    return topicList.value[currentAnswerIndex.value];
+  });
+
+  //上一题,下一题
+  const currentAnswerIndexBack = () => {
+    if (topicList.value.length == 0) return;
+    currentAnswerIndex.value =
+      (currentAnswerIndex.value - 1 + topicList.value.length) %
+      topicList.value.length;
+  };
+  const currentAnswerIndexGo = () => {
+    if (topicList.value.length == 0) return;
+    currentAnswerIndex.value =
+      (currentAnswerIndex.value + 1) % topicList.value.length;
+  };
+
+  //选择答案后
+  const userAnswerChange = () => {
+    currentAnswer.value.optsBack = currentAnswer.value.opts.map(
+      (val: String) => {
+        let status;
+        if (currentAnswer.value.answer.includes(val)) {
+          status = 1;
+        } else {
+          status = 0;
+        }
+        if (currentAnswer.value.userAnswer.includes(val)) {
+          status += 2;
+        }
+        return { opt: val, status };
+      }
+    );
+    if (
+      JSON.stringify(currentAnswer.value.answer) ==
+      JSON.stringify(currentAnswer.value.userAnswer)
+    ) {
+      console.log("答案正确");
+      currentAnswer.value.isTrue = true;
+      trueNum.value++;
+      if (isJump.value)
+        setTimeout(() => {
+          currentAnswerIndexGo();
+        }, 200);
+    } else {
+      console.log("错误");
+      currentAnswer.value.isTrue = false;
+      falseNum.value++;
+    }
+  };
+  const topicType = (type: Number) => {
+    switch (type) {
+      case 0:
+        return "判断题";
+      case 1:
+        return "单选题";
+      case 2:
+        return "多选题";
+    }
+  };
+
+  return {
+    topicList,
+    currentAnswerIndex,
+    currentAnswer,
+    currentAnswerIndexBack,
+    currentAnswerIndexGo,
+    userAnswerChange,
+    topicType
+  }
+}

+ 526 - 0
src/views/exercise/index.vue

@@ -0,0 +1,526 @@
+<template>
+  <!-- 导航栏 -->
+  <van-nav-bar
+    title="标题"
+    left-arrow
+    @click-left="onClickLeft"
+    fixed
+    placeholder
+  >
+    <template #right>
+      <m-icon type="shezhi" @click="setShow = true" />
+    </template>
+  </van-nav-bar>
+  <!-- 导航栏end -->
+  <!-- 答题模式选择 -->
+  <div class="answerType">
+    <span
+      v-for="(answerType, index) in answerTypeList"
+      :key="index"
+      :class="{ selected: currentType == index }"
+      @click="currentType = index"
+      >{{ answerType.name }}</span
+    >
+    <span :class="{ selected: aotuPlayFlag }" @click="aotuPlaySet"
+      >自动读题</span
+    >
+  </div>
+  <!-- 答题模式选择end -->
+  <!-- 分割线 -->
+  <div class="divider" />
+  <!-- 题目模块 -->
+  <!-- 题目预加载 -->
+  <m-empty v-if="!currentAnswer" />
+  <!-- 题目预加载end -->
+  <div class="problem-box" v-else>
+    <!-- 题目内容 -->
+    <div class="problem">
+      <span class="type">{{ topicType(currentAnswer.type) }}</span>
+      <span class="text">{{ currentAnswer.explain }}</span>
+      <img
+        src="https://t1-1305573081.file.myqcloud.com/image/5.jpg"
+        class="img"
+      />
+    </div>
+    <!-- 背题模式展示 -->
+    <div v-if="typeParams.answerShow">
+      <div>
+        <div
+          class="answer-box"
+          v-for="(item, index) in currentAnswer.opts"
+          :key="Number(index)"
+        >
+          <div
+            class="choose-icon"
+          >
+            {{ String.fromCharCode(65 + Number(index)) }}
+          </div>
+          <span
+            class="answer-text"
+            :class="{ true: currentAnswer.answer.includes(item) }"
+          >
+            {{ item }}
+          </span>
+        </div>
+      </div>
+      <div class="checkbox-answer">
+        答案: {{ currentAnswer.answer.toString() }}
+      </div>
+    </div>
+    <!-- 背题模式展示end -->
+    <!-- 选择内容 -->
+    <div v-else-if="currentAnswer.isTrue === null">
+      <!-- 单选 -->
+      <van-radio-group
+        v-model="currentAnswer.userAnswer"
+        v-if="currentAnswer.type < 2"
+        @change="userAnswerChange"
+        icon-size="35px"
+      >
+        <van-radio
+          v-for="(item, index) in currentAnswer.opts"
+          :key="Number(index)"
+          :name="item"
+          class="answer"
+          >{{ item }}
+          <template #icon="props">
+            <div class="choose-icon" :class="{ selected: props.checked }">
+              {{ String.fromCharCode(65 + Number(index)) }}
+            </div>
+          </template>
+        </van-radio>
+      </van-radio-group>
+      <!-- 多选 -->
+      <div v-else>
+        <van-checkbox-group v-model="currentAnswer.userAnswer" icon-size="35px">
+          <van-checkbox
+            v-for="(item, index) in currentAnswer.opts"
+            :key="Number(index)"
+            :name="item"
+            class="answer"
+            >{{ item }}
+            <template #icon="props">
+              <div class="choose-icon" :class="{ selected: props.checked }">
+                {{ String.fromCharCode(65 + Number(index)) }}
+              </div>
+            </template>
+          </van-checkbox>
+        </van-checkbox-group>
+        <van-button
+          round
+          type="primary"
+          class="checkbox-btn"
+          :disabled="currentAnswer.userAnswer.length == 0"
+          @click="userAnswerChange"
+          >确定</van-button
+        >
+      </div>
+    </div>
+    <!-- 展示答题后选择内容 -->
+    <div v-else>
+      <div>
+        <div
+          v-for="(item, index) in currentAnswer.optsBack"
+          :key="Number(index)"
+          class="answer-box"
+        >
+          <div
+            class="choose-icon"
+            :class="{ iconTrue: item.status % 2 !== 0 }"
+            v-if="item.status < 2"
+          >
+            {{ String.fromCharCode(65 + Number(index)) }}
+          </div>
+          <m-icon
+            v-else-if="item.status == 3"
+            type="dui"
+            size="30px"
+            style="margin-left: 5px"
+          />
+          <m-icon
+            v-else-if="item.status == 2"
+            size="30px"
+            type="cuo"
+            style="margin-left: 5px"
+          />
+          <span
+            class="answer-text"
+            :class="{ true: item.status % 2 !== 0, false: item.status == 2 }"
+          >
+            {{ item.opt }}
+          </span>
+        </div>
+      </div>
+      <div class="checkbox-answer">
+        答案: {{ currentAnswer.answer.toString() }}
+      </div>
+    </div>
+    <!-- 展示答题后选择内容end -->
+  </div>
+  <!-- 选择内容End -->
+  <!-- 分割线 -->
+  <van-divider />
+  <!-- 功能选择列表 -->
+  <div class="function-list">
+    <div class="function-item">
+      <m-icon type="shoucanghui" size="25px" />
+      <span>收藏</span>
+    </div>
+    <div class="function-item" @click="answerAudioPlay">
+      <m-icon type="a-dtda" size="25px" />
+      <span>读题+答案</span>
+    </div>
+    <div class="function-item" @click="issueAudioPlay">
+      <m-icon type="duti" size="25px" />
+      <span>读题</span>
+    </div>
+    <div class="function-item" @click="skillsShow = true">
+      <m-icon type="jqjj" size="25px" />
+      <span>技巧讲解</span>
+    </div>
+  </div>
+  <!-- 功能选择列表End -->
+  <!-- 技巧讲解 -->
+  <van-overlay :show="skillsShow" @click="skillsShow = false" z-index="10">
+    <div class="skills-box" @click.stop>
+      <div class="skills">
+        <div class="title">技巧讲解</div>
+        <img
+          src="https://t1-1305573081.file.myqcloud.com/gif/2.gif"
+          class="img"
+        />
+        <van-divider class="divider">本题速记口诀</van-divider>
+        <div class="text">题目以“拘役”结尾.答对;以“徒刑”结尾.答错</div>
+        <div class="btn">
+          <span @click="skillsShow = false">关闭</span>
+          <span @click="JQexplainAudioPlay">语音重播</span>
+        </div>
+      </div>
+    </div>
+  </van-overlay>
+  <!-- 技巧讲解end -->
+  <!-- 官方解释 -->
+  <van-overlay :show="officialShow" @click="officialShow = false" z-index="10">
+    <div class="skills-box" @click.stop>
+      <div class="skills">
+        <div class="title">官方解释</div>
+        <div class="text">
+          1、申请城市公交车、大型货车、无轨电车或者有轨电车准驾车型的,在20周岁以上,50周岁以下;2、申请大型客车准驾车型的,在26周岁以上,50周岁以下;3、申请中型客车准驾车型的,在21周岁以上,50周岁以下;4、申请牵引车准驾车型的,在24周岁以上,50周岁以下。
+        </div>
+        <div class="btn">
+          <span @click="officialShow = false">关闭</span>
+          <span @click="explainAudioPlay">语音重播</span>
+        </div>
+      </div>
+    </div>
+  </van-overlay>
+  <!-- 官方解释end -->
+  <!-- 音频模块 -->
+  <audio ref="audio"></audio>
+  <!-- 音频模块end -->
+  <!-- 题目模块end -->
+  <!-- 设置操作栏 -->
+  <van-popup v-model:show="setShow" position="bottom">
+    <van-cell center title="答对跳转下一题">
+      <template #right-icon>
+        <van-switch v-model="isJump" size="24" />
+      </template>
+    </van-cell>
+    <van-cell center title="答题音效提示">
+      <template #right-icon>
+        <van-switch v-model="isSoundEffect" size="24" />
+      </template>
+    </van-cell>
+  </van-popup>
+  <!-- 设置操作栏end -->
+  <!-- 底部操作栏 -->
+  <van-tabbar placeholder route>
+    <van-tabbar-item @click="currentAnswerIndexBack"
+      >上一题
+      <template #icon>
+        <m-icon type="shangyiti" />
+      </template>
+    </van-tabbar-item>
+    <van-tabbar-item
+      >{{ trueNum }}
+      <template #icon>
+        <m-icon type="dui" />
+      </template>
+    </van-tabbar-item>
+    <van-tabbar-item
+      >{{ falseNum }}
+      <template #icon>
+        <m-icon type="cuo" />
+      </template>
+    </van-tabbar-item>
+    <van-tabbar-item
+      >{{ idIndex }}/{{ total }}
+      <template #icon>
+        <m-icon type="zongtishu" />
+      </template>
+    </van-tabbar-item>
+    <van-tabbar-item @click="officialShow = true"
+      >官方解释
+      <template #icon>
+        <m-icon type="gfjs" />
+      </template>
+    </van-tabbar-item>
+    <van-tabbar-item @click="currentAnswerIndexGo"
+      >下一题
+      <template #icon>
+        <m-icon type="xiayiti" />
+      </template>
+    </van-tabbar-item>
+  </van-tabbar>
+  <!-- 底部操作栏end -->
+</template>
+
+<script lang="ts" setup>
+import * as Api from "@/api";
+import { useRouter } from "vue-router";
+import { ref, watch, computed, reactive, onBeforeMount, nextTick } from "vue";
+import { useTopicMode, useAudioSet, useTopicShow } from "./hooks";
+const router = useRouter();
+const onClickLeft = () => {
+  router.back();
+};
+
+//答题模式选择逻辑
+const { answerTypeList, currentType, typeParams } = useTopicMode();
+
+//技巧讲解
+const skillsShow = ref(false); //显示技巧讲解
+
+//官方解释
+const officialShow = ref(false); //显示官方解释
+
+//设置操作栏
+const setShow = ref(false); //显示设置栏
+const isJump = ref(false); //答对跳转下一题
+const isSoundEffect = ref(true); //答题音效
+
+//记录模块
+const trueNum = ref(0); //答对数量
+const falseNum = ref(0); //答错数量
+const idIndex = ref(0); //当前题目标志位
+const total = ref(0); //题目总数量
+
+//题目展示逻辑
+const {
+  topicList,
+  topicType,
+  currentAnswerIndex,
+  currentAnswer,
+  currentAnswerIndexBack,
+  currentAnswerIndexGo,
+  userAnswerChange,
+} = useTopicShow(trueNum, falseNum, idIndex, total, isJump);
+
+//音频模块
+const {
+  aotuPlayFlag,
+  audio,
+  answerAudioPlay,
+  audioPause,
+  aotuPlaySet,
+  issueAudioPlay,
+  explainAudioPlay,
+  JQexplainAudioPlay,
+} = useAudioSet(currentAnswerIndex);
+</script>
+
+<style lang="scss" scoped>
+.parsing-img {
+  width: 100%;
+  margin-top: 10px;
+}
+.function-list {
+  width: 100%;
+  font-size: 13px;
+  display: flex;
+  justify-content: space-around;
+  padding: 15px;
+  box-sizing: border-box;
+  .function-item {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    font-size: 13px;
+    font-weight: 400;
+    color: #8a9099;
+    span {
+      margin-top: 5px;
+    }
+  }
+}
+.answerType {
+  width: 100%;
+  font-size: 13px;
+  display: flex;
+  justify-content: space-around;
+  padding: 15px;
+  box-sizing: border-box;
+  span {
+    border-radius: 20px;
+    padding: 3px 10px;
+    background-color: #b8c0cc;
+    color: #ffffff;
+  }
+  .selected {
+    background-color: #498ef5;
+  }
+}
+.divider {
+  width: 100%;
+  height: 10px;
+  background-color: #f2f3f5;
+}
+.problem-box {
+  font-size: 17px;
+  padding: 15px;
+  .problem {
+    .type {
+      width: 47px;
+      height: 24px;
+      background: #498ef5;
+      border-radius: 10px 10px 0px 10px;
+      font-size: 11px;
+      padding: 2px 7px;
+      margin-right: 5px;
+    }
+    .text {
+      font-family: PingFang SC;
+      font-weight: 400;
+      color: #0a1a33;
+      letter-spacing: 0.3px;
+    }
+    .img {
+      width: 100%;
+      margin-top: 10px;
+    }
+  }
+  .answer {
+    margin-top: 25px;
+  }
+  .answer-box {
+    display: flex;
+    margin-top: 25px;
+    align-items: center;
+    .iconTrue {
+      background-color: #01c18d;
+    }
+    .answer-text {
+      margin-left: 10px;
+    }
+    .true {
+      color: #01c18d;
+    }
+    .false {
+      color: #ff4d53;
+    }
+  }
+
+  .choose-icon {
+    width: 30px;
+    height: 30px;
+    border-radius: 50%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    font-size: 17px;
+    box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.16);
+    box-sizing: border-box;
+    margin-left: 5px;
+    margin-top: 1px;
+  }
+  .selected {
+    background-color: #498ef5;
+  }
+  .checkbox-btn {
+    width: 266px;
+    height: 40px;
+    margin: auto;
+    margin-top: 25px;
+    left: 50%;
+    transform: translateX(-50%);
+  }
+  .checkbox-answer {
+    padding: 8px 10px;
+    background-color: #f2f3f5;
+    margin-top: 25px;
+  }
+}
+.skills-box {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 100%;
+  .skills {
+    width: 290px;
+    background: #ffffff;
+    box-shadow: 0px 0px 8px rgba(124, 129, 136, 0.16);
+    border-radius: 10px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding: 20px 16px;
+    box-sizing: border-box;
+    .title {
+      font-size: 15px;
+      font-family: PingFang SC;
+      font-weight: bold;
+      line-height: 21px;
+      color: #0a1a33;
+    }
+    .img {
+      width: 258px;
+      height: 129px;
+      border: 1px solid #e8e8e8;
+      margin-top: 16px;
+    }
+    .divider {
+      margin-top: 20px;
+      color: #0a1a33;
+      background: #ffffff;
+    }
+    .text {
+      font-size: 13px;
+      font-family: PingFang SC;
+      font-weight: 400;
+      line-height: 19px;
+      color: #5c6066;
+      margin-top: 10px;
+    }
+    .btn {
+      width: 100%;
+      display: flex;
+      justify-content: space-between;
+      padding: 0 40px;
+      box-sizing: border-box;
+      margin-top: 20px;
+      span {
+        width: 76px;
+        height: 30px;
+        border-radius: 15px;
+        font-size: 13px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        &:active {
+          background-color: #afaaaa;
+          filter: brightness(50%);
+        }
+        &:nth-of-type(1) {
+          border: 1px solid #707070;
+          color: #5c6066;
+        }
+        &:nth-of-type(2) {
+          background: #498ef5;
+          border: 1px solid #498ef5;
+          color: #ffffff;
+        }
+      }
+    }
+  }
+}
+</style>

+ 29 - 0
src/views/home/children/find/children/find1/index.vue

@@ -0,0 +1,29 @@
+<template>
+  <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
+    <van-swipe-item>1</van-swipe-item>
+    <van-swipe-item>2</van-swipe-item>
+    <van-swipe-item>3</van-swipe-item>
+    <van-swipe-item>4</van-swipe-item>
+  </van-swipe>
+  <button type="button" @click="increment">count is: {{ count }}</button>
+</template>
+
+<script lang="ts" setup>
+import { ref, watch } from "vue";
+let count = ref(1);
+watch(count, (val: Number) => {
+  console.log(val);
+});
+const increment = () => {
+  count.value++;
+};
+</script>
+
+<style scoped lang="scss">
+.my-swipe {
+  background-color: red;
+  width: 345px;
+  height: 100px;
+  margin: auto;
+}
+</style>

+ 29 - 0
src/views/home/children/find/index.vue

@@ -0,0 +1,29 @@
+<template>
+  <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
+    <van-swipe-item>1</van-swipe-item>
+    <van-swipe-item>2</van-swipe-item>
+    <van-swipe-item>3</van-swipe-item>
+    <van-swipe-item>4</van-swipe-item>
+  </van-swipe>
+  <button type="button" @click="increment">count is: {{ count }}</button>
+</template>
+
+<script lang="ts" setup>
+import { ref, watch } from "vue";
+let count = ref(1);
+watch(count, (val: Number) => {
+  console.log(val);
+});
+const increment = () => {
+  count.value++;
+};
+</script>
+
+<style scoped lang="scss">
+.my-swipe {
+  background-color: red;
+  width: 345px;
+  height: 100px;
+  margin: auto;
+}
+</style>

+ 160 - 0
src/views/home/children/test/components/sujectOne.vue

@@ -0,0 +1,160 @@
+<template>
+  <div class="sujectOne-box">
+    <div class="test-choose" v-for="(testObj, index) in testList" :key="index">
+      <div class="min">
+        <div
+          class="icon-box"
+          v-for="(item, index) in testObj.left"
+          :key="index"
+          @click="gotoRoute(item.route)"
+        >
+          <m-icon :type="item.icon" isSvg />
+          <span>{{ item.name }}</span>
+        </div>
+      </div>
+      <div class="max">
+        <div
+          class="icon-box"
+          v-for="(item, index) in testObj.center"
+          :key="index"
+          @click="gotoRoute(item.route)"
+        >
+          <m-icon :type="item.icon" isSvg />
+          <span>{{ item.name }}</span>
+        </div>
+      </div>
+      <div class="min">
+        <div
+          class="icon-box"
+          v-for="(item, index) in testObj.right"
+          :key="index"
+          @click="gotoRoute(item.route)"
+        >
+          <m-icon :type="item.icon" isSvg />
+          <span>{{ item.name }}</span>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from "vue";
+import { useRouter } from "vue-router";
+
+export default defineComponent({
+  setup() {
+    const router = useRouter();
+    const gotoRoute = (obj: any) => {
+      router.push(obj);
+    };
+    const testList = [
+      {
+        left: [
+          { icon: "顺序练习", name: "顺序练习", route: { name: "exercise" } },
+          { icon: "分类练习", name: "分类练习", route: { name: "classify" } },
+        ],
+        center: [
+          {
+            icon: "精选考题",
+            name: "精选考题500题",
+            route: { name: "exercise" },
+          },
+        ],
+        right: [
+          { icon: "地方专题", name: "地方专题", route: { name: "topicType" } },
+          { icon: "错题收藏", name: "错题收藏", route: { name: "collection" } },
+        ],
+      },
+      {
+        left: [
+          {
+            icon: "真实考场模拟",
+            name: "考场模拟",
+            route: { name: "mockTest" },
+          },
+          { icon: "模拟成绩", name: "模拟成绩", route: { name: "testScores" } },
+        ],
+        center: [
+          {
+            icon: "模拟考试仿真题目",
+            name: "模拟考试仿真题目",
+            route: { name: "exercise" },
+          },
+        ],
+        right: [
+          {
+            icon: "考前须知",
+            name: "考前须知",
+            route: { name: "marked", query: { markdown: "考前须知" } },
+          },
+          {
+            icon: "学车必看",
+            name: "学车必看",
+            route: { name: "marked", query: { markdown: "学车必看" } },
+          },
+        ],
+      },
+    ];
+    return {
+      gotoRoute,
+      testList,
+    };
+  },
+});
+</script>
+
+<style lang="scss" scoped>
+.sujectOne-box {
+  padding-bottom: 30px;
+}
+.test-choose {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin: 30px 25px;
+  .min {
+    width: 55px;
+    height: 150px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    flex-direction: column;
+    .icon-box {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      flex-direction: column;
+      font-size: 13px;
+      .icon {
+        width: 51px;
+        height: 51px;
+      }
+    }
+  }
+  .max {
+    width: 125px;
+    height: 150px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    .icon-box {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      position: relative;
+      .icon {
+        width: 125px;
+        height: 125px;
+      }
+      span {
+        position: absolute;
+        font-size: 14px;
+        color: #ffffff;
+        width: 60px;
+        text-align: center;
+      }
+    }
+  }
+}
+</style>

+ 25 - 0
src/views/home/children/test/components/swiper.vue

@@ -0,0 +1,25 @@
+<template>
+  <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
+    <van-swipe-item v-for="item in 4" :key="item">
+      <img src="@/assets/img/mb.png" class="banner">
+    </van-swipe-item>
+  </van-swipe>
+</template>
+
+<script>
+export default {};
+</script>
+
+<style lang="scss" scoped>
+.my-swipe {
+  background-color: red;
+  width: 345px;
+  height: 100px;
+  margin: auto;
+  margin-top: 12px;
+  .banner{
+    width: 100%;
+    height: 100%;
+  }
+}
+</style>

+ 36 - 0
src/views/home/children/test/components/userData.vue

@@ -0,0 +1,36 @@
+<template>
+  <van-nav-bar fixed placeholder>
+    <template #left>
+      <div class="vip-box">
+        <van-image
+          round
+          class="user-avatar"
+          src="https://img.yzcdn.cn/vant/cat.jpeg"
+        />
+        <span>我有六把刀</span>
+      </div>
+    </template>
+    <template #right>
+      <div class="vip-box">
+        <m-icon type="huiyuan" />
+        <span>VIP会员</span>
+      </div>
+    </template>
+  </van-nav-bar>
+</template>
+
+<script lang='ts' setup>
+</script>
+
+<style lang="scss" scoped>
+.vip-box {
+  display: flex;
+  align-items: center;
+  font-size: 17px;
+  .user-avatar{
+      width: 24px;
+      height: 24px;
+      margin-right: 2px;
+  }
+}
+</style>

+ 131 - 0
src/views/home/children/test/index.vue

@@ -0,0 +1,131 @@
+<template>
+  <!-- 用户信息展示 -->
+  <userData />
+  <!-- 轮播图 -->
+  <swiper />
+  <!-- 用户做题预选界面 -->
+  <van-tabs class="car-type" line-width="0" animated>
+    <van-tab v-for="(carTypeItem, index) in carTypeList" :key="index">
+      <template #title>
+        <div class="car-choose">
+          <m-icon :type="carTypeItem.icon" class="img"/>
+          <span>{{ carTypeItem.cert }}</span>
+          <span>{{ carTypeItem.name }}</span>
+        </div>
+      </template>
+      <van-tabs class="test-type" animated>
+        <van-tab
+          :title="sujectItem.name"
+          v-for="(sujectItem, index) in carTypeItem.sujectList"
+          :key="index"
+        >
+          <component :is="sujectOne"></component>
+        </van-tab>
+      </van-tabs>
+    </van-tab>
+  </van-tabs>
+</template>
+
+<script lang="ts" setup>
+import sujectOne from "./components/sujectOne.vue";
+import swiper from "./components/swiper.vue";
+import userData from "./components/userData.vue";
+
+
+import { ref } from "vue";
+
+const carTypeList = ref([
+  {
+    name: "轿车",
+    cert: "C1/C2/C3",
+    icon:'jiaoche',
+    sujectList: [
+      { name: "科目一" },
+      // { name: "科目二" },
+      // { name: "科目三" },
+      { name: "科目四" },
+    ],
+  },
+  {
+    name: "客车",
+    cert: "A1/A3/B1",
+    icon:'keche',
+    sujectList: [
+      { name: "科目一" },
+      // { name: "科目二" },
+      // { name: "科目三" },
+      { name: "科目四" },
+    ],
+  },
+  {
+    name: "货车",
+    cert: "A2/B2",
+    icon:'huoche',
+    sujectList: [
+      { name: "科目一" },
+      // { name: "科目二" },
+      // { name: "科目三" },
+      { name: "科目四" },
+    ],
+  },
+  {
+    name: "摩托车",
+    cert: "D/E/F",
+    icon:'motuoche',
+    sujectList: [
+      { name: "科目一" },
+      // { name: "科目二" },
+      // { name: "科目三" },
+      { name: "科目四" },
+    ],
+  },
+]);
+</script>
+
+<style lang="scss">
+.car-type {
+  margin: 21px 15px;
+  --van-tabs-line-height: 88px;
+  .van-tab--active {
+    .car-choose {
+      &::after {
+        content: "";
+        width: 100%;
+        height: 78px;
+        background-color: royalblue;
+        position: absolute;
+        top: 0;
+        left: 0;
+        opacity: 0.2;
+      }
+      &::before {
+        content: "";
+        width: 0px;
+        height: 0px;
+        border: 10px solid #000;
+        border-top-color: royalblue;
+        border-bottom-color: transparent;
+        border-left-color: transparent;
+        border-right-color: transparent;
+        position: absolute;
+        bottom: 0;
+        transform: translateY(50%);
+        opacity: 0.2;
+      }
+    }
+  }
+  .test-type {
+    --van-tabs-line-height: 44px;
+  }
+  .car-choose {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    flex-direction: column;
+    .img {
+      width: 66px;
+      height: 22px;
+    }
+  }
+}
+</style>

+ 72 - 0
src/views/home/children/user/index.vue

@@ -0,0 +1,72 @@
+<template>
+  <div class="user">
+    <van-cell
+      title="我有六把刀"
+      icon="shop-o"
+      label="未绑定手机号"
+      is-link
+      center
+    >
+      <template #icon>
+        <van-image
+          round
+          class="user-avatar"
+          src="https://img.yzcdn.cn/vant/cat.jpeg"
+        />
+      </template>
+    </van-cell>
+    <van-cell-group class="group">
+      <van-cell title="会员有效期" value="内容" is-link center>
+        <template #icon>
+          <m-icon type="hyyxq" class="cell-icon" />
+        </template>
+      </van-cell>
+      <van-cell title="激活码" is-link center>
+        <template #icon>
+          <m-icon type="jihuoma" class="cell-icon" />
+        </template>
+      </van-cell>
+      <van-cell title="专属老师" is-link center>
+        <template #icon>
+          <m-icon type="zsls" class="cell-icon" />
+        </template>
+      </van-cell>
+    </van-cell-group>
+    <van-cell-group class="group">
+      <van-cell title="版本更新" is-link center>
+        <template #icon>
+          <m-icon type="bbgx" class="cell-icon" />
+        </template>
+      </van-cell>
+      <van-cell title="反馈帮助" is-link center>
+        <template #icon>
+          <m-icon type="fkbz" class="cell-icon" />
+        </template>
+      </van-cell>
+    </van-cell-group>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, defineComponent, computed, watch } from "vue";
+import { useStore } from "vuex";
+import { useRouter, useRoute } from "vue-router";
+</script>
+
+<style scoped lang="scss">
+.user {
+  background-color: #f2f3f5;
+  height: 100vh;
+  .group {
+    margin: 10px 0;
+  }
+  .user-avatar {
+    width: 46px;
+    height: 46px;
+    margin-right: 10px;
+  }
+}
+.cell-icon {
+  margin-right: 5px;
+}
+</style>

+ 36 - 0
src/views/home/index.vue

@@ -0,0 +1,36 @@
+<template>
+  <router-view></router-view>
+  <van-tabbar safe-area-inset-bottom route>
+    <van-tabbar-item to="/home/test" icon="home-o"
+      >驾考
+      <template #icon="props">
+        <m-icon :type="props.active ? 'jiakao' : 'jiakaohui'" />
+      </template>
+    </van-tabbar-item>
+    <!-- <van-tabbar-item to="/find" icon="search">发现</van-tabbar-item> -->
+    <van-tabbar-item to="/home/user" icon="friends-o"
+      >我的
+      <template #icon="props">
+        <m-icon :type="props.active ? 'wode' : 'wodehui'" />
+      </template>
+    </van-tabbar-item>
+  </van-tabbar>
+</template>
+
+<script lang="ts" setup>
+import { useRouter } from "vue-router";
+const router = useRouter();
+router.push("/home/test");
+</script>
+
+<style scoped lang="scss">
+.my-swipe {
+  background-color: red;
+  width: 345px;
+  height: 100px;
+  margin: auto;
+}
+.iconActive {
+  fill: #ffffff;
+}
+</style>

+ 40 - 0
src/views/login/index.vue

@@ -0,0 +1,40 @@
+<template>
+  <div class="login-box">
+    <!-- 登陆中 -->
+    <div v-if="loginState == 0">
+      <van-empty description="登陆中"></van-empty>
+    </div>
+    <!-- 登陆成功 -->
+    <div v-else-if="loginState == 1">
+      <van-empty description="登陆成功"></van-empty>
+    </div>
+    <!-- 登陆失败 -->
+    <div v-else-if="loginState == 2">
+      <van-empty image="network" description="登录失败"></van-empty>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useRouter } from "vue-router";
+import * as API from "@/api";
+import { ref } from "vue";
+const router = useRouter();
+const loginState = ref(0);
+API.login("1231231").then((res) => {
+  if (res.data.code == 200) {
+    loginState.value = 1;
+    router.push("/home/test");
+  } else {
+    loginState.value = 2;
+  }
+});
+</script>
+
+<style scoped lang="scss">
+.login-box {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+</style>

+ 33 - 0
src/views/marked/index copy.vue

@@ -0,0 +1,33 @@
+<template>
+  <m-nav-bar class="navbar" title="学车必看" v-if="navbar" />
+  <div class="markdown" v-html="markdownHtml"></div>
+</template>
+
+<script lang="ts" setup>
+import { ref } from "vue";
+import marked from "marked";
+import axios from "axios";
+import { useRoute } from "vue-router";
+marked.setOptions({
+  renderer: new marked.Renderer(),
+});
+const route = useRoute();
+const markdownHtml = ref();
+const navbar = route.query.navbar === "false" ? false : true;
+axios({
+  url: `/markdown/${route.query.markdown}.md`,
+}).then((res) => {
+  markdownHtml.value = marked(res.data);
+});
+</script>
+
+<style scoped lang="scss">
+
+.navbar{
+    background-color: #ffffff;
+}
+.markdown{
+    font-size: 17px;
+    width: 100%;
+}
+</style>

+ 158 - 0
src/views/marked/index.vue

@@ -0,0 +1,158 @@
+<template>
+  <m-nav-bar class="navbar" title="学车必看" v-if="navbar" />
+  <div v-for="oneLevel in jsonData" class="flex-box">
+    <div class="one-level-title">
+      <m-icon type="biaotizhuangshi3" />
+      {{ oneLevel.title }}
+      <m-icon class="icon-right" type="biaotizhuangshi3" />
+    </div>
+    <div v-if="oneLevel.explain" class="one-level-explain box-set">
+      {{ oneLevel.explain }}
+    </div>
+    <div class="two-flex-box" v-for="twoLevel in oneLevel.twoLevel">
+      <div class="two-level-title">
+        <m-icon type="biaotizhuangshi1" />
+        {{ twoLevel.title }}
+        <m-icon class="icon-right" type="biaotizhuangshi1" />
+      </div>
+      <div v-if="twoLevel.explain" class="box-set">
+        {{ twoLevel.explain }}
+      </div>
+      <div
+        class="box-set three-level-explain"
+        v-for="threeLevel in twoLevel.threeLevel"
+      >
+        <div class="three-level-title">{{ threeLevel.title }}</div>
+        <div
+          class="four-level-explain"
+          v-for="(item, index) in threeLevel.list"
+          :key="item"
+        >
+          <span class="four-level-title">{{ Number(index) + 1 }}</span>
+          <div>
+            {{ item }}
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref } from "vue";
+import marked from "marked";
+import axios from "axios";
+import { useRoute } from "vue-router";
+marked.setOptions({
+  renderer: new marked.Renderer(),
+});
+const route = useRoute();
+const jsonData = ref(<any>[]);
+const navbar = route.query.navbar === "false" ? false : true;
+axios({
+  url: `/markdown/${route.query.markdown}.json`,
+}).then((res) => {
+  jsonData.value = res.data.data;
+});
+</script>
+
+<style scoped lang="scss">
+.navbar {
+  background-color: #ffffff;
+  z-index: 10;
+}
+.flex-box {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  font-size: 17px;
+  font-family: PingFang SC;
+  padding: 40px 0 20px;
+  .box-set {
+    width: 336px;
+    border: 1px solid #498ef5;
+    border-radius: 5px;
+    padding: 20px;
+    box-sizing: border-box;
+    background-color: #f6f6f6;
+    color: #5c6066;
+    font-size: 15px;
+    font-weight: 400;
+    line-height: 23px;
+    position: relative;
+    margin-top: 40px;
+  }
+  .icon-right {
+    transform: rotate(180deg);
+  }
+  .two-flex-box {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    margin-top: 30px;
+  }
+  .one-level-title {
+    font-size: 28px;
+    font-weight: bold;
+    color: #000000;
+    position: relative;
+    &::after {
+      content: "";
+      width: 100%;
+      height: 4px;
+      border-top: 1px dashed #498ef5;
+      border-bottom: 1px solid #498ef5;
+      position: absolute;
+      bottom: 0;
+      left: 0;
+      transform: translateY(100%);
+    }
+  }
+  .one-level-explain {
+  }
+  .three-level-explain {
+    padding-top: 30px;
+  }
+  .two-level-title {
+    font-size: 24px;
+    font-weight: bold;
+    color: #0a1a33;
+  }
+  .three-level-title {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    padding: 0 16px;
+    height: 35px;
+    background: #498ef5;
+    border-radius: 18px;
+    font-size: 20px;
+    font-weight: bold;
+    color: #ffffff;
+    line-height: 43px;
+    position: absolute;
+    left: 40px;
+    top: 0;
+    transform: translateY(-50%);
+  }
+  .four-level-title {
+    width: 18px;
+    height: 18px;
+    flex-shrink: 0;
+    margin-top: 3px;
+    margin-right: 5px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    background-color: #498ef5;
+    border-radius: 50%;
+    font-size: 15px;
+    font-weight: 400;
+    color: #fefeff;
+  }
+  .four-level-explain {
+    display: flex;
+    margin-bottom: 5px;
+  }
+}
+</style>

+ 137 - 0
src/views/mockTest/components/initMockTest.vue

@@ -0,0 +1,137 @@
+<template>
+  <div class="header-back">
+    <m-nav-bar title="模拟考试" />
+    <div class="user-data">
+      <m-user-avatar />
+      <m-user-name />
+    </div>
+  </div>
+  <div class="content">
+    <div class="title">考试说明</div>
+    <div class="class">
+      <span>考试科目</span>
+      <span>科目一</span>
+    </div>
+    <div class="class">
+      <span>考试题库</span>
+      <span>轿车(C1/C2/C3)</span>
+    </div>
+    <div class="class">
+      <span>考试时间</span>
+      <span>100题,45分钟</span>
+    </div>
+    <div class="class">
+      <span>合格标准</span>
+      <span>90分及格</span>
+    </div>
+    <div class="remind">
+      答题后不可修改,累计错题扣分导致分数不及格时,系统自动交卷,考试不通过。
+    </div>
+    <m-button
+      class="start"
+      width="266px"
+      height="40px"
+      text="开始考试"
+      @click="gotoTest"
+    />
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { defineEmits } from "vue";
+
+const emits = defineEmits(["next"]);
+const gotoTest = () => {
+  emits("next");
+};
+</script>
+
+<style scoped lang="scss">
+.header-back {
+  width: 375px;
+  padding-bottom: 82px;
+  background: linear-gradient(180deg, #498ef5 0%, #4da8e6 100%);
+  border-radius: 0px 0px 82px 82px;
+  .header {
+    position: relative;
+    font-size: 15px;
+    padding: 15px;
+    color: #ffffff;
+    .title {
+      position: absolute;
+      left: 50%;
+      top: 50%;
+      transform: translate(-50%, -50%);
+    }
+  }
+  .user-data {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding: 15px;
+    justify-content: space-between;
+    height: 80px;
+    color: #ffffff;
+    font-size: 15px;
+    font-family: PingFang SC;
+    font-weight: 400;
+  }
+}
+
+.content {
+  width: 345px;
+  background: #ffffff;
+  box-shadow: 0px 0px 8px rgba(124, 129, 136, 0.2);
+  border-radius: 10px;
+  position: relative;
+  left: 50%;
+  top: -82px;
+  transform: translateX(-50%);
+  padding: 38px 15px;
+  box-sizing: border-box;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .title {
+    font-size: 15px;
+    font-family: PingFang SC;
+    font-weight: 400;
+    color: #0a1a33;
+    margin-bottom: 5px;
+  }
+  .class {
+    font-size: 13px;
+    font-family: PingFang SC;
+    font-weight: 400;
+    display: flex;
+    justify-content: space-between;
+    width: 170px;
+    margin-top: 13px;
+    span {
+      &:nth-of-type(1) {
+        color: #8a9099;
+      }
+      &:nth-of-type(2) {
+        color: #5c6066;
+      }
+    }
+  }
+  .remind {
+    width: 315px;
+    background: rgba(255, 77, 83, 0.1);
+    font-size: 13px;
+    font-family: PingFang SC;
+    font-weight: 400;
+    line-height: 19px;
+    color: #ff4d53;
+    padding: 8px 12px;
+    box-sizing: border-box;
+    margin-top: 24px;
+  }
+  .start {
+    color: #ffffff;
+    margin-top: 30px;
+    background: #498ef5;
+  }
+}
+</style>

+ 101 - 0
src/views/mockTest/components/mockTestEnd.vue

@@ -0,0 +1,101 @@
+<template>
+  <m-nav-bar title="考试结果" />
+  <div class="result-box">
+    <img class="img" src="/img/考试合格.png" />
+    <span class="text">恭喜你,测试通过~</span>
+    <div class="fraction-box"><span class="fraction">98</span>分</div>
+    <span class="hint">(满分:100;合格:90)</span>
+    <span class="time">用时:0分2秒</span>
+    <span class="evaluation"
+      >天赋异禀、骨骼惊奇,想来是百年难得一见的考试奇才。</span
+    >
+    <div class="btn-box">
+      <m-button class="btn1" text="错题重做" />
+      <m-button class="btn2" text="重新测试" />
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { defineEmits } from "vue";
+
+const emits = defineEmits(["next"]);
+const gotoTest = () => {
+  emits("next");
+};
+</script>
+
+<style lang="scss" scoped>
+.result-box {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 30px 15px;
+  .img {
+    width: 246px;
+    height: 216px;
+  }
+  .text {
+    margin-top: 23px;
+    font-size: 15px;
+    font-family: PingFang SC;
+    font-weight: 400;
+    color: #5c6066;
+    line-height: 23px;
+  }
+  .fraction-box {
+    font-size: 15px;
+    font-family: PingFang SC;
+    font-weight: bold;
+    color: #8a9099;
+    line-height: 23px;
+    margin-top: 30px;
+    .fraction {
+      font-size: 60px;
+      font-family: PingFang SC;
+      font-weight: bold;
+      color: #ff4d53;
+    }
+  }
+  .hint {
+    font-size: 13px;
+    font-family: PingFang SC;
+    font-weight: 400;
+    color: #8a9099;
+    line-height: 23px;
+  }
+  .time {
+    font-size: 13px;
+    font-family: PingFang SC;
+    font-weight: 400;
+    color: #498ef5;
+    line-height: 23px;
+  }
+  .evaluation {
+    margin-top: 30px;
+    font-size: 15px;
+    font-family: PingFang SC;
+    font-weight: 400;
+    color: #5c6066;
+    line-height: 23px;
+  }
+  .btn-box {
+    margin-top: 45px;
+    width: 230px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    color: #ffffff;
+    font-size: 15px;
+    font-family: PingFang SC;
+    font-weight: 400;
+    line-height: 23px;
+    .btn1 {
+      background-color: #498ef5;
+    }
+    .btn2 {
+      background-color: #01c18d;
+    }
+  }
+}
+</style>

+ 680 - 0
src/views/mockTest/components/startTest.vue

@@ -0,0 +1,680 @@
+<template>
+  <!-- 导航栏 -->
+  <van-nav-bar
+    title="标题"
+    left-arrow
+    @click-left="onClickLeft"
+    fixed
+    placeholder
+  >
+    <template #right>
+      <m-icon type="shezhi" @click="setShow = true" />
+    </template>
+  </van-nav-bar>
+  <!-- 导航栏end -->
+  <!-- 考试倒计时 -->
+  <div class="dowm-box">
+    <van-count-down :time="90 * 60 * 1000" format="剩余答题时间: mm分ss秒" />
+  </div>
+  <!-- 考试倒计时end -->
+  <!-- 分割线 -->
+  <div class="divider" />
+  <!-- 题目模块 -->
+  <!-- 题目预加载 -->
+  <m-empty v-if="!currentAnswer" />
+  <!-- 题目预加载end -->
+  <div class="problem-box" v-else>
+    <!-- 题目内容 -->
+    <div class="problem">
+      <span class="type">{{ topicType(currentAnswer.type) }}</span>
+      <span class="text">{{ currentAnswer.explain }}</span>
+      <img
+        src="https://t1-1305573081.file.myqcloud.com/image/5.jpg"
+        class="img"
+      />
+    </div>
+    <!-- 选择内容 -->
+    <div v-if="true">
+      <!-- 单选 -->
+      <van-radio-group
+        v-model="currentAnswer.userAnswer"
+        v-if="currentAnswer.type < 2"
+        @change="userAnswerChange"
+        icon-size="35px"
+      >
+        <van-radio
+          v-for="(item, index) in currentAnswer.opts"
+          :key="Number(index)"
+          :name="item"
+          class="answer"
+          >{{ item }}
+          <template #icon="props">
+            <div class="choose-icon" :class="{ selected: props.checked }">
+              {{ String.fromCharCode(65 + Number(index)) }}
+            </div>
+          </template>
+        </van-radio>
+      </van-radio-group>
+      <!-- 多选 -->
+      <div v-else>
+        <van-checkbox-group v-model="currentAnswer.userAnswer" icon-size="35px">
+          <van-checkbox
+            v-for="(item, index) in currentAnswer.opts"
+            :key="Number(index)"
+            :name="item"
+            class="answer"
+            >{{ item }}
+            <template #icon="props">
+              <div class="choose-icon" :class="{ selected: props.checked }">
+                {{ String.fromCharCode(65 + Number(index)) }}
+              </div>
+            </template>
+          </van-checkbox>
+        </van-checkbox-group>
+        <van-button
+          round
+          type="primary"
+          class="checkbox-btn"
+          :disabled="currentAnswer.userAnswer.length == 0"
+          @click="userAnswerChange"
+          >确定</van-button
+        >
+      </div>
+    </div>
+    <!-- 展示答题后选择内容 -->
+    <div v-else-if="false">
+      <div>
+        <div
+          v-for="(item, index) in currentAnswer.optsBack"
+          :key="Number(index)"
+          class="answer-box"
+        >
+          <div
+            class="choose-icon"
+            :class="{ iconTrue: item.status % 2 !== 0 }"
+            v-if="item.status < 2"
+          >
+            {{ String.fromCharCode(65 + Number(index)) }}
+          </div>
+          <m-icon
+            v-else-if="item.status == 3"
+            type="dui"
+            size="30px"
+            style="margin-left: 5px"
+          />
+          <m-icon
+            v-else-if="item.status == 2"
+            size="30px"
+            type="cuo"
+            style="margin-left: 5px"
+          />
+          <span
+            class="answer-text"
+            :class="{ true: item.status % 2 !== 0, false: item.status == 2 }"
+          >
+            {{ item.opt }}
+          </span>
+        </div>
+      </div>
+      <div class="checkbox-answer">
+        答案: {{ currentAnswer.answer.toString() }}
+      </div>
+    </div>
+    <!-- 展示答题后选择内容end -->
+  </div>
+  <!-- 选择内容End -->
+  <!-- 分割线 -->
+  <van-divider />
+  <!-- 功能选择列表 -->
+  <div class="function-list">
+    <div class="function-item">
+      <m-icon type="shoucanghui" size="25px" />
+      <span>收藏</span>
+    </div>
+    <div class="function-item" @click="answerAudioPlay">
+      <m-icon type="a-dtda" size="25px" />
+      <span>读题+答案</span>
+    </div>
+    <div class="function-item" @click="issueAudioPlay">
+      <m-icon type="duti" size="25px" />
+      <span>读题</span>
+    </div>
+    <!-- <div class="function-item" @click="currentAnswerIndexBack">
+      <m-icon type="shangyiti" size="25px" />
+      <span>上一题</span>
+    </div>
+    <div class="function-item" @click="skillsShow = true">
+      <m-icon type="zongtishu" size="25px" />
+      <span>1/100</span>
+    </div>
+    <div class="function-item" @click="currentAnswerIndexGo">
+      <m-icon type="xiayiti" size="25px" />
+      <span>下一题</span>
+    </div> -->
+  </div>
+  <!-- 功能选择列表End -->
+  <!-- 技巧讲解 -->
+  <van-overlay :show="skillsShow" @click="skillsShow = false" z-index="10">
+    <div class="skills-box" @click.stop>
+      <div class="skills">
+        <div class="title">技巧讲解</div>
+        <img
+          src="https://t1-1305573081.file.myqcloud.com/gif/2.gif"
+          class="img"
+        />
+        <van-divider class="divider">本题速记口诀</van-divider>
+        <div class="text">题目以“拘役”结尾.答对;以“徒刑”结尾.答错</div>
+        <div class="btn">
+          <span @click="skillsShow = false">关闭</span>
+          <span @click="JQexplainAudioPlay">语音重播</span>
+        </div>
+      </div>
+    </div>
+  </van-overlay>
+  <!-- 技巧讲解end -->
+  <!-- 官方解释 -->
+  <van-overlay :show="officialShow" @click="officialShow = false" z-index="10">
+    <div class="skills-box" @click.stop>
+      <div class="skills">
+        <div class="title">官方解释</div>
+        <div class="text">
+          1、申请城市公交车、大型货车、无轨电车或者有轨电车准驾车型的,在20周岁以上,50周岁以下;2、申请大型客车准驾车型的,在26周岁以上,50周岁以下;3、申请中型客车准驾车型的,在21周岁以上,50周岁以下;4、申请牵引车准驾车型的,在24周岁以上,50周岁以下。
+        </div>
+        <div class="btn">
+          <span @click="officialShow = false">关闭</span>
+          <span @click="explainAudioPlay">语音重播</span>
+        </div>
+      </div>
+    </div>
+  </van-overlay>
+  <!-- 官方解释end -->
+  <!-- 音频模块 -->
+  <audio ref="audio"></audio>
+  <!-- 音频模块end -->
+  <!-- 题目模块end -->
+  <!-- 设置操作栏 -->
+  <van-popup v-model:show="setShow" position="bottom">
+    <van-cell center title="答对跳转下一题">
+      <template #right-icon>
+        <van-switch v-model="isJump" size="24" />
+      </template>
+    </van-cell>
+    <van-cell center title="答题音效提示">
+      <template #right-icon>
+        <van-switch v-model="isSoundEffect" size="24" />
+      </template>
+    </van-cell>
+  </van-popup>
+  <!-- 设置操作栏end -->
+  <!-- 底部操作栏 -->
+  <!-- <div style="height: 40px"></div> -->
+  <!-- <m-button class="submitButton" text="交卷" /> -->
+  <van-tabbar placeholder route>
+    <van-tabbar-item @click="currentAnswerIndexBack"
+      >上一题
+      <template #icon>
+        <m-icon type="shangyiti" />
+      </template>
+    </van-tabbar-item>
+    <van-tabbar-item
+      >{{ idIndex }}/{{ total }}
+      <template #icon>
+        <m-icon type="zongtishu" />
+      </template>
+    </van-tabbar-item>
+    <van-tabbar-item @click="gotoTest"
+      >交卷
+      <template #icon>
+        <m-icon type="jiaojuan" />
+      </template>
+    </van-tabbar-item>
+    <van-tabbar-item @click="currentAnswerIndexGo"
+      >下一题
+      <template #icon>
+        <m-icon type="xiayiti" />
+      </template>
+    </van-tabbar-item>
+  </van-tabbar>
+  <!-- 底部操作栏end -->
+</template>
+
+<script lang="ts" setup>
+import * as Api from "@/api";
+import { useRouter } from "vue-router";
+import {
+  ref,
+  watch,
+  computed,
+  reactive,
+  onBeforeMount,
+  nextTick,
+  defineEmits,
+} from "vue";
+import { Dialog } from "vant";
+const router = useRouter();
+const onClickLeft = () => {
+  router.back();
+};
+
+//父级传参
+const emits = defineEmits(["next"]);
+const gotoTest = () => {
+  Dialog.confirm({
+    message: "确认交卷吗?",
+  })
+    .then(() => {
+      emits("next");
+    })
+    .catch(() => {});
+};
+
+//答题模式选择逻辑
+const answerTypeList = ref([
+  { name: "顺序练习" },
+  { name: "随机练习" },
+  { name: "背题模式" },
+]);
+const currentType = ref(0);
+const typeParams = ref({
+  order: true, //顺序练习
+  answerShow: false, //背题模式
+});
+watch(currentType, (currentVal) => {
+  switch (currentVal) {
+    case 0:
+      typeParams.value.order = true;
+      typeParams.value.answerShow = false;
+      break;
+    case 1:
+      typeParams.value.order = false;
+      typeParams.value.answerShow = false;
+      break;
+    case 2:
+      typeParams.value.order = true;
+      typeParams.value.answerShow = true;
+      break;
+  }
+});
+
+//自动读题
+const aotuPlayFlag = ref(false);
+const aotuPlaySet = () => {
+  aotuPlayFlag.value = !aotuPlayFlag.value;
+  if (aotuPlayFlag.value) issueAudioPlay();
+  if (!aotuPlayFlag.value) audioPause();
+};
+onBeforeMount(() => {
+  watch(currentAnswerIndex, () => {
+    if (aotuPlayFlag.value) issueAudioPlay(); //自动读题
+  });
+});
+//答题模式选择逻辑end
+
+//题目展示逻辑
+const topicList = ref([]);
+console.log(topicList);
+
+//API请求接口数据
+onBeforeMount(async () => {
+  const topicListApiRes = Api.getTopicList();
+  setTimeout(() => {
+    topicList.value = topicListApiRes.data.list;
+    idIndex.value = 200;
+    total.value = 1999;
+  }, 1000);
+});
+
+//当前题目数据
+const currentAnswerIndex = ref(0);
+const currentAnswer: any = computed(() => {
+  return topicList.value[currentAnswerIndex.value];
+});
+
+//上一题,下一题
+const currentAnswerIndexBack = () => {
+  if (topicList.value.length == 0) return;
+  currentAnswerIndex.value =
+    (currentAnswerIndex.value - 1 + topicList.value.length) %
+    topicList.value.length;
+};
+const currentAnswerIndexGo = () => {
+  if (topicList.value.length == 0) return;
+  currentAnswerIndex.value =
+    (currentAnswerIndex.value + 1) % topicList.value.length;
+};
+
+//选择答案后
+const userAnswerChange = () => {
+  currentAnswer.value.optsBack = currentAnswer.value.opts.map((val: String) => {
+    let status;
+    if (currentAnswer.value.answer.includes(val)) {
+      status = 1;
+    } else {
+      status = 0;
+    }
+    if (currentAnswer.value.userAnswer.includes(val)) {
+      status += 2;
+    }
+    return { opt: val, status };
+  });
+  if (
+    JSON.stringify(currentAnswer.value.answer) ==
+    JSON.stringify(currentAnswer.value.userAnswer)
+  ) {
+    console.log("答案正确");
+    currentAnswer.value.isTrue = true;
+    trueNum.value++;
+    if (isJump.value)
+      setTimeout(() => {
+        currentAnswerIndexGo();
+      }, 200);
+  } else {
+    console.log("错误");
+    currentAnswer.value.isTrue = false;
+    falseNum.value++;
+  }
+};
+const topicType = (type: Number) => {
+  switch (type) {
+    case 0:
+      return "判断题";
+    case 1:
+      return "单选题";
+    case 2:
+      return "多选题";
+  }
+};
+//题目展示逻辑end
+
+//技巧讲解
+const skillsShow = ref(false); //显示技巧讲解
+//技巧讲解end
+
+//官方解释
+const officialShow = ref(false); //显示官方解释
+//官方解释end
+
+//设置操作栏
+const setShow = ref(false); //显示设置栏
+const isJump = ref(false); //答对跳转下一题
+const isSoundEffect = ref(true); //答题音效
+//设置操作栏end
+
+//音频模块
+const audio = ref();
+
+/**
+ * 读题
+ */
+const issueAudioPlay = () => {
+  audio.value.src = "https://t1-1305573081.file.myqcloud.com/issue/issue1.mp3";
+  audio.value.play();
+};
+
+/**
+ * 读答案
+ */
+const answerAudioPlay = () => {
+  audio.value.src =
+    "https://t1-1305573081.file.myqcloud.com/answer/answer1.mp3";
+  audio.value.play();
+};
+
+/**
+ * 读官方解释
+ */
+const explainAudioPlay = () => {
+  audio.value.src =
+    "https://t1-1305573081.file.myqcloud.com/explainjs/explainJS1.mp3";
+  audio.value.play();
+};
+
+/**
+ * 读技巧解释
+ */
+const JQexplainAudioPlay = () => {
+  audio.value.src = "https://t1-1305573081.file.myqcloud.com/mp3/explain1.mp3";
+  audio.value.play();
+};
+
+/**
+ * 停止播放
+ */
+const audioPause = () => {
+  audio.value.pause();
+};
+
+//音频模块end
+
+//记录模块
+const trueNum = ref(0); //答对数量
+const falseNum = ref(0); //答错数量
+const idIndex = ref(0); //当前题目标志位
+const total = ref(0); //题目总数量
+onBeforeMount(() => {
+  watch(currentAnswerIndex, () => {
+    idIndex.value = currentAnswerIndex.value;
+  });
+});
+//记录模块end
+</script>
+
+<style lang="scss" scoped>
+.dowm-box {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 10px;
+  position: sticky;
+  top: 45px;
+  font-size: 30px;
+  background-color: #ffffff;
+}
+.parsing-img {
+  width: 100%;
+  margin-top: 10px;
+}
+.function-list {
+  width: 100%;
+  font-size: 13px;
+  display: flex;
+  justify-content: space-around;
+  flex-wrap: wrap;
+  padding: 15px;
+  box-sizing: border-box;
+  .function-item {
+    margin-bottom: 20px;
+    width: 30%;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    font-size: 13px;
+    font-weight: 400;
+    color: #8a9099;
+    span {
+      margin-top: 5px;
+    }
+  }
+}
+.answerType {
+  width: 100%;
+  font-size: 13px;
+  display: flex;
+  justify-content: space-around;
+  padding: 15px;
+  box-sizing: border-box;
+  span {
+    border-radius: 20px;
+    padding: 3px 10px;
+    background-color: #b8c0cc;
+    color: #ffffff;
+  }
+  .selected {
+    background-color: #498ef5;
+  }
+}
+.divider {
+  width: 100%;
+  height: 10px;
+  background-color: #f2f3f5;
+}
+.problem-box {
+  font-size: 17px;
+  padding: 15px;
+  .problem {
+    .type {
+      width: 47px;
+      height: 24px;
+      background: #498ef5;
+      border-radius: 10px 10px 0px 10px;
+      font-size: 11px;
+      padding: 2px 7px;
+      margin-right: 5px;
+    }
+    .text {
+      font-family: PingFang SC;
+      font-weight: 400;
+      color: #0a1a33;
+      letter-spacing: 0.3px;
+    }
+    .img {
+      width: 100%;
+      margin-top: 10px;
+    }
+  }
+  .answer {
+    margin-top: 25px;
+  }
+  .answer-box {
+    display: flex;
+    margin-top: 25px;
+    align-items: center;
+    .iconTrue {
+      background-color: #01c18d;
+    }
+    .answer-text {
+      margin-left: 10px;
+    }
+    .true {
+      color: #01c18d;
+    }
+    .false {
+      color: #ff4d53;
+    }
+  }
+
+  .choose-icon {
+    width: 30px;
+    height: 30px;
+    border-radius: 50%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    font-size: 17px;
+    box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.16);
+    box-sizing: border-box;
+    margin-left: 5px;
+    margin-top: 1px;
+  }
+  .selected {
+    background-color: #498ef5;
+  }
+  .checkbox-btn {
+    width: 266px;
+    height: 40px;
+    margin: auto;
+    margin-top: 25px;
+    left: 50%;
+    transform: translateX(-50%);
+  }
+  .checkbox-answer {
+    padding: 8px 10px;
+    background-color: #f2f3f5;
+    margin-top: 25px;
+  }
+}
+.skills-box {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 100%;
+  .skills {
+    width: 290px;
+    background: #ffffff;
+    box-shadow: 0px 0px 8px rgba(124, 129, 136, 0.16);
+    border-radius: 10px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding: 20px 16px;
+    box-sizing: border-box;
+    .title {
+      font-size: 15px;
+      font-family: PingFang SC;
+      font-weight: bold;
+      line-height: 21px;
+      color: #0a1a33;
+    }
+    .img {
+      width: 258px;
+      height: 129px;
+      border: 1px solid #e8e8e8;
+      margin-top: 16px;
+    }
+    .divider {
+      margin-top: 20px;
+      color: #0a1a33;
+      background: #ffffff;
+    }
+    .text {
+      font-size: 13px;
+      font-family: PingFang SC;
+      font-weight: 400;
+      line-height: 19px;
+      color: #5c6066;
+      margin-top: 10px;
+    }
+    .btn {
+      width: 100%;
+      display: flex;
+      justify-content: space-between;
+      padding: 0 40px;
+      box-sizing: border-box;
+      margin-top: 20px;
+      span {
+        width: 76px;
+        height: 30px;
+        border-radius: 15px;
+        font-size: 13px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        &:active {
+          background-color: #afaaaa;
+          filter: brightness(50%);
+        }
+        &:nth-of-type(1) {
+          border: 1px solid #707070;
+          color: #5c6066;
+        }
+        &:nth-of-type(2) {
+          background: #498ef5;
+          border: 1px solid #498ef5;
+          color: #ffffff;
+        }
+      }
+    }
+  }
+}
+
+.submitButton {
+  background-color: #498ef5;
+  position: fixed;
+  left: 50%;
+  transform: translateX(-50%);
+  bottom: 0;
+  width: 80%;
+  color: #ffffff;
+  font-size: 16px;
+}
+</style>

+ 29 - 0
src/views/mockTest/index.vue

@@ -0,0 +1,29 @@
+<template>
+  <component :is="currentComponent" @next="next"></component>
+</template>
+
+<script lang="ts" setup>
+import initMockTest from "./components/initMockTest.vue";
+import mockTestEnd from "./components/mockTestEnd.vue";
+import startTest from "./components/startTest.vue";
+import { defineComponent, ref } from "vue";
+
+const currentComponent = ref(initMockTest);
+const comIndex = ref(0);
+const next = () => {
+  comIndex.value++;
+  switch (comIndex.value) {
+    case 0:
+      currentComponent.value = initMockTest;
+      break;
+    case 1:
+      currentComponent.value = startTest;
+      break;
+    case 2:
+      currentComponent.value = mockTestEnd;
+      break;
+  }
+};
+</script>
+
+<style scoped lang="scss"></style>

+ 152 - 0
src/views/testScores/index.vue

@@ -0,0 +1,152 @@
+<template>
+  <div class="header-back">
+    <m-nav-bar title="模拟考试" />
+    <div class="user-data">
+      <div class="left">
+        <m-user-avatar />
+        <div class="name">
+          <m-user-name />
+          <span>最高成绩<span class="grade">60</span>分</span>
+        </div>
+      </div>
+      <m-button class="continue" width="90px" height="30px" text="继续考试" />
+    </div>
+  </div>
+  <div class="summary content-box">
+    <div class="item">
+      <div><span class="number">10</span>次</div>
+      <div>考试次数</div>
+    </div>
+    <div class="item">
+      <div><span class="number">20</span>次</div>
+      <div>平均成绩</div>
+    </div>
+    <div class="item">
+      <div><span class="number">0</span>次</div>
+      <div>成绩预测</div>
+    </div>
+  </div>
+  <div class="test-scores content-box">
+    <table class="table">
+      <tr>
+        <th>车型</th>
+        <th>科目</th>
+        <th>分数</th>
+        <th>时间</th>
+      </tr>
+      <tr v-for="(item,index) in 10" :key="index">
+        <td>摩托车</td>
+        <td>科目一</td>
+        <td>0</td>
+        <td>2021-05-20 15:20:30</td>
+      </tr>
+    </table>
+  </div>
+</template>
+
+<script>
+export default {};
+</script>
+
+<style scoped lang="scss">
+.header-back {
+  width: 375px;
+  padding-bottom: 82px;
+  background: linear-gradient(180deg, #498ef5 0%, #4da8e6 100%);
+  border-radius: 0px 0px 82px 82px;
+  .user-data {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 19px 17px 24px;
+    .left {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      .name {
+        display: flex;
+        flex-direction: column;
+        font-size: 13px;
+        color: #ffffff;
+        justify-content: space-between;
+        margin-left: 6px;
+        .grade {
+          font-size: 24px;
+          padding: 4px;
+        }
+      }
+    }
+    .continue {
+      font-size: 13px;
+      font-family: PingFang SC;
+      font-weight: 400;
+      line-height: 19px;
+      color: #ffffff;
+      background: #01c18d;
+    }
+  }
+}
+.content-box {
+  width: 345px;
+  background: #ffffff;
+  box-shadow: 0px 0px 8px rgba(124, 129, 136, 0.2);
+  border-radius: 10px;
+  position: relative;
+  left: 50%;
+  transform: translateX(-50%);
+  top: -82px;
+  margin-top: 10px;
+}
+.summary {
+  display: flex;
+  justify-content: space-around;
+  padding: 25px 30px;
+  box-sizing: border-box;
+  .item {
+    font-size: 13px;
+    font-family: PingFang SC;
+    font-weight: 400;
+    line-height: 19px;
+    color: #8a9099;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    .number {
+      font-size: 24px;
+      color: #0a1a33;
+      padding: 4px;
+    }
+  }
+}
+.test-scores {
+  font-size: 13px;
+  font-family: PingFang SC;
+  font-weight: 400;
+  line-height: 19px;
+  color: #0a1a33;
+  padding: 15px;
+  box-sizing: border-box;
+  .table {
+    width: 100%;
+    border-collapse: collapse;
+    font-size: 13px;
+    th {
+      padding: 5px;
+      color: #0a1a33;
+    }
+    td {
+      text-align: center;
+      padding: 5px;
+      color: #8a9099;
+    }
+    tr {
+      &:nth-of-type(n) {
+        background: #ffffff;
+      }
+      &:nth-of-type(2n) {
+        background: rgba(73, 142, 245, 0.15);
+      }
+    }
+  }
+}
+</style>

+ 58 - 0
src/views/topicType/index.vue

@@ -0,0 +1,58 @@
+<template>
+  <m-nav-bar title="地方专题"/>
+  <van-cell
+    v-for="(item, index) in 6"
+    :key="item"
+    center
+    icon="location-o"
+    title="单元格"
+  >
+    <template #icon>
+      <div class="topic-index">{{ index + 1 }}</div>
+    </template>
+    <template #value>
+      <div class="answerType">
+        <div class="icon-box">
+          <m-icon type="yyjj" />
+          <span>语言讲解</span>
+        </div>
+        <div class="icon-box">
+          <m-icon type="dxxz" />
+          <span>单项测试</span>
+        </div>
+      </div>
+    </template>
+  </van-cell>
+</template>
+
+<script lang="ts" setup>
+</script>
+
+<style lang="scss" scoped>
+.topic-index {
+  width: 20px;
+  height: 20px;
+  border-radius: 50%;
+  background-color: #498ef5;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  color: #ffffff;
+  margin-right: 5px;
+}
+.answerType {
+  display: flex;
+  justify-content: space-between;
+  .icon-box {
+    display: flex;
+    background-color: #498ef5;
+    border-radius: 20px;
+    padding: 2px 6px;
+    align-items: center;
+    span {
+      color: #ffffff;
+      font-size: 13px;
+    }
+  }
+}
+</style>

+ 1 - 0
src/vite-env.d.ts

@@ -0,0 +1 @@
+/// <reference types="vite/client" />

+ 18 - 0
tsconfig.json

@@ -0,0 +1,18 @@
+{
+  "compilerOptions": {
+    "target": "esnext",
+    "module": "esnext",
+    "moduleResolution": "node",
+    "strict": true,
+    "jsx": "preserve",
+    "sourceMap": true,
+    "resolveJsonModule": true,
+    "esModuleInterop": true,
+    "lib": ["esnext", "dom"],
+    "baseUrl": ".",
+    "paths": {
+      "@/*": ["src/*"]
+    }
+  },
+  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
+}

+ 16 - 0
vite.config.ts

@@ -0,0 +1,16 @@
+import { defineConfig } from "vite";
+import vue from "@vitejs/plugin-vue";
+import path from "path";
+
+// https://vitejs.dev/config/
+export default defineConfig({
+  plugins: [vue()],
+  resolve: {
+    alias: {
+      "@": path.resolve(__dirname, "src"),
+    },
+  },
+  server: {
+    host: "0.0.0.0",
+  },
+});

Some files were not shown because too many files changed in this diff