From 55725f3f0f6cc228d4796442231084f03aad4213 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 1 Dec 2024 00:17:27 +0800 Subject: [PATCH] first commit --- .env.development | 1 + .gitignore | 58 ++ index.html | 13 + package-lock.json | 1082 ++++++++++++++++++++++++++++++++++ package.json | 22 + src/App.vue | 14 + src/api/request.js | 75 +++ src/api/task.js | 95 +++ src/api/user.js | 107 ++++ src/assets/logo.png | Bin 0 -> 26338 bytes src/config/api.config.js | 8 + src/layout/Layout.vue | 196 ++++++ src/main.js | 17 + src/router/index.js | 119 ++++ src/views/ConfigView.vue | 247 ++++++++ src/views/Dashboard.vue | 305 ++++++++++ src/views/LoginView.vue | 208 +++++++ src/views/RegisterView.vue | 201 +++++++ src/views/TaskManagement.vue | 780 ++++++++++++++++++++++++ src/views/UserEvents.vue | 249 ++++++++ src/views/UserManagement.vue | 523 ++++++++++++++++ src/views/UserProfile.vue | 335 +++++++++++ src/views/VerifyAdmin.vue | 192 ++++++ vite.config.js | 16 + 24 files changed, 4863 insertions(+) create mode 100644 .env.development create mode 100644 .gitignore create mode 100644 index.html create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/App.vue create mode 100644 src/api/request.js create mode 100644 src/api/task.js create mode 100644 src/api/user.js create mode 100644 src/assets/logo.png create mode 100644 src/config/api.config.js create mode 100644 src/layout/Layout.vue create mode 100644 src/main.js create mode 100644 src/router/index.js create mode 100644 src/views/ConfigView.vue create mode 100644 src/views/Dashboard.vue create mode 100644 src/views/LoginView.vue create mode 100644 src/views/RegisterView.vue create mode 100644 src/views/TaskManagement.vue create mode 100644 src/views/UserEvents.vue create mode 100644 src/views/UserManagement.vue create mode 100644 src/views/UserProfile.vue create mode 100644 src/views/VerifyAdmin.vue create mode 100644 vite.config.js diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..48ed9af --- /dev/null +++ b/.env.development @@ -0,0 +1 @@ +VITE_API_BASE_URL=http://localhost:5098 \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5067151 --- /dev/null +++ b/.gitignore @@ -0,0 +1,58 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +# Dependencies +node_modules +.yarn +.pnp +.pnp.js + +# Build output +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +!.vscode/settings.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# Environment files +.env +.env.local +.env.*.local + +# Cache files +.DS_Store +Thumbs.db + +# Testing +coverage +/cypress/videos/ +/cypress/screenshots/ + +# Temporary files +*.tmp +*.bak +*.swp + +# System Files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..a6507ff --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + 后台管理系统 + + +
+ + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..fc91745 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1082 @@ +{ + "name": "admin-system", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "admin-system", + "version": "0.0.0", + "dependencies": { + "@element-plus/icons-vue": "^2.1.0", + "axios": "^1.7.8", + "element-plus": "^2.9.0", + "vue": "^3.3.4", + "vue-router": "^4.2.4" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^4.2.3", + "vite": "^4.4.6" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "dependencies": { + "@babel/types": "^7.26.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.0", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@element-plus/icons-vue": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz", + "integrity": "sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==", + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.8", + "resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.6.8.tgz", + "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", + "dependencies": { + "@floating-ui/utils": "^0.2.8" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.12", + "resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.6.12.tgz", + "integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.8" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.8", + "resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.8.tgz", + "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==" + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "node_modules/@popperjs/core": { + "name": "@sxzz/popperjs-es", + "version": "2.11.7", + "resolved": "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz", + "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@types/lodash": { + "version": "4.17.13", + "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.13.tgz", + "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.16", + "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", + "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "4.6.2", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz", + "integrity": "sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==", + "dev": true, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.0.0 || ^5.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.13.tgz", + "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/shared": "3.5.13", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz", + "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", + "dependencies": { + "@vue/compiler-core": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz", + "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/compiler-core": "3.5.13", + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.11", + "postcss": "^8.4.48", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz", + "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==", + "dependencies": { + "@vue/compiler-dom": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==" + }, + "node_modules/@vue/reactivity": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.13.tgz", + "integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==", + "dependencies": { + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.13.tgz", + "integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==", + "dependencies": { + "@vue/reactivity": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz", + "integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==", + "dependencies": { + "@vue/reactivity": "3.5.13", + "@vue/runtime-core": "3.5.13", + "@vue/shared": "3.5.13", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.13.tgz", + "integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==", + "dependencies": { + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13" + }, + "peerDependencies": { + "vue": "3.5.13" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.13.tgz", + "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==" + }, + "node_modules/@vueuse/core": { + "version": "9.13.0", + "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-9.13.0.tgz", + "integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==", + "dependencies": { + "@types/web-bluetooth": "^0.0.16", + "@vueuse/metadata": "9.13.0", + "@vueuse/shared": "9.13.0", + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/metadata": { + "version": "9.13.0", + "resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.13.0.tgz", + "integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "9.13.0", + "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.13.0.tgz", + "integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==", + "dependencies": { + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/async-validator": { + "version": "4.2.5", + "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz", + "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.7.8", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.8.tgz", + "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/element-plus": { + "version": "2.9.0", + "resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.0.tgz", + "integrity": "sha512-ccOFXKsauo2dtokAr4OX7gZsb7TuAoVxA2zGRZo5o2yyDDBLBaZxOoFQPoxITSLcHbBfQuNDGK5Iag5hnyKkZA==", + "dependencies": { + "@ctrl/tinycolor": "^3.4.1", + "@element-plus/icons-vue": "^2.3.1", + "@floating-ui/dom": "^1.0.1", + "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7", + "@types/lodash": "^4.14.182", + "@types/lodash-es": "^4.17.6", + "@vueuse/core": "^9.1.0", + "async-validator": "^4.2.5", + "dayjs": "^1.11.13", + "escape-html": "^1.0.3", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "lodash-unified": "^1.0.2", + "memoize-one": "^6.0.0", + "normalize-wheel-es": "^1.2.0" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "node_modules/lodash-unified": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/lodash-unified/-/lodash-unified-1.0.3.tgz", + "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==", + "peerDependencies": { + "@types/lodash-es": "*", + "lodash": "*", + "lodash-es": "*" + } + }, + "node_modules/magic-string": { + "version": "0.30.14", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.14.tgz", + "integrity": "sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/normalize-wheel-es": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz", + "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/rollup": { + "version": "3.29.5", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-3.29.5.tgz", + "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vite": { + "version": "4.5.5", + "resolved": "https://registry.npmmirror.com/vite/-/vite-4.5.5.tgz", + "integrity": "sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ==", + "dev": true, + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vue": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.13.tgz", + "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==", + "dependencies": { + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-sfc": "3.5.13", + "@vue/runtime-dom": "3.5.13", + "@vue/server-renderer": "3.5.13", + "@vue/shared": "3.5.13" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-router": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.0.tgz", + "integrity": "sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..be76806 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "admin-system", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "@element-plus/icons-vue": "^2.1.0", + "axios": "^1.7.8", + "element-plus": "^2.9.0", + "vue": "^3.3.4", + "vue-router": "^4.2.4" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^4.2.3", + "vite": "^4.4.6" + } +} diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..3038288 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/src/api/request.js b/src/api/request.js new file mode 100644 index 0000000..1b8eff6 --- /dev/null +++ b/src/api/request.js @@ -0,0 +1,75 @@ +import axios from 'axios' +import { ElMessage, ElMessageBox } from 'element-plus' +import router from '../router' +import { API_BASE_URL } from '../config/api.config' + +const request = axios.create({ + baseURL: API_BASE_URL, + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 请求拦截器 +request.interceptors.request.use( + config => { + // 如果不是登录请求,就添加token + if (!config.url.includes('/user/login') && !config.url.includes('/user/register')) { + const token = JSON.parse(localStorage.getItem('token')).token + if (token) { + config.headers.Authorization = `Bearer ${token}` + } + console.log('Request Headers:', config.headers.Authorization) + } + return config + }, + error => { + return Promise.reject(error) + } +) + +// 响应拦截器 +request.interceptors.response.use( + response => { + const { data } = response + console.log('Response Data:', data) + + if (data.retcode === 0) { + return data + } + // 显示错误消息对话框 + ElMessageBox.alert(data.message || '操作失败', '错误', { + type: 'error', + confirmButtonText: '确定' + }) + return Promise.reject(new Error(data.message || '操作失败')) + }, + error => { + console.error('Request Error:', error) + + if (error.response) { + switch (error.response.status) { + case 401: + localStorage.removeItem('token') + localStorage.removeItem('userRole') + router.push('/login') + break + case 403: + ElMessage.error('没有权限访问') + break + default: + ElMessage.error(error.response.data?.message || '请求失败') + } + } else if (error.request) { + // 请求已发出但没有收到响应 + ElMessage.error('服务器无响应,请检查后端服务是否启动') + } else { + // 请求配置出错 + ElMessage.error('请求配置错误') + } + return Promise.reject(error) + } +) + +export default request \ No newline at end of file diff --git a/src/api/task.js b/src/api/task.js new file mode 100644 index 0000000..f5385cf --- /dev/null +++ b/src/api/task.js @@ -0,0 +1,95 @@ +import request from './request' +import { API_ENDPOINTS } from '../config/api.config' + +export const TaskAPI = { + /** + * 获取任务列表 + * @param {Object} params 查询参数 + * @param {number} params.page 页码 + * @param {number} params.pageSize 每页数量 + * @param {number} params.status 任务状态 + */ + getTaskList(params) { + return request.get(API_ENDPOINTS.TASK.LIST, { params }) + }, + + /** + * 获取任务进程信息 + * @param {string} taskId 任务ID + */ + getProcessInfo(taskId) { + return request.get(`/Management/GetProcessInfo/${taskId}`) + }, + + /** + * 删除任务 + * @param {string} taskId 任务ID + */ + deleteTask(taskId) { + return request.delete(`/Management/DeleteTask/${taskId}`) + }, + + /** + * 获取任务详细信息 + * @param {string} taskId 任务ID + */ + getTaskDetails(taskId) { + return request.get(`/Management/GetTaskDetail/${taskId}`) + }, + + /** + * 终止任务 + * @param {string} taskId 任务ID + */ + killTask(taskId) { + return request.post(`/Management/KillTask/${taskId}`) + }, + + /** + * 获取系统配置 + */ + getSystemConfig() { + return request.get('/Management/GetSystemConfig') + }, + + /** + * 获取任务概览数据 + */ + getTaskOverview() { + return request.get('/Management/GetTaskOverview') + }, + + /** + * 重试任务 + * @param {string} taskId 任务ID + */ + retryTask(taskId) { + return request.post(`/Management/RetryTask/${taskId}`) + }, + + /** + * 立即执行任务(调整优先级) + * @param {string} taskId 任务ID + */ + prioritizeTask(taskId) { + return request.post(`/Management/PrioritizeTask/${taskId}`) + }, + + /** + * 立即执行任务 + * @param {string} taskId 任务ID + */ + executeImmediately(taskId) { + return request.post(`/Management/ExecuteImmediately/${taskId}`) + }, + + /** + * 添加离线任务 + * @param {string} url 下载地址 + */ + addOfflineTask(url) { + return request.post('/AddOfflineTask', null, { + params: { url } + }) + } +} \ No newline at end of file diff --git a/src/api/user.js b/src/api/user.js new file mode 100644 index 0000000..f957dd6 --- /dev/null +++ b/src/api/user.js @@ -0,0 +1,107 @@ +import request from './request' + +export const UserAPI = { + /** + * 用户注册 + * @param {Object} data 注册信息 + * @param {string} data.username 用户名 + * @param {string} data.password 密码 + */ + register(data) { + return request.post('/user/register', data) + }, + + /** + * 用户登录 + * @param {Object} data 登录信息 + * @param {string} data.username 用户名 + * @param {string} data.password 密码 + */ + login(data) { + return request.post('/user/login', data) + }, + + /** + * 获取用户信息 + */ + getUserInfo() { + return request.get('/user/info') + }, + + /** + * 获取用户列表 + * @param {Object} params 查询参数 + * @param {number} params.page 页码 + * @param {number} params.pageSize 每页数量 + */ + getUserList(params) { + return request.get('/user/list', { params }) + }, + + /** + * 修改用户权限 + * @param {string} userId 用户ID + * @param {number} newMask 新的权限掩码 + */ + updateUserMask(userId, newMask) { + return request.post(`/user/updateMask/${userId}`, { + newMask + }) + }, + + /** + * 修改昵称 + * @param {string} newNickname 新昵称 + */ + updateNickname(newNickname) { + return request.post('/user/updateNickname', { + newNickname + }) + }, + + /** + * 修改密码 + * @param {string} oldPassword 旧密码 + * @param {string} newPassword 新密码 + */ + updatePassword(oldPassword, newPassword) { + return request.post('/user/updatePassword', { + oldPassword, + newPassword + }) + }, + + /** + * 重置用户密码(超级管理员) + * @param {string} userId 用户ID + * @param {string} newPassword 新密码 + */ + resetPassword(userId, newPassword) { + return request.post(`/user/resetPassword/${userId}`, { + newPassword + }) + }, + + /** + * 获取用户事件列表 + * @param {Object} params 查询参数 + * @param {number} params.page 页码 + * @param {number} params.pageSize 每页数量 + * @param {string} [params.userId] 用户ID(超级管理员可选) + * @param {string} [params.keyword] 搜索关键词 + */ + getUserEvents(params) { + return request.get('/user/events', { params }) + }, + + /** + * 修改用户昵称(超级管理员) + * @param {string} userId 用户ID + * @param {string} newNickname 新昵称 + */ + updateUserNickname(userId, newNickname) { + return request.post(`/user/updateNickname/${userId}`, { + newNickname + }) + } +} \ No newline at end of file diff --git a/src/assets/logo.png b/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8d3aa6d4ee43bd119cab5a2401733c924b332902 GIT binary patch literal 26338 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 literal 0 HcmV?d00001 diff --git a/src/config/api.config.js b/src/config/api.config.js new file mode 100644 index 0000000..f9d54b6 --- /dev/null +++ b/src/config/api.config.js @@ -0,0 +1,8 @@ +export const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:5000' + +export const API_ENDPOINTS = { + TASK: { + LIST: '/Management/GetTaskList', + PROCESS: (id) => `/Management/${id}/process`, + } +} \ No newline at end of file diff --git a/src/layout/Layout.vue b/src/layout/Layout.vue new file mode 100644 index 0000000..1b92365 --- /dev/null +++ b/src/layout/Layout.vue @@ -0,0 +1,196 @@ + + + + + \ No newline at end of file diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..4172f83 --- /dev/null +++ b/src/main.js @@ -0,0 +1,17 @@ +import { createApp } from 'vue' +import App from './App.vue' +import router from './router' +import ElementPlus from 'element-plus' +import 'element-plus/dist/index.css' +import * as ElementPlusIconsVue from '@element-plus/icons-vue' + +const app = createApp(App) + +// 注册所有图标 +for (const [key, component] of Object.entries(ElementPlusIconsVue)) { + app.component(key, component) +} + +app.use(router) +app.use(ElementPlus) +app.mount('#app') \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..f5232b8 --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,119 @@ +import { createRouter, createWebHistory } from 'vue-router' +import { ElMessage } from 'element-plus' +import Layout from '../layout/Layout.vue' +import { UserAPI } from '../api/user' + +const routes = [ + { + path: '/login', + name: 'Login', + component: () => import('../views/LoginView.vue') + }, + { + path: '/register', + name: 'Register', + component: () => import('../views/RegisterView.vue') + }, + { + path: '/', + component: Layout, + redirect: '/dashboard', + children: [ + { + path: 'dashboard', + name: 'Dashboard', + component: () => import('../views/Dashboard.vue'), + meta: { roles: ['admin', 'guest'] } + }, + { + path: 'tasks', + name: 'Tasks', + component: () => import('../views/TaskManagement.vue'), + meta: { roles: ['admin'] } + }, + { + path: 'config', + name: 'Config', + component: () => import('../views/ConfigView.vue'), + meta: { roles: ['admin'] } + }, + { + path: 'users', + name: 'Users', + component: () => import('../views/UserManagement.vue'), + meta: { roles: ['admin'] } + }, + { + path: 'profile', + name: 'Profile', + component: () => import('../views/UserProfile.vue'), + meta: { roles: ['admin', 'guest'] } + }, + { + path: 'events', + name: 'Events', + component: () => import('../views/UserEvents.vue'), + meta: { roles: ['admin', 'guest'] } + } + ] + }, + { + path: '/:pathMatch(.*)*', + redirect: '/dashboard' + } +] + +const router = createRouter({ + history: createWebHistory(), + routes +}) + +// 简化路由守卫 +router.beforeEach(async (to, from, next) => { + const token = localStorage.getItem('token') + const isAuthenticated = localStorage.getItem('isAuthenticated') + const userRole = localStorage.getItem('userRole') + + // 登录页和注册页可以直接访问 + if (to.path === '/login' || to.path === '/register') { + if (isAuthenticated) { + next('/dashboard') + } else { + next() + } + return + } + + if (!isAuthenticated) { + next('/login') + return + } + + // 如果是管理员但没有用户信息,尝试获取 + if (userRole === 'admin' && token) { + try { + const response = await UserAPI.getUserInfo() + if (response.retcode !== 0) { + // 用户信息获取失败,清除登录状态 + localStorage.clear() + next('/login') + return + } + } catch (error) { + localStorage.clear() + next('/login') + return + } + } + + // 检查权限 + if (to.meta.roles && !to.meta.roles.includes(userRole)) { + ElMessage.error('没有访问权限') + next('/dashboard') + return + } + + next() +}) + +export default router \ No newline at end of file diff --git a/src/views/ConfigView.vue b/src/views/ConfigView.vue new file mode 100644 index 0000000..8fbc619 --- /dev/null +++ b/src/views/ConfigView.vue @@ -0,0 +1,247 @@ + + + + + \ No newline at end of file diff --git a/src/views/Dashboard.vue b/src/views/Dashboard.vue new file mode 100644 index 0000000..40c03bc --- /dev/null +++ b/src/views/Dashboard.vue @@ -0,0 +1,305 @@ + + + + + \ No newline at end of file diff --git a/src/views/LoginView.vue b/src/views/LoginView.vue new file mode 100644 index 0000000..21d7695 --- /dev/null +++ b/src/views/LoginView.vue @@ -0,0 +1,208 @@ + + + + + \ No newline at end of file diff --git a/src/views/RegisterView.vue b/src/views/RegisterView.vue new file mode 100644 index 0000000..40d8850 --- /dev/null +++ b/src/views/RegisterView.vue @@ -0,0 +1,201 @@ + + + + + \ No newline at end of file diff --git a/src/views/TaskManagement.vue b/src/views/TaskManagement.vue new file mode 100644 index 0000000..bb031fe --- /dev/null +++ b/src/views/TaskManagement.vue @@ -0,0 +1,780 @@ + + + + + \ No newline at end of file diff --git a/src/views/UserEvents.vue b/src/views/UserEvents.vue new file mode 100644 index 0000000..a3c88f4 --- /dev/null +++ b/src/views/UserEvents.vue @@ -0,0 +1,249 @@ + + + + + \ No newline at end of file diff --git a/src/views/UserManagement.vue b/src/views/UserManagement.vue new file mode 100644 index 0000000..c94fee8 --- /dev/null +++ b/src/views/UserManagement.vue @@ -0,0 +1,523 @@ + + + + + \ No newline at end of file diff --git a/src/views/UserProfile.vue b/src/views/UserProfile.vue new file mode 100644 index 0000000..aa2b898 --- /dev/null +++ b/src/views/UserProfile.vue @@ -0,0 +1,335 @@ + + + + + \ No newline at end of file diff --git a/src/views/VerifyAdmin.vue b/src/views/VerifyAdmin.vue new file mode 100644 index 0000000..d7657c2 --- /dev/null +++ b/src/views/VerifyAdmin.vue @@ -0,0 +1,192 @@ + + + + + \ No newline at end of file diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..4418be9 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,16 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import path from 'path' + +export default defineConfig({ + plugins: [vue()], + server: { + port: 3000, + open: true + }, + resolve: { + alias: { + '@': path.resolve(__dirname, 'src') + } + } +}) \ No newline at end of file