diff --git a/.env.production b/.env.production index 135c28322..3165da1b5 100644 --- a/.env.production +++ b/.env.production @@ -1,6 +1,6 @@ -VITE_VISUALIZER=true +VITE_VISUALIZER=false -VITE_COMPRESS=true +VITE_COMPRESS=false # gzip | brotliCompress | deflate | deflateRaw VITE_COMPRESS_TYPE=gzip diff --git a/.eslintrc.js b/.eslintrc.js index 04227e0cd..70de12e5b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -55,12 +55,11 @@ module.exports = { group: 'external', position: 'before' }, - // ui framework, such as "naive-ui" - // { - // pattern: 'naive-ui', - // group: 'external', - // position: 'before' - // }, + { + pattern: 'naive-ui', + group: 'external', + position: 'before' + }, { pattern: '@/config', group: 'internal', @@ -142,13 +141,7 @@ module.exports = { position: 'before' } ], - pathGroupsExcludedImportTypes: [ - 'vue', - 'vue-router', - 'vuex', - 'pinia' - // 'naive-ui' - ] + pathGroupsExcludedImportTypes: ['vue', 'vue-router', 'vuex', 'pinia', 'naive-ui'] } ], 'import/no-unresolved': 'off', @@ -171,17 +164,7 @@ module.exports = { ignores: ['index'] } ], - '@typescript-eslint/ban-types': [ - 'error', - { - types: { - '{}': { - message: 'Use object instead', - fixWith: 'object' - } - } - } - ], + '@typescript-eslint/ban-types': 'off', '@typescript-eslint/no-empty-interface': [ 'error', { @@ -192,17 +175,12 @@ module.exports = { '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/no-shadow': 'error', '@typescript-eslint/no-unused-vars': ['warn', { ignoreRestSiblings: true, varsIgnorePattern: '^_' }], - '@typescript-eslint/no-use-before-define': ['error', { classes: true, functions: false, typedefs: false }] + '@typescript-eslint/no-use-before-define': ['warn', { classes: true, functions: false, typedefs: false }] }, overrides: [ { files: ['*.vue'], - parser: 'vue-eslint-parser', - parserOptions: { - parser: '@typescript-eslint/parser' - }, rules: { - 'no-unused-vars': 'off', 'no-undef': 'off' } }, diff --git a/.vscode/settings.json b/.vscode/settings.json index 7520e13cd..49e3eb2cb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -33,7 +33,6 @@ "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, - "javascript.updateImportsOnFileMove.enabled": "always", "[javascriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -72,5 +71,6 @@ "business": "core", "request": "api", "adapter": "middleware" - } + }, + "unocss.root": "src" } diff --git a/mock/api/auth.ts b/mock/api/auth.ts index 941c78e6c..8435b7476 100644 --- a/mock/api/auth.ts +++ b/mock/api/auth.ts @@ -1,9 +1,10 @@ import type { MockMethod } from 'vite-plugin-mock'; +import { userModel } from '../model'; -const token: ApiAuth.Token = { - token: '__TEMP_TOKEN__', - refreshToken: '__TEMP_REFRESH_TOKEN__' -}; +/** 参数错误的状态码 */ +const ERROR_PARAM_CODE = 10000; + +const ERROR_PARAM_MSG = '参数校验失败!'; const apis: MockMethod[] = [ // 获取验证码 @@ -18,73 +19,107 @@ const apis: MockMethod[] = [ }; } }, - // 密码登录 - { - url: '/mock/loginByPwd', - method: 'post', - response: (): Service.MockServiceResult => { - return { - code: 200, - message: 'ok', - data: token - }; - } - }, - // 验证码登录 + // 用户+密码 登录 { - url: '/mock/loginByCode', + url: '/mock/login', method: 'post', - response: (): Service.MockServiceResult => { + response: (options: Service.MockOption): Service.MockServiceResult => { + const { userName = undefined, password = undefined } = options.body; + + if (!userName || !password) { + return { + code: ERROR_PARAM_CODE, + message: ERROR_PARAM_MSG, + data: null + }; + } + + const findItem = userModel.find(item => item.userName === userName && item.password === password); + + if (findItem) { + return { + code: 200, + message: 'ok', + data: { + token: findItem.token, + refreshToken: findItem.refreshToken + } + }; + } return { - code: 200, - message: 'ok', - data: token + code: 1000, + message: '用户名或密码错误!', + data: null }; } }, - // 获取用户信息(请求头携带token) + // 获取用户信息(请求头携带token, 根据token获取用户信息) { url: '/mock/getUserInfo', method: 'get', - response: (): Service.MockServiceResult => { - return { - code: 200, - message: 'ok', - data: { - userId: '0', - userName: 'Soybean', - userPhone: '15170283876', - userRole: 'super' - } - }; - } - }, - { - url: '/mock/testToken', - method: 'post', - response: (option: Service.MockOption): Service.MockServiceResult => { - if (option.headers?.authorization !== token.token) { + response: (options: Service.MockOption): Service.MockServiceResult => { + // 这里的mock插件得到的字段是authorization, 前端传递的是Authorization字段 + const { authorization = '' } = options.headers; + const REFRESH_TOKEN_CODE = 66666; + + if (!authorization) { return { - code: 66666, - message: 'token 失效', + code: REFRESH_TOKEN_CODE, + message: '用户已失效或不存在!', data: null }; } + const userInfo: Auth.UserInfo = { + userId: '', + userName: '', + userRole: 'user' + }; + const isInUser = userModel.some(item => { + const flag = item.token === authorization; + if (flag) { + const { userId: itemUserId, userName, userRole } = item; + Object.assign(userInfo, { userId: itemUserId, userName, userRole }); + } + return flag; + }); + + if (isInUser) { + return { + code: 200, + message: 'ok', + data: userInfo + }; + } + return { - code: 200, - message: 'ok', - data: true + code: REFRESH_TOKEN_CODE, + message: '用户信息异常!', + data: null }; } }, { url: '/mock/updateToken', method: 'post', - response: (): Service.MockServiceResult => { + response: (options: Service.MockOption): Service.MockServiceResult => { + const { refreshToken = '' } = options.body; + + const findItem = userModel.find(item => item.refreshToken === refreshToken); + + if (findItem) { + return { + code: 200, + message: 'ok', + data: { + token: findItem.token, + refreshToken: findItem.refreshToken + } + }; + } return { - code: 200, - message: 'ok', - data: token + code: 3000, + message: '用户已失效或不存在!', + data: null }; } } diff --git a/mock/api/route.ts b/mock/api/route.ts index d6e3f66f4..c89f4f686 100644 --- a/mock/api/route.ts +++ b/mock/api/route.ts @@ -1,403 +1,26 @@ import type { MockMethod } from 'vite-plugin-mock'; -import { filterAuthRoutesByUserPermission } from '../utils'; +import { userModel, routeModel } from '../model'; -const routes: AuthRoute.Route[] = [ - { - name: 'dashboard', - path: '/dashboard', - component: 'basic', - children: [ - { - name: 'dashboard_analysis', - path: '/dashboard/analysis', - component: 'self', - meta: { - title: '分析页', - requiresAuth: true, - icon: 'icon-park-outline:analysis' - } - }, - { - name: 'dashboard_workbench', - path: '/dashboard/workbench', - component: 'self', - meta: { - title: '工作台', - requiresAuth: true, - permissions: ['super', 'admin'], - icon: 'icon-park-outline:workbench' - } - } - ], - meta: { - title: '仪表盘', - icon: 'carbon:dashboard', - order: 1 - } - }, - { - name: 'document', - path: '/document', - component: 'basic', - children: [ - { - name: 'document_vue', - path: '/document/vue', - component: 'self', - meta: { - title: 'vue文档', - requiresAuth: true, - icon: 'mdi:vuejs' - } - }, - { - name: 'document_vue-new', - path: '/document/vue-new', - component: 'self', - meta: { - title: 'vue文档(新版)', - requiresAuth: true, - icon: 'mdi:vuejs' - } - }, - { - name: 'document_vite', - path: '/document/vite', - component: 'self', - meta: { - title: 'vite文档', - requiresAuth: true, - icon: 'simple-icons:vite' - } - }, - { - name: 'document_project', - path: '/document/project', - meta: { - title: '项目文档(外链)', - requiresAuth: true, - icon: 'mdi:file-link-outline', - href: 'https://docs.soybean.pro/' - } - } - ], - meta: { - title: '文档', - icon: 'carbon:document', - order: 2 - } - }, - { - name: 'component', - path: '/component', - component: 'basic', - children: [ - { - name: 'component_button', - path: '/component/button', - component: 'self', - meta: { - title: '按钮', - requiresAuth: true, - icon: 'ic:baseline-radio-button-checked' - } - }, - { - name: 'component_card', - path: '/component/card', - component: 'self', - meta: { - title: '卡片', - requiresAuth: true, - icon: 'mdi:card-outline' - } - }, - { - name: 'component_table', - path: '/component/table', - component: 'self', - meta: { - title: '表格', - requiresAuth: true, - icon: 'mdi:table-large' - } - } - ], - meta: { - title: '组件示例', - icon: 'fluent:app-store-24-regular', - order: 3 - } - }, - { - name: 'plugin', - path: '/plugin', - component: 'basic', - children: [ - { - name: 'plugin_map', - path: '/plugin/map', - component: 'self', - meta: { - title: '地图', - requiresAuth: true, - icon: 'mdi:map' - } - }, - { - name: 'plugin_video', - path: '/plugin/video', - component: 'self', - meta: { - title: '视频', - requiresAuth: true, - icon: 'mdi:video' - } - }, - { - name: 'plugin_editor', - path: '/plugin/editor', - component: 'multi', - children: [ - { - name: 'plugin_editor_quill', - path: '/plugin/editor/quill', - component: 'self', - meta: { - title: '富文本编辑器', - requiresAuth: true, - icon: 'mdi:file-document-edit-outline' - } - }, - { - name: 'plugin_editor_markdown', - path: '/plugin/editor/markdown', - component: 'self', - meta: { - title: 'markdown编辑器', - requiresAuth: true, - icon: 'ri:markdown-line' - } - } - ], - meta: { - title: '编辑器', - icon: 'icon-park-outline:editor' - } - }, - { - name: 'plugin_swiper', - path: '/plugin/swiper', - component: 'self', - meta: { - title: 'Swiper插件', - requiresAuth: true, - icon: 'simple-icons:swiper' - } - }, - { - name: 'plugin_copy', - path: '/plugin/copy', - component: 'self', - meta: { - title: '剪贴板', - requiresAuth: true, - icon: 'mdi:clipboard-outline' - } - }, - { - name: 'plugin_icon', - path: '/plugin/icon', - component: 'self', - meta: { - title: '图标', - requiresAuth: true, - icon: 'ic:baseline-insert-emoticon' - } - }, - { - name: 'plugin_print', - path: '/plugin/print', - component: 'self', - meta: { - title: '打印', - requiresAuth: true, - icon: 'ic:baseline-local-printshop' - } - } - ], - meta: { - title: '插件示例', - icon: 'clarity:plugin-line', - order: 4 - } - }, - { - name: 'auth-demo', - path: '/auth-demo', - component: 'basic', - children: [ - { - name: 'auth-demo_permission', - path: '/auth-demo/permission', - component: 'self', - meta: { - title: '权限切换', - requiresAuth: true, - icon: 'ic:round-construction' - } - }, - { - name: 'auth-demo_super', - path: '/auth-demo/super', - component: 'self', - meta: { - title: '超级管理员可见', - requiresAuth: true, - permissions: ['super'], - icon: 'ic:round-supervisor-account' - } - } - ], - meta: { - title: '权限示例', - icon: 'ic:baseline-security', - order: 5 - } - }, - { - name: 'exception', - path: '/exception', - component: 'basic', - children: [ - { - name: 'exception_403', - path: '/exception/403', - component: 'self', - meta: { - title: '异常页403', - requiresAuth: true, - icon: 'ic:baseline-block' - } - }, - { - name: 'exception_404', - path: '/exception/404', - component: 'self', - meta: { - title: '异常页404', - requiresAuth: true, - icon: 'ic:baseline-web-asset-off' - } - }, - { - name: 'exception_500', - path: '/exception/500', - component: 'self', - meta: { - title: '异常页500', - requiresAuth: true, - icon: 'ic:baseline-wifi-off' - } - } - ], - meta: { - title: '异常页', - icon: 'ant-design:exception-outlined', - order: 6 - } - }, - { - name: 'multi-menu', - path: '/multi-menu', - component: 'basic', - children: [ - { - name: 'multi-menu_first', - path: '/multi-menu/first', - component: 'multi', - children: [ - { - name: 'multi-menu_first_second', - path: '/multi-menu/first/second', - component: 'self', - meta: { - title: '二级菜单', - requiresAuth: true, - icon: 'ic:outline-menu' - } - }, - { - name: 'multi-menu_first_second-new', - path: '/multi-menu/first/second-new', - component: 'multi', - children: [ - { - name: 'multi-menu_first_second-new_third', - path: '/multi-menu/first/second-new/third', - component: 'self', - meta: { - title: '三级菜单', - requiresAuth: true, - icon: 'ic:outline-menu' - } - } - ], - meta: { - title: '二级菜单(有子菜单)', - icon: 'ic:outline-menu' - } - } - ], - meta: { - title: '一级菜单', - icon: 'ic:outline-menu' - } - } - ], - meta: { - title: '多级菜单', - icon: 'carbon:menu', - order: 7 - } - }, +const apis: MockMethod[] = [ { - name: 'about', - path: '/about', - component: 'self', - meta: { - title: '关于', - requiresAuth: true, - singleLayout: 'basic', - permissions: ['super', 'admin', 'user'], - icon: 'fluent:book-information-24-regular', - order: 8 - } - } -]; - -function dataMiddleware(data: AuthRoute.Route[]): ApiRoute.Route { - const routeHomeName: AuthRoute.RouteKey = 'dashboard_analysis'; + url: '/mock/getUserRoutes', + method: 'post', + response: (options: Service.MockOption): Service.MockServiceResult => { + const { userId = undefined } = options.body; - data.sort((next, pre) => Number(next.meta?.order) - Number(pre.meta?.order)); + const routeHomeName: AuthRoute.RouteKey = 'dashboard_analysis'; - const filters = filterAuthRoutesByUserPermission(data, 'admin'); + const role = userModel.find(item => item.userId === userId)?.userRole || 'user'; - return { - routes: filters, - home: routeHomeName - }; -} + const filterRoutes = routeModel[role]; -const apis: MockMethod[] = [ - { - url: '/mock/getUserRoutes', - method: 'post', - response: (): Service.MockServiceResult => { return { code: 200, message: 'ok', - data: dataMiddleware(routes) + data: { + routes: filterRoutes, + home: routeHomeName + } }; } } diff --git a/mock/model/auth.ts b/mock/model/auth.ts new file mode 100644 index 000000000..eb72554a3 --- /dev/null +++ b/mock/model/auth.ts @@ -0,0 +1,40 @@ +interface UserModel extends Auth.UserInfo { + token: string; + refreshToken: string; + password: string; +} + +export const userModel: UserModel[] = [ + { + token: '__TOKEN_SOYBEAN__', + refreshToken: '__REFRESH_TOKEN_SOYBEAN__', + userId: '0', + userName: 'Soybean', + userRole: 'super', + password: 'soybean123' + }, + { + token: '__TOKEN_SUPER__', + refreshToken: '__REFRESH_TOKEN_SUPER__', + userId: '1', + userName: 'Super', + userRole: 'super', + password: 'super123' + }, + { + token: '__TOKEN_ADMIN__', + refreshToken: '__REFRESH_TOKEN_ADMIN__', + userId: '2', + userName: 'Admin', + userRole: 'admin', + password: 'admin123' + }, + { + token: '__TOKEN_USER01__', + refreshToken: '__REFRESH_TOKEN_USER01__', + userId: '3', + userName: 'User01', + userRole: 'user', + password: 'user01123' + } +]; diff --git a/mock/model/index.ts b/mock/model/index.ts new file mode 100644 index 000000000..89f4e5819 --- /dev/null +++ b/mock/model/index.ts @@ -0,0 +1,2 @@ +export * from './auth'; +export * from './route'; diff --git a/mock/model/route.ts b/mock/model/route.ts index 74624b317..1d0b2809f 100644 --- a/mock/model/route.ts +++ b/mock/model/route.ts @@ -1,4 +1,4 @@ -const routes: Record = { +export const routeModel: Record = { super: [ { name: 'dashboard', @@ -844,5 +844,3 @@ const routes: Record = { } ] }; - -export default routes; diff --git a/mock/model/user.ts b/mock/model/user.ts deleted file mode 100644 index 384311c77..000000000 --- a/mock/model/user.ts +++ /dev/null @@ -1,35 +0,0 @@ -interface ModelUser { - userId: string; - userName: string; - password: string; - role: Auth.RoleType; -} - -const users: ModelUser[] = [ - { - userId: '0', - userName: 'Soybean', - password: 'soybean', - role: 'super' - }, - { - userId: '1', - userName: 'Super', - password: 'super', - role: 'super' - }, - { - userId: '2', - userName: 'Admin', - password: 'admin', - role: 'admin' - }, - { - userId: '3', - userName: 'User01', - password: 'user01', - role: 'user' - } -]; - -export default users; diff --git a/mock/utils/index.ts b/mock/utils/index.ts deleted file mode 100644 index 52943addd..000000000 --- a/mock/utils/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * 根据用户权限过滤路由 - * @param routes - 权限路由 - * @param permission - 权限 - */ -export function filterAuthRoutesByUserPermission(routes: AuthRoute.Route[], permission: Auth.RoleType) { - return routes.map(route => filterAuthRouteByUserPermission(route, permission)).flat(1); -} - -/** - * 根据用户权限过滤单个路由 - * @param route - 单个权限路由 - * @param permission - 权限 - */ -function filterAuthRouteByUserPermission(route: AuthRoute.Route, permission: Auth.RoleType): AuthRoute.Route[] { - const hasPermission = - !route.meta.permissions || permission === 'super' || route.meta.permissions.includes(permission); - - if (route.children) { - const filterChildren = route.children.map(item => filterAuthRouteByUserPermission(item, permission)).flat(1); - Object.assign(route, { children: filterChildren }); - } - return hasPermission ? [route] : []; -} diff --git a/package.json b/package.json index 3e537d451..9d77bf892 100644 --- a/package.json +++ b/package.json @@ -52,8 +52,8 @@ }, "devDependencies": { "@amap/amap-jsapi-types": "^0.0.8", - "@commitlint/cli": "^16.2.3", - "@commitlint/config-conventional": "^16.2.1", + "@commitlint/cli": "^16.2.4", + "@commitlint/config-conventional": "^16.2.4", "@iconify/json": "^2.1.33", "@iconify/vue": "^3.2.1", "@types/bmapgl": "^0.0.5", @@ -86,7 +86,7 @@ "rollup-plugin-visualizer": "^5.6.0", "sass": "^1.51.0", "typescript": "^4.6.3", - "unocss": "^0.31.17", + "unocss": "^0.32.1", "unplugin-icons": "^0.14.1", "unplugin-vue-components": "0.19.3", "unplugin-vue-define-options": "^0.6.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a1af35fe3..1dec26336 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,8 +4,8 @@ specifiers: '@amap/amap-jsapi-types': ^0.0.8 '@antv/g2plot': ^2.4.16 '@better-scroll/core': ^2.4.2 - '@commitlint/cli': ^16.2.3 - '@commitlint/config-conventional': ^16.2.1 + '@commitlint/cli': ^16.2.4 + '@commitlint/config-conventional': ^16.2.4 '@iconify/json': ^2.1.33 '@iconify/vue': ^3.2.1 '@soybeanjs/vue-admin-layout': ^1.0.3 @@ -54,7 +54,7 @@ specifiers: swiper: ^8.1.4 typescript: ^4.6.3 ua-parser-js: ^1.0.2 - unocss: ^0.31.17 + unocss: ^0.32.1 unplugin-icons: ^0.14.1 unplugin-vue-components: 0.19.3 unplugin-vue-define-options: ^0.6.1 @@ -97,8 +97,8 @@ dependencies: devDependencies: '@amap/amap-jsapi-types': 0.0.8 - '@commitlint/cli': 16.2.3 - '@commitlint/config-conventional': 16.2.1 + '@commitlint/cli': 16.2.4 + '@commitlint/config-conventional': 16.2.4 '@iconify/json': 2.1.33 '@iconify/vue': 3.2.1_vue@3.2.33 '@types/bmapgl': 0.0.5 @@ -131,7 +131,7 @@ devDependencies: rollup-plugin-visualizer: 5.6.0 sass: 1.51.0 typescript: 4.6.3 - unocss: 0.31.17_vite@2.9.6 + unocss: 0.32.1_vite@2.9.6 unplugin-icons: 0.14.1_vite@2.9.6 unplugin-vue-components: 0.19.3_vite@2.9.6+vue@3.2.33 unplugin-vue-define-options: 0.6.1_vite@2.9.6+vue@3.2.33 @@ -649,14 +649,14 @@ packages: resolution: {integrity: sha512-Gy/Jfbpu+hq0u+PcjkTqyXGqAf+0dexTzEZ5IDXEVwJVLmd3cx8A73oTcAZ8QZgk4wSHvlMjXecSaptkhnNPEw==} dev: false - /@commitlint/cli/16.2.3: - resolution: {integrity: sha512-VsJBQLvhhlOgEfxs/Z5liYuK0dXqLE5hz1VJzLBxiOxG31kL/X5Q4OvK292BmO7IGZcm1yJE3XQPWSiFaEHbWA==} + /@commitlint/cli/16.2.4: + resolution: {integrity: sha512-rbvqvz9JI+uiKxV2nH65BtSU01fsADd3bxe9fWtO3rM0c+CI/H9FfzKkDLvSRmXjvk1G2/wXlCGeqO9IBT4X9g==} engines: {node: '>=v12'} hasBin: true dependencies: '@commitlint/format': 16.2.1 - '@commitlint/lint': 16.2.1 - '@commitlint/load': 16.2.3 + '@commitlint/lint': 16.2.4 + '@commitlint/load': 16.2.4 '@commitlint/read': 16.2.1 '@commitlint/types': 16.2.1 lodash: 4.17.21 @@ -668,8 +668,8 @@ packages: - '@swc/wasm' dev: true - /@commitlint/config-conventional/16.2.1: - resolution: {integrity: sha512-cP9gArx7gnaj4IqmtCIcHdRjTYdRUi6lmGE+lOzGGjGe45qGOS8nyQQNvkNy2Ey2VqoSWuXXkD8zCUh6EHf1Ww==} + /@commitlint/config-conventional/16.2.4: + resolution: {integrity: sha512-av2UQJa3CuE5P0dzxj/o/B9XVALqYzEViHrMXtDrW9iuflrqCStWBAioijppj9URyz6ONpohJKAtSdgAOE0gkA==} engines: {node: '>=v12'} dependencies: conventional-changelog-conventionalcommits: 4.6.3 @@ -704,21 +704,21 @@ packages: chalk: 4.1.2 dev: true - /@commitlint/is-ignored/16.2.1: - resolution: {integrity: sha512-exl8HRzTIfb1YvDJp2b2HU5z1BT+9tmgxR2XF0YEzkMiCIuEKh+XLeocPr1VcvAKXv3Cmv5X/OfNRp+i+/HIhQ==} + /@commitlint/is-ignored/16.2.4: + resolution: {integrity: sha512-Lxdq9aOAYCOOOjKi58ulbwK/oBiiKz+7Sq0+/SpFIEFwhHkIVugvDvWjh2VRBXmRC/x5lNcjDcYEwS/uYUvlYQ==} engines: {node: '>=v12'} dependencies: '@commitlint/types': 16.2.1 - semver: 7.3.5 + semver: 7.3.7 dev: true - /@commitlint/lint/16.2.1: - resolution: {integrity: sha512-fNINQ3X2ZqsCkNB3Z0Z8ElmhewqrS3gy2wgBTx97BkcjOWiyPAGwDJ752hwrsUnWAVBRztgw826n37xPzxsOgg==} + /@commitlint/lint/16.2.4: + resolution: {integrity: sha512-AUDuwOxb2eGqsXbTMON3imUGkc1jRdtXrbbohiLSCSk3jFVXgJLTMaEcr39pR00N8nE9uZ+V2sYaiILByZVmxQ==} engines: {node: '>=v12'} dependencies: - '@commitlint/is-ignored': 16.2.1 + '@commitlint/is-ignored': 16.2.4 '@commitlint/parse': 16.2.1 - '@commitlint/rules': 16.2.1 + '@commitlint/rules': 16.2.4 '@commitlint/types': 16.2.1 dev: true @@ -741,6 +741,27 @@ packages: - '@swc/core' - '@swc/wasm' dev: true + optional: true + + /@commitlint/load/16.2.4: + resolution: {integrity: sha512-HjANm3/29ROV+zt4yfaY/K6gpr9Dbzgtlp0kSwZGW0poDXlD/yqVYgPQ6JolJzZii5FUz5R4yVLC15hVL/w60w==} + engines: {node: '>=v12'} + dependencies: + '@commitlint/config-validator': 16.2.1 + '@commitlint/execute-rule': 16.2.1 + '@commitlint/resolve-extends': 16.2.1 + '@commitlint/types': 16.2.1 + '@types/node': 17.0.29 + chalk: 4.1.2 + cosmiconfig: 7.0.1 + cosmiconfig-typescript-loader: 1.0.9_5281fe59fc32158e106b8b5e2bebb315 + lodash: 4.17.21 + resolve-from: 5.0.0 + typescript: 4.6.3 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + dev: true /@commitlint/message/16.2.1: resolution: {integrity: sha512-2eWX/47rftViYg7a3axYDdrgwKv32mxbycBJT6OQY/MJM7SUfYNYYvbMFOQFaA4xIVZt7t2Alyqslbl6blVwWw==} @@ -778,8 +799,8 @@ packages: resolve-global: 1.0.0 dev: true - /@commitlint/rules/16.2.1: - resolution: {integrity: sha512-ZFezJXQaBBso+BOTre/+1dGCuCzlWVaeLiVRGypI53qVgPMzQqZhkCcrxBFeqB87qeyzr4A4EoG++IvITwwpIw==} + /@commitlint/rules/16.2.4: + resolution: {integrity: sha512-rK5rNBIN2ZQNQK+I6trRPK3dWa0MtaTN4xnwOma1qxa4d5wQMQJtScwTZjTJeallFxhOgbNOgr48AMHkdounVg==} engines: {node: '>=v12'} dependencies: '@commitlint/ensure': 16.2.1 @@ -1238,14 +1259,14 @@ packages: eslint-visitor-keys: 3.3.0 dev: true - /@unocss/cli/0.31.17: - resolution: {integrity: sha512-at/gAnZBrutoTuee7dujhN/TRSCWAq+1QYm2ekfNktt4dgA5xVzvFQo63GEUvnM4tE51SQkIbznf44BxNbuEUQ==} + /@unocss/cli/0.32.1: + resolution: {integrity: sha512-KrO0SCiyss9fYl+VM4yNdYUqqMGpNQdOjPXErr12eNLnY68WiM7yEPZrcQL3QZO2tza7CObkivMkuCC1PMITbQ==} engines: {node: '>=14'} hasBin: true dependencies: - '@unocss/config': 0.31.17 - '@unocss/core': 0.31.17 - '@unocss/preset-uno': 0.31.17 + '@unocss/config': 0.32.1 + '@unocss/core': 0.32.1 + '@unocss/preset-uno': 0.32.1 cac: 6.7.12 chokidar: 3.5.3 colorette: 2.0.16 @@ -1255,107 +1276,112 @@ packages: perfect-debounce: 0.1.3 dev: true - /@unocss/config/0.31.17: - resolution: {integrity: sha512-Ggj2yCOeLxRfXd2Qt4ajWXJXQilZc/ozBFZM0vU77iFFq/yBlCWH6rLlhkYqGvSQT+K5SfaKluncskSG2090YA==} + /@unocss/config/0.32.1: + resolution: {integrity: sha512-BuS22lneXnuC6KkZUOYLVPdWnYKUx5reYzFOayUp0FmMcG2uMuMWZGGBx10JV/hWSWq3FKkCT8bNM0QcNZXysw==} engines: {node: '>=14'} dependencies: - '@unocss/core': 0.31.17 + '@unocss/core': 0.32.1 unconfig: 0.3.3 dev: true - /@unocss/core/0.31.17: - resolution: {integrity: sha512-DJ3Uk2ePVXvV1qQmgoLK44aqB6f0s+naOEvouI97nzVXDZgxDQPBxIPB/L4vvE4U+gQxEiHwwE3gJ75iPqVzXw==} + /@unocss/core/0.32.1: + resolution: {integrity: sha512-VlLF00eRvP8lsEspPWTju6kgl67R3POYl1HKZP0IPknbm9o6dyEwsKkG9VAHHvO4lDiQMI5O3ahI+DRvN0zmfg==} dev: true - /@unocss/inspector/0.31.17: - resolution: {integrity: sha512-eBRSBtiSvIk5mVJnNyN6Ag9ykBmQi2xROvcNS5sa11SHMkwWEaj1/8kBxyYFuOvl6ysEtdC7eSzv0tMRjXuuTw==} + /@unocss/inspector/0.32.1: + resolution: {integrity: sha512-BaKKYg9llm1ZyPpvHfffBNJmJ2DqageFUQjd2uRFZCGjYzqiXF7wCSGFccYAwbS7vs+DhAqDuoAAS2F8n/Hbew==} dependencies: gzip-size: 6.0.0 sirv: 2.0.2 dev: true - /@unocss/preset-attributify/0.31.17: - resolution: {integrity: sha512-Kar6K6oF7Zp/qXbWq1g+RwphOKCHiU3kWhulgbwy/HbdhSXsR0EE8zAHIgEga25q72Mm0hxBlowPtbjvX107rQ==} + /@unocss/preset-attributify/0.32.1: + resolution: {integrity: sha512-rqjR/RDePVEoqEJMtnQ7uGE1qTHlzf07nQqVPBwebadOhbype4YguoC1Y7Dgiqc78tEiGj88OMoO1vBXMkw3SQ==} dependencies: - '@unocss/core': 0.31.17 + '@unocss/core': 0.32.1 dev: true - /@unocss/preset-icons/0.31.17: - resolution: {integrity: sha512-cdS/BuL15NOKWIBxTW8e3xnr26MmC1dOtOtPLljLyMhdnEWOwHQA2PB9YtUZIEvrr2zTyMv/9aPQlBQ78973kg==} + /@unocss/preset-icons/0.32.1: + resolution: {integrity: sha512-S31Qlqbr7NBduQR/jdirYHecyM8DNT9TpXjqvxX2ssKMB1Ie1zpAWrtwM5Y0JaprjKa0mmL1KZ0wWGTHJ+LypA==} dependencies: '@iconify/utils': 1.0.32 - '@unocss/core': 0.31.17 + '@unocss/core': 0.32.1 transitivePeerDependencies: - supports-color dev: true - /@unocss/preset-mini/0.31.17: - resolution: {integrity: sha512-gVgMTOKLt3O1ym348QIBmR5sS9W0Ozkk5xelhH6e0VXcpg0dXDPDrl4hFErMy4x6IB86yyJG6Dz5JhcwQB13Ig==} + /@unocss/preset-mini/0.32.1: + resolution: {integrity: sha512-9cq1yfJLKmgim8lr/CmfpGTEVOCdg5W1F5MbutRtRijYrsSsETCGLLCfdq4QhV4o84QE8kAM6iLoUm0j+Gn8Sg==} dependencies: - '@unocss/core': 0.31.17 + '@unocss/core': 0.32.1 dev: true - /@unocss/preset-typography/0.31.17: - resolution: {integrity: sha512-zFFZeGdcXxpjgLG1o1zUQNFCdBqyGoFfUa0Zj0SeIYs11a4Y3ra701jHr1F4X4mhYzIyCUEfGC9X852o0iPa+A==} + /@unocss/preset-typography/0.32.1: + resolution: {integrity: sha512-+bekG07fiOjSzzyaJ2LmaGbJJab9XNyyC18TOYPCtryChO3kr2AmJyqows2II2+uqcGlexe6rsjeNteHy58cNg==} dependencies: - '@unocss/core': 0.31.17 + '@unocss/core': 0.32.1 dev: true - /@unocss/preset-uno/0.31.17: - resolution: {integrity: sha512-zSajrrPQlPXBr+egbQ00Nvku9YrqFh3pWByVSx/4XPpZ1oSSjOqMAfGcdDPlmOWi++G6FLU28sglc3JB7jJEZA==} + /@unocss/preset-uno/0.32.1: + resolution: {integrity: sha512-SHLusZNl2d1mfqyu425xCUkShLOrqYANxXVvb/HOhDXtWDtf8dglE3afbYCcklTb1YDZ08M6k4AsSgZjsv23ng==} dependencies: - '@unocss/core': 0.31.17 - '@unocss/preset-mini': 0.31.17 - '@unocss/preset-wind': 0.31.17 + '@unocss/core': 0.32.1 + '@unocss/preset-mini': 0.32.1 + '@unocss/preset-wind': 0.32.1 dev: true - /@unocss/preset-web-fonts/0.31.17: - resolution: {integrity: sha512-4FVNYMBN70j8xNOTxnUG6XeEJ/1WoJ1shQ72UhXDMaH4ZgCORvmAYdjl4opjEEB4RoXg5yJ1N1W6B3O/bsupbQ==} + /@unocss/preset-web-fonts/0.32.1: + resolution: {integrity: sha512-cPIcrkRZKejGNwF/ZzrhGW8gLQpgAdr1EIhSNPsJG77kpWn7fnsA+VUqa//2shKYhx0hezS3Tbq47hDK5qc4gQ==} dependencies: - '@unocss/core': 0.31.17 + '@unocss/core': 0.32.1 axios: 0.26.1 transitivePeerDependencies: - debug dev: true - /@unocss/preset-wind/0.31.17: - resolution: {integrity: sha512-GYVxPA66BovfXO9IAbSlE5yuBTO3ko7ChJS1Oisy3Y0+JBNXJsqzKlyLRLeKOSK76o2b/D0wRO8xEqirh76GQA==} + /@unocss/preset-wind/0.32.1: + resolution: {integrity: sha512-StgSnYQ4w7sUYqW1GURCICQ42qL83SQ1H5KZbSIJVnv2VVgo77m6dt96TmTmvizWJWH4Ga597YFhjXP4WUv6mw==} dependencies: - '@unocss/core': 0.31.17 - '@unocss/preset-mini': 0.31.17 + '@unocss/core': 0.32.1 + '@unocss/preset-mini': 0.32.1 dev: true /@unocss/reset/0.31.17: resolution: {integrity: sha512-g3+bqtM6LetSEJ5NYhi2P4vdP8yVLUQLbNZUdMtggcmHXTY08ISWaJKWmnHptrO13rtRoQ+l9gFc4Y7kRpD7NA==} + dev: false + + /@unocss/reset/0.32.1: + resolution: {integrity: sha512-tC2gCYY2isEDfBo1LWfcPAnxuM3my29fWtFUQRGvViZVTwYFjVIGD8BgIfiioifGumLunRW78qN7LT22fXoxgg==} + dev: true - /@unocss/scope/0.31.17: - resolution: {integrity: sha512-X6V62OKexnhePLuVj9FtrpAJYUCpIedIieogvl6gHDZMnTnJPNaW9jJ7/e6r21F3u9IrqOzlikgCicFSm4J/TA==} + /@unocss/scope/0.32.1: + resolution: {integrity: sha512-6Xsas4Fm797IIONNXP7Y7JLL7B4NTjk/BeFX7j++CS14SfGzF0wTTkyaHxE9ETecOiouUABwoiPQRzHNAkrNIA==} dev: true - /@unocss/transformer-directives/0.31.17: - resolution: {integrity: sha512-1FF6PQybr2eFVp1mlz+OeTDAIWTuJw61EJneFWlsnWk2PgqBlX25SIuQjTWhXfjWihL3n8F2wHrX8i0vcG39bg==} + /@unocss/transformer-directives/0.32.1: + resolution: {integrity: sha512-F4rPaNGaKbRGKksHuzAfSrsIaMZLpvqRhlk1xpwN5AGHClhK+Ak0z9j+N9Yy4rUuRx5OeOCuOj9Kcvq8cL8JnA==} dependencies: - '@unocss/core': 0.31.17 + '@unocss/core': 0.32.1 css-tree: 2.1.0 dev: true - /@unocss/transformer-variant-group/0.31.17: - resolution: {integrity: sha512-q1L7jckHicv2GwdKp7KGhufHeH5sGhJeRv1EGVZkb7KFKt9AROH9X9LDzE6Xr0jWgywrCIyTUIBdZwb2aKrjeg==} + /@unocss/transformer-variant-group/0.32.1: + resolution: {integrity: sha512-SrT5nWvNuuGFlMSGYgP7+KemYaBSUlP7i6v5QqzbjX9bcMz8JicT5Rwvy1Z1GOdtRGCy7e5aB6LW3Mxpd/pQhw==} dependencies: - '@unocss/core': 0.31.17 + '@unocss/core': 0.32.1 dev: true - /@unocss/vite/0.31.17_vite@2.9.6: - resolution: {integrity: sha512-+NH/In8zqBXbTWfpiu8u/7jkwBJdaq2lM/ErXzd0q07w8Jv0FmKRWxBGml168uDA6dHHoJRcGO1AvzOYxsv9+A==} + /@unocss/vite/0.32.1_vite@2.9.6: + resolution: {integrity: sha512-XLbBodjSfgoyTRUGL5XY8Fw+pW7GOZ1WrT1C+QfVJt8+BgY6wIdVhaERbfgOdAw/trzM0PYwhhbMHZp0SyJE5Q==} peerDependencies: vite: ^2.9.0 dependencies: '@rollup/pluginutils': 4.2.1 - '@unocss/config': 0.31.17 - '@unocss/core': 0.31.17 - '@unocss/inspector': 0.31.17 - '@unocss/scope': 0.31.17 - '@unocss/transformer-directives': 0.31.17 + '@unocss/config': 0.32.1 + '@unocss/core': 0.32.1 + '@unocss/inspector': 0.32.1 + '@unocss/scope': 0.32.1 + '@unocss/transformer-directives': 0.32.1 magic-string: 0.26.1 vite: 2.9.6_sass@1.51.0 dev: true @@ -2293,7 +2319,7 @@ packages: longest: 2.0.1 word-wrap: 1.2.3 optionalDependencies: - '@commitlint/load': 16.2.3 + '@commitlint/load': 16.2.4 transitivePeerDependencies: - '@swc/core' - '@swc/wasm' @@ -5177,14 +5203,6 @@ packages: hasBin: true dev: true - /semver/7.3.5: - resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - dev: true - /semver/7.3.7: resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==} engines: {node: '>=10'} @@ -5793,23 +5811,23 @@ packages: engines: {node: '>= 10.0.0'} dev: true - /unocss/0.31.17_vite@2.9.6: - resolution: {integrity: sha512-JJsxXfHfRRDvimDSgTTIpDPpYsVcp/jMxj+I/WsDIFQjBKhB4dq0VyjKl5dXlicgMTJfy2wrj/zBGMPl9W6/qA==} + /unocss/0.32.1_vite@2.9.6: + resolution: {integrity: sha512-Flp6FHOLznE7nTOSTSNPiyL3dd9V8TvhXPnReEwRo8yZxXOIg/+9cVzvF1nwGCIbfDYbjNK+eNKmtwxVmB78og==} engines: {node: '>=14'} dependencies: - '@unocss/cli': 0.31.17 - '@unocss/core': 0.31.17 - '@unocss/preset-attributify': 0.31.17 - '@unocss/preset-icons': 0.31.17 - '@unocss/preset-mini': 0.31.17 - '@unocss/preset-typography': 0.31.17 - '@unocss/preset-uno': 0.31.17 - '@unocss/preset-web-fonts': 0.31.17 - '@unocss/preset-wind': 0.31.17 - '@unocss/reset': 0.31.17 - '@unocss/transformer-directives': 0.31.17 - '@unocss/transformer-variant-group': 0.31.17 - '@unocss/vite': 0.31.17_vite@2.9.6 + '@unocss/cli': 0.32.1 + '@unocss/core': 0.32.1 + '@unocss/preset-attributify': 0.32.1 + '@unocss/preset-icons': 0.32.1 + '@unocss/preset-mini': 0.32.1 + '@unocss/preset-typography': 0.32.1 + '@unocss/preset-uno': 0.32.1 + '@unocss/preset-web-fonts': 0.32.1 + '@unocss/preset-wind': 0.32.1 + '@unocss/reset': 0.32.1 + '@unocss/transformer-directives': 0.32.1 + '@unocss/transformer-variant-group': 0.32.1 + '@unocss/vite': 0.32.1_vite@2.9.6 transitivePeerDependencies: - debug - supports-color diff --git a/src/config/regexp.ts b/src/config/regexp.ts index b94e15c48..d3cf01425 100644 --- a/src/config/regexp.ts +++ b/src/config/regexp.ts @@ -5,9 +5,9 @@ export const REGEXP_PHONE = /** 邮箱正则 */ export const REGEXP_EMAIL = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/; -/** 密码正则(密码为8-18位数字/字符/符号的组合) */ +/** 密码正则(密码为6-18位数字/字符/符号的组合) */ export const REGEXP_PWD = - /^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)]|[()])+$)(?!^.*[\u4E00-\u9FA5].*$)([^(0-9a-zA-Z)]|[()]|[a-z]|[A-Z]|[0-9]){8,18}$/; + /^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)]|[()])+$)(?!^.*[\u4E00-\u9FA5].*$)([^(0-9a-zA-Z)]|[()]|[a-z]|[A-Z]|[0-9]){6,18}$/; /** 6位数字验证码正则 */ export const REGEXP_CODE_SIX = /^\d{6}$/; diff --git a/src/layouts/common/GlobalTab/components/TabDetail/index.vue b/src/layouts/common/GlobalTab/components/TabDetail/index.vue index 94306a711..f6fd2472b 100644 --- a/src/layouts/common/GlobalTab/components/TabDetail/index.vue +++ b/src/layouts/common/GlobalTab/components/TabDetail/index.vue @@ -50,7 +50,7 @@ const activeComponent = computed(() => (isChromeMode.value ? ChromeTab : ButtonT const tabRef = ref(); async function getActiveTabClientX() { await nextTick(); - if (tabRef.value) { + if (tabRef.value && tabRef.value.children.length && tabRef.value.children[tab.activeTabIndex]) { const activeTabElement = tabRef.value.children[tab.activeTabIndex]; const { x, width } = activeTabElement.getBoundingClientRect(); const clientX = x + width / 2; diff --git a/src/service/adapter/index.ts b/src/service/adapter/index.ts index 65f3ab507..162913440 100644 --- a/src/service/adapter/index.ts +++ b/src/service/adapter/index.ts @@ -1,4 +1,6 @@ -export function adapterOfDataWithAdapter(res: Service.RequestResult): Demo.DataWithAdapter { +export function adapterOfFetchDataWithAdapter( + res: Service.RequestResult +): Demo.DataWithAdapter { const { dataId, dataName } = res.data!; const result: Demo.DataWithAdapter = { diff --git a/src/service/api/auth.ts b/src/service/api/auth.ts index 29cb808cd..f717362d1 100644 --- a/src/service/api/auth.ts +++ b/src/service/api/auth.ts @@ -11,15 +11,11 @@ export function fetchSmsCode(phone: string) { /** * 登录 - * @param phone - 手机号 - * @param pwdOrCode - 密码或验证码 - * @param type - 登录方式: pwd - 密码登录; sms - 验证码登录 + * @param userName - 用户名 + * @param password - 密码 */ -export function fetchLogin(phone: string, pwdOrCode: string, type: 'pwd' | 'sms') { - if (type === 'pwd') { - return mockRequest.post('/loginByPwd', { phone, pwd: pwdOrCode }); - } - return mockRequest.post('/loginByCode', { phone, code: pwdOrCode }); +export function fetchLogin(userName: string, password: string) { + return mockRequest.post('/login', { userName, password }); } /** 获取用户信息 */ diff --git a/src/service/api/demo.ts b/src/service/api/demo.ts index adb7a0edd..024d65dc5 100644 --- a/src/service/api/demo.ts +++ b/src/service/api/demo.ts @@ -1,9 +1,14 @@ -import { adapterOfServiceResult } from '@/utils'; -import { mockRequest } from '../request'; -import { adapterOfDataWithAdapter } from '../adapter'; +import { serviceAdapter } from '@/utils'; +import { request, mockRequest } from '../request'; +import { adapterOfFetchDataWithAdapter } from '../adapter'; /** 带有适配器的请求(将请求结果进行数据处理) */ export async function fetchDataWithAdapter() { const res = await mockRequest.post('/apiDemoWithAdapter'); - return adapterOfServiceResult(adapterOfDataWithAdapter, res); + return serviceAdapter(adapterOfFetchDataWithAdapter, res); +} + +/** 测试代理后的请求 */ +export function testRequestWithProxy() { + return request.get('/test-proxy'); // 确保.env-config的url和当前地址组成的 `${url}/test-proxy` 是有效的后端接口 } diff --git a/src/store/modules/auth/index.ts b/src/store/modules/auth/index.ts index af09fd198..755402a82 100644 --- a/src/store/modules/auth/index.ts +++ b/src/store/modules/auth/index.ts @@ -1,9 +1,11 @@ -import { unref } from 'vue'; +import { unref, nextTick } from 'vue'; import { defineStore } from 'pinia'; import { router as globalRouter } from '@/router'; import { useRouterPush } from '@/composables'; import { fetchLogin, fetchUserInfo } from '@/service'; import { getUserInfo, getToken, setUserInfo, setToken, setRefreshToken, clearAuthStorage } from '@/utils'; +import { useTabStore } from '../tab'; +import { useRouteStore } from '../route'; interface AuthState { /** 用户信息 */ @@ -30,6 +32,8 @@ export const useAuthStore = defineStore('auth-store', { /** 重置auth状态 */ resetAuthStore() { const { toLogin } = useRouterPush(false); + const { resetTabStore } = useTabStore(); + const { resetRouteStore } = useRouteStore(); const route = unref(globalRouter.currentRoute); clearAuthStorage(); @@ -38,6 +42,11 @@ export const useAuthStore = defineStore('auth-store', { if (route.meta.requiresAuth) { toLogin(); } + + nextTick(() => { + resetTabStore(); + resetRouteStore(); + }); }, /** * 根据token进行登录 @@ -46,7 +55,7 @@ export const useAuthStore = defineStore('auth-store', { async loginByToken(backendToken: ApiAuth.Token) { const { toLoginRedirect } = useRouterPush(false); - // 先把token存储到缓存中 + // 先把token存储到缓存中(后面接口的请求头需要token) const { token, refreshToken } = backendToken; setToken(token); setRefreshToken(refreshToken); @@ -76,13 +85,12 @@ export const useAuthStore = defineStore('auth-store', { }, /** * 登录 - * @param phone - 手机号 - * @param pwdOrCode - 密码或验证码 - * @param type - 登录方式: pwd - 密码登录; sms - 验证码登录 + * @param userName - 用户名 + * @param password - 密码 */ - async login(phone: string, pwdOrCode: string, type: 'pwd' | 'sms') { + async login(userName: string, password: string) { this.loginLoading = true; - const { data } = await fetchLogin(phone, pwdOrCode, type); + const { data } = await fetchLogin(userName, password); if (data) { await this.loginByToken(data); } diff --git a/src/store/modules/route/index.ts b/src/store/modules/route/index.ts index 0184efa97..41d361994 100644 --- a/src/store/modules/route/index.ts +++ b/src/store/modules/route/index.ts @@ -43,6 +43,9 @@ export const useRouteStore = defineStore('route-store', { cacheRoutes: [] }), actions: { + resetRouteStore() { + this.$reset(); + }, /** * 处理权限路由 * @param routes - 权限路由 @@ -53,6 +56,7 @@ export const useRouteStore = defineStore('route-store', { this.searchMenus = transformAuthRoutesToSearchMenus(routes); const vueRoutes = transformAuthRoutesToVueRoutes(routes); + vueRoutes.forEach(route => { router.addRoute(route); }); diff --git a/src/store/modules/tab/index.ts b/src/store/modules/tab/index.ts index 6acabc598..c2a302458 100644 --- a/src/store/modules/tab/index.ts +++ b/src/store/modules/tab/index.ts @@ -1,7 +1,7 @@ import type { Router, RouteLocationNormalizedLoaded } from 'vue-router'; import { defineStore } from 'pinia'; import { useRouterPush } from '@/composables'; -import { getTabRoutes } from '@/utils'; +import { getTabRoutes, clearTabRoutes } from '@/utils'; import { useThemeStore } from '../theme'; import { getTabRouteByVueRoute, isInTabRoutes, getIndexInTabRoutes } from './helpers'; @@ -38,6 +38,11 @@ export const useTabStore = defineStore('tab-store', { } }, actions: { + /** 重置Tab状态 */ + resetTabStore() { + clearTabRoutes(); + this.$reset(); + }, /** * 设置当前路由对应的页签为激活状态 * @param path - 路由path diff --git a/src/store/modules/theme/helpers.ts b/src/store/modules/theme/helpers.ts index a8249f2a8..f2b173ba7 100644 --- a/src/store/modules/theme/helpers.ts +++ b/src/store/modules/theme/helpers.ts @@ -71,18 +71,3 @@ export function getNaiveThemeOverrides(colors: Record): Globa } }; } - -/** windicss 暗黑模式 */ -export function handleWindicssDarkMode() { - const DARK_CLASS = 'dark'; - function addDarkClass() { - document.documentElement.classList.add(DARK_CLASS); - } - function removeDarkClass() { - document.documentElement.classList.remove(DARK_CLASS); - } - return { - addDarkClass, - removeDarkClass - }; -} diff --git a/src/store/subscribe/theme.ts b/src/store/subscribe/theme.ts index c0ac0b189..c6459c954 100644 --- a/src/store/subscribe/theme.ts +++ b/src/store/subscribe/theme.ts @@ -11,7 +11,7 @@ export default function subscribeThemeStore() { const theme = useThemeStore(); const osTheme = useOsTheme(); const { width } = useElementSize(document.documentElement); - const { addDarkClass, removeDarkClass } = handleWindicssDarkMode(); + const { addDarkClass, removeDarkClass } = handleCssDarkMode(); // 监听主题颜色 const stopThemeColor = watch( @@ -76,8 +76,8 @@ export default function subscribeThemeStore() { }); } -/** windicss 暗黑模式 */ -function handleWindicssDarkMode() { +/** css 暗黑模式 */ +function handleCssDarkMode() { const DARK_CLASS = 'dark'; function addDarkClass() { document.documentElement.classList.add(DARK_CLASS); diff --git a/src/typings/business.d.ts b/src/typings/business.d.ts index 073b6d2c5..b2480b1fb 100644 --- a/src/typings/business.d.ts +++ b/src/typings/business.d.ts @@ -15,8 +15,6 @@ declare namespace Auth { userId: string; /** 用户名 */ userName: string; - /** 用户手机号 */ - userPhone: string; /** 用户角色类型 */ userRole: RoleType; } diff --git a/src/typings/env.d.ts b/src/typings/env.d.ts index c13db3c0b..7f99e555e 100644 --- a/src/typings/env.d.ts +++ b/src/typings/env.d.ts @@ -8,9 +8,9 @@ type EnvType = 'dev' | 'test' | 'prod'; /** env环境配置 */ interface EnvConfig { - /** 请求地址 */ + /** 后端的请求地址 */ url: string; - /** 代理地址 */ + /** 代理标识, 用于拦截地址转发代理(如:"/api",这个和后端路径有无 "/api" 路径没有任何关系) */ proxy: string; } diff --git a/src/utils/auth/user.ts b/src/utils/auth/user.ts index 6000ee6d4..690301135 100644 --- a/src/utils/auth/user.ts +++ b/src/utils/auth/user.ts @@ -36,7 +36,6 @@ export function getUserInfo() { const emptyInfo: Auth.UserInfo = { userId: '', userName: '', - userPhone: '', userRole: 'user' }; const userInfo: Auth.UserInfo = getLocal(EnumStorageKey['user-info']) || emptyInfo; diff --git a/src/utils/form/rule.ts b/src/utils/form/rule.ts index 1366b5b24..bdb05103e 100644 --- a/src/utils/form/rule.ts +++ b/src/utils/form/rule.ts @@ -22,7 +22,7 @@ export const formRules: CustomFormRules = { ], pwd: [ { required: true, message: '请输入密码' }, - { pattern: REGEXP_PWD, message: '密码为8-18位数字/字符/符号,至少2种组合', trigger: 'input' } + { pattern: REGEXP_PWD, message: '密码为6-18位数字/字符/符号,至少2种组合', trigger: 'input' } ], code: [ { required: true, message: '请输入验证码' }, diff --git a/src/utils/service/handler.ts b/src/utils/service/handler.ts index c32bda272..2cbc306b4 100644 --- a/src/utils/service/handler.ts +++ b/src/utils/service/handler.ts @@ -21,7 +21,7 @@ type Adapter = (...args: Service.RequestResult[]) => T; * @param adapter - 适配器函数 * @param args - 适配器函数的参数 */ -export function adapterOfServiceResult(adapter: T, ...args: TypeUtil.GetFunArgs) { +export function serviceAdapter(adapter: T, ...args: TypeUtil.GetFunArgs) { let result: Service.RequestResult | undefined; const hasError = args.some(item => { diff --git a/src/views/about/components/ProjectIntroduction.vue b/src/views/about/components/ProjectIntroduction.vue index c86733c54..0d54ffaad 100644 --- a/src/views/about/components/ProjectIntroduction.vue +++ b/src/views/about/components/ProjectIntroduction.vue @@ -1,6 +1,6 @@