Przeglądaj źródła

Merge branch 'master' of http://git.dayaedu.com/lex/classroom-instruments

mo 1 rok temu
rodzic
commit
9557e7b74d

+ 1 - 0
components.d.ts

@@ -9,6 +9,7 @@ export {}
 
 declare module '@vue/runtime-core' {
   export interface GlobalComponents {
+    Application: typeof import('./src/components/Application/Application.vue')['default']
     HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']

+ 157 - 186
package-lock.json

@@ -15,7 +15,7 @@
         "numeral": "^2.0.6",
         "pinia": "^2.1.4",
         "umi-request": "^1.4.0",
-        "vue": "^3.2.47",
+        "vue": "^3.3.4",
         "vue-router": "^4.1.6",
         "vue3-lottie": "^2.7.0"
       },
@@ -2214,8 +2214,7 @@
     "node_modules/@jridgewell/sourcemap-codec": {
       "version": "1.4.15",
       "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
-      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
-      "dev": true
+      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
     },
     "node_modules/@jridgewell/trace-mapping": {
       "version": "0.3.18",
@@ -2982,49 +2981,49 @@
       }
     },
     "node_modules/@vue/compiler-core": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.2.47.tgz",
-      "integrity": "sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz",
+      "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==",
       "dependencies": {
-        "@babel/parser": "^7.16.4",
-        "@vue/shared": "3.2.47",
+        "@babel/parser": "^7.21.3",
+        "@vue/shared": "3.3.4",
         "estree-walker": "^2.0.2",
-        "source-map": "^0.6.1"
+        "source-map-js": "^1.0.2"
       }
     },
     "node_modules/@vue/compiler-dom": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz",
-      "integrity": "sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz",
+      "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==",
       "dependencies": {
-        "@vue/compiler-core": "3.2.47",
-        "@vue/shared": "3.2.47"
+        "@vue/compiler-core": "3.3.4",
+        "@vue/shared": "3.3.4"
       }
     },
     "node_modules/@vue/compiler-sfc": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz",
-      "integrity": "sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==",
-      "dependencies": {
-        "@babel/parser": "^7.16.4",
-        "@vue/compiler-core": "3.2.47",
-        "@vue/compiler-dom": "3.2.47",
-        "@vue/compiler-ssr": "3.2.47",
-        "@vue/reactivity-transform": "3.2.47",
-        "@vue/shared": "3.2.47",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz",
+      "integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==",
+      "dependencies": {
+        "@babel/parser": "^7.20.15",
+        "@vue/compiler-core": "3.3.4",
+        "@vue/compiler-dom": "3.3.4",
+        "@vue/compiler-ssr": "3.3.4",
+        "@vue/reactivity-transform": "3.3.4",
+        "@vue/shared": "3.3.4",
         "estree-walker": "^2.0.2",
-        "magic-string": "^0.25.7",
+        "magic-string": "^0.30.0",
         "postcss": "^8.1.10",
-        "source-map": "^0.6.1"
+        "source-map-js": "^1.0.2"
       }
     },
     "node_modules/@vue/compiler-ssr": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz",
-      "integrity": "sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz",
+      "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==",
       "dependencies": {
-        "@vue/compiler-dom": "3.2.47",
-        "@vue/shared": "3.2.47"
+        "@vue/compiler-dom": "3.3.4",
+        "@vue/shared": "3.3.4"
       }
     },
     "node_modules/@vue/devtools-api": {
@@ -3071,60 +3070,60 @@
       }
     },
     "node_modules/@vue/reactivity": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.2.47.tgz",
-      "integrity": "sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.4.tgz",
+      "integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==",
       "dependencies": {
-        "@vue/shared": "3.2.47"
+        "@vue/shared": "3.3.4"
       }
     },
     "node_modules/@vue/reactivity-transform": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz",
-      "integrity": "sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz",
+      "integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==",
       "dependencies": {
-        "@babel/parser": "^7.16.4",
-        "@vue/compiler-core": "3.2.47",
-        "@vue/shared": "3.2.47",
+        "@babel/parser": "^7.20.15",
+        "@vue/compiler-core": "3.3.4",
+        "@vue/shared": "3.3.4",
         "estree-walker": "^2.0.2",
-        "magic-string": "^0.25.7"
+        "magic-string": "^0.30.0"
       }
     },
     "node_modules/@vue/runtime-core": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.2.47.tgz",
-      "integrity": "sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.3.4.tgz",
+      "integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==",
       "dependencies": {
-        "@vue/reactivity": "3.2.47",
-        "@vue/shared": "3.2.47"
+        "@vue/reactivity": "3.3.4",
+        "@vue/shared": "3.3.4"
       }
     },
     "node_modules/@vue/runtime-dom": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz",
-      "integrity": "sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz",
+      "integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==",
       "dependencies": {
-        "@vue/runtime-core": "3.2.47",
-        "@vue/shared": "3.2.47",
-        "csstype": "^2.6.8"
+        "@vue/runtime-core": "3.3.4",
+        "@vue/shared": "3.3.4",
+        "csstype": "^3.1.1"
       }
     },
     "node_modules/@vue/server-renderer": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.2.47.tgz",
-      "integrity": "sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.3.4.tgz",
+      "integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==",
       "dependencies": {
-        "@vue/compiler-ssr": "3.2.47",
-        "@vue/shared": "3.2.47"
+        "@vue/compiler-ssr": "3.3.4",
+        "@vue/shared": "3.3.4"
       },
       "peerDependencies": {
-        "vue": "3.2.47"
+        "vue": "3.3.4"
       }
     },
     "node_modules/@vue/shared": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.2.47.tgz",
-      "integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ=="
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz",
+      "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ=="
     },
     "node_modules/acorn": {
       "version": "8.8.2",
@@ -3787,9 +3786,9 @@
       }
     },
     "node_modules/csstype": {
-      "version": "2.6.21",
-      "resolved": "https://registry.npmmirror.com/csstype/-/csstype-2.6.21.tgz",
-      "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
+      "version": "3.1.2",
+      "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.2.tgz",
+      "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
     },
     "node_modules/date-fns": {
       "version": "2.30.0",
@@ -5985,11 +5984,14 @@
       }
     },
     "node_modules/magic-string": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.25.9.tgz",
-      "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
+      "version": "0.30.0",
+      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.0.tgz",
+      "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==",
       "dependencies": {
-        "sourcemap-codec": "^1.4.8"
+        "@jridgewell/sourcemap-codec": "^1.4.13"
+      },
+      "engines": {
+        "node": ">=12"
       }
     },
     "node_modules/make-dir": {
@@ -7381,6 +7383,7 @@
       "version": "0.6.1",
       "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
       "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
@@ -7393,12 +7396,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/sourcemap-codec": {
-      "version": "1.4.8",
-      "resolved": "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
-      "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
-      "deprecated": "Please use @jridgewell/sourcemap-codec instead"
-    },
     "node_modules/stdin-discarder": {
       "version": "0.1.0",
       "resolved": "https://registry.npmmirror.com/stdin-discarder/-/stdin-discarder-0.1.0.tgz",
@@ -7798,18 +7795,6 @@
         "balanced-match": "^1.0.0"
       }
     },
-    "node_modules/unplugin-vue-components/node_modules/magic-string": {
-      "version": "0.30.0",
-      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.0.tgz",
-      "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==",
-      "dev": true,
-      "dependencies": {
-        "@jridgewell/sourcemap-codec": "^1.4.13"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
     "node_modules/unplugin-vue-components/node_modules/minimatch": {
       "version": "7.4.6",
       "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-7.4.6.tgz",
@@ -8014,15 +7999,15 @@
       }
     },
     "node_modules/vue": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/vue/-/vue-3.2.47.tgz",
-      "integrity": "sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/vue/-/vue-3.3.4.tgz",
+      "integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==",
       "dependencies": {
-        "@vue/compiler-dom": "3.2.47",
-        "@vue/compiler-sfc": "3.2.47",
-        "@vue/runtime-dom": "3.2.47",
-        "@vue/server-renderer": "3.2.47",
-        "@vue/shared": "3.2.47"
+        "@vue/compiler-dom": "3.3.4",
+        "@vue/compiler-sfc": "3.3.4",
+        "@vue/runtime-dom": "3.3.4",
+        "@vue/server-renderer": "3.3.4",
+        "@vue/shared": "3.3.4"
       }
     },
     "node_modules/vue-demi": {
@@ -9975,8 +9960,7 @@
     "@jridgewell/sourcemap-codec": {
       "version": "1.4.15",
       "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
-      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
-      "dev": true
+      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
     },
     "@jridgewell/trace-mapping": {
       "version": "0.3.18",
@@ -10580,49 +10564,49 @@
       }
     },
     "@vue/compiler-core": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.2.47.tgz",
-      "integrity": "sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz",
+      "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==",
       "requires": {
-        "@babel/parser": "^7.16.4",
-        "@vue/shared": "3.2.47",
+        "@babel/parser": "^7.21.3",
+        "@vue/shared": "3.3.4",
         "estree-walker": "^2.0.2",
-        "source-map": "^0.6.1"
+        "source-map-js": "^1.0.2"
       }
     },
     "@vue/compiler-dom": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz",
-      "integrity": "sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz",
+      "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==",
       "requires": {
-        "@vue/compiler-core": "3.2.47",
-        "@vue/shared": "3.2.47"
+        "@vue/compiler-core": "3.3.4",
+        "@vue/shared": "3.3.4"
       }
     },
     "@vue/compiler-sfc": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz",
-      "integrity": "sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==",
-      "requires": {
-        "@babel/parser": "^7.16.4",
-        "@vue/compiler-core": "3.2.47",
-        "@vue/compiler-dom": "3.2.47",
-        "@vue/compiler-ssr": "3.2.47",
-        "@vue/reactivity-transform": "3.2.47",
-        "@vue/shared": "3.2.47",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz",
+      "integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==",
+      "requires": {
+        "@babel/parser": "^7.20.15",
+        "@vue/compiler-core": "3.3.4",
+        "@vue/compiler-dom": "3.3.4",
+        "@vue/compiler-ssr": "3.3.4",
+        "@vue/reactivity-transform": "3.3.4",
+        "@vue/shared": "3.3.4",
         "estree-walker": "^2.0.2",
-        "magic-string": "^0.25.7",
+        "magic-string": "^0.30.0",
         "postcss": "^8.1.10",
-        "source-map": "^0.6.1"
+        "source-map-js": "^1.0.2"
       }
     },
     "@vue/compiler-ssr": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz",
-      "integrity": "sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz",
+      "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==",
       "requires": {
-        "@vue/compiler-dom": "3.2.47",
-        "@vue/shared": "3.2.47"
+        "@vue/compiler-dom": "3.3.4",
+        "@vue/shared": "3.3.4"
       }
     },
     "@vue/devtools-api": {
@@ -10652,57 +10636,57 @@
       }
     },
     "@vue/reactivity": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.2.47.tgz",
-      "integrity": "sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.4.tgz",
+      "integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==",
       "requires": {
-        "@vue/shared": "3.2.47"
+        "@vue/shared": "3.3.4"
       }
     },
     "@vue/reactivity-transform": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz",
-      "integrity": "sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz",
+      "integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==",
       "requires": {
-        "@babel/parser": "^7.16.4",
-        "@vue/compiler-core": "3.2.47",
-        "@vue/shared": "3.2.47",
+        "@babel/parser": "^7.20.15",
+        "@vue/compiler-core": "3.3.4",
+        "@vue/shared": "3.3.4",
         "estree-walker": "^2.0.2",
-        "magic-string": "^0.25.7"
+        "magic-string": "^0.30.0"
       }
     },
     "@vue/runtime-core": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.2.47.tgz",
-      "integrity": "sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.3.4.tgz",
+      "integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==",
       "requires": {
-        "@vue/reactivity": "3.2.47",
-        "@vue/shared": "3.2.47"
+        "@vue/reactivity": "3.3.4",
+        "@vue/shared": "3.3.4"
       }
     },
     "@vue/runtime-dom": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz",
-      "integrity": "sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz",
+      "integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==",
       "requires": {
-        "@vue/runtime-core": "3.2.47",
-        "@vue/shared": "3.2.47",
-        "csstype": "^2.6.8"
+        "@vue/runtime-core": "3.3.4",
+        "@vue/shared": "3.3.4",
+        "csstype": "^3.1.1"
       }
     },
     "@vue/server-renderer": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.2.47.tgz",
-      "integrity": "sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.3.4.tgz",
+      "integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==",
       "requires": {
-        "@vue/compiler-ssr": "3.2.47",
-        "@vue/shared": "3.2.47"
+        "@vue/compiler-ssr": "3.3.4",
+        "@vue/shared": "3.3.4"
       }
     },
     "@vue/shared": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.2.47.tgz",
-      "integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ=="
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz",
+      "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ=="
     },
     "acorn": {
       "version": "8.8.2",
@@ -11250,9 +11234,9 @@
       "dev": true
     },
     "csstype": {
-      "version": "2.6.21",
-      "resolved": "https://registry.npmmirror.com/csstype/-/csstype-2.6.21.tgz",
-      "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
+      "version": "3.1.2",
+      "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.2.tgz",
+      "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
     },
     "date-fns": {
       "version": "2.30.0",
@@ -12974,11 +12958,11 @@
       }
     },
     "magic-string": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.25.9.tgz",
-      "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
+      "version": "0.30.0",
+      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.0.tgz",
+      "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==",
       "requires": {
-        "sourcemap-codec": "^1.4.8"
+        "@jridgewell/sourcemap-codec": "^1.4.13"
       }
     },
     "make-dir": {
@@ -14077,18 +14061,14 @@
     "source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true
     },
     "source-map-js": {
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz",
       "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
     },
-    "sourcemap-codec": {
-      "version": "1.4.8",
-      "resolved": "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
-      "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="
-    },
     "stdin-discarder": {
       "version": "0.1.0",
       "resolved": "https://registry.npmmirror.com/stdin-discarder/-/stdin-discarder-0.1.0.tgz",
@@ -14391,15 +14371,6 @@
             "balanced-match": "^1.0.0"
           }
         },
-        "magic-string": {
-          "version": "0.30.0",
-          "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.0.tgz",
-          "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==",
-          "dev": true,
-          "requires": {
-            "@jridgewell/sourcemap-codec": "^1.4.13"
-          }
-        },
         "minimatch": {
           "version": "7.4.6",
           "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-7.4.6.tgz",
@@ -14535,15 +14506,15 @@
       }
     },
     "vue": {
-      "version": "3.2.47",
-      "resolved": "https://registry.npmmirror.com/vue/-/vue-3.2.47.tgz",
-      "integrity": "sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==",
-      "requires": {
-        "@vue/compiler-dom": "3.2.47",
-        "@vue/compiler-sfc": "3.2.47",
-        "@vue/runtime-dom": "3.2.47",
-        "@vue/server-renderer": "3.2.47",
-        "@vue/shared": "3.2.47"
+      "version": "3.3.4",
+      "resolved": "https://registry.npmmirror.com/vue/-/vue-3.3.4.tgz",
+      "integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==",
+      "requires": {
+        "@vue/compiler-dom": "3.3.4",
+        "@vue/compiler-sfc": "3.3.4",
+        "@vue/runtime-dom": "3.3.4",
+        "@vue/server-renderer": "3.3.4",
+        "@vue/shared": "3.3.4"
       }
     },
     "vue-demi": {

+ 1 - 1
package.json

@@ -28,7 +28,7 @@
     "numeral": "^2.0.6",
     "pinia": "^2.1.4",
     "umi-request": "^1.4.0",
-    "vue": "^3.2.47",
+    "vue": "^3.3.4",
     "vue-router": "^4.1.6",
     "vue3-lottie": "^2.7.0"
   },

+ 31 - 2
src/App.tsx

@@ -1,10 +1,39 @@
-import { defineComponent } from 'vue';
+import { computed, defineComponent } from 'vue';
+import { NConfigProvider, zhCN, dateZhCN } from 'naive-ui';
+import { AppProvider } from './components/Application';
+import { RouterView } from 'vue-router';
+import setting from './settings/designSetting';
+import { lighten } from './utils';
 export default defineComponent({
   name: 'App',
   setup() {
+    const getThemeOverrides = computed(() => {
+      const appTheme = setting.appTheme;
+      const lightenStr = lighten(setting.appTheme, 6);
+      return {
+        common: {
+          primaryColor: appTheme,
+          primaryColorHover: lightenStr,
+          primaryColorPressed: lightenStr
+        },
+        LoadingBar: {
+          colorLoading: appTheme
+        }
+      };
+    });
     return () => (
       <>
-        <router-view></router-view>
+        <NConfigProvider
+          locale={zhCN}
+          themeOverrides={getThemeOverrides.value}
+          // :theme="getDarkTheme"
+          // :theme-overrides="getThemeOverrides"
+          dateLocale={dateZhCN}>
+          <AppProvider>
+            <RouterView />
+            {/* <RouterError /> */}
+          </AppProvider>
+        </NConfigProvider>
       </>
     );
   }

BIN
src/common/text-security-disc.woff


+ 21 - 0
src/components/Application/Application.tsx

@@ -0,0 +1,21 @@
+import { defineComponent } from 'vue';
+import {
+  NDialogProvider,
+  NNotificationProvider,
+  NMessageProvider
+} from 'naive-ui';
+
+export default defineComponent({
+  name: 'application-page',
+  setup(props, { slots }) {
+    return () => (
+      <NDialogProvider>
+        <NNotificationProvider>
+          <NMessageProvider max={1}>
+            {slots.default && slots.default()}
+          </NMessageProvider>
+        </NNotificationProvider>
+      </NDialogProvider>
+    );
+  }
+});

+ 3 - 0
src/components/Application/index.ts

@@ -0,0 +1,3 @@
+import AppProvider from './Application';
+
+export { AppProvider };

+ 5 - 2
src/main.ts

@@ -2,7 +2,8 @@ import { createApp } from 'vue';
 import App from './App.tsx';
 import router from './router/index';
 import dayjs from 'dayjs';
-// import { setupStore } from './store';
+import { setupNaive } from './plugins';
+import { setupStore } from './store';
 import 'dayjs/locale/zh-cn';
 import './styles/index.less';
 
@@ -14,8 +15,10 @@ async function setupApp() {
 
   const app = createApp(App);
 
+  setupNaive(app);
+
   // store plugin: pinia
-  // setupStore(app);
+  setupStore(app);
 
   dayjs.locale('zh-ch');
 

+ 1 - 0
src/plugins/index.ts

@@ -0,0 +1 @@
+export { setupNaive } from '@/plugins/naive';

+ 138 - 0
src/plugins/naive.ts

@@ -0,0 +1,138 @@
+import type { App } from 'vue';
+import * as NaiveUI from 'naive-ui';
+import { computed } from 'vue';
+
+// import { MessageProviderProps } from 'naive-ui';
+import { lighten } from '@/utils';
+import setting from '@/settings/designSetting';
+
+// NaiveUI 全局方法注册
+const configProviderPropsRef = computed(() => ({
+  theme: undefined,
+  themeOverrides: {
+    common: {
+      primaryColor: setting.appTheme,
+      primaryColorHover: lighten(setting.appTheme, 6),
+      primaryColorPressed: lighten(setting.appTheme, 6)
+    },
+    LoadingBar: {
+      colorLoading: setting.appTheme
+    }
+  }
+}));
+
+// const messageProviderPropsRef = computed(
+//   () =>
+//     ({
+//       closable: false,
+//       containerStyle: 'undefined',
+//       duration: 3,
+//       keepAliveOnHover: false,
+//       max: 1,
+//       placement: 'top',
+//       to: 'body'
+//     } as MessageProviderProps)
+// );
+
+// const { message, dialog, notification, loadingBar } = NaiveUI.createDiscreteApi(
+//   ['message', 'dialog', 'notification', 'loadingBar'],
+//   {
+//     configProviderProps: configProviderPropsRef
+//   }
+// )
+
+// const w = window as any
+// window['$message'] = message
+// window['$dialog'] = dialog
+// window['$notification'] = notification
+// window['$loading'] = loadingBar
+
+const naive = NaiveUI.create({
+  components: [
+    NaiveUI.NMessageProvider,
+    NaiveUI.NDialogProvider,
+    NaiveUI.NConfigProvider,
+    NaiveUI.NInput,
+    NaiveUI.NButton,
+    NaiveUI.NForm,
+    NaiveUI.NFormItem,
+    NaiveUI.NCheckboxGroup,
+    NaiveUI.NCheckbox,
+    NaiveUI.NIcon,
+    NaiveUI.NLayout,
+    NaiveUI.NLayoutHeader,
+    NaiveUI.NLayoutContent,
+    NaiveUI.NLayoutFooter,
+    NaiveUI.NLayoutSider,
+    NaiveUI.NMenu,
+    NaiveUI.NBreadcrumb,
+    NaiveUI.NBreadcrumbItem,
+    NaiveUI.NDropdown,
+    NaiveUI.NSpace,
+    NaiveUI.NTooltip,
+    NaiveUI.NAvatar,
+    NaiveUI.NTabs,
+    NaiveUI.NTabPane,
+    NaiveUI.NCard,
+    NaiveUI.NRow,
+    NaiveUI.NCol,
+    NaiveUI.NDrawer,
+    NaiveUI.NDrawerContent,
+    NaiveUI.NDivider,
+    NaiveUI.NSwitch,
+    NaiveUI.NBadge,
+    NaiveUI.NAlert,
+    NaiveUI.NElement,
+    NaiveUI.NTag,
+    NaiveUI.NNotificationProvider,
+    NaiveUI.NProgress,
+    NaiveUI.NDatePicker,
+    NaiveUI.NGrid,
+    NaiveUI.NGridItem,
+    NaiveUI.NList,
+    NaiveUI.NListItem,
+    NaiveUI.NThing,
+    NaiveUI.NDataTable,
+    NaiveUI.NPopover,
+    NaiveUI.NPagination,
+    NaiveUI.NSelect,
+    NaiveUI.NRadioGroup,
+    NaiveUI.NRadio,
+    NaiveUI.NSteps,
+    NaiveUI.NStep,
+    NaiveUI.NInputGroup,
+    NaiveUI.NResult,
+    NaiveUI.NDescriptions,
+    NaiveUI.NDescriptionsItem,
+    NaiveUI.NTable,
+    NaiveUI.NInputNumber,
+    NaiveUI.NLoadingBarProvider,
+    NaiveUI.NModal,
+    NaiveUI.NUpload,
+    NaiveUI.NTree,
+    NaiveUI.NSpin,
+    NaiveUI.NTimePicker,
+    NaiveUI.NBackTop,
+    NaiveUI.NSkeleton
+  ]
+});
+
+const { message, dialog, notification, loadingBar } = NaiveUI.createDiscreteApi(
+  ['message', 'dialog', 'notification', 'loadingBar'],
+  {
+    configProviderProps: configProviderPropsRef
+    // messageProviderProps: messageProviderPropsRef
+  }
+);
+
+(window as any)['$message'] = message;
+
+// const w = window as any
+// window['$message'] = message
+// window['$dialog'] = dialog
+// window['$notification'] = notification
+// window['$loading'] = loadingBar
+
+export function setupNaive(app: App<Element>) {
+  app.use(naive);
+}

+ 25 - 24
src/router/router-guards.ts

@@ -1,9 +1,9 @@
 import { isNavigationFailure, Router } from 'vue-router';
 // import { useUserStoreWidthOut } from '@/store/modules/user';
-// import { ACCESS_TOKEN } from '@/store/mutation-types';
-// import { storage } from '@/utils/storage';
+import { storage } from '@/utils/storage';
 import { PageEnum } from '@/enums/pageEnum';
 import { useLoadingBar } from 'naive-ui';
+import { ACCESS_TOKEN } from '@/store/mutation-types';
 
 const LOGIN_PATH = PageEnum.BASE_LOGIN;
 
@@ -14,6 +14,7 @@ const Loading = useLoadingBar();
 export function createRouterGuards(router: Router) {
   // const userStore = useUserStoreWidthOut();
   router.beforeEach(async (to, from, next) => {
+    console.log('access token');
     Loading && Loading.start();
     if (from.path === LOGIN_PATH && to.name === 'errorPage') {
       next(PageEnum.BASE_HOME);
@@ -26,28 +27,28 @@ export function createRouterGuards(router: Router) {
       return;
     }
 
-    // const token = storage.get(ACCESS_TOKEN);
-
-    // if (!token) {
-    //   // You can access without permissions. You need to set the routing meta.ignoreAuth to true
-    //   if (to.meta.ignoreAuth) {
-    //     next();
-    //     return;
-    //   }
-    //   // redirect login page
-    //   const redirectData: { path: string; replace: boolean; query?: any } = {
-    //     path: LOGIN_PATH,
-    //     replace: true
-    //   };
-    //   if (to.path) {
-    //     redirectData.query = {
-    //       ...redirectData.query,
-    //       redirect: to.path
-    //     };
-    //   }
-    //   next(redirectData);
-    //   return;
-    // }
+    const token = storage.get(ACCESS_TOKEN);
+    console.log(token, 'access token');
+    if (!token) {
+      // You can access without permissions. You need to set the routing meta.ignoreAuth to true
+      if (to.meta.ignoreAuth) {
+        next();
+        return;
+      }
+      // redirect login page
+      const redirectData: { path: string; replace: boolean; query?: any } = {
+        path: LOGIN_PATH,
+        replace: true
+      };
+      if (to.path) {
+        redirectData.query = {
+          ...redirectData.query,
+          redirect: to.path
+        };
+      }
+      next(redirectData);
+      return;
+    }
 
     // await userStore.GetInfo();
 

+ 2 - 1
src/router/routes/index.ts

@@ -33,7 +33,8 @@ export const constantRoutes: any[] = [
   // 匹配无效路径的路由
   {
     name: 'not-found',
-    path: '/:pathMatch(.*)*',
+    path: '/:path(.*)*',
+    component: () => import('@/views/404/index'),
     meta: {
       title: '未找到',
       singleLayout: 'blank'

+ 32 - 0
src/settings/designSetting.ts

@@ -0,0 +1,32 @@
+// app theme preset color
+export const appThemeList: string[] = [
+  '#2d8cf0',
+  '#0960bd',
+  '#0084f4',
+  '#009688',
+  '#536dfe',
+  '#ff5c93',
+  '#ee4f12',
+  '#0096c7',
+  '#9c27b0',
+  '#ff9800',
+  '#FF3D68',
+  '#00C1D4',
+  '#71EFA3',
+  '#171010',
+  '#78DEC7',
+  '#1768AC',
+  '#FB9300',
+  '#FC5404'
+];
+
+const setting = {
+  //深色主题
+  darkTheme: false,
+  //系统主题色
+  appTheme: '#198CFE',
+  //系统内置主题色列表
+  appThemeList
+};
+
+export default setting;

+ 1 - 2
src/store/modules/users.ts

@@ -1,5 +1,4 @@
 import { defineStore } from 'pinia';
-import { store } from '@/store';
 import { ACCESS_TOKEN, CURRENT_USER, IM_TOKEN } from '@/store/mutation-types';
 import { storage } from '@/utils/storage';
 
@@ -50,7 +49,7 @@ export const useUserStore = defineStore('user-store', {
       this.info = info;
     },
     // 登录
-    async login(userInfo: any) {
+    async login() {
       try {
         // const response = (await login(userInfo)) as any;
         // const { data, code } = response;

+ 6 - 0
src/styles/index.less

@@ -14,4 +14,10 @@
 
 body {
   user-select: none;
+}
+
+@font-face {
+  font-family: 'dotfont';
+  /* Project id  */
+  src: url('../common/text-security-disc.woff') format('woff');
 }

+ 267 - 0
src/utils/index.ts

@@ -0,0 +1,267 @@
+import { h, unref } from 'vue';
+import type { App, Plugin } from 'vue';
+import { NIcon, NTag } from 'naive-ui';
+import { PageEnum } from '@/enums/pageEnum';
+import { isObject } from './is/index';
+import { cloneDeep } from 'lodash-es';
+/**
+ * render 图标
+ * */
+export function renderIcon(icon: any) {
+  return () => h(NIcon, null, { default: () => h(icon) });
+}
+/**
+ * font 图标(Font class)
+ * */
+export function renderFontClassIcon(icon: string, iconName = 'iconfont') {
+  return () => h('span', { class: [iconName, icon] });
+}
+/**
+ * font 图标(Unicode)
+ * */
+export function renderUnicodeIcon(icon: string, iconName = 'iconfont') {
+  return () => h('span', { class: [iconName], innerHTML: icon });
+}
+/**
+ * font svg 图标
+ * */
+export function renderfontsvg(icon: any) {
+  return () =>
+    h(NIcon, null, {
+      default: () =>
+        h(
+          'svg',
+          { class: `icon`, 'aria-hidden': 'true' },
+          h('use', { 'xlink:href': `#${icon}` })
+        )
+    });
+}
+
+/**
+ * render new Tag
+ * */
+const newTagColors = { color: '#f90', textColor: '#fff', borderColor: '#f90' };
+export function renderNew(
+  type = 'warning',
+  text = 'New',
+  color: object = newTagColors
+) {
+  return () =>
+    h(
+      NTag as any,
+      {
+        type,
+        round: true,
+        size: 'small',
+        color
+      },
+      { default: () => text }
+    );
+}
+
+/**
+ * 递归组装菜单格式
+ */
+export function generatorMenu(routerMap: Array<any>) {
+  return filterRouter(routerMap).map(item => {
+    const isRoot = isRootRouter(item);
+    if (isRoot) {
+      console.log(item.children[0], 'isRoot');
+    }
+    const info = isRoot ? item.children[0] : item;
+    // console.log(item)
+    const currentMenu = {
+      ...info,
+      ...info.meta,
+      label: info.meta?.title,
+      key: info.key,
+      icon: info.meta?.icon
+    };
+    // 是否有子菜单,并递归处理
+    if (info.children && info.children.length > 0) {
+      // Recursion
+      currentMenu.children = generatorMenu(info.children);
+    }
+    return currentMenu;
+  });
+}
+
+/**
+ * 混合菜单
+ * */
+export function generatorMenuMix(
+  routerMap: Array<any>,
+  routerName: string,
+  location: string
+) {
+  const cloneRouterMap = cloneDeep(routerMap);
+  const newRouter = filterRouter(cloneRouterMap);
+  if (location === 'header') {
+    const firstRouter: any[] = [];
+    newRouter.forEach(item => {
+      const isRoot = isRootRouter(item);
+      const info = isRoot ? item.children[0] : item;
+      info.children = undefined;
+      const currentMenu = {
+        ...info,
+        ...info.meta,
+        label: info.meta?.title,
+        key: info.name
+      };
+      firstRouter.push(currentMenu);
+    });
+    return firstRouter;
+  } else {
+    // 混合菜单
+    console.log('混合菜单');
+    return getChildrenRouter(
+      newRouter.filter(item => item.name === routerName)
+    );
+  }
+}
+
+/**
+ * 递归组装子菜单
+ * */
+export function getChildrenRouter(routerMap: Array<any>) {
+  return filterRouter(routerMap).map(item => {
+    const isRoot = isRootRouter(item);
+    const info = isRoot ? item.children[0] : item;
+    const currentMenu = {
+      ...info,
+      ...info.meta,
+      label: info.meta?.title,
+      key: info.name
+    };
+    // 是否有子菜单,并递归处理
+    if (info.children && info.children.length > 0) {
+      // Recursion
+      currentMenu.children = getChildrenRouter(info.children);
+    }
+    return currentMenu;
+  });
+}
+
+/**
+ * 判断根路由 Router
+ * */
+export function isRootRouter(item: any) {
+  return item.meta?.isRoot === true;
+}
+
+/**
+ * 排除Router
+ * */
+export function filterRouter(routerMap: Array<any>) {
+  return routerMap.filter(item => {
+    // console.log(
+    //   (item.meta?.hidden || false) != true &&
+    //   !['/:path(.*)*', PageEnum.REDIRECT, PageEnum.BASE_LOGIN].includes(item.path),
+    //   '过滤完之后的路由'
+    // )
+    return (
+      (item.meta?.hidden || false) != true &&
+      !['/:path(.*)*', PageEnum.REDIRECT, PageEnum.BASE_LOGIN].includes(
+        item.path
+      )
+    );
+  });
+}
+
+export const withInstall = <T>(component: T, alias?: string) => {
+  const comp = component as any;
+  comp.install = (app: App) => {
+    app.component(comp.name || comp.displayName, component as any);
+    if (alias) {
+      app.config.globalProperties[alias] = component;
+    }
+  };
+  return component as T & Plugin;
+};
+
+/**
+ *  找到对应的节点
+ * */
+let result = null as any;
+export function getTreeItem(data: any[], key?: string | number): any {
+  data.map(item => {
+    if (item.key === key) {
+      result = item;
+    } else {
+      if (item.children && item.children.length) {
+        getTreeItem(item.children, key);
+      }
+    }
+  });
+  return result;
+}
+
+/**
+ *  找到所有节点
+ * */
+const treeAll: any[] = [];
+export function getTreeAll(data: any[]): any[] {
+  data.map(item => {
+    treeAll.push(item.key);
+    if (item.children && item.children.length) {
+      getTreeAll(item.children);
+    }
+  });
+  return treeAll;
+}
+
+export function deepMerge<T = any>(src: any = {}, target: any = {}): T {
+  let key: string;
+  for (key in target) {
+    src[key] = isObject(src[key])
+      ? deepMerge(src[key], target[key])
+      : (src[key] = target[key]);
+  }
+  return src;
+}
+
+/**
+ * Sums the passed percentage to the R, G or B of a HEX color
+ * @param {string} color The color to change
+ * @param {number} amount The amount to change the color by
+ * @returns {string} The processed part of the color
+ */
+function addLight(color: string, amount: number) {
+  const cc = parseInt(color, 16) + amount;
+  const c = cc > 255 ? 255 : cc;
+  return c.toString(16).length > 1 ? c.toString(16) : `0${c.toString(16)}`;
+}
+
+/**
+ * Lightens a 6 char HEX color according to the passed percentage
+ * @param {string} color The color to change
+ * @param {number} amount The amount to change the color by
+ * @returns {string} The processed color represented as HEX
+ */
+export function lighten(color: string, amount: number) {
+  color = color.indexOf('#') >= 0 ? color.substring(1, color.length) : color;
+  amount = Math.trunc((255 * amount) / 100);
+  return `#${addLight(color.substring(0, 2), amount)}${addLight(
+    color.substring(2, 4),
+    amount
+  )}${addLight(color.substring(4, 6), amount)}`;
+}
+
+/**
+ * 判断是否 url
+ * */
+export function isUrl(url: string) {
+  return /^(http|https):\/\//g.test(url);
+}
+
+/** 递归清除空数据 */
+export function clearEmtryData(list: any[], key: string) {
+  for (let i = 0; i < list.length; i++) {
+    if (Array.isArray(list[i][key]) && !list[i][key].length) {
+      list[i][key] = '';
+    } else {
+      list[i][key] = clearEmtryData(list[i][key], key);
+    }
+  }
+  return list;
+}

+ 125 - 0
src/utils/is/index.ts

@@ -0,0 +1,125 @@
+const toString = Object.prototype.toString;
+
+/**
+ * @description: 判断值是否未某个类型
+ */
+export function is(val: unknown, type: string) {
+  return toString.call(val) === `[object ${type}]`;
+}
+
+/**
+ * @description:  是否为函数
+ */
+export function isFunction(val: unknown) {
+  return is(val, 'Function') || is(val, 'AsyncFunction');
+}
+
+/**
+ * @description: 是否已定义
+ */
+export const isDef = <T = unknown>(val?: T): val is T => {
+  return typeof val !== 'undefined';
+};
+
+export const isUnDef = <T = unknown>(val?: T): val is T => {
+  return !isDef(val);
+};
+/**
+ * @description: 是否为对象
+ */
+export const isObject = (val: any): val is Record<any, any> => {
+  return val !== null && is(val, 'Object');
+};
+
+/**
+ * @description:  是否为时间
+ */
+export function isDate(val: unknown): val is Date {
+  return is(val, 'Date');
+}
+
+/**
+ * @description:  是否为数值
+ */
+export function isNumber(val: unknown): val is number {
+  return is(val, 'Number');
+}
+
+/**
+ * @description:  是否为AsyncFunction
+ */
+export function isAsyncFunction<T = any>(
+  val: unknown
+): val is () => Promise<T> {
+  return is(val, 'AsyncFunction');
+}
+
+/**
+ * @description:  是否为promise
+ */
+export function isPromise<T = any>(val: unknown): val is Promise<T> {
+  return (
+    is(val, 'Promise') &&
+    isObject(val) &&
+    isFunction(val.then) &&
+    isFunction(val.catch)
+  );
+}
+
+/**
+ * @description:  是否为字符串
+ */
+export function isString(val: unknown): val is string {
+  return is(val, 'String');
+}
+
+/**
+ * @description:  是否为boolean类型
+ */
+export function isBoolean(val: unknown): val is boolean {
+  return is(val, 'Boolean');
+}
+
+/**
+ * @description:  是否为数组
+ */
+export function isArray(val: any): val is Array<any> {
+  return val && Array.isArray(val);
+}
+
+/**
+ * @description: 是否客户端
+ */
+export const isClient = () => {
+  return typeof window !== 'undefined';
+};
+
+/**
+ * @description: 是否为浏览器
+ */
+export const isWindow = (val: any): val is Window => {
+  return typeof window !== 'undefined' && is(val, 'Window');
+};
+
+export const isElement = (val: unknown): val is Element => {
+  return isObject(val) && !!val.tagName;
+};
+
+export const isServer = typeof window === 'undefined';
+
+// 是否为图片节点
+export function isImageDom(o: Element) {
+  return o && ['IMAGE', 'IMG'].includes(o.tagName);
+}
+
+export function isNull(val: unknown): val is null {
+  return val === null;
+}
+
+export function isNullAndUnDef(val: unknown): val is null | undefined {
+  return isUnDef(val) && isNull(val);
+}
+
+export function isNullOrUnDef(val: unknown): val is null | undefined {
+  return isUnDef(val) || isNull(val);
+}

+ 16 - 1
src/views/404/index.tsx

@@ -1,8 +1,23 @@
 import { defineComponent } from 'vue';
+import { NEmpty, NButton } from 'naive-ui';
 
 export default defineComponent({
   name: '404-page',
   setup() {
-    return () => <>404</>;
+    return () => (
+      <div
+        style={{
+          height: '220px',
+          'margin-top': '150px',
+          'padding-top': '30px',
+          'font-size': '15px',
+          'text-align': 'center'
+        }}>
+        <NEmpty description="你访问的页面不见了,你还可以" size="large" />
+        <NButton type="primary" text>
+          返回上一页
+        </NButton>
+      </div>
+    );
   }
 });

BIN
src/views/login/images/closeEye.png


BIN
src/views/login/images/lock-icon.png


BIN
src/views/login/images/login_bg.png


BIN
src/views/login/images/login_styles.png


BIN
src/views/login/images/openEye.png


BIN
src/views/login/images/user-icon.png


+ 114 - 0
src/views/login/index.module.less

@@ -0,0 +1,114 @@
+.no-pwd {
+  font-family: "dotfont";
+
+  ::v-deep .n-input__input-el {
+    -webkit-text-security: disc !important;
+    -moz-text-security: disc !important;
+  }
+}
+
+.view-account {
+  background: url("./images/login_bg.png") no-repeat 100% 100%;
+  background-size: 100%;
+  display: flex;
+  flex-direction: column;
+  min-height: 100vh;
+  width: 100vw;
+  background-color: #e9f7ff;
+  overflow: auto;
+
+  &-container {
+    margin-top: 10%;
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+    align-items: center;
+
+    .stylesWrap {
+      width: 40%;
+      margin-right: 190px;
+
+      img {
+        width: 100%;
+        // height: 100%;
+      }
+    }
+  }
+
+  &-form {
+    width: 30%;
+
+    .view-account-form-wrap {
+      position: relative;
+      padding: 12% 15% 12%;
+      background: #ffffff;
+      border-radius: 16px;
+
+      .prefixIcon {
+        width: 18px;
+        height: 18px;
+        margin-right: 5px;
+      }
+
+      .pwdIcon {
+        width: 24px;
+        height: 24px;
+        cursor: pointer;
+      }
+
+      .formTitle {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        font-size: 32px;
+
+        font-weight: 600;
+        color: #333333;
+        line-height: 45px;
+        margin-bottom: 50px;
+
+        .dot {
+          width: 6px;
+          height: 21px;
+          background: #3594fa;
+          border-radius: 3px;
+          margin-right: 8px;
+        }
+      }
+    }
+  }
+
+  .submitBtm {
+    margin-top: 20px;
+    background: #3594fa;
+    border-radius: 35px;
+    font-size: 22px;
+    font-family: PingFangSC-Semibold, PingFang SC;
+    font-weight: 600;
+    color: #ffffff;
+    height: 50px;
+    line-height: 50px;
+  }
+
+  &-top {
+    padding: 32px 0;
+    text-align: center;
+
+    &-desc {
+      font-size: 14px;
+      color: #808695;
+    }
+  }
+
+  &-other {
+    width: 100%;
+  }
+
+  .default-color {
+    color: #515a6e;
+
+    .ant-checkbox-wrapper {
+      color: #515a6e;
+    }
+  }
+}

+ 180 - 5
src/views/login/index.tsx

@@ -1,13 +1,188 @@
-import { defineComponent } from 'vue';
-import { NButton } from 'naive-ui';
+import { defineComponent, reactive, ref } from 'vue';
+import loginStyles from './images/login_styles.png';
+import lockIcon from './images/lock-icon.png';
+import useIcon from './images/user-icon.png';
+import openEye from './images/openEye.png';
+import closeEye from './images/closeEye.png';
+import { PageEnum } from '@/enums/pageEnum';
+import {
+  useMessage,
+  NForm,
+  NFormItem,
+  NInput,
+  NButton,
+  NCheckbox
+} from 'naive-ui';
+import { useUserStore } from '@/store/modules/users';
+import styles from './index.module.less';
+import { ResultEnum } from '@/enums/httpEnum';
+import { useRoute, useRouter } from 'vue-router';
+import { storage } from '@/utils/storage';
+
+interface FormState {
+  username: string;
+  password: string;
+  grant_type: string;
+  loginType: string;
+  client_id: string;
+  client_secret: string;
+}
 
 export default defineComponent({
   name: 'login-page',
   setup() {
+    const router = useRouter();
+    const route = useRoute();
+    const formRef = ref();
+    const message = useMessage();
+    console.log(message);
+    const loading = ref(false);
+    const autoLogin = ref(true);
+    const LOGIN_NAME = PageEnum.BASE_LOGIN_NAME;
+    const showPwd = ref(false);
+    const formInline = reactive({
+      username: '',
+      password: '',
+      isCaptcha: true
+    });
+    const userStore = useUserStore();
+
+    const handleSubmit = async () => {
+      formRef.value.validate(async (errors: any) => {
+        if (!errors) {
+          const { username, password } = formInline;
+          message.loading('登录中...');
+          loading.value = true;
+
+          const params: FormState = {
+            username,
+            password,
+            loginType: 'password',
+            grant_type: 'password',
+            client_id: 'jmedu-backend',
+            client_secret: 'jmedu-backend'
+          };
+
+          try {
+            const some = await userStore.login();
+            // return;
+            message.destroyAll();
+            // if (some.code == ResultEnum.SUCCESS) {
+            //  判断是否勾选自动登录
+            if (autoLogin.value) {
+              storage.set('userInfo', JSON.stringify(formInline));
+            } else {
+              storage.remove('userInfo');
+            }
+
+            // route.query?.redirect ||
+            const toPath = decodeURIComponent('/' as string);
+
+            message.success('登录成功,即将进入系统');
+            if (route.name === LOGIN_NAME) {
+              router.replace('/');
+            } else router.replace(toPath);
+            // } else {
+            //   // message.info(some.msg || "登录失败");
+            // }
+          } finally {
+            loading.value = false;
+          }
+        }
+      });
+    };
     return () => (
-      <>
-        <NButton>测试</NButton>
-      </>
+      <div class={styles['view-account']}>
+        <div class={styles['view-account-container']}>
+          <div class={styles['stylesWrap']}>
+            <img src={loginStyles} alt="" />
+          </div>
+          <div class={styles['view-account-form']}>
+            <div class={styles['view-account-form-wrap']}>
+              <div class={styles.formTitle}>
+                <div class={styles.dot}></div>
+                酷乐秀课堂乐器
+              </div>
+              <NForm
+                ref={formRef}
+                label-placement="left"
+                size="large"
+                model={formInline}>
+                <NFormItem
+                  path="username"
+                  rule={[
+                    { required: true, message: '请输入用户名', trigger: 'blur' }
+                  ]}>
+                  <NInput
+                    v-model:value={formInline.username}
+                    placeholder="请输入用户名">
+                    {{
+                      prefix: () => (
+                        <img src={useIcon} class={styles.prefixIcon} alt="" />
+                      )
+                    }}
+                  </NInput>
+                </NFormItem>
+                <NFormItem
+                  path="password"
+                  rule={[
+                    { required: true, message: '请输入密码', trigger: 'blur' }
+                  ]}>
+                  <NInput
+                    v-model:value={formInline.password}
+                    type="text"
+                    showPasswordOn="click"
+                    placeholder="请输入密码"
+                    inputProps={{ autocomplete: 'off' }}
+                    class={[showPwd.value ? '' : styles['no-pwd']]}
+                    onKeydown={(e: KeyboardEvent) => {
+                      console.log(e, 'onKeydown');
+                      if (e.keyCode === 13) {
+                        handleSubmit();
+                      }
+                    }}>
+                    {{
+                      prefix: () => (
+                        <img src={lockIcon} class={styles.prefixIcon} alt="" />
+                      ),
+                      suffix: () => (
+                        <img
+                          src={showPwd.value ? closeEye : openEye}
+                          class={styles.pwdIcon}
+                          alt=""
+                          onClick={() => {
+                            showPwd.value = !showPwd.value;
+                          }}
+                        />
+                      )
+                    }}
+                  </NInput>
+                </NFormItem>
+                <NFormItem class={styles['default-color']}>
+                  <div class={[styles['flex'], styles['justify-between']]}>
+                    <div class={styles['flex-initial']}>
+                      <NCheckbox v-model:checked={autoLogin.value}>
+                        记住密码
+                      </NCheckbox>
+                    </div>
+                  </div>
+                </NFormItem>
+                <NFormItem>
+                  <NButton
+                    class={styles.submitBtm}
+                    type="primary"
+                    onClick={handleSubmit}
+                    size="large"
+                    loading={loading.value}
+                    block>
+                    登录
+                  </NButton>
+                </NFormItem>
+              </NForm>
+            </div>
+          </div>
+        </div>
+      </div>
     );
   }
 });

+ 3 - 2
vite.config.ts

@@ -2,7 +2,7 @@ import { defineConfig } from 'vite';
 import vue from '@vitejs/plugin-vue';
 import vueJsx from '@vitejs/plugin-vue-jsx';
 import Components from 'unplugin-vue-components/vite';
-import { VantResolver } from 'unplugin-vue-components/resolvers';
+import { NaiveUiResolver } from 'unplugin-vue-components/resolvers';
 import viteESLint from 'vite-plugin-eslint';
 // eslint-disable-next-line @typescript-eslint/no-var-requires
 const path = require('path');
@@ -18,7 +18,8 @@ export default defineConfig({
     vueJsx(),
     viteESLint(),
     Components({
-      resolvers: [VantResolver()]
+      dts: true,
+      resolvers: [NaiveUiResolver()]
     })
   ],
   resolve: {