能看到内容了
This commit is contained in:
@@ -4,7 +4,50 @@ import router from './router'
|
||||
import App from './App.vue'
|
||||
import './assets/styles/global.css'
|
||||
|
||||
// 导入所有使用到的 Naive UI 组件
|
||||
import {
|
||||
NConfigProvider,
|
||||
NMessageProvider,
|
||||
NDialogProvider,
|
||||
NButton,
|
||||
NInput,
|
||||
NForm,
|
||||
NFormItem,
|
||||
NAvatar,
|
||||
NBadge,
|
||||
NCard,
|
||||
NDataTable,
|
||||
NSwitch,
|
||||
NSelect,
|
||||
NButtonGroup,
|
||||
} from 'naive-ui'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(createPinia())
|
||||
app.use(router)
|
||||
|
||||
// 全局注册 Naive UI 组件
|
||||
// 注意:必须用带 N 前缀的名字注册,因为模板中使用 <n-button> 等
|
||||
// Vue 会把 n-button 解析为 NButton,而 component.name 是 "Button"(无前缀),所以不能用 .name
|
||||
const naiveComponents: Record<string, any> = {
|
||||
NConfigProvider,
|
||||
NMessageProvider,
|
||||
NDialogProvider,
|
||||
NButton,
|
||||
NInput,
|
||||
NForm,
|
||||
NFormItem,
|
||||
NAvatar,
|
||||
NBadge,
|
||||
NCard,
|
||||
NDataTable,
|
||||
NSwitch,
|
||||
NSelect,
|
||||
NButtonGroup,
|
||||
}
|
||||
Object.entries(naiveComponents).forEach(([name, component]) => {
|
||||
app.component(name, component)
|
||||
})
|
||||
|
||||
app.mount('#app')
|
||||
|
||||
@@ -2,36 +2,30 @@ import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
// ==================== 认证页面(套用 AuthLayout)=====================
|
||||
{
|
||||
path: '/login',
|
||||
name: 'Login',
|
||||
component: () => import('@/views/auth/LoginView.vue'),
|
||||
meta: { requiresAuth: false, layout: 'auth' },
|
||||
},
|
||||
{
|
||||
path: '/register',
|
||||
name: 'Register',
|
||||
component: () => import('@/views/auth/RegisterView.vue'),
|
||||
meta: { requiresAuth: false, layout: 'auth' },
|
||||
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') },
|
||||
],
|
||||
},
|
||||
|
||||
// ==================== 聊天主界面(套用 ChatLayout)=====================
|
||||
{
|
||||
path: '/',
|
||||
component: () => import('@/layouts/ChatLayout.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
children: [
|
||||
{ path: '', redirect: '/chat' },
|
||||
{
|
||||
path: 'chat',
|
||||
name: 'ChatList',
|
||||
component: () => import('@/views/chat/ChatListView.vue'),
|
||||
},
|
||||
{
|
||||
path: 'chat/:id',
|
||||
name: 'ChatRoom',
|
||||
component: () => import('@/views/chat/ChatRoomView.vue'),
|
||||
},
|
||||
{ path: 'chat', name: 'ChatList', component: () => import('@/views/chat/ChatListView.vue') },
|
||||
{ path: 'chat/:id', name: 'ChatRoom', component: () => import('@/views/chat/ChatRoomView.vue') },
|
||||
],
|
||||
},
|
||||
|
||||
// ==================== 通讯录(套用 MainLayout)=====================
|
||||
{
|
||||
path: '/contacts',
|
||||
component: () => import('@/layouts/MainLayout.vue'),
|
||||
@@ -41,6 +35,8 @@ const routes: RouteRecordRaw[] = [
|
||||
{ path: 'search', name: 'Search', component: () => import('@/views/contacts/SearchView.vue') },
|
||||
],
|
||||
},
|
||||
|
||||
// ==================== 个人中心 =====================
|
||||
{
|
||||
path: '/profile',
|
||||
component: () => import('@/layouts/MainLayout.vue'),
|
||||
@@ -49,27 +45,24 @@ const routes: RouteRecordRaw[] = [
|
||||
{ path: '', name: 'Profile', component: () => import('@/views/profile/ProfileView.vue') },
|
||||
],
|
||||
},
|
||||
|
||||
// ==================== 管理后台 =====================
|
||||
{
|
||||
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: 'login',
|
||||
name: 'AdminLogin',
|
||||
component: () => import('@/views/admin/AdminLoginView.vue'),
|
||||
meta: { layout: 'auth' },
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/layouts/AdminLayout.vue'),
|
||||
meta: { requiresAdmin: 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') },
|
||||
],
|
||||
},
|
||||
{ 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') },
|
||||
],
|
||||
},
|
||||
]
|
||||
@@ -80,16 +73,22 @@ const router = createRouter({
|
||||
})
|
||||
|
||||
// 路由守卫
|
||||
router.beforeEach((to, _from, next) => {
|
||||
router.beforeEach(async (to, _from, next) => {
|
||||
const authStore = useAuthStore()
|
||||
|
||||
if (to.meta.requiresAuth && !authStore.isAuthenticated) {
|
||||
next({ name: 'Login', query: { redirect: to.fullPath } })
|
||||
return
|
||||
// 首次加载时尝试恢复登录状态
|
||||
if (!authStore.isAuthenticated && localStorage.getItem('access_token')) {
|
||||
try {
|
||||
await authStore.fetchProfile()
|
||||
} catch {
|
||||
authStore.logout()
|
||||
}
|
||||
}
|
||||
|
||||
if (to.meta.requiresAuth === false && authStore.isAuthenticated) {
|
||||
next({ name: 'ChatList' })
|
||||
const needsAuth = to.matched.some((record) => record.meta.requiresAuth)
|
||||
|
||||
if (needsAuth && !authStore.isAuthenticated) {
|
||||
next({ name: 'Login', query: { redirect: to.fullPath } })
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user