feat(other): init
This commit is contained in:
9
src/router/guard/index.js
Normal file
9
src/router/guard/index.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import { createPageLoadingGuard } from './page-loading-guard'
|
||||
import { createPageTitleGuard } from './page-title-guard'
|
||||
import { createPermissionGuard } from './permission-guard'
|
||||
|
||||
export function setupRouterGuard(router) {
|
||||
createPageLoadingGuard(router)
|
||||
createPermissionGuard(router)
|
||||
createPageTitleGuard(router)
|
||||
}
|
||||
15
src/router/guard/page-loading-guard.js
Normal file
15
src/router/guard/page-loading-guard.js
Normal file
@@ -0,0 +1,15 @@
|
||||
export function createPageLoadingGuard(router) {
|
||||
router.beforeEach(() => {
|
||||
window.$loadingBar?.start()
|
||||
})
|
||||
|
||||
router.afterEach(() => {
|
||||
setTimeout(() => {
|
||||
window.$loadingBar?.finish()
|
||||
}, 200)
|
||||
})
|
||||
|
||||
router.onError(() => {
|
||||
window.$loadingBar?.error()
|
||||
})
|
||||
}
|
||||
12
src/router/guard/page-title-guard.js
Normal file
12
src/router/guard/page-title-guard.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const baseTitle = import.meta.env.VITE_TITLE
|
||||
|
||||
export function createPageTitleGuard(router) {
|
||||
router.afterEach((to) => {
|
||||
const pageTitle = to.meta?.title
|
||||
if (pageTitle) {
|
||||
document.title = `${pageTitle} | ${baseTitle}`
|
||||
} else {
|
||||
document.title = baseTitle
|
||||
}
|
||||
})
|
||||
}
|
||||
34
src/router/guard/permission-guard.js
Normal file
34
src/router/guard/permission-guard.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import { getToken, isNullOrWhitespace } from '@/utils'
|
||||
import { addDynamicRoutes } from '@/router'
|
||||
|
||||
const WHITE_LIST = ['/login', '/404']
|
||||
export function createPermissionGuard(router) {
|
||||
router.beforeEach(async (to) => {
|
||||
const token = getToken()
|
||||
|
||||
/** 没有token的情况 */
|
||||
if (isNullOrWhitespace(token)) {
|
||||
if (WHITE_LIST.includes(to.path)) return true
|
||||
return { path: 'login', query: { ...to.query, redirect: to.path } }
|
||||
}
|
||||
|
||||
/** 有token的情况 */
|
||||
if (to.path === '/login') return { path: '/' }
|
||||
|
||||
// 确保动态路由已加载
|
||||
if (token && !router.hasRoute('Dashboard')) {
|
||||
try {
|
||||
await addDynamicRoutes()
|
||||
// 如果当前路径不存在,重定向到工作台
|
||||
if (to.path !== '/' && !router.hasRoute(to.name)) {
|
||||
return { path: '/workbench' }
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('动态路由加载失败:', error)
|
||||
return { path: '/login' }
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
}
|
||||
87
src/router/index.js
Normal file
87
src/router/index.js
Normal file
@@ -0,0 +1,87 @@
|
||||
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
|
||||
import { setupRouterGuard } from './guard'
|
||||
import { basicRoutes, EMPTY_ROUTE, NOT_FOUND_ROUTE } from './routes'
|
||||
import { getToken, isNullOrWhitespace } from '@/utils'
|
||||
import { usePermissionStore } from '@/store'
|
||||
|
||||
const isHash = false
|
||||
export const router = createRouter({
|
||||
history: isHash ? createWebHashHistory('/') : createWebHistory('/'),
|
||||
routes: basicRoutes,
|
||||
scrollBehavior: () => ({ left: 0, top: 0 }),
|
||||
})
|
||||
|
||||
export async function setupRouter(app) {
|
||||
await addDynamicRoutes()
|
||||
setupRouterGuard(router)
|
||||
app.use(router)
|
||||
}
|
||||
|
||||
export async function addDynamicRoutes() {
|
||||
const token = getToken()
|
||||
|
||||
// 没有token情况
|
||||
if (isNullOrWhitespace(token)) {
|
||||
router.addRoute(EMPTY_ROUTE)
|
||||
return
|
||||
}
|
||||
|
||||
// 有token的情况
|
||||
try {
|
||||
const permissionStore = usePermissionStore()
|
||||
const accessRoutes = permissionStore.generateRoutes()
|
||||
|
||||
// 确保路由按正确顺序添加
|
||||
accessRoutes.forEach((route) => {
|
||||
if (!router.hasRoute(route.name)) {
|
||||
router.addRoute(route)
|
||||
}
|
||||
})
|
||||
|
||||
// 移除空路由,添加404路由
|
||||
if (router.hasRoute(EMPTY_ROUTE.name)) {
|
||||
router.removeRoute(EMPTY_ROUTE.name)
|
||||
}
|
||||
router.addRoute(NOT_FOUND_ROUTE)
|
||||
|
||||
// 确保根路径重定向到工作台
|
||||
// if (!router.hasRoute('workbench')) {
|
||||
// const workbenchRoute = {
|
||||
// name: 'workbench',
|
||||
// path: '/',
|
||||
// component: () => import('@/views/workbench/index.vue'),
|
||||
// redirect: '/workbench',
|
||||
// // children: [
|
||||
// // {
|
||||
// // name: 'Workbench',
|
||||
// // path: 'workbench',
|
||||
// // component: () => import('@/views/workbench/index.vue'),
|
||||
// // meta: {
|
||||
// // title: '工作台',
|
||||
// // icon: 'mdi:index',
|
||||
// // order: 0,
|
||||
// // },
|
||||
// // },
|
||||
// // ],
|
||||
// }
|
||||
// router.addRoute(workbenchRoute)
|
||||
// }
|
||||
|
||||
// console.log(router)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export function getRouteNames(routes) {
|
||||
return routes.map((route) => getRouteName(route)).flat(1)
|
||||
}
|
||||
|
||||
function getRouteName(route) {
|
||||
const names = [route.name]
|
||||
if (route.subMenu && route.subMenu.length) {
|
||||
names.push(...route.subMenu.map((item) => getRouteName(item)).flat(1))
|
||||
}
|
||||
return names
|
||||
}
|
||||
31
src/router/routes/index.js
Normal file
31
src/router/routes/index.js
Normal file
@@ -0,0 +1,31 @@
|
||||
export const basicRoutes = [
|
||||
{
|
||||
name: '404',
|
||||
path: '/404',
|
||||
component: () => import('@/views/error-page/404.vue'),
|
||||
isHidden: true,
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Login',
|
||||
path: '/login',
|
||||
component: () => import('@/views/login/index.vue'),
|
||||
isHidden: true,
|
||||
meta: {
|
||||
title: '登录页',
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
export const NOT_FOUND_ROUTE = {
|
||||
name: 'NotFound',
|
||||
path: '/:pathMatch(.*)*',
|
||||
redirect: '/404',
|
||||
isHidden: true,
|
||||
}
|
||||
|
||||
export const EMPTY_ROUTE = {
|
||||
name: 'Empty',
|
||||
path: '/:pathMatch(.*)*',
|
||||
component: null,
|
||||
}
|
||||
Reference in New Issue
Block a user