141 lines
3.4 KiB
JavaScript
141 lines
3.4 KiB
JavaScript
import { createRouter, createWebHistory } from 'vue-router'
|
|
import { hasValidToken, getUserInfo, logoutUser } from '../utils/jwt';
|
|
import { justLoggedIn } from '../utils/authSessionState';
|
|
|
|
const routes = [
|
|
{
|
|
path: '/dashboard',
|
|
redirect: '/backend/dashboard'
|
|
},
|
|
{
|
|
path: '/',
|
|
component: () => import('@/views/index.vue'),
|
|
children: [
|
|
{
|
|
path: '',
|
|
redirect: '/maps'
|
|
},
|
|
{
|
|
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: 'weapon-match',
|
|
name: 'WeaponMatch',
|
|
component: () => import('@/views/index/WeaponMatch.vue'),
|
|
meta: { requiresAuth: true }
|
|
},
|
|
{
|
|
path: 'competition',
|
|
name: 'Competition',
|
|
component: () => import('@/views/index/Competition.vue'),
|
|
meta: { requiresAuth: true }
|
|
},
|
|
{
|
|
path: 'competition/add',
|
|
name: 'AddCompetition',
|
|
component: () => import('@/views/index/AddContestant.vue'),
|
|
meta: { requiresAuth: true }
|
|
},
|
|
{
|
|
path: 'competition/detail',
|
|
name: 'CompetitionDetail',
|
|
component: () => import('@/views/index/CompetitionDetail.vue'),
|
|
meta: { requiresAuth: true }
|
|
},
|
|
{
|
|
path: 'competition/signup',
|
|
name: 'CompetitionSignUp',
|
|
component: () => import('@/views/index/CompetitionSignUp.vue'),
|
|
meta: { requiresAuth: true }
|
|
}
|
|
]
|
|
},
|
|
{
|
|
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 }
|
|
}
|
|
]
|
|
}
|
|
]
|
|
|
|
const router = createRouter({
|
|
history: createWebHistory(),
|
|
routes,
|
|
linkActiveClass: 'router-link-active',
|
|
linkExactActiveClass: 'router-link-exact-active'
|
|
})
|
|
|
|
// 路由守卫
|
|
router.beforeEach(async (to, from, next) => {
|
|
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
|
|
|
|
if (requiresAuth) {
|
|
const tokenExists = hasValidToken();
|
|
|
|
if (justLoggedIn.value) {
|
|
justLoggedIn.value = false;
|
|
if (tokenExists) {
|
|
next();
|
|
} else {
|
|
logoutUser();
|
|
next({ path: '/backend/login', query: { redirect: to.fullPath, sessionExpired: 'true' }});
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (tokenExists) {
|
|
const user = await getUserInfo();
|
|
if (user) {
|
|
next();
|
|
} else {
|
|
logoutUser();
|
|
next({
|
|
path: '/backend/login',
|
|
query: { redirect: to.fullPath, sessionExpired: 'true' }
|
|
});
|
|
}
|
|
} else {
|
|
next({
|
|
path: '/backend/login',
|
|
query: { redirect: to.fullPath }
|
|
});
|
|
}
|
|
} else {
|
|
next();
|
|
}
|
|
});
|
|
|
|
export default router
|