| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- import { createRouter, createWebHistory } from 'vue-router'
- import type { RouteRecordRaw } from 'vue-router'
- import { useAuthStore } from '@/stores/auth'
- import MainLayout from '@/layouts/MainLayout.vue'
- const routes: RouteRecordRaw[] = [
- {
- path: '/',
- redirect: '/dashboard'
- },
- {
- path: '/login',
- name: 'Login',
- component: () => import('@/views/auth/Login.vue'),
- meta: { requiresGuest: true }
- },
- {
- path: '/register',
- name: 'Register',
- component: () => import('@/views/auth/Register.vue'),
- meta: { requiresGuest: true }
- },
- {
- path: '/oauth/callback',
- name: 'OAuthCallback',
- component: () => import('@/views/auth/OAuthCallback.vue')
- },
- {
- path: '/',
- component: MainLayout,
- meta: { requiresAuth: true },
- children: [
- {
- path: 'admin/basic-info',
- name: 'BasicInfo',
- redirect: '/admin/basic-info/standard',
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/basic-info/standard',
- name: 'BasicInfoStandard',
- component: () => import('@/views/basic-info/Index.vue'),
- props: { infoType: 'standard' },
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/basic-info/construction_plan',
- name: 'BasicInfoConstructionPlan',
- component: () => import('@/views/basic-info/Index.vue'),
- props: { infoType: 'construction_plan' },
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/basic-info/regulation',
- name: 'BasicInfoRegulation',
- component: () => import('@/views/basic-info/Index.vue'),
- props: { infoType: 'regulation' },
- meta: { requiresAdmin: true }
- },
- {
- path: 'dashboard',
- name: 'Dashboard',
- component: () => import('@/views/dashboard/Index.vue')
- },
- {
- path: 'profile',
- name: 'Profile',
- component: () => import('@/views/user/Profile.vue')
- },
- {
- path: 'admin',
- redirect: '/admin/dashboard'
- },
- {
- path: 'admin/dashboard',
- name: 'AdminDashboard',
- component: () => import('@/views/admin/Dashboard.vue'),
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/users',
- name: 'AdminUsers',
- component: () => import('@/views/admin/Users.vue'),
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/roles',
- name: 'AdminRoles',
- component: () => import('@/views/admin/Roles.vue'),
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/menus',
- name: 'AdminMenus',
- component: () => import('@/views/admin/Menus.vue'),
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/tasks',
- name: 'AdminTasks',
- component: () => import('@/views/admin/TaskManagement.vue'),
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/permissions',
- name: 'AdminPermissions',
- component: () => import('@/views/admin/Permissions.vue'),
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/apps',
- name: 'AdminApps',
- component: () => import('@/views/admin/Apps.vue'),
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/logs',
- name: 'AdminLogs',
- component: () => import('@/views/admin/Logs.vue'),
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/settings',
- name: 'AdminSettings',
- component: () => import('@/views/admin/Settings.vue'),
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/tags',
- name: 'AdminTags',
- component: () => import('@/views/admin/Tag.vue'),
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/documents',
- name: 'Documents',
- component: () => import('@/views/documents/Index.vue'),
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/images',
- name: 'Images',
- component: () => import('@/views/images/Index.vue'),
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/documents/kb',
- name: 'KnowledgeBase',
- component: () => import('@/views/documents/KnowledgeBase.vue'),
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/documents/snippet',
- name: 'KnowledgeSnippet',
- component: () => import('@/views/documents/KnowledgeSnippet.vue'),
- meta: { requiresAdmin: true }
- },
- {
- path: 'admin/documents/search-engine',
- name: 'SearchEngine',
- component: () => import('@/views/documents/SearchEngine.vue'),
- meta: { requiresAdmin: true }
- }
- ]
- },
- {
- path: '/unauthorized',
- name: 'Unauthorized',
- component: () => import('@/views/error/403.vue')
- },
- {
- path: '/:pathMatch(.*)*',
- name: 'NotFound',
- component: () => import('@/views/error/404.vue')
- }
- ]
- const router = createRouter({
- history: createWebHistory(),
- routes
- })
- // 路由守卫
- router.beforeEach(async (to, from, next) => {
- const authStore = useAuthStore()
-
- // 如果有token但没有用户信息,先尝试获取用户信息
- if (authStore.token && !authStore.user && !authStore.loading) {
- try {
- await authStore.checkAuth()
- } catch (error) {
- console.error('路由守卫检查认证状态失败:', error)
- }
- }
-
- // 检查是否需要认证
- if (to.meta.requiresAuth) {
- if (!authStore.isAuthenticated) {
- // 未登录,重定向到登录页
- next({
- name: 'Login',
- query: { redirect: to.fullPath }
- })
- return
- }
-
- // 检查是否需要管理员权限
- if (to.meta.requiresAdmin) {
- // For admin routes, check permissions
- if (authStore.isAdmin) {
- // Super admin or admin users can access all admin routes
- next()
- return
- } else {
- // For non-admin users, check if they have menu access to this specific path
- if (authStore.hasPathAccess(to.path)) {
- next()
- return
- } else {
- next({ name: 'Unauthorized' })
- return
- }
- }
- }
- }
-
- // 检查是否需要访客权限(已登录用户不能访问登录/注册页)
- if (to.meta.requiresGuest && authStore.isAuthenticated) {
- next({ name: 'Dashboard' })
- return
- }
-
- next()
- })
- export default router
|