From e8941adde4c5156bbe7f2d95f013add353aee61b Mon Sep 17 00:00:00 2001 From: Charles7c Date: Thu, 21 Nov 2024 22:47:54 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=8B=86=E5=88=86=E5=B9=B6?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=B7=AF=E7=94=B1=E5=AE=88=E5=8D=AB=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=A1=B6=E9=83=A8=E8=BF=9B=E5=BA=A6=E6=9D=A1?= =?UTF-8?q?=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.ts | 2 +- src/router/{permission.ts => guard.ts} | 25 ++++--- src/router/index.ts | 90 +------------------------- src/router/route.ts | 90 ++++++++++++++++++++++++++ src/stores/modules/route.ts | 4 +- src/stores/modules/user.ts | 2 +- 6 files changed, 113 insertions(+), 100 deletions(-) rename src/router/{permission.ts => guard.ts} (91%) create mode 100644 src/router/route.ts diff --git a/src/main.ts b/src/main.ts index c4c1c24..4eb0f14 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,7 +9,7 @@ import ArcoVueIcon from '@arco-design/web-vue/es/icon' import App from './App.vue' import router from './router' -import '@/router/permission' +import '@/router/guard' // 使用动画库 import 'animate.css/animate.min.css' diff --git a/src/router/permission.ts b/src/router/guard.ts similarity index 91% rename from src/router/permission.ts rename to src/router/guard.ts index 9b8a4c5..bd330bd 100644 --- a/src/router/permission.ts +++ b/src/router/guard.ts @@ -6,7 +6,13 @@ import { getToken } from '@/utils/auth' import { isHttp } from '@/utils/validate' import 'nprogress/nprogress.css' -NProgress.configure({ showSpinner: false }) // NProgress Configuration +NProgress.configure({ + easing: 'ease', // 动画方式 + speed: 500, // 递增进度条的速度 + showSpinner: false, // 是否显示圆圈加载 + trickleSpeed: 200, // 自动递增间隔 + minimum: 0.3, // 初始化时的最小百分比 +}) // 版本更新 let versionTag: string | null = null // 版本标识 @@ -70,15 +76,14 @@ export const resetHasRouteFlag = () => { } router.beforeEach(async (to, from, next) => { + NProgress.start() const userStore = useUserStore() const routeStore = useRouteStore() - NProgress.start() // 判断该用户是否登录 if (getToken()) { if (to.path === '/login') { // 如果已经登录,并准备进入 Login 页面,则重定向到主页 next() - NProgress.done() } else { if (!hasRouteFlag) { try { @@ -86,7 +91,6 @@ router.beforeEach(async (to, from, next) => { if (userStore.userInfo.pwdExpired && to.path !== '/pwdExpired') { Message.warning('密码已过期,请修改密码') next('/pwdExpired') - NProgress.done() } const accessRoutes = await routeStore.generateRoutes() accessRoutes.forEach((route) => { @@ -98,16 +102,13 @@ router.beforeEach(async (to, from, next) => { // 确保添加路由已完成 // 设置 replace: true, 因此导航将不会留下历史记录 next({ ...to, replace: true }) - NProgress.done() } catch (error: any) { // 过程中发生任何错误,都直接重置 Token,并重定向到登录页面 await userStore.logoutCallBack() next(`/login?redirect=${to.path}`) - NProgress.done() } } else { next() - NProgress.done() } } } else { @@ -115,11 +116,9 @@ router.beforeEach(async (to, from, next) => { if (whiteList.includes(to.path)) { // 如果在免登录的白名单中,则直接进入 next() - NProgress.done() } else { // 其他没有访问权限的页面将被重定向到登录页面 next('/login') - NProgress.done() } } @@ -129,3 +128,11 @@ router.beforeEach(async (to, from, next) => { await compareTag() } }) + +router.onError(() => { + NProgress.done() +}) + +router.afterEach(() => { + NProgress.done() +}) diff --git a/src/router/index.ts b/src/router/index.ts index 6bdcd05..2755719 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,94 +1,10 @@ -import { type RouteRecordRaw, createRouter, createWebHistory } from 'vue-router' +import { createRouter, createWebHistory } from 'vue-router' import { useRouteStore } from '@/stores' - -/** 默认布局 */ -const Layout = () => import('@/layout/index.vue') - -/** 静态路由 */ -export const constantRoutes: RouteRecordRaw[] = [ - { - path: '/redirect', - component: Layout, - meta: { hidden: true }, - children: [ - { - path: '/redirect/:path(.*)', - component: () => import('@/views/default/redirect/index.vue'), - }, - ], - }, - { - path: '/login', - name: 'Login', - component: () => import('@/views/login/index.vue'), - meta: { hidden: true }, - }, - { - path: '/:pathMatch(.*)*', - component: () => import('@/views/default/error/404.vue'), - meta: { hidden: true }, - }, - { - path: '/403', - component: () => import('@/views/default/error/403.vue'), - meta: { hidden: true }, - }, - { - path: '/', - name: 'Dashboard', - component: Layout, - redirect: '/dashboard/workplace', - meta: { title: '仪表盘', icon: 'dashboard', hidden: false }, - children: [ - { - path: '/dashboard/workplace', - name: 'Workplace', - component: () => import('@/views/dashboard/workplace/index.vue'), - meta: { title: '工作台', icon: 'desktop', hidden: false, affix: true }, - }, - { - path: '/dashboard/analysis', - name: 'Analysis', - component: () => import('@/views/dashboard/analysis/index.vue'), - meta: { title: '分析页', icon: 'insert-chart', hidden: false }, - }, - ], - }, - { - path: '/social/callback', - component: () => import('@/views/login/social/index.vue'), - meta: { hidden: true }, - }, - { - path: '/pwdExpired', - component: () => import('@/views/login/pwdExpired/index.vue'), - meta: { hidden: true }, - }, - { - path: '/setting', - name: 'Setting', - component: Layout, - meta: { hidden: true }, - children: [ - { - path: '/setting/profile', - name: 'SettingProfile', - component: () => import('@/views/setting/profile/index.vue'), - meta: { title: '个人中心', showInTabs: false }, - }, - { - path: '/setting/message', - name: 'SettingMessage', - component: () => import('@/views/setting/message/index.vue'), - meta: { title: '消息中心', showInTabs: false }, - }, - ], - }, -] +import { constantRoutes, systemRoutes } from '@/router/route' const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), - routes: constantRoutes, + routes: [...constantRoutes, ...systemRoutes], scrollBehavior: () => ({ left: 0, top: 0 }), }) diff --git a/src/router/route.ts b/src/router/route.ts new file mode 100644 index 0000000..73265fe --- /dev/null +++ b/src/router/route.ts @@ -0,0 +1,90 @@ +import type { RouteRecordRaw } from 'vue-router' + +/** 默认布局 */ +const Layout = () => import('@/layout/index.vue') + +/** 系统路由 */ +export const systemRoutes: RouteRecordRaw[] = [ + { + path: '/login', + name: 'Login', + component: () => import('@/views/login/index.vue'), + meta: { hidden: true }, + }, + { + path: '/', + name: 'Dashboard', + component: Layout, + redirect: '/dashboard/workplace', + meta: { title: '仪表盘', icon: 'dashboard', hidden: false }, + children: [ + { + path: '/dashboard/workplace', + name: 'Workplace', + component: () => import('@/views/dashboard/workplace/index.vue'), + meta: { title: '工作台', icon: 'desktop', hidden: false, affix: true }, + }, + { + path: '/dashboard/analysis', + name: 'Analysis', + component: () => import('@/views/dashboard/analysis/index.vue'), + meta: { title: '分析页', icon: 'insert-chart', hidden: false }, + }, + ], + }, + { + path: '/social/callback', + component: () => import('@/views/login/social/index.vue'), + meta: { hidden: true }, + }, + { + path: '/pwdExpired', + component: () => import('@/views/login/pwdExpired/index.vue'), + meta: { hidden: true }, + }, + { + path: '/setting', + name: 'Setting', + component: Layout, + meta: { hidden: true }, + children: [ + { + path: '/setting/profile', + name: 'SettingProfile', + component: () => import('@/views/setting/profile/index.vue'), + meta: { title: '个人中心', showInTabs: false }, + }, + { + path: '/setting/message', + name: 'SettingMessage', + component: () => import('@/views/setting/message/index.vue'), + meta: { title: '消息中心', showInTabs: false }, + }, + ], + }, +] + +// 固定路由(默认路由) +export const constantRoutes: RouteRecordRaw[] = [ + { + path: '/redirect', + component: Layout, + meta: { hidden: true }, + children: [ + { + path: '/redirect/:path(.*)', + component: () => import('@/views/default/redirect/index.vue'), + }, + ], + }, + { + path: '/:pathMatch(.*)*', + component: () => import('@/views/default/error/404.vue'), + meta: { hidden: true }, + }, + { + path: '/403', + component: () => import('@/views/default/error/403.vue'), + meta: { hidden: true }, + }, +] diff --git a/src/stores/modules/route.ts b/src/stores/modules/route.ts index 49f1622..4f4699b 100644 --- a/src/stores/modules/route.ts +++ b/src/stores/modules/route.ts @@ -3,7 +3,7 @@ import { defineStore } from 'pinia' import type { RouteRecordRaw } from 'vue-router' import { mapTree, toTreeArray } from 'xe-utils' import { cloneDeep, omit } from 'lodash-es' -import { constantRoutes } from '@/router' +import { constantRoutes, systemRoutes } from '@/router/route' import ParentView from '@/components/ParentView/index.vue' import { type RouteItem, getUserRoute } from '@/apis' import { transformPathToName } from '@/utils' @@ -103,7 +103,7 @@ const storeSetup = () => { // 合并路由 const setRoutes = (data: RouteRecordRaw[]) => { - routes.value = constantRoutes.concat(data) + routes.value = [...constantRoutes, ...systemRoutes].concat(data) asyncRoutes.value = data } diff --git a/src/stores/modules/user.ts b/src/stores/modules/user.ts index 18f35b3..5463279 100644 --- a/src/stores/modules/user.ts +++ b/src/stores/modules/user.ts @@ -14,7 +14,7 @@ import { socialLogin as socialLoginApi, } from '@/apis' import { clearToken, getToken, setToken } from '@/utils/auth' -import { resetHasRouteFlag } from '@/router/permission' +import { resetHasRouteFlag } from '@/router/guard' const storeSetup = () => { const userInfo = reactive({