178 lines
5.2 KiB
TypeScript
178 lines
5.2 KiB
TypeScript
import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'
|
||
import { useAuthStore } from '@/stores/auth'
|
||
|
||
const routes: RouteRecordRaw[] = [
|
||
// ==================== 认证页面(套用 AuthLayout)=====================
|
||
{
|
||
path: '/auth',
|
||
component: () => import('@/layouts/AuthLayout.vue'),
|
||
meta: { requiresAuth: false },
|
||
children: [
|
||
{ path: '/login', name: 'Login', component: () => import('@/views/auth/LoginView.vue') },
|
||
{ path: '/register', name: 'Register', component: () => import('@/views/auth/RegisterView.vue') },
|
||
],
|
||
},
|
||
|
||
// ==================== 主界面(统一布局)=====================
|
||
{
|
||
path: '/',
|
||
component: () => import('@/layouts/UnifiedLayout.vue'),
|
||
meta: { requiresAuth: true },
|
||
children: [
|
||
// 聊天
|
||
{
|
||
path: 'chat',
|
||
children: [
|
||
{
|
||
path: '',
|
||
name: 'ChatList',
|
||
components: {
|
||
secondary: () => import('@/views/chat/ConversationListPanel.vue'),
|
||
default: () => import('@/views/chat/ChatListView.vue'),
|
||
},
|
||
},
|
||
{
|
||
path: ':id',
|
||
name: 'ChatRoom',
|
||
meta: { hideSecondary: true },
|
||
components: {
|
||
secondary: () => import('@/views/chat/ConversationListPanel.vue'),
|
||
default: () => import('@/views/chat/ChatRoomView.vue'),
|
||
},
|
||
},
|
||
],
|
||
},
|
||
|
||
// 通讯录
|
||
{
|
||
path: 'contacts',
|
||
children: [
|
||
{
|
||
path: '',
|
||
name: 'Contacts',
|
||
components: {
|
||
secondary: () => import('@/views/contacts/ContactsSidebar.vue'),
|
||
default: () => import('@/views/contacts/ContactsView.vue'),
|
||
},
|
||
},
|
||
{
|
||
path: 'search',
|
||
name: 'Search',
|
||
components: {
|
||
secondary: () => import('@/views/contacts/ContactsSidebar.vue'),
|
||
default: () => import('@/views/contacts/SearchView.vue'),
|
||
},
|
||
},
|
||
],
|
||
},
|
||
|
||
// 朋友圈
|
||
{
|
||
path: 'moments',
|
||
name: 'Moments',
|
||
components: {
|
||
secondary: () => import('@/views/moments/MomentsFeedView.vue'),
|
||
default: () => import('@/views/moments/MomentsFeedView.vue'),
|
||
},
|
||
},
|
||
|
||
// 设置
|
||
{
|
||
path: 'settings',
|
||
children: [
|
||
{
|
||
path: '',
|
||
redirect: '/settings/profile',
|
||
},
|
||
{
|
||
path: 'profile',
|
||
name: 'SettingsProfile',
|
||
components: {
|
||
secondary: () => import('@/views/settings/SettingsSidebar.vue'),
|
||
default: () => import('@/views/settings/ProfileSettingsView.vue'),
|
||
},
|
||
},
|
||
{
|
||
path: 'account',
|
||
name: 'SettingsAccount',
|
||
components: {
|
||
secondary: () => import('@/views/settings/SettingsSidebar.vue'),
|
||
default: () => import('@/views/settings/AccountSettingsView.vue'),
|
||
},
|
||
},
|
||
{
|
||
path: 'notifications',
|
||
name: 'SettingsNotifications',
|
||
components: {
|
||
secondary: () => import('@/views/settings/SettingsSidebar.vue'),
|
||
default: () => import('@/views/settings/NotificationSettingsView.vue'),
|
||
},
|
||
},
|
||
{
|
||
path: 'about',
|
||
name: 'SettingsAbout',
|
||
components: {
|
||
secondary: () => import('@/views/settings/SettingsSidebar.vue'),
|
||
default: () => import('@/views/settings/AboutView.vue'),
|
||
},
|
||
},
|
||
],
|
||
},
|
||
|
||
// 根路径重定向
|
||
{ path: '', redirect: '/chat' },
|
||
{ path: 'profile', redirect: '/settings/profile' },
|
||
],
|
||
},
|
||
|
||
// ==================== 管理后台 =====================
|
||
{
|
||
path: '/admin/login',
|
||
name: 'AdminLogin',
|
||
component: () => import('@/views/admin/AdminLoginView.vue'),
|
||
meta: { requiresAuth: false },
|
||
},
|
||
{
|
||
path: '/admin',
|
||
component: () => import('@/layouts/AdminLayout.vue'),
|
||
meta: { requiresAuth: true },
|
||
children: [
|
||
{ path: '', redirect: '/admin/dashboard' },
|
||
{ path: 'dashboard', name: 'AdminDashboard', component: () => import('@/views/admin/AdminDashboardView.vue') },
|
||
{ path: 'users', name: 'AdminUsers', component: () => import('@/views/admin/AdminUsersView.vue') },
|
||
{ path: 'messages', name: 'AdminMessages', component: () => import('@/views/admin/AdminMessagesView.vue') },
|
||
{ path: 'config', name: 'AdminConfig', component: () => import('@/views/admin/AdminConfigView.vue') },
|
||
],
|
||
},
|
||
]
|
||
|
||
const router = createRouter({
|
||
history: createWebHistory(),
|
||
routes,
|
||
})
|
||
|
||
// 路由守卫
|
||
router.beforeEach(async (to, _from, next) => {
|
||
const authStore = useAuthStore()
|
||
|
||
// 首次加载时尝试恢复登录状态
|
||
if (!authStore.isAuthenticated && localStorage.getItem('access_token')) {
|
||
try {
|
||
await authStore.fetchProfile()
|
||
} catch {
|
||
authStore.logout()
|
||
}
|
||
}
|
||
|
||
const needsAuth = to.matched.some((record) => record.meta.requiresAuth)
|
||
|
||
if (needsAuth && !authStore.isAuthenticated) {
|
||
next({ name: 'Login', query: { redirect: to.fullPath } })
|
||
return
|
||
}
|
||
|
||
next()
|
||
})
|
||
|
||
export default router
|