DCFronted/src/router/index.js

197 lines
5.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { createRouter, createWebHistory } from 'vue-router'
import { hasValidToken, getUserInfo, logoutUser, getStoredUser } from '../utils/jwt';
import { justLoggedIn } from '../utils/authSessionState';
import EditorsMaps from '@/views/index/EditorsMaps.vue'
import mitt from 'mitt'
import { hasPrivilege, hasPrivilegeWithTemp } from '@/utils/privilege'
const routes = [
{
path: '/dashboard',
redirect: '/backend/dashboard'
},
{
path: '/',
component: () => import('@/views/index.vue'),
children: [
{
path: '',
name: 'Home',
component: () => import('@/views/index/Home.vue')
},
{
path: 'demands',
name: 'DemandList',
component: () => import('@/views/index/DemandList.vue'),
meta: { requiresAuth: true }
},
{
path: 'maps',
name: 'Maps',
component: () => import('@/views/index/Maps.vue')
},
{
path: 'weekly',
name: 'WeeklyRecommend',
component: () => import('@/views/index/WeeklyRecommend.vue')
},
{
path: 'map/:id',
name: 'MapDetail',
component: () => import('@/views/index/MapDetail.vue')
},
{
path: 'author',
name: 'ActiveAuthor',
component: () => import('@/views/index/ActiveAuthor.vue')
},
{
path: 'weapon-match',
name: 'WeaponMatch',
component: () => import('@/views/weapon/WeaponMatch.vue'),
meta: { requiresAuth: true, requiredPrivilege: ['lv-admin','lv-mod'] }
},
{
path: 'configEditor',
name: 'ConfigEditor',
component: () => import('@/views/index/ConfigEditor.vue'),
meta: { requiresAuth: true, requiredPrivilege: ['lv-admin','lv-mod'] }
},
{
path: 'competition',
name: 'Competition',
component: () => import('@/views/competition/Competition.vue'),
// meta: { requiresAuth: true, requiredPrivilege: ['lv-admin','lv-competitor'] }
meta: { requiresAuth: true}
},
{
path: 'competition/add',
name: 'AddCompetition',
component: () => import('@/views/competition/AddContestant.vue'),
meta: { requiresAuth: true }
},
{
path: 'competition/detail',
name: 'CompetitionDetail',
component: () => import('@/views/competition/CompetitionDetail.vue'),
meta: { requiresAuth: true }
},
{
path: 'competition/signup',
name: 'CompetitionSignUp',
component: () => import('@/views/competition/CompetitionSignUp.vue'),
meta: { requiresAuth: true }
},
// {
// path: 'competition',
// name: 'Competition',
// component: () => import('@/views/competition/Competition.vue'),
// meta: { requiresAuth: true}
// },
{
path: 'editors-maps',
name: 'EditorsMaps',
component: () => import('@/views/index/EditorsMaps.vue')
},
{
path:'terrain',
name: 'Terrain',
component: () => import('@/views/index/TerrainList.vue')
},
{
path: 'PIC2TGA',
name: 'PIC2TGA',
component: () => import('@/views/index/PIC2TGA.vue'),
meta: { requiredPrivilege: ['lv-admin','lv-mod','lv-map','lv-competitor'] }
},
{
path: 'terrainGenerate',
name: 'TerrainGenerate',
component: () => import('@/views/index/TerrainGenerate.vue'),
meta: { requiredPrivilege: ['lv-admin','lv-mod','lv-map','lv-competitor'] }
}
]
},
{
path: '/backend',
component: () => import('@/views/backend.vue'),
children: [
{
path: '',
redirect: 'dashboard'
},
{
path: 'login',
name: 'Login',
component: () => import('@/views/backend/Login.vue')
},
{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/backend/Dashboard.vue'),
meta: { requiresAuth: true }
}
]
},
{
path: '/user/resetpassword/:token',
name: 'ResetPassword',
component: () => import('@/views/ResetPassword.vue')
}
]
const router = createRouter({
history: createWebHistory(),
routes,
linkActiveClass: 'router-link-active',
linkExactActiveClass: 'router-link-exact-active'
})
export const eventBus = mitt()
// 路由守卫
router.beforeEach(async (to, from, next) => {
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
const requiredPrivilege = to.matched.find(record => record.meta.requiredPrivilege)?.meta.requiredPrivilege;
if (!requiresAuth && !requiredPrivilege) {
return next(); // 如果页面不需要认证和权限,直接放行
}
if (hasValidToken()) {
try {
await getUserInfo(); // 尝试获取用户信息该函数会把用户信息存入SessionStorage
// 继续检查权限
} catch (error) {
// 获取失败 (token无效, 网络问题等)
logoutUser(); // 清除所有凭证
return next({
path: '/backend/login',
query: { redirect: to.fullPath, sessionExpired: 'true' }
});
// return next('/maps')
}
}
// 登录校验:如果页面需要登录但本地没有有效 token则跳转登录页
if (requiresAuth && !hasValidToken()) {
return next({
path: '/',
query: { redirect: to.fullPath }
})
}
// 权限校验
if (requiredPrivilege) {
const user = getStoredUser();
if (!user || !hasPrivilegeWithTemp(user, requiredPrivilege)) {
// 通过事件总线通知弹窗
eventBus.emit('no-privilege')
return next({ path: '/', replace: true })
}
}
return next();
});
export default router