feat: 完成情绪博物馆项目重构和功能增强 - 新增日记评论和帖子功能 - 重构前端架构,优化用户体验 - 完善WebSocket通信机制 - 更新项目文档和部署配置

This commit is contained in:
2025-07-27 10:05:59 +08:00
parent 6903ac1c0d
commit cc886cd4d5
126 changed files with 21179 additions and 15734 deletions
+270
View File
@@ -0,0 +1,270 @@
/**
* 路由守卫
*/
import type { Router, RouteLocationNormalized, NavigationGuardNext } from 'vue-router'
import { ElMessage } from 'element-plus'
import { useAuthStore } from '@/stores/auth'
import { envConfig } from '@/config/env'
// 不需要登录的路由白名单
const whiteList = [
'/login',
'/register',
'/forgot-password',
'/reset-password',
'/',
'/404',
'/403',
'/500'
]
// 需要登录的路由
const authRequiredRoutes = [
'/chat',
'/chat-history',
'/diary',
'/life-milestones',
'/life-trajectory',
'/messages',
'/personal-dashboard',
'/settings',
'/topic-tracker',
'/emotion',
'/map',
'/social',
'/analysis',
'/profile'
]
/**
* 检查路由是否需要认证
*/
const requiresAuth = (path: string): boolean => {
return authRequiredRoutes.some(route => path.startsWith(route))
}
/**
* 检查路由是否在白名单中
*/
const isInWhiteList = (path: string): boolean => {
return whiteList.includes(path) || whiteList.some(route => path.startsWith(route))
}
/**
* 权限检查守卫
*/
const authGuard = async (
to: RouteLocationNormalized,
from: RouteLocationNormalized,
next: NavigationGuardNext
) => {
const authStore = useAuthStore()
// 如果目标路由不需要认证,直接通过
if (!requiresAuth(to.path)) {
next()
return
}
// 检查是否已登录
if (!authStore.isLoggedIn) {
// 未登录,跳转到登录页
ElMessage.warning('请先登录')
next({
path: '/login',
query: { redirect: to.fullPath }
})
return
}
// 已登录,检查token是否有效
try {
// 这里可以添加token验证逻辑
// const isValid = await authStore.validateToken()
// if (!isValid) {
// throw new Error('Token无效')
// }
next()
} catch (error) {
console.error('Token验证失败:', error)
ElMessage.error('登录状态已过期,请重新登录')
// 清除认证状态
await authStore.logout()
// 跳转到登录页
next({
path: '/login',
query: { redirect: to.fullPath }
})
}
}
/**
* 页面标题守卫
*/
const titleGuard = (
to: RouteLocationNormalized,
from: RouteLocationNormalized,
next: NavigationGuardNext
) => {
// 设置页面标题
const title = to.meta.title as string
if (title) {
document.title = `${title} - ${envConfig.appTitle}`
} else {
document.title = envConfig.appTitle
}
next()
}
/**
* 页面加载进度守卫
*/
const progressGuard = (
to: RouteLocationNormalized,
from: RouteLocationNormalized,
next: NavigationGuardNext
) => {
// 这里可以添加页面加载进度条逻辑
// NProgress.start()
next()
}
/**
* 页面加载完成守卫
*/
const progressDoneGuard = () => {
// 这里可以添加页面加载完成逻辑
// NProgress.done()
}
/**
* 登录重定向守卫
*/
const loginRedirectGuard = (
to: RouteLocationNormalized,
from: RouteLocationNormalized,
next: NavigationGuardNext
) => {
const authStore = useAuthStore()
// 如果已登录且访问登录页,重定向到首页
if (authStore.isLoggedIn && (to.path === '/login' || to.path === '/register')) {
const redirect = to.query.redirect as string || '/'
next(redirect)
return
}
next()
}
// 移除权限检查守卫,该功能不存在
/**
* 安装路由守卫
*/
export const setupRouterGuards = (router: Router) => {
// 全局前置守卫
router.beforeEach(async (to, from, next) => {
try {
// 页面加载进度
// NProgress.start()
const authStore = useAuthStore()
console.log('🔍 路由守卫检查:', {
to: to.path,
from: from.path,
isLoggedIn: authStore.isLoggedIn,
hasToken: !!authStore.accessToken,
hasUserInfo: !!authStore.userInfo
})
// 如果已登录且访问登录页,重定向到首页
if (authStore.isLoggedIn && (to.path === '/login' || to.path === '/register')) {
const redirect = to.query.redirect as string || '/'
console.log('🔍 已登录用户访问登录页,重定向到:', redirect)
next(redirect)
return
}
// 检查是否需要认证
if (requiresAuth(to.path)) {
console.log('🔍 页面需要认证:', to.path)
// 如果当前未登录,先尝试恢复本地存储的认证状态
if (!authStore.isLoggedIn) {
console.log('🔍 路由守卫:尝试恢复本地认证状态')
const restored = authStore.restoreLocalAuth()
console.log('🔍 路由守卫:恢复结果:', restored)
if (restored) {
console.log('🔍 认证状态已恢复:', {
isLoggedIn: authStore.isLoggedIn,
hasToken: !!authStore.accessToken,
hasUserInfo: !!authStore.userInfo
})
}
}
// 再次检查登录状态
if (!authStore.isLoggedIn) {
console.log('🔍 用户未登录,跳转到登录页')
// 未登录,跳转到登录页
ElMessage.warning('请先登录')
next({
path: '/login',
query: { redirect: to.fullPath }
})
return
}
console.log('🔍 用户已登录,允许访问:', to.path)
}
// 设置页面标题
const title = to.meta.title as string
if (title) {
document.title = `${title} - ${envConfig.appTitle}`
} else {
document.title = envConfig.appTitle
}
next()
} catch (error) {
console.error('路由守卫错误:', error)
next()
}
})
// 全局后置守卫
router.afterEach((to, from) => {
// 页面加载完成
progressDoneGuard()
// 页面访问统计
if (envConfig.debug) {
console.log(`路由跳转: ${from.path} -> ${to.path}`)
}
})
// 全局解析守卫
router.beforeResolve((to, from, next) => {
// 这里可以添加异步数据加载逻辑
next()
})
}
export {
authGuard,
titleGuard,
progressGuard,
progressDoneGuard,
loginRedirectGuard,
requiresAuth,
isInWhiteList
}