From 32686ad80709940efc3211daf6a2c4513550a79c Mon Sep 17 00:00:00 2001 From: "Ray.Hao" <1490493387@qq.com> Date: Sat, 24 May 2025 07:35:46 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=A1=B9=E7=9B=AE=E9=87=8D?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 6 +- eslint.config.ts | 151 ++-- src/api/auth.api.ts | 2 +- src/api/codegen.api.ts | 4 +- src/api/file.api.ts | 4 +- src/api/system/config.api.ts | 4 +- src/api/system/dept.api.ts | 4 +- src/api/system/dict.api.ts | 8 +- src/api/system/menu.api.ts | 6 +- src/api/system/notice.api.ts | 4 +- src/api/system/role.api.ts | 6 +- src/api/system/user.api.ts | 20 +- src/components/AppLink/index.vue | 2 +- src/components/CURD/PageContent.vue | 9 +- src/components/CURD/PageSearch.vue | 4 +- src/components/CURD/types.ts | 2 +- src/components/CURD/usePage.ts | 8 +- src/components/TableSelect/index.vue | 2 +- src/components/Upload/FileUpload.vue | 6 +- src/composables/useDictSync.ts | 52 +- src/composables/useOnlineCount.ts | 98 ++- src/composables/useStomp.ts | 146 ++-- src/lang/index.ts | 2 +- .../NavBar/components/NavbarActions.vue | 1 - src/layouts/components/Settings/index.vue | 2 +- src/layouts/components/TagsView/index.vue | 643 +++++++++--------- src/plugins/permission.ts | 183 +++-- src/plugins/websocket.ts | 124 +++- src/store/modules/permission.store.ts | 10 + src/store/modules/settings.store.ts | 2 +- src/store/modules/user.store.ts | 11 + src/types/global.d.ts | 2 +- src/utils/request.ts | 174 +++-- src/views/codegen/index.vue | 2 +- src/views/demo/curd/config/content.ts | 4 +- src/views/demo/curd/config/edit.ts | 2 +- src/views/demo/curd/config/options.ts | 6 +- src/views/demo/curd/config2/add.ts | 2 +- src/views/demo/curd/config2/content.ts | 2 +- src/views/demo/curd/config2/edit.ts | 2 +- src/views/demo/curd/config2/search.ts | 2 +- src/views/demo/dictionary.vue | 12 +- src/views/demo/icon-selector.vue | 14 +- src/views/demo/signature.vue | 44 +- src/views/demo/table-select/config/select.ts | 2 +- src/views/demo/table-select/index.vue | 46 +- src/views/demo/text-scroll.vue | 2 +- src/views/demo/wang-editor.vue | 12 +- src/views/login/components/Login.vue | 12 +- tsconfig.json | 2 +- vite.config.ts | 27 +- 51 files changed, 1201 insertions(+), 696 deletions(-) diff --git a/.env.development b/.env.development index 55b854a1..782874ea 100644 --- a/.env.development +++ b/.env.development @@ -5,11 +5,11 @@ VITE_APP_PORT=3000 VITE_APP_BASE_API=/dev-api # 接口地址 -VITE_APP_API_URL=https://api.youlai.tech # 线上 -# VITE_APP_API_URL=http://localhost:8989 # 本地 +# VITE_APP_API_URL=https://api.youlai.tech # 线上 +VITE_APP_API_URL=http://localhost:8989 # 本地 # WebSocket 端点(不配置则关闭),线上 ws://api.youlai.tech/ws ,本地 ws://localhost:8989/ws -VITE_APP_WS_ENDPOINT= +VITE_APP_WS_ENDPOINT=ws://localhost:8989/ws # 启用 Mock 服务 VITE_MOCK_DEV_SERVER=false diff --git a/eslint.config.ts b/eslint.config.ts index 319b85fe..9ad5e1f1 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -2,8 +2,7 @@ import eslint from "@eslint/js"; import pluginVue from "eslint-plugin-vue"; -import pluginTypeScript from "@typescript-eslint/eslint-plugin"; -import parserTypeScript from "@typescript-eslint/parser"; +import * as typescriptEslint from "typescript-eslint"; import vueParser from "vue-eslint-parser"; import globals from "globals"; import configPrettier from "eslint-config-prettier"; @@ -52,73 +51,108 @@ const elementPlusComponents = { }; export default [ + // 忽略文件配置 + { + ignores: [ + "**/node_modules/**", + "**/dist/**", + "**/build/**", + "**/.nuxt/**", + "**/.output/**", + "**/coverage/**", + "**/*.min.*", + "**/auto-imports.d.ts", + "**/components.d.ts", + ], + }, + + // 基础 JavaScript 配置 + eslint.configs.recommended, + + // Vue 推荐配置 + ...pluginVue.configs["flat/recommended"], + + // TypeScript 推荐配置 + ...typescriptEslint.configs.recommended, + // 全局配置 { // 指定要检查的文件 - files: ["**/*.js", "**/*.ts", "**/*.vue"], - ignores: ["node_modules/**", "dist/**", "build/**"], + files: ["**/*.{js,mjs,cjs,ts,mts,cts,vue}"], languageOptions: { - ecmaVersion: 2022, + ecmaVersion: "latest", sourceType: "module", globals: { ...globals.browser, // 浏览器环境全局变量 ...globals.node, // Node.js 环境全局变量 + ...globals.es2022, // ES2022 全局对象 ...autoImportGlobals, // 自动导入的 API 函数 ...elementPlusComponents, // Element Plus 组件 // 全局类型定义,解决 TypeScript 中定义但 ESLint 不识别的问题 PageQuery: "readonly", PageResult: "readonly", OptionType: "readonly", - ResponseData: "readonly", + ApiResponse: "readonly", ExcelResult: "readonly", TagView: "readonly", AppSettings: "readonly", __APP_INFO__: "readonly", }, - parser: parserTypeScript, - parserOptions: { - sourceType: "module", - }, + }, + plugins: { + vue: pluginVue, + "@typescript-eslint": typescriptEslint.plugin, }, rules: { - // 全局规则 - "no-unused-vars": [ - "error", - { - vars: "all", - args: "after-used", - ignoreRestSiblings: true, - argsIgnorePattern: "^_", // 忽略以下划线开头的参数 - varsIgnorePattern: "^[A-Z][A-Z0-9_]*$", // 忽略全大写的常量/枚举 - }, - ], - // 禁用未定义变量检查,TypeScript 已处理类型检查 + // 基础规则 + "no-console": process.env.NODE_ENV === "production" ? "warn" : "off", + "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", + + // ES6+ 规则 + "prefer-const": "error", + "no-var": "error", + "object-shorthand": "error", + + // 最佳实践 + eqeqeq: ["error", "always", { null: "ignore" }], + "no-multi-spaces": "error", + "no-multiple-empty-lines": ["error", { max: 1, maxBOF: 0, maxEOF: 0 }], + + // 禁用与 TypeScript 冲突的规则 + "no-unused-vars": "off", "no-undef": "off", + "no-redeclare": "off", }, }, - // 基础 JavaScript 配置 - eslint.configs.recommended, - - // Vue 配置 + // Vue 文件特定配置 { files: ["**/*.vue"], - plugins: { - vue: pluginVue, - }, languageOptions: { parser: vueParser, parserOptions: { - ecmaVersion: 2022, + ecmaVersion: "latest", sourceType: "module", - parser: parserTypeScript, + parser: typescriptEslint.parser, + extraFileExtensions: [".vue"], }, }, - processor: pluginVue.processors[".vue"], rules: { + // Vue 规则 "vue/multi-word-component-names": "off", "vue/no-v-html": "off", "vue/require-default-prop": "off", + "vue/require-explicit-emits": "error", + "vue/no-unused-vars": "error", + "vue/no-mutating-props": "error", + "vue/attribute-hyphenation": ["error", "always"], + "vue/v-on-event-hyphenation": ["error", "always"], + "vue/block-order": [ + "error", + { + order: ["template", "script", "style"], + }, + ], "vue/html-self-closing": [ "error", { @@ -127,20 +161,27 @@ export default [ normal: "never", component: "always", }, + svg: "always", + math: "always", }, ], - "vue/no-unused-vars": "off", + "vue/component-name-in-template-casing": ["error", "PascalCase"], }, }, - // TypeScript 配置 + // TypeScript 文件特定配置 { - files: ["**/*.ts", "**/*.tsx", "**/*.vue"], - plugins: { - "@typescript-eslint": pluginTypeScript, + files: ["**/*.{ts,tsx,mts,cts}"], + languageOptions: { + parser: typescriptEslint.parser, + parserOptions: { + project: true, + tsconfigRootDir: import.meta.dirname, + }, }, rules: { - "@typescript-eslint/no-explicit-any": "off", + // TypeScript 规则 + "@typescript-eslint/no-explicit-any": "warn", "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-empty-object-type": "off", "@typescript-eslint/ban-ts-comment": "off", @@ -155,6 +196,32 @@ export default [ varsIgnorePattern: "^[A-Z][A-Z0-9_]*$", // 忽略全大写的常量/枚举 }, ], + "@typescript-eslint/consistent-type-imports": [ + "error", + { + prefer: "type-imports", + fixStyle: "inline-type-imports", + }, + ], + "@typescript-eslint/no-import-type-side-effects": "error", + }, + }, + + // .d.ts 文件配置 + { + files: ["**/*.d.ts"], + rules: { + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-unused-vars": "off", + }, + }, + + // 测试文件配置 + { + files: ["**/__tests__/**", "**/*.{test,spec}.{js,ts,vue}"], + rules: { + "no-console": "off", + "@typescript-eslint/no-explicit-any": "off", }, }, @@ -167,10 +234,6 @@ export default [ }, }, - // Prettier 集成 - { - rules: { - ...configPrettier.rules, - }, - }, + // Prettier 集成(必须放在最后) + configPrettier, ]; diff --git a/src/api/auth.api.ts b/src/api/auth.api.ts index e27d85e0..772e9ef3 100644 --- a/src/api/auth.api.ts +++ b/src/api/auth.api.ts @@ -25,7 +25,7 @@ const AuthAPI = { return request({ url: `${AUTH_BASE_URL}/refresh-token`, method: "post", - params: { refreshToken: refreshToken }, + params: { refreshToken }, headers: { Authorization: "no-auth", }, diff --git a/src/api/codegen.api.ts b/src/api/codegen.api.ts index b3b613fc..cddee813 100644 --- a/src/api/codegen.api.ts +++ b/src/api/codegen.api.ts @@ -8,7 +8,7 @@ const GeneratorAPI = { return request>({ url: `${GENERATOR_BASE_URL}/table/page`, method: "get", - params: params, + params, }); }, @@ -25,7 +25,7 @@ const GeneratorAPI = { return request({ url: `${GENERATOR_BASE_URL}/${tableName}/config`, method: "post", - data: data, + data, }); }, diff --git a/src/api/file.api.ts b/src/api/file.api.ts index 0b109772..504d916e 100644 --- a/src/api/file.api.ts +++ b/src/api/file.api.ts @@ -42,7 +42,7 @@ const FileAPI = { return request({ url: "/api/v1/files", method: "delete", - params: { filePath: filePath }, + params: { filePath }, }); }, @@ -53,7 +53,7 @@ const FileAPI = { */ download(url: string, fileName?: string) { return request({ - url: url, + url, method: "get", responseType: "blob", }).then((res) => { diff --git a/src/api/system/config.api.ts b/src/api/system/config.api.ts index f280ee1c..42ba7672 100644 --- a/src/api/system/config.api.ts +++ b/src/api/system/config.api.ts @@ -25,7 +25,7 @@ const ConfigAPI = { return request({ url: `${CONFIG_BASE_URL}`, method: "post", - data: data, + data, }); }, @@ -34,7 +34,7 @@ const ConfigAPI = { return request({ url: `${CONFIG_BASE_URL}/${id}`, method: "put", - data: data, + data, }); }, diff --git a/src/api/system/dept.api.ts b/src/api/system/dept.api.ts index 200065d3..6182a555 100644 --- a/src/api/system/dept.api.ts +++ b/src/api/system/dept.api.ts @@ -48,7 +48,7 @@ const DeptAPI = { return request({ url: `${DEPT_BASE_URL}`, method: "post", - data: data, + data, }); }, @@ -63,7 +63,7 @@ const DeptAPI = { return request({ url: `${DEPT_BASE_URL}/${id}`, method: "put", - data: data, + data, }); }, diff --git a/src/api/system/dict.api.ts b/src/api/system/dict.api.ts index b148e0a4..0f8a4fd5 100644 --- a/src/api/system/dict.api.ts +++ b/src/api/system/dict.api.ts @@ -55,7 +55,7 @@ const DictAPI = { return request({ url: `${DICT_BASE_URL}`, method: "post", - data: data, + data, }); }, @@ -69,7 +69,7 @@ const DictAPI = { return request({ url: `${DICT_BASE_URL}/${id}`, method: "put", - data: data, + data, }); }, @@ -119,7 +119,7 @@ const DictAPI = { return request({ url: `${DICT_BASE_URL}/${dictCode}/items`, method: "post", - data: data, + data, }); }, @@ -143,7 +143,7 @@ const DictAPI = { return request({ url: `${DICT_BASE_URL}/${dictCode}/items/${id}`, method: "put", - data: data, + data, }); }, diff --git a/src/api/system/menu.api.ts b/src/api/system/menu.api.ts index 06c11ed2..45f95b3c 100644 --- a/src/api/system/menu.api.ts +++ b/src/api/system/menu.api.ts @@ -40,7 +40,7 @@ const MenuAPI = { return request({ url: `${MENU_BASE_URL}/options`, method: "get", - params: { onlyParent: onlyParent }, + params: { onlyParent }, }); }, @@ -66,7 +66,7 @@ const MenuAPI = { return request({ url: `${MENU_BASE_URL}`, method: "post", - data: data, + data, }); }, @@ -81,7 +81,7 @@ const MenuAPI = { return request({ url: `${MENU_BASE_URL}/${id}`, method: "put", - data: data, + data, }); }, diff --git a/src/api/system/notice.api.ts b/src/api/system/notice.api.ts index b5e65e79..471c5e7b 100644 --- a/src/api/system/notice.api.ts +++ b/src/api/system/notice.api.ts @@ -35,7 +35,7 @@ const NoticeAPI = { return request({ url: `${NOTICE_BASE_URL}`, method: "post", - data: data, + data, }); }, @@ -49,7 +49,7 @@ const NoticeAPI = { return request({ url: `${NOTICE_BASE_URL}/${id}`, method: "put", - data: data, + data, }); }, diff --git a/src/api/system/role.api.ts b/src/api/system/role.api.ts index be680229..6a822efb 100644 --- a/src/api/system/role.api.ts +++ b/src/api/system/role.api.ts @@ -42,7 +42,7 @@ const RoleAPI = { return request({ url: `${ROLE_BASE_URL}/${roleId}/menus`, method: "put", - data: data, + data, }); }, @@ -64,7 +64,7 @@ const RoleAPI = { return request({ url: `${ROLE_BASE_URL}`, method: "post", - data: data, + data, }); }, @@ -78,7 +78,7 @@ const RoleAPI = { return request({ url: `${ROLE_BASE_URL}/${id}`, method: "put", - data: data, + data, }); }, diff --git a/src/api/system/user.api.ts b/src/api/system/user.api.ts index 1d16fd1c..2a26b34c 100644 --- a/src/api/system/user.api.ts +++ b/src/api/system/user.api.ts @@ -50,7 +50,7 @@ const UserAPI = { return request({ url: `${USER_BASE_URL}`, method: "post", - data: data, + data, }); }, @@ -64,7 +64,7 @@ const UserAPI = { return request({ url: `${USER_BASE_URL}/${id}`, method: "put", - data: data, + data, }); }, @@ -78,7 +78,7 @@ const UserAPI = { return request({ url: `${USER_BASE_URL}/${id}/password/reset`, method: "put", - params: { password: password }, + params: { password }, }); }, @@ -129,7 +129,7 @@ const UserAPI = { return request({ url: `${USER_BASE_URL}/import`, method: "post", - params: { deptId: deptId }, + params: { deptId }, data: formData, headers: { "Content-Type": "multipart/form-data", @@ -150,7 +150,7 @@ const UserAPI = { return request({ url: `${USER_BASE_URL}/profile`, method: "put", - data: data, + data, }); }, @@ -159,7 +159,7 @@ const UserAPI = { return request({ url: `${USER_BASE_URL}/password`, method: "put", - data: data, + data, }); }, @@ -168,7 +168,7 @@ const UserAPI = { return request({ url: `${USER_BASE_URL}/mobile/code`, method: "post", - params: { mobile: mobile }, + params: { mobile }, }); }, @@ -177,7 +177,7 @@ const UserAPI = { return request({ url: `${USER_BASE_URL}/mobile`, method: "put", - data: data, + data, }); }, @@ -186,7 +186,7 @@ const UserAPI = { return request({ url: `${USER_BASE_URL}/email/code`, method: "post", - params: { email: email }, + params: { email }, }); }, @@ -195,7 +195,7 @@ const UserAPI = { return request({ url: `${USER_BASE_URL}/email`, method: "put", - data: data, + data, }); }, diff --git a/src/components/AppLink/index.vue b/src/components/AppLink/index.vue index b97aacfe..b3b8f172 100644 --- a/src/components/AppLink/index.vue +++ b/src/components/AppLink/index.vue @@ -33,6 +33,6 @@ const linkProps = (to: any) => { rel: "noopener noreferrer", }; } - return { to: to }; + return { to }; }; diff --git a/src/components/CURD/PageContent.vue b/src/components/CURD/PageContent.vue index ace91a2a..cddab0a8 100644 --- a/src/components/CURD/PageContent.vue +++ b/src/components/CURD/PageContent.vue @@ -8,9 +8,10 @@