diff --git a/electron.vite.config.ts b/electron.vite.config.ts index 77601dd..a9a06ec 100644 --- a/electron.vite.config.ts +++ b/electron.vite.config.ts @@ -2,7 +2,7 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2025-07-02 13:17:44 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2025-07-03 17:51:36 + * @LastEditTime: 2025-07-09 12:40:47 * @FilePath: \electron-project\Robot-Al\Robot-Al-Platform-Web\electron.vite.config.ts * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AEmpo */ @@ -12,6 +12,8 @@ import vue from '@vitejs/plugin-vue' import AutoImport from 'unplugin-auto-import/vite' import Components from 'unplugin-vue-components/vite' import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' +import { viteMockServe } from 'vite-plugin-mock' + export default defineConfig({ main: { plugins: [externalizeDepsPlugin(), bytecodePlugin()] @@ -31,6 +33,14 @@ export default defineConfig({ }, plugins: [ vue(), + viteMockServe({ + // 设置模拟.ts文件的存储位置 + mockPath: 'src/renderer/src/mock', + // 设置是否启用本地 mock 功能 + enable: true, + // 控制是否在控制台显示请求日志 + logger: true + }), AutoImport({ imports: ['vue'], eslintrc: { @@ -39,6 +49,18 @@ export default defineConfig({ resolvers: [ElementPlusResolver()] }) ], + // 开发服务器配置 + // server: { + // port: 5173, + // host: '0.0.0.0', + // proxy: { + // '/api': { + // target: 'http://localhost:5173', + // changeOrigin: true, + // rewrite: (path) => path.replace(/^\/api/, '') + // } + // } + // }, build: { // 核心:指定 Vue 打包输出目录(用于 Web 部署) outDir: 'dist', // 例如输出到项目根目录的 dist/web 文件夹 diff --git a/package-lock.json b/package-lock.json index 32c2e2d..07eb590 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,9 @@ "@electron-toolkit/utils": "^3.0.0", "axios": "^1.10.0", "element-plus": "^2.10.2", + "mockjs": "^1.1.0", "pinia": "^3.0.3", + "vite-plugin-mock": "^3.0.2", "vue-router": "^4.5.1" }, "devDependencies": { @@ -904,7 +906,6 @@ "cpu": [ "ppc64" ], - "dev": true, "optional": true, "os": [ "aix" @@ -920,7 +921,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "android" @@ -936,7 +936,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "android" @@ -952,7 +951,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "android" @@ -968,7 +966,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -984,7 +981,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -1000,7 +996,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -1016,7 +1011,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -1032,7 +1026,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1048,7 +1041,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1064,7 +1056,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1080,7 +1071,6 @@ "cpu": [ "loong64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1096,7 +1086,6 @@ "cpu": [ "mips64el" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1112,7 +1101,6 @@ "cpu": [ "ppc64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1128,7 +1116,6 @@ "cpu": [ "riscv64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1144,7 +1131,6 @@ "cpu": [ "s390x" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1160,7 +1146,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1176,7 +1161,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "netbsd" @@ -1192,7 +1176,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "openbsd" @@ -1208,7 +1191,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "sunos" @@ -1224,7 +1206,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -1240,7 +1221,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" @@ -1256,7 +1236,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -1675,7 +1654,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1688,7 +1666,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "engines": { "node": ">= 8" } @@ -1697,7 +1674,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1710,7 +1686,6 @@ "version": "2.5.1", "resolved": "https://registry.npmmirror.com/@parcel/watcher/-/watcher-2.5.1.tgz", "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", - "dev": true, "hasInstallScript": true, "optional": true, "dependencies": { @@ -1749,7 +1724,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "android" @@ -1769,7 +1743,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -1789,7 +1762,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -1809,7 +1781,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -1829,7 +1800,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1849,7 +1819,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1869,7 +1838,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1889,7 +1857,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1909,7 +1876,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1929,7 +1895,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1949,7 +1914,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -1969,7 +1933,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" @@ -1989,7 +1952,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -2006,7 +1968,6 @@ "version": "7.1.1", "resolved": "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-7.1.1.tgz", "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "dev": true, "optional": true }, "node_modules/@pkgjs/parseargs": { @@ -2048,7 +2009,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "android" @@ -2061,7 +2021,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "android" @@ -2074,7 +2033,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -2087,7 +2045,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -2100,7 +2057,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2113,7 +2069,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2126,7 +2081,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2139,7 +2093,6 @@ "cpu": [ "riscv64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2152,7 +2105,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2165,7 +2117,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2178,7 +2129,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -2191,7 +2141,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" @@ -2204,7 +2153,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -2623,8 +2571,7 @@ "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "node_modules/@types/fs-extra": { "version": "9.0.13", @@ -3335,7 +3282,6 @@ "version": "3.1.3", "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -3588,7 +3534,6 @@ "version": "2.3.0", "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, "engines": { "node": ">=8" }, @@ -3644,7 +3589,6 @@ "version": "3.0.3", "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, "dependencies": { "fill-range": "^7.1.1" }, @@ -3807,6 +3751,20 @@ "node": ">= 10.0.0" } }, + "node_modules/bundle-require": { + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/bundle-require/-/bundle-require-4.2.1.tgz", + "integrity": "sha512-7Q/6vkyYAwOmQNRw75x+4yRtZCZJXUDmHHlFdkiV0wgv/reNjtJwpu1jPJ0w2kbEpIM0uoKI3S4/f39dU7AjSA==", + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.17" + } + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -3899,7 +3857,6 @@ "version": "3.6.0", "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -3923,7 +3880,6 @@ "version": "5.1.2", "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -4036,7 +3992,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "dev": true, "engines": { "node": ">= 6" } @@ -4100,6 +4055,33 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmmirror.com/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -4277,7 +4259,6 @@ "version": "1.0.3", "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dev": true, "optional": true, "bin": { "detect-libc": "bin/detect-libc.js" @@ -4459,6 +4440,11 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, "node_modules/ejs": { "version": "3.1.9", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", @@ -4668,6 +4654,14 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -4724,7 +4718,6 @@ "version": "0.19.12", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", - "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -5094,7 +5087,6 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -5110,7 +5102,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -5134,7 +5125,6 @@ "version": "1.17.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.0.tgz", "integrity": "sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==", - "dev": true, "dependencies": { "reusify": "^1.0.4" } @@ -5184,7 +5174,6 @@ "version": "7.1.1", "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -5192,6 +5181,36 @@ "node": ">=8" } }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -5342,7 +5361,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -5778,7 +5796,7 @@ "version": "5.1.3", "resolved": "https://registry.npmmirror.com/immutable/-/immutable-5.1.3.tgz", "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", - "dev": true + "devOptional": true }, "node_modules/import-fresh": { "version": "3.3.0", @@ -5825,7 +5843,6 @@ "version": "2.1.0", "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -5864,7 +5881,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -5882,7 +5898,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -5894,7 +5909,6 @@ "version": "7.0.0", "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -6108,7 +6122,7 @@ "version": "1.30.1", "resolved": "https://registry.npmmirror.com/lightningcss/-/lightningcss-1.30.1.tgz", "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", - "dev": true, + "devOptional": true, "dependencies": { "detect-libc": "^2.0.3" }, @@ -6139,7 +6153,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -6159,7 +6172,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -6179,7 +6191,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -6199,7 +6210,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -6219,7 +6229,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -6239,7 +6248,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -6259,7 +6267,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -6279,7 +6286,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -6299,7 +6305,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -6319,7 +6324,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -6336,7 +6340,7 @@ "version": "2.0.4", "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.0.4.tgz", "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "dev": true, + "devOptional": true, "engines": { "node": ">=8" } @@ -6359,6 +6363,14 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmmirror.com/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/local-pkg": { "version": "1.1.1", "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-1.1.1.tgz", @@ -6463,7 +6475,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "engines": { "node": ">= 8" } @@ -6472,7 +6483,6 @@ "version": "4.0.8", "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -6630,6 +6640,17 @@ "pathe": "^2.0.1" } }, + "node_modules/mockjs": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/mockjs/-/mockjs-1.1.0.tgz", + "integrity": "sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==", + "dependencies": { + "commander": "*" + }, + "bin": { + "random": "bin/random" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", @@ -6692,7 +6713,6 @@ "version": "3.0.0", "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -6761,6 +6781,17 @@ "node": ">= 0.4" } }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -6842,6 +6873,14 @@ "node": ">=6" } }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", @@ -6906,6 +6945,11 @@ "node": "14 || >=16.14" } }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==" + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -6940,7 +6984,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -7287,7 +7330,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -7344,7 +7386,6 @@ "version": "3.6.0", "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -7419,7 +7460,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -7466,7 +7506,6 @@ "version": "4.9.6", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.6.tgz", "integrity": "sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==", - "dev": true, "dependencies": { "@types/estree": "1.0.5" }, @@ -7498,7 +7537,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -7536,7 +7574,7 @@ "version": "1.89.2", "resolved": "https://registry.npmmirror.com/sass/-/sass-1.89.2.tgz", "integrity": "sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==", - "dev": true, + "devOptional": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", @@ -7556,7 +7594,7 @@ "version": "4.0.3", "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, + "devOptional": true, "dependencies": { "readdirp": "^4.0.1" }, @@ -7571,7 +7609,7 @@ "version": "4.1.2", "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, + "devOptional": true, "engines": { "node": ">= 14.18.0" }, @@ -7776,6 +7814,14 @@ "node": ">= 6" } }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -8229,7 +8275,6 @@ "version": "5.0.1", "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -8384,6 +8429,14 @@ "node": ">= 4.0.0" } }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/unplugin": { "version": "2.3.5", "resolved": "https://registry.npmmirror.com/unplugin/-/unplugin-2.3.5.tgz", @@ -8568,6 +8621,14 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/verror": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", @@ -8587,7 +8648,6 @@ "version": "5.0.12", "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.12.tgz", "integrity": "sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==", - "dev": true, "dependencies": { "esbuild": "^0.19.3", "postcss": "^8.4.32", @@ -8638,6 +8698,28 @@ } } }, + "node_modules/vite-plugin-mock": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/vite-plugin-mock/-/vite-plugin-mock-3.0.2.tgz", + "integrity": "sha512-bD//HvkTygGmk+LsIAdf0jGNlCv4iWv0kZlH9UEgWT6QYoUwfjQAE4SKxHRw2tfLgVhbPQVv/+X3YlNWvueGUA==", + "dependencies": { + "bundle-require": "^4.0.1", + "chokidar": "^3.5.3", + "connect": "^3.7.0", + "debug": "^4.3.4", + "fast-glob": "^3.2.12", + "path-to-regexp": "^6.2.1", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.17", + "mockjs": ">=1.1.0", + "vite": ">=4.0.0" + } + }, "node_modules/vite-plugin-sass": { "version": "0.1.0", "resolved": "https://registry.npmmirror.com/vite-plugin-sass/-/vite-plugin-sass-0.1.0.tgz", diff --git a/package.json b/package.json index e044f9c..773b5d5 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,9 @@ "@electron-toolkit/utils": "^3.0.0", "axios": "^1.10.0", "element-plus": "^2.10.2", + "mockjs": "^1.1.0", "pinia": "^3.0.3", + "vite-plugin-mock": "^3.0.2", "vue-router": "^4.5.1" }, "devDependencies": { diff --git a/src/renderer/src/api/log.ts b/src/renderer/src/api/log.ts new file mode 100644 index 0000000..5cc7a1a --- /dev/null +++ b/src/renderer/src/api/log.ts @@ -0,0 +1,28 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-07-08 17:07:13 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-07-10 10:18:22 + * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\api\log.ts + * @Description: 日志管理 + */ +import request from '@/utils/request/instance' + +type ResultList = { + success: boolean + data?: { + count: number // 总条数 + page: number // 当前页 + pageSize: number // 每页条数 + /** 列表数据 */ + data: Array + } +} + +/** 获取日志 */ + +export const getLogListApi = (params: { url: string }) => { + return request.get(`/api/getLogList`, params, { + showLoading: false // 单独关闭loading + }) +} diff --git a/src/renderer/src/api/user.ts b/src/renderer/src/api/user.ts new file mode 100644 index 0000000..b873f24 --- /dev/null +++ b/src/renderer/src/api/user.ts @@ -0,0 +1,35 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-03-12 15:13:38 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-07-10 10:20:57 + * @FilePath: \5G-Loading-Bay-Web\src\api\user.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +import request from '@/utils/request/instance' +import { config } from '@/config' + +// 定义响应类型 +interface LoginRes { + token: string + userInfo: { + id: number + username: string + } +} + +export const loginApi = (data: { username: string; password: string }) => { + return request.post(`/api/user/login/`, data, { + showLoading: false // 单独关闭loading + }) +} + +export const loginOutApi = () => { + return request.post( + `/api/user/logout/`, + {}, + { + showLoading: false // 单独关闭loading + } + ) +} diff --git a/src/renderer/src/api/utils.ts b/src/renderer/src/api/utils.ts new file mode 100644 index 0000000..2f0d1a1 --- /dev/null +++ b/src/renderer/src/api/utils.ts @@ -0,0 +1,2 @@ +const { VITE_APP_BASE_URL } = import.meta.env; +export const baseUrlApi = (url: string) => `${VITE_APP_BASE_URL}/api/${url}`; diff --git a/src/renderer/src/components/Table/src/baseTable.scss b/src/renderer/src/components/Table/src/baseTable.scss index cdbc876..5d37341 100644 --- a/src/renderer/src/components/Table/src/baseTable.scss +++ b/src/renderer/src/components/Table/src/baseTable.scss @@ -7,13 +7,13 @@ /* 去掉表头下边框 */ .el-table__header-wrapper thead th { - border-bottom: none !important; + // border-bottom: none !important; border: none !important; } /* 去掉单元格边框 */ .el-table td, .el-table th.is-leaf { - border-bottom: none !important; + // border-bottom: none !important; border: none !important; } /* 去掉纵向分割线 */ @@ -25,7 +25,7 @@ .el-table--border, .el-table--group { border-right: none !important; - border-bottom: none !important; + // border-bottom: none !important; border: none !important; } .el-table td, @@ -53,7 +53,7 @@ color: #fff; background: transparent; border-top: 1px solid transparent; - border-bottom: 1px solid transparent; + border-bottom: 1px solid #4e5969; &:hover td { background: transparent !important; @@ -85,17 +85,19 @@ .el-table__header > thead { color: #9fb5d7; - background-color: #104284 !important; + background-color: var(--ds-color-primary-light-1) !important; tr { - background-color: #104284 !important; + background-color: var(--ds-color-primary-light-1) !important; } th { - background-color: #104284 !important; + background-color: var(--ds-color-primary-light-1) !important; } } } .fixed_pagination { - padding: 12px 20px 0; + display: flex; + justify-content: flex-end; + padding: 24px 0 0; } /* full_table */ &.full_table { @@ -127,12 +129,12 @@ .el-table__header > thead { color: #9fb5d7; - background-color: #104284 !important; + background-color: var(--ds-color-primary-light-1) !important; tr { - background-color: #104284 !important; + background-color: var(--ds-color-primary-light-1) !important; } th { - background-color: #104284 !important; + background-color: var(--ds-color-primary-light-1) !important; } } } @@ -151,3 +153,59 @@ background-color: white; z-index: 9; } +.el-pagination { + .el-pagination__total { + color: var(--ds-color-info); + } + button { + background-color: transparent; + color: var(--ds-color-info); + } + button:disabled, + button.is-disabled { + background-color: transparent; + } + + .el-pagination--small .btn-prev, + .el-pagination--small .btn-next, + .el-pagination--small .el-pager li { + height: 28px; + line-height: 28px; + min-width: 28px; + } + .el-select--small .el-select__wrapper { + width: 92px; + } + .el-select--small .el-select__wrapper { + padding: 8px 15px; + } + .el-pagination__jump { + color: var(--ds-color-info); + .el-input { + width: 40px; + height: 28px; + } + .el-input__wrapper { + background-color: transparent; + + .el-input__inner { + color: var(--ds-color-info); + line-height: 24px; + } + } + } + &.el-pagination--small button, + &.el-pagination--small span:not([class*='suffix']) { + font-size: 12px; + } + &.el-pagination--small .el-pagination__goto{ + font-size: 14px !important; + } + .ds-pagination__goto_next { + color: var(--ds-color-info); + } +} +.el-pager li { + background-color: transparent; + color: var(--ds-color-info); +} diff --git a/src/renderer/src/components/Table/src/baseTable.tsx b/src/renderer/src/components/Table/src/baseTable.tsx index 190effa..8739d71 100644 --- a/src/renderer/src/components/Table/src/baseTable.tsx +++ b/src/renderer/src/components/Table/src/baseTable.tsx @@ -1,21 +1,15 @@ -import { ElLoading, ElPagination, ElTable, ElTableColumn } from "element-plus"; -import BaseColumn from "./baseColumn.vue"; -import { isUndefined } from "@/utils/is"; -import { - computed, - defineComponent, - nextTick, - reactive, - type PropType -} from "vue"; -import "./baseTable.scss"; +import { ElLoading, ElPagination, ElTable, ElTableColumn } from 'element-plus' +import BaseColumn from './baseColumn.vue' +import { isUndefined } from '@/utils/is' +import { computed, defineComponent, nextTick, reactive, type PropType } from 'vue' +import './baseTable.scss' function getDefaultSort(attrs: Record): any { - return attrs["default-sort"] || attrs.defaultSort; + return attrs['default-sort'] || attrs.defaultSort } export default defineComponent({ - name: "XTable", + name: 'XTable', directives: { loading: ElLoading.directive }, @@ -49,8 +43,8 @@ export default defineComponent({ * 最大高度,包含分页高度 */ maxHeight: { - type: [Number, String] as PropType, - default: "auto" + type: [Number, String] as PropType, + default: 'auto' }, /** @@ -60,10 +54,10 @@ export default defineComponent({ * 为 true 时,只有有数据时才显示 */ pageable: { - type: [Boolean, String] as PropType, + type: [Boolean, String] as PropType, default: true, - validator(value: boolean | "always") { - return ["always", true, false].includes(value); + validator(value: boolean | 'always') { + return ['always', true, false].includes(value) } }, @@ -72,14 +66,12 @@ export default defineComponent({ */ pagerLayout: { type: String, - default: "total, sizes, prev, pager, next, jumper", + default: 'total, sizes, prev, pager, next, jumper', validator(value: string) { return value - .split(",") - .map(item => item.trim()) - .every(item => - ["total", "sizes", "prev", "pager", "next", "jumper"].includes(item) - ); + .split(',') + .map((item) => item.trim()) + .every((item) => ['total', 'sizes', 'prev', 'pager', 'next', 'jumper'].includes(item)) } }, @@ -113,7 +105,7 @@ export default defineComponent({ pageSizes: { type: Array as PropType, default() { - return [15, 20, 30, 50]; + return [10, 20, 30, 40] } }, @@ -121,10 +113,8 @@ export default defineComponent({ * 行数据的 Key */ rowKey: { - type: [Function, String] as PropType< - (row: XTableData) => string | string - >, - default: "id" + type: [Function, String] as PropType<(row: XTableData) => string | string>, + default: 'id' }, /** @@ -152,36 +142,36 @@ export default defineComponent({ // default: () => {} // } }, - emits: ["change", "columnChange", "update:visibleColumn", "actions"], + emits: ['change', 'columnChange', 'update:visibleColumn', 'actions'], setup(props, { slots, attrs, emit }) { - const nonPropsAttrs = attrs; - const { prop: sortBy, order: sortOrder } = getDefaultSort(attrs) || {}; + const nonPropsAttrs = attrs + const { prop: sortBy, order: sortOrder } = getDefaultSort(attrs) || {} const tableState = reactive({ tid: 0, sortBy, sortOrder - }); + }) const showPagination = computed(() => { - if (props.pageable === "always") return true; - return props.pageable && props.dataSource.length > 0; - }); + if (props.pageable === 'always') return true + return props.pageable && props.dataSource.length > 0 + }) const mHeight = computed(() => { - if (props.maxHeight === "auto") { - return "auto"; + if (props.maxHeight === 'auto') { + return 'auto' } - return showPagination.value ? props.maxHeight - 44 : props.maxHeight; - }); + return showPagination.value ? props.maxHeight - 44 : props.maxHeight + }) /** * 获取插槽 */ function getSlot(column: XTableColumn, suffix?: string) { - const name = column.prop || column.type; + const name = column.prop || column.type if (name) { - const key = suffix ? `${name}-${suffix}` : name; - return slots[key]; + const key = suffix ? `${name}-${suffix}` : name + return slots[key] } } @@ -189,29 +179,29 @@ export default defineComponent({ * 改变表格列的排序和分页 */ function onChange(data: XTableChangeData) { - emit("change", data); + emit('change', data) } /** * 改变页数 */ function handlePageNumChange(page: number) { - const { sortBy, sortOrder } = tableState; - const { pageSize } = props; + const { sortBy, sortOrder } = tableState + const { pageSize } = props onChange({ page, pageSize, prop: sortBy, order: sortOrder, - type: "number" - }); + type: 'number' + }) } /** * 改变每页显示的条数 */ function handlePageSizeChange(pageSize: number) { - const { sortBy, sortOrder } = tableState; + const { sortBy, sortOrder } = tableState nextTick(() => { // 下拉框溢出可能导致溢出 body 出现滚动条 // 加个延迟,等下拉隐藏 @@ -220,64 +210,63 @@ export default defineComponent({ pageSize, prop: sortBy, order: sortOrder, - type: "size" - }); - }); + type: 'size' + }) + }) } /** * 排序 */ function handleTableSortChange({ prop, order }: XTableSort) { - const { pageSize } = props; - onChange({ page: 1, pageSize, prop, order, type: "sort" }); + const { pageSize } = props + onChange({ page: 1, pageSize, prop, order, type: 'sort' }) } /** * 自定义列回调 */ function handleColumnChange(cols: XTableColumn[]) { - emit("columnChange", cols); + emit('columnChange', cols) } /** * 自定义列隐藏 */ function handleVisibleChange(val: boolean) { - emit("update:visibleColumn", val); + emit('update:visibleColumn', val) } /** * 获取表格列的属性 */ function getColumnProps(column: XTableColumn) { - const col = { ...column }; - Reflect.deleteProperty(col, "children"); - Reflect.deleteProperty(col, "hidden"); - col.key = column.key || column.prop || column.type; - col.showOverflowTooltip = col.showOverflowTooltip ?? true; - col.showOverflowTooltip = - column.prop === "action" ? false : column.showOverflowTooltip; - return col; + const col = { ...column } + Reflect.deleteProperty(col, 'children') + Reflect.deleteProperty(col, 'hidden') + col.key = column.key || column.prop || column.type + col.showOverflowTooltip = col.showOverflowTooltip ?? true + col.showOverflowTooltip = column.prop === 'action' ? false : column.showOverflowTooltip + return col } /** * 渲染特殊列 */ function renderTypeColumn(column: XTableColumn) { - if (column.type === "expand") { + if (column.type === 'expand') { return ( {{ default: (scope: Record) => { - const slot = getSlot(column); - return slot?.(scope); + const slot = getSlot(column) + return slot?.(scope) } }} - ); + ) } - if (column.type === "action") { + if (column.type === 'action') { return ( {{ @@ -305,13 +294,13 @@ export default defineComponent({ */} - ); + ) } }} - ); + ) } - return ; + return } /**操作按钮事件 */ @@ -329,34 +318,32 @@ export default defineComponent({ */ function renderBaseColumn(column: XTableColumn) { const columnSlots: { - default?: (scope: Record) => any; - header?: (scope: Record) => any; - } = {}; - const slot = getSlot(column); - const headerSlot = getSlot(column, "header"); + default?: (scope: Record) => any + header?: (scope: Record) => any + } = {} + const slot = getSlot(column) + const headerSlot = getSlot(column, 'header') if (slot) { - columnSlots.default = scope => slot(scope); + columnSlots.default = (scope) => slot(scope) } if (headerSlot) { - columnSlots.header = scope => headerSlot(scope); + columnSlots.header = (scope) => headerSlot(scope) } - return ( - {columnSlots} - ); + return {columnSlots} } /** * 渲染列 */ function renderTableColumn(column: XTableColumn) { - if (column.hidden) return; + if (column.hidden) return if (column.type) { - return renderTypeColumn(column); + return renderTypeColumn(column) } - return renderBaseColumn(column); + return renderBaseColumn(column) } /** @@ -364,14 +351,14 @@ export default defineComponent({ */ function renderColumnChildren( column: XTableColumn, - children: Required["children"] + children: Required['children'] ) { - if (column.hidden) return; + if (column.hidden) return return ( - {children.map(column => renderTableColumn(column))} + {children.map((column) => renderTableColumn(column))} - ); + ) } /** @@ -379,7 +366,7 @@ export default defineComponent({ */ function renderPagination() { const paginationProps = { - size: "small", + size: 'small', background: false, total: props.total, layout: props.pagerLayout, @@ -388,20 +375,21 @@ export default defineComponent({ currentPage: props.page, onSizeChange: handlePageSizeChange, onCurrentChange: handlePageNumChange - }; + } return (
+ + 页 +
- ); + ) } /** @@ -413,32 +401,32 @@ export default defineComponent({ visible: props.visibleColumn, onChange: handleColumnChange, onVisibleChange: handleVisibleChange - }; + } - return ; + return } return () => { const tableProps = { - ref: "elTableRef", + ref: 'elTableRef', ...nonPropsAttrs, maxHeight: mHeight.value, data: props.dataSource, rowKey: props.rowKey, onSortChange: handleTableSortChange - }; + } const extraSlots: { - append?: () => any; - empty?: () => any; - } = {}; + append?: () => any + empty?: () => any + } = {} if (slots.append) { - extraSlots.append = () => slots.append?.(); + extraSlots.append = () => slots.append?.() } if (slots.empty) { - extraSlots.empty = () => slots.empty?.(); + extraSlots.empty = () => slots.empty?.() } return ( @@ -449,11 +437,11 @@ export default defineComponent({ v-loading={props.loading} v-slots={extraSlots} > - {props.columns.map(column => { + {props.columns.map((column) => { if (Array.isArray(column.children)) { - return renderColumnChildren(column, column.children); + return renderColumnChildren(column, column.children) } - return renderTableColumn(column); + return renderTableColumn(column) })} {/* 使用插槽引入操作栏的内容 */} {/* @@ -482,7 +470,7 @@ export default defineComponent({ {showPagination.value && renderPagination()} {!isUndefined(props.visibleColumn) && renderCustomColumn()} - ); - }; + ) + } } -}); \ No newline at end of file +}) diff --git a/src/renderer/src/config/index.ts b/src/renderer/src/config/index.ts new file mode 100644 index 0000000..be7f971 --- /dev/null +++ b/src/renderer/src/config/index.ts @@ -0,0 +1,21 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-07-08 17:34:38 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-07-10 09:16:34 + * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\config\index.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +const env = import.meta.env + +export const config = { + env: 'development', + baseURL: '/', + timeout: 10000, + url: '', + showLoading: false, + loadingInstance: null + // uploadURL: env.VITE_APP_UPLOAD_URL, + // appName: env.VITE_APP_NAME, + // version: env.VITE_APP_VERSION +} diff --git a/src/renderer/src/main.ts b/src/renderer/src/main.ts index 186dbdc..3046caa 100644 --- a/src/renderer/src/main.ts +++ b/src/renderer/src/main.ts @@ -2,7 +2,7 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2025-07-02 13:17:44 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2025-07-03 17:18:59 + * @LastEditTime: 2025-07-09 12:42:56 * @FilePath: \electron-project\Robot-Al\Robot-Al-Platform-Web\src\renderer\src\main.ts * @Description: 入口文件 */ @@ -15,12 +15,12 @@ import router from '@router' import { createPinia } from 'pinia' import zhCn from '@/plugins/zhCnElement' // 引入中文语言包 -createApp(App) - .use(router) - .use(createPinia()) - .use(ElementPlus, { - locale: zhCn, - size: 'large', // 全局组件尺寸 - zIndex: 3000 // 全局z-index - }) - .mount('#app') +const app = createApp(App) + +app.use(router).use(createPinia()).use(ElementPlus, { + locale: zhCn, + size: 'large', // 全局组件尺寸 + zIndex: 3000 // 全局z-index +}) + +app.mount('#app') diff --git a/src/renderer/src/mock/log.ts b/src/renderer/src/mock/log.ts new file mode 100644 index 0000000..09bcfaa --- /dev/null +++ b/src/renderer/src/mock/log.ts @@ -0,0 +1,31 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-07-08 17:08:58 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-07-10 09:52:32 + * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\mock\log.ts + * @Description: mock的日志数据 + */ +import { MockMethod } from 'vite-plugin-mock' +import { logListData } from './pools/logData' +import { fetchCurrPageByList } from './utils/apiMock' + +export default [ + { + url: '/api/getLogList', + method: 'get', + response: (req) => { + const { page, pageSize } = req.query + return { + ...fetchCurrPageByList({ + ...logListData, + data: { + ...logListData.data, + page: page || 1, + pageSize: pageSize || 10 + } + }) + } + } + } +] as MockMethod[] diff --git a/src/renderer/src/mock/pools/logData.ts b/src/renderer/src/mock/pools/logData.ts new file mode 100644 index 0000000..317278e --- /dev/null +++ b/src/renderer/src/mock/pools/logData.ts @@ -0,0 +1,90 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-07-08 15:58:01 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-07-10 10:19:20 + * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\mock\pools\logData.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +import Mock from 'mockjs' + +// [ +// { +// created_at: '2024-06-10 14:22:18', +// type: '3', +// content: '系统备份完成' +// }, +// { +// created_at: '2024-05-3009:15:47', +// type: '1', +// content: '用户登录成功' +// }, +// { +// created_at: '2024-06-05 16:45:33', +// type: '2', +// content: '数据同步失败' +// }, +// { +// created_at: '2024-06-1508:30:12', +// type: '3', +// content: '安全审计通过' +// }, +// { +// created_at: '2024-05-25 11:05:29', +// type: '1', +// content: '新用户注册' +// }, +// { +// created_at: '2024-06-08 13:50:01', +// type: '2', +// content: 'API调用超时' +// }, +// { +// created_at: '2024-06-18 17:22:44', +// type: '3', +// content: '版本更新部署' +// }, +// { +// created_at: '2024-05-28 10:33:17', +// type: '1', +// content: '密码重置请求' +// }, +// { +// created_at: '2024-06-12 15:18:09', +// type: '2', +// content: '磁盘空间不足' +// }, +// { +// created_at: '2024-06-03 09:42:56', +// type: '3', +// content: '防火墙配置更新' +// }, +// { +// created_at: '2024-06-20 14:05:38', +// type: '1', +// content: '订单支付成功' +// } +// ] + +const logCount = 101 +const mockLogListData = Mock.mock({ + [`data|${logCount}`]: [ + { + 'id|+1': 35, + key: function () { + return this.id.toString() + }, + type: function () { + const codeArr = ['1', '2', '3'] + return codeArr[Math.floor(Math.random() * 3)] + }, + content: '@cparagraph(1, 1)', // 随机生成一段文本 + created_at: '@datetime("yyyy-MM-dd HH:mm:ss")', // 随机生成日期时间 + updated_at: '@datetime("yyyy-MM-dd HH:mm:ss")' + } + ] +}) + +export const logListData = { + data: { ...mockLogListData, count: logCount } +} diff --git a/src/renderer/src/mock/pools/testListData.ts b/src/renderer/src/mock/pools/testListData.ts new file mode 100644 index 0000000..74406e2 --- /dev/null +++ b/src/renderer/src/mock/pools/testListData.ts @@ -0,0 +1,120 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-07-08 15:57:23 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-07-08 17:11:43 + * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\mock\pools\deviceStatusData.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2024-02-22 13:38:04 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-03-14 14:03:18 + * @FilePath: \General-AI-Platform-Web-Client\mock\pools\deviceStatusData.ts + * @Description: 设备状态数据 + */ +import { generateRandomDateTimeByYear } from '../utils/mockMoment' +import Mock from 'mockjs' + +// 定义一些公开的可测试的视频链接 +const videoUrls = [ + 'https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4', + 'https://www.sample-videos.com/video123/mp4/1080/big_buck_bunny_1080p_100mb.mp4', + 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', + 'https://www.sample-videos.com/video123/mp4/360/big_buck_bunny_360p_5mb.mp4', + 'https://media.w3.org/2010/05/video/movie_300.mp4', + 'https://www.w3schools.com/html/mov_bbb.mp4', + 'https://media.w3.org/2010/05/sintel/trailer.mp4', + 'https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/360/Big_Buck_Bunny_360_10s_1MB.mp4', + 'https://archive.org/download/Popeye_forPresident/Popeye_forPresident_512kb.mp4', + 'https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4' +] + +function fetchList(): Record[] { + const currList: Record[] = [] + const nameArr = [ + '摄像模组表面缺陷检测设备', + '镜片表面缺陷检测设备', + '中板表面缺陷检测设备', + 'Logo表面缺陷检测设备', + '手机电池表面缺陷检测设备', + '部件表面缺陷检测设备', + '边距缺陷检测设备', + '成品组装缺陷检测设备', + '金属工件表面缺陷检测设备', + '管材表面缺陷检测设备' + ] + + const codeArr = ['MSRF', 'RL0F', 'TLOC', 'E1AIS', 'CRM'] + const deviceGroupArr = ['立杆', '东西货区', '送料区'] + + for (let i = 0; i < 35; i++) { + currList.push({ + id: i, + createTime: generateRandomDateTimeByYear(2023), + updateTime: '2023-10-17T02:35:41.14308Z', + name: nameArr[Math.floor(Math.random() * 3)], + code: codeArr[Math.floor(Math.random() * 4)] + '-' + i, + deviceGroup: + deviceGroupArr[Math.floor(Math.random() * 3)] + (Math.floor(Math.random() * 3) + 1), + status: Math.floor(Math.random() * 3) + 1, + remark: '' + }) + } + return currList +} + +// 缺陷从EXL里选几个就好了 +// 告警代码MSRF-0 RL0F HTFIF-02 TLOC-1 E1AIS-05 +// 设备组:核心检测组001 无尘总装组005 送料监测线02 + +const mockHistroyData = Mock.mock({ + [`list|${videoUrls.length}`]: [ + { + 'id|+1': 10, + key: function () { + return this.id.toString() + }, + video_url: function () { + // 依次取出视频链接 + return videoUrls[this.id - 10] + }, + created_at: function () { + // 定义起始和结束时间戳 + const startDate = new Date('2025-01-01').getTime() + const endDate = new Date('2025-03-14 23:59:59').getTime() + // 生成随机时间戳 + const randomTimestamp = startDate + Math.random() * (endDate - startDate) + // 根据随机时间戳创建日期对象 + const randomDate = new Date(randomTimestamp) + // 格式化日期为 yyyy-MM-dd HH:mm:ss 格式 + const year = randomDate.getFullYear() + const month = String(randomDate.getMonth() + 1).padStart(2, '0') + const day = String(randomDate.getDate()).padStart(2, '0') + const hours = String(randomDate.getHours()).padStart(2, '0') + const minutes = String(randomDate.getMinutes()).padStart(2, '0') + const seconds = String(randomDate.getSeconds()).padStart(2, '0') + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` + }, + device: 1 + } + ] +}) + +const currentData = fetchList() +const currentHistroyData = mockHistroyData.list + +// +export const deviceStatusListData = { + data: { + data: currentData, + total: currentData.length, + current: 1, + pageSize: 10 + } +} + +export const deviceHistoryListData = { + data: currentHistroyData +} diff --git a/src/renderer/src/mock/typing.ts b/src/renderer/src/mock/typing.ts new file mode 100644 index 0000000..ded9753 --- /dev/null +++ b/src/renderer/src/mock/typing.ts @@ -0,0 +1,17 @@ +/**成功返回数据结构 */ +export interface successMockApiProps { + code: number; // 0 成功 + success: boolean; // true 成功 + data: any; // mock业务层数据 + msg: string | undefined; // 成功提示 + isMock: boolean; // true 标识当前是模拟数据 +} + +/**失败返回数据结构 */ +export interface failMockApiProps { + code?: number; // 7 失败 + success: boolean; // false 失败 + data: any; // mock业务层数据 + msg: string | undefined; // 成功提示 + isMock: boolean; // true 标识当前是模拟数据 +} diff --git a/src/renderer/src/mock/user.ts b/src/renderer/src/mock/user.ts new file mode 100644 index 0000000..a45617a --- /dev/null +++ b/src/renderer/src/mock/user.ts @@ -0,0 +1,28 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-03-06 11:37:14 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-03-06 11:38:11 + * @FilePath: \vite-ai\data-dashboard\mock\user.ts + * @Description: 模拟登录接口 + */ +export default [ + { + url: '/api/login', + method: 'post', + response: ({ body }) => { + if (body.username === 'admin' && body.password === 'admin123') { + return { + code: 200, + data: { + token: 'MOCK_TOKEN_' + Date.now() + } + } + } + return { + code: 401, + message: '用户名或密码错误' + } + } + } + ] \ No newline at end of file diff --git a/src/renderer/src/mock/utils/apiMock.ts b/src/renderer/src/mock/utils/apiMock.ts new file mode 100644 index 0000000..aa90342 --- /dev/null +++ b/src/renderer/src/mock/utils/apiMock.ts @@ -0,0 +1,42 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-07-08 15:57:23 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-07-10 10:16:38 + * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\mock\utils\apiMock.ts + * @Description: mock返回结果模版 + */ +import { failMockApiProps, successMockApiProps } from '../typing' +export function fetchMockSuccessFullByOther({ data, msg }): successMockApiProps { + const result: successMockApiProps = { + code: 200, // 200 成功 + success: true, // true 成功 + data: data || null, // mock业务层数据 + msg: msg as string | 'ok', // 成功提示 + isMock: true // true 标识当前是模拟数据 + } + return result +} + +export function fetchMockFailFullByOther({ data, msg }): failMockApiProps { + const result: failMockApiProps = { + code: 599, // 200 成功 + success: false, // true 成功 + data: data || null, // mock业务层数据 + msg: msg as string | 'fail', // 成功提示 + isMock: true // true 标识当前是模拟数据 + } + return result +} + +// 分页展示 +export function fetchCurrPageByList({ data }): successMockApiProps { + // console.log("fetchCurrPageByList_data", data); + const { page, pageSize } = data + const prevPage = page - 1 + const currPageData = { + ...data, + data: data.data.slice(prevPage * pageSize, page * pageSize) + } + return fetchMockSuccessFullByOther({ data: currPageData }) +} diff --git a/src/renderer/src/mock/utils/is.ts b/src/renderer/src/mock/utils/is.ts new file mode 100644 index 0000000..84e81f8 --- /dev/null +++ b/src/renderer/src/mock/utils/is.ts @@ -0,0 +1,43 @@ +/** + * 判断文件名是否为图片 + * @param {string} filename 完整文件名(含路径和扩展名) + * @returns {boolean} 是否为图片 + */ + +const IMAGE_EXTENSIONS = new Set([ + "jpg", + "jpeg", + "png", + "gif", + "bmp", + "svg", + "webp", + "tiff", + "psd", + "ico", + "jfif", + "apng", + "avif", +]); +export function isImage(filename) { + // 1. 去除路径,只保留文件名 + const baseName = filename.split("/").pop().split("\\").pop(); + if (!baseName) return false; + + // 2. 提取扩展名(处理多扩展名,取最后一个) + const ext = baseName.split(".").pop()?.toLowerCase(); + if (!ext || ext.length < 2) return false; // 扩展名长度至少2位(如.jpg) + + // 3. 检查是否在图片扩展名白名单 + return IMAGE_EXTENSIONS.has(ext); +} + +// 示例测试 +// console.log(isImage('photo.jpg')); // true +// console.log(isImage('image.png')); // true +// console.log(isImage('logo.svg')); // true +// console.log(isImage('cover.tar.gz')); // false(非图片扩展名) +// console.log(isImage('file')); // false(无扩展名) +// console.log(isImage('.hidden.png')); // true(隐藏文件) +// console.log(isImage('icon.JPEG')); // true(大小写不敏感) +// console.log(isImage('video.mp4')); // false(视频) diff --git a/src/renderer/src/mock/utils/mockMoment.ts b/src/renderer/src/mock/utils/mockMoment.ts new file mode 100644 index 0000000..5bdbeb0 --- /dev/null +++ b/src/renderer/src/mock/utils/mockMoment.ts @@ -0,0 +1,38 @@ +export function generateRandomDateTimeByYear(year) { + // 生成随机月份(1-12) + const month = Math.floor(Math.random() * 12) + 1; + + // 生成随机日期(1-31) + const day = Math.floor(Math.random() * 31) + 1; + + // 生成随机小时(0-23) + const hour = Math.floor(Math.random() * 24); + + // 生成随机分钟(0-59) + const minute = Math.floor(Math.random() * 60); + + // 生成随机秒钟(0-59) + const second = Math.floor(Math.random() * 60); + + // 返回随机日期和时间的字符串 + return `${year}-${month < 10 ? "0" : ""}${month}-${ + day < 10 ? "0" : "" + }${day} ${hour < 10 ? "0" : ""}${hour}:${minute < 10 ? "0" : ""}${minute}:${ + second < 10 ? "0" : "" + }${second}`; +} + +export function generateRandomMoment(date = new Date(), type = "HH:mm:ss") { + // 生成随机小时(0-23) + const hour = Math.floor(Math.random() * 24); + + // 生成随机分钟(0-59) + const minute = Math.floor(Math.random() * 60); + + // 生成随机秒钟(0-59) + const second = Math.floor(Math.random() * 60); + // 返回随机日期和时间的字符串 + return `${hour < 10 ? "0" : ""}${hour}:${minute < 10 ? "0" : ""}${minute}:${ + second < 10 ? "0" : "" + }${second}`; +} diff --git a/src/renderer/src/plugins/zhCnElement.ts b/src/renderer/src/plugins/zhCnElement.ts index b9e3324..d8d541c 100644 --- a/src/renderer/src/plugins/zhCnElement.ts +++ b/src/renderer/src/plugins/zhCnElement.ts @@ -2,19 +2,18 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2025-03-11 11:09:39 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2025-06-12 17:54:08 + * @LastEditTime: 2025-07-08 16:50:31 * @FilePath: \5G-Loading-Bay-Web\src\plugins\zhCn.ts * @Description: element-plus 中文 */ -import zhCn from "element-plus/es/locale/lang/zh-cn"; +import zhCn from 'element-plus/es/locale/lang/zh-cn' // 自定义分页器文案 - zhCn.el.pagination = { - goto: "跳至", - pageClassifier: "", - pagesize: "条/页", - total: "" - // total: "共 {total} 条" -}; +zhCn.el.pagination = { + goto: '前往', + pageClassifier: '', + pagesize: '条/页', + total: '共 {total} 条' +} -export default zhCn; +export default zhCn diff --git a/src/renderer/src/router/index.ts b/src/renderer/src/router/index.ts index 021b41b..82b2b59 100644 --- a/src/renderer/src/router/index.ts +++ b/src/renderer/src/router/index.ts @@ -1,3 +1,11 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-07-02 13:17:44 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-07-08 17:40:18 + * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\router\index.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ import { createRouter, createWebHashHistory } from 'vue-router' import Home from '@views/Home/index.vue' import Design from '@views/Design/index.vue' @@ -5,3 +13,13 @@ export default createRouter({ history: createWebHashHistory(), //hash模式 routes: [{ path: '/', component: Design }] //路由配置规则数组 }) + +/** 重置路由 */ +export function resetRouter() { + router.getRoutes().forEach((route) => { + const { name, meta } = route + if (name && router.hasRoute(name) && meta?.backstage) { + router.removeRoute(name) + } + }) +} diff --git a/src/renderer/src/store/index.ts b/src/renderer/src/store/index.ts deleted file mode 100644 index 7a8437b..0000000 --- a/src/renderer/src/store/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { defineStore } from 'pinia' - -export const useStore = defineStore('storeId', { - state: () => { - return { - counter: 0 - } - }, - - getters: {}, - - actions: {} -}) diff --git a/src/renderer/src/stores/index.ts b/src/renderer/src/stores/index.ts new file mode 100644 index 0000000..c5347f9 --- /dev/null +++ b/src/renderer/src/stores/index.ts @@ -0,0 +1,21 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-07-02 13:17:44 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-07-08 17:37:12 + * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\stores\index.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +import { defineStore } from 'pinia' + +export const useStore = defineStore('storeId', { + state: () => { + return { + counter: 0 + } + }, + + getters: {}, + + actions: {} +}) diff --git a/src/renderer/src/stores/user.ts b/src/renderer/src/stores/user.ts new file mode 100644 index 0000000..f8fa849 --- /dev/null +++ b/src/renderer/src/stores/user.ts @@ -0,0 +1,42 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-03-06 17:57:05 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-07-08 17:37:38 + * @FilePath: \5G-Loading-Bay-Web\src\stores\user.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +import { defineStore } from 'pinia' +import router, { resetRouter } from '@/router' +import { getLocal, setLocal, removeLocal } from '@/utils/local' +import { loginOutApi } from '@/api/user' +import { isSuccessApi } from '@/utils/forApi' +import { ElMessage } from 'element-plus' + +interface UserState { + token: string | null +} + +export const useUserStore = defineStore('user', { + state: (): UserState => ({ + token: getLocal('token') + }), + actions: { + login(token: string, form: { remember: boolean; username: string; password: string }) { + this.token = token + setLocal('token', token) + form.remember ? setLocal('userLoginInfo', form) : removeLocal('userLoginInfo') + }, + async logout() { + const res = await loginOutApi() + if (isSuccessApi(res)) { + ElMessage.success(`退出登录`) + } + this.token = null + removeLocal('token') + resetRouter() + // TODO 暂未实现 + // router.replace("/login"); + } + } +}) diff --git a/src/renderer/src/styles/element-plus.scss b/src/renderer/src/styles/element-plus.scss index a3d0b64..775914b 100644 --- a/src/renderer/src/styles/element-plus.scss +++ b/src/renderer/src/styles/element-plus.scss @@ -46,7 +46,6 @@ } /* 弹框 */ - .ds-dialog { --el-dialog-padding-primary: 0; // 弹窗内边距 --el-dialog-bg-color: var(--ds-dialog-background-color) !important; // 弹窗背景颜色 diff --git a/src/renderer/src/styles/global.scss b/src/renderer/src/styles/global.scss index 14002f4..9a64a0c 100644 --- a/src/renderer/src/styles/global.scss +++ b/src/renderer/src/styles/global.scss @@ -1,5 +1,7 @@ :root { --ds-color-primary: rgb(21, 77, 221); // 主色调 + --ds-color-primary-light-1: rgba(21, 77, 221, 0.1); + --ds-color-primary-light-3: rgba(21, 77, 221, 0.3); --ds-color-primary-light-5: rgba(21, 77, 221, 0.5); --ds-color-primary-light-7: rgba(21, 77, 221, 0.7); diff --git a/src/renderer/src/utils/forApi.ts b/src/renderer/src/utils/forApi.ts new file mode 100644 index 0000000..b9d5875 --- /dev/null +++ b/src/renderer/src/utils/forApi.ts @@ -0,0 +1,19 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2024-08-14 14:42:09 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-03-13 10:20:54 + * @FilePath: \General-AI-Platform-Web-Client\src\utils\forApi.ts + * @Description: 这是接口层和业务层的转换工具方法集 + */ +/** + * @判断接口数据是否成功返回 + * @param result 接口返回数据 + * @returns boolean + */ +export function isSuccessApi(result): boolean { + if ([200].includes(result.code)) { + return true; + } + return false; +} diff --git a/src/renderer/src/utils/is.ts b/src/renderer/src/utils/is.ts new file mode 100644 index 0000000..5d862cf --- /dev/null +++ b/src/renderer/src/utils/is.ts @@ -0,0 +1,57 @@ +const { toString } = Object.prototype; + +export function is(val: unknown, type: string): boolean { + return toString.call(val) === `[object ${type}]`; +} + +export function isString(val: any): val is string { + return is(val, "String"); +} + +export function isNumber(val: any): val is number { + return is(val, "Number"); +} + +export function isBoolean(val: any): val is boolean { + return is(val, "Boolean"); +} + +export function isObject(val: any): val is Record { + return val !== null && is(val, "Object"); +} + +export function isEmptyObject(val: any): val is boolean { + return isObject(val) && Object.keys(val).length === 0; +} + +export function isArray(val: any): val is any[] { + return val && Array.isArray(val); +} + +export function isNull(val: any): val is null { + return is(val, "Null"); +} + +export function isUndefined(val: any): val is undefined { + return is(val, "Undefined"); +} + +export function isFunction(val: any): val is (...args: any[]) => any { + return typeof val === "function"; +} + +export function isFile(val: any): val is File { + return is(val, "File"); +} + +export function isBlob(val: any): val is Blob { + return is(val, "Blob"); +} + +export function isRegExp(val: any) { + return is(val, "RegExp"); +} + +export function isExternal(val: any) { + return /^(https?:|mailto:|tel:)/.test(val); +} diff --git a/src/renderer/src/utils/local.ts b/src/renderer/src/utils/local.ts new file mode 100644 index 0000000..458c5f5 --- /dev/null +++ b/src/renderer/src/utils/local.ts @@ -0,0 +1,44 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-03-10 13:45:52 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-03-11 15:29:40 + * @FilePath: \5G-Loading-Bay-Web\src\utils\local.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +/** + * get localStorage 获取本地存储 + * @param { String } key + */ +export function getLocal(key: string) { + // if (!key) throw new Error("key is empty"); + const value = localStorage.getItem(key); + return value ? JSON.parse(value) : null; +} + +/** + * set localStorage 设置本地存储 + * @param { String } key + * @param value + */ +export function setLocal(key: string, value: unknown) { + if (!key) throw new Error("key is empty"); + if (!value) return; + return localStorage.setItem(key, JSON.stringify(value)); +} + +/** + * remove localStorage 移除某个本地存储 + * @param { String } key + */ +export function removeLocal(key: string) { + if (!key) throw new Error("key is empty"); + return localStorage.removeItem(key); +} + +/** + * clear localStorage 清除本地存储 + */ +export function clearLocal() { + return localStorage.clear(); +} diff --git a/src/renderer/src/utils/request.ts b/src/renderer/src/utils/request.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/renderer/src/utils/request/index.ts b/src/renderer/src/utils/request/index.ts new file mode 100644 index 0000000..811bab9 --- /dev/null +++ b/src/renderer/src/utils/request/index.ts @@ -0,0 +1,121 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-03-12 15:11:56 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-03-13 10:48:58 + * @FilePath: \5G-Loading-Bay-Web\src\utils\request\index.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios"; +import { ElMessage, ElMessageBox } from "element-plus"; +import type { RequestConfig, RequestInterceptors } from "./type"; +import { useUserStore } from "@/stores/user"; + +class Request { + instance: AxiosInstance; + interceptors?: RequestInterceptors; + + constructor(config: RequestConfig) { + this.instance = axios.create(config); + this.interceptors = config.interceptors; + + // 全局请求拦截器 + this.instance.interceptors.request.use( + (config: RequestConfig) => { + // 处理 token + const userStore = useUserStore(); + if (userStore.token) { + config.headers!.Access = `Bearer ${userStore.token}`; + } + return config; + }, + (error: any) => Promise.reject(error) + ); + + // 实例拦截器 + this.instance.interceptors.request.use( + this.interceptors?.requestInterceptor, + this.interceptors?.requestInterceptorCatch + ); + + this.instance.interceptors.response.use( + this.interceptors?.responseInterceptor, + this.interceptors?.responseInterceptorCatch + ); + + // 全局响应拦截器 + this.instance.interceptors.response.use( + (res: AxiosResponse) => { + const { code, message } = res.data; + if (code !== 200) { + ElMessage.error(message || "请求失败"); + return Promise.reject(message); + } + return res.data; + }, + (error: any) => { + // 处理 HTTP 状态码 + if (error.response?.status === 401) { + ElMessageBox.confirm("登录已过期,请重新登录", "提示", { + confirmButtonText: "重新登录", + cancelButtonText: "取消", + type: "warning", + }).then(() => { + const userStore = useUserStore(); + userStore.logout(); + }); + } + ElMessage.error(error.message || "请求错误"); + return Promise.reject(error); + } + ); + } + + request(config: RequestConfig): Promise { + return new Promise((resolve, reject) => { + // 单个请求的拦截器 + if (config.interceptors?.requestInterceptor) { + config = config.interceptors.requestInterceptor(config); + } + + this.instance + .request(config) + .then((res) => { + if (config.interceptors?.responseInterceptor) { + res = config.interceptors.responseInterceptor(res); + } + resolve(res); + }) + .catch((err) => { + reject(err); + }); + }); + } + + get( + url: string, + params?: any, + config?: RequestConfig + ): Promise { + return this.request({ ...config, method: "GET", url, params }); + } + + post( + url: string, + data?: any, + config?: RequestConfig + ): Promise { + return this.request({ ...config, method: "POST", url, data }); + } + delete( + url: string, + data?: any, + config?: RequestConfig + ): Promise { + return this.request({ ...config, method: "DELETE", url, data }); + } + + // 其他方法类似... +} + +export default Request; diff --git a/src/renderer/src/utils/request/instance.ts b/src/renderer/src/utils/request/instance.ts new file mode 100644 index 0000000..9fdf2f9 --- /dev/null +++ b/src/renderer/src/utils/request/instance.ts @@ -0,0 +1,58 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-03-12 15:12:58 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-07-08 17:52:46 + * @FilePath: \5G-Loading-Bay-Web\src\utils\request\instance.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +import Request from './index' +import { config } from '@/config' +import { ElLoading } from 'element-plus' + +// 根据环境显示不同提示 +const envTagMap = { + development: '【开发环境】', + // staging: '【测试环境】', + production: '【生产环境】' +} + +const request = new Request({ + baseURL: config.baseURL, + timeout: config.timeout, + interceptors: { + requestInterceptor: (config) => { + // 开发环境显示环境标识 + // if (import.meta.env.DEV) { + // console.log(`${envTagMap[config.env]} 请求路径: ${config.url}`) + // } + + // 全局 loading 配置 + if (config.showLoading) { + const loading = ElLoading.service({ + lock: true, + text: '加载中...', + background: 'rgba(0, 0, 0, 0.7)' + }) + config.loadingInstance = loading + } + return config + }, + + responseInterceptor: (res) => { + // 关闭 loading + res.config.loadingInstance?.close() + + // 测试环境记录详细日志 + // if (config.env === 'staging') { + // console.groupCollapsed(`[${res.config.method}] ${res.config.url}`) + // console.log('请求参数:', res.config.data) + // console.log('响应数据:', res.data) + // console.groupEnd() + // } + return res + } + } +}) + +export default request diff --git a/src/renderer/src/utils/request/type.ts b/src/renderer/src/utils/request/type.ts new file mode 100644 index 0000000..c1f3d82 --- /dev/null +++ b/src/renderer/src/utils/request/type.ts @@ -0,0 +1,13 @@ +import type { AxiosRequestConfig, AxiosResponse } from 'axios' + +export interface RequestInterceptors { + requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig + requestInterceptorCatch?: (error: any) => any + responseInterceptor?: (res: T) => T + responseInterceptorCatch?: (error: any) => any +} + +export interface RequestConfig extends AxiosRequestConfig { + interceptors?: RequestInterceptors + showLoading?: boolean +} \ No newline at end of file diff --git a/src/renderer/src/views/Design/LogManagement/logList.scss b/src/renderer/src/views/Design/LogManagement/logList.scss index 76fa258..e837f34 100644 --- a/src/renderer/src/views/Design/LogManagement/logList.scss +++ b/src/renderer/src/views/Design/LogManagement/logList.scss @@ -1,4 +1,6 @@ .logList-dialog{ - + .logList-table{ + height: 450px; + } } \ No newline at end of file diff --git a/src/renderer/src/views/Design/LogManagement/logList.vue b/src/renderer/src/views/Design/LogManagement/logList.vue index cb569dd..e494cf4 100644 --- a/src/renderer/src/views/Design/LogManagement/logList.vue +++ b/src/renderer/src/views/Design/LogManagement/logList.vue @@ -1,37 +1,44 @@ + @@ -39,6 +46,8 @@