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