Files
AIGC/demo/frontend/src/router/index.js

320 lines
9.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { createRouter, createWebHistory } from 'vue-router'
import { useUserStore } from '@/stores/user'
import { ElMessage } from 'element-plus'
// 路由组件 - 使用懒加载优化性能
const Login = () => import('@/views/Login.vue')
const Register = () => import('@/views/Register.vue')
const OrderDetail = () => import('@/views/OrderDetail.vue')
const OrderCreate = () => import('@/views/OrderCreate.vue')
const Payments = () => import('@/views/Payments.vue')
const PaymentCreate = () => import('@/views/PaymentCreate.vue')
const AdminOrders = () => import('@/views/AdminOrders.vue')
const AdminDashboard = () => import('@/views/AdminDashboard.vue')
const Welcome = () => import('@/views/Welcome.vue')
const Profile = () => import('@/views/Profile.vue')
const Subscription = () => import('@/views/Subscription.vue')
const MyWorks = () => import('@/views/MyWorks.vue')
const VideoDetail = () => import('@/views/VideoDetail.vue')
const TextToVideo = () => import('@/views/TextToVideo.vue')
const TextToVideoCreate = () => import('@/views/TextToVideoCreate.vue')
const ImageToVideo = () => import('@/views/ImageToVideo.vue')
const ImageToVideoCreate = () => import('@/views/ImageToVideoCreate.vue')
const ImageToVideoDetail = () => import('@/views/ImageToVideoDetail.vue')
const StoryboardVideo = () => import('@/views/StoryboardVideo.vue')
const StoryboardVideoCreate = () => import('@/views/StoryboardVideoCreate.vue')
const MemberManagement = () => import('@/views/MemberManagement.vue')
const SystemSettings = () => import('@/views/SystemSettings.vue')
const GenerateTaskRecord = () => import('@/views/GenerateTaskRecord.vue')
const HelloWorld = () => import('@/views/HelloWorld.vue')
const TaskStatusPage = () => import('@/views/TaskStatusPage.vue')
const TermsOfService = () => import('@/views/TermsOfService.vue')
const UserAgreement = () => import('@/views/UserAgreement.vue')
const PrivacyPolicy = () => import('@/views/PrivacyPolicy.vue')
const ChangePassword = () => import('@/views/ChangePassword.vue')
const SetPassword = () => import('@/views/SetPassword.vue')
const routes = [
{
path: '/works',
name: 'MyWorks',
component: MyWorks,
meta: { title: '我的作品', requiresAuth: true, keepAlive: true }
},
{
path: '/task-status',
name: 'TaskStatus',
component: TaskStatusPage,
meta: { title: '任务状态', requiresAuth: true }
},
{
path: '/video/:id',
name: 'VideoDetail',
component: VideoDetail,
meta: { title: '视频详情', requiresAuth: true }
},
{
path: '/text-to-video',
name: 'TextToVideo',
component: TextToVideo,
meta: { title: '文生视频', requiresAuth: true, keepAlive: true }
},
{
path: '/text-to-video/create',
name: 'TextToVideoCreate',
component: TextToVideoCreate,
meta: { title: '文生视频创作' }
},
{
path: '/image-to-video',
name: 'ImageToVideo',
component: ImageToVideo,
meta: { title: '图生视频', requiresAuth: true, keepAlive: true }
},
{
path: '/image-to-video/create',
name: 'ImageToVideoCreate',
component: ImageToVideoCreate,
meta: { title: '图生视频创作' }
},
{
path: '/image-to-video/detail/:taskId',
name: 'ImageToVideoDetail',
component: ImageToVideoDetail,
meta: { title: '图生视频详情', requiresAuth: true }
},
{
path: '/storyboard-video',
name: 'StoryboardVideo',
component: StoryboardVideo,
meta: { title: '分镜视频', requiresAuth: true, keepAlive: true }
},
{
path: '/storyboard-video/create',
name: 'StoryboardVideoCreate',
component: StoryboardVideoCreate,
meta: { title: '分镜视频创作' }
},
{
path: '/',
name: 'Root',
redirect: '/welcome' // 默认重定向到欢迎页面
},
{
path: '/welcome',
name: 'Welcome',
component: Welcome,
meta: { title: '欢迎', guest: true }
},
{
path: '/profile',
name: 'Profile',
component: Profile,
meta: { title: '个人主页', requiresAuth: true }
},
{
path: '/subscription',
name: 'Subscription',
component: Subscription,
meta: { title: '会员订阅', requiresAuth: true }
},
{
path: '/login',
name: 'Login',
component: Login,
meta: { title: '登录', guest: true }
},
{
path: '/register',
name: 'Register',
component: Register,
meta: { title: '注册', guest: true }
},
{
path: '/orders/:id',
name: 'OrderDetail',
component: OrderDetail,
meta: { title: '订单详情', requiresAuth: true }
},
{
path: '/orders/create',
name: 'OrderCreate',
component: OrderCreate,
meta: { title: '创建订单', requiresAuth: true }
},
{
path: '/payments',
name: 'Payments',
component: Payments,
meta: { title: '支付记录', requiresAuth: true }
},
{
path: '/payments/create',
name: 'PaymentCreate',
component: PaymentCreate,
meta: { title: '创建支付', requiresAuth: true }
},
{
path: '/admin/orders',
name: 'AdminOrders',
component: AdminOrders,
meta: { title: '订单管理', requiresAuth: true, requiresAdmin: true }
},
{
path: '/admin/dashboard',
name: 'AdminDashboard',
component: AdminDashboard,
meta: { title: '后台管理', requiresAuth: true, requiresAdmin: true }
},
{
path: '/member-management',
name: 'MemberManagement',
component: MemberManagement,
meta: { title: '会员管理', requiresAuth: true, requiresAdmin: true }
},
{
path: '/system-settings',
name: 'SystemSettings',
component: SystemSettings,
meta: { title: '系统设置', requiresAuth: true, requiresAdmin: true }
},
{
path: '/generate-task-record',
name: 'GenerateTaskRecord',
component: GenerateTaskRecord,
meta: { title: '生成任务记录', requiresAuth: true, requiresAdmin: true }
},
{
path: '/api-management',
name: 'ApiManagement',
component: () => import('@/views/ApiManagement.vue'),
meta: { title: 'API管理', requiresAuth: true, requiresAdmin: true }
},
{
path: '/admin/error-statistics',
name: 'ErrorStatistics',
component: () => import('@/views/ErrorStatistics.vue'),
meta: { title: '错误统计', requiresAuth: true, requiresAdmin: true }
},
{
path: '/hello',
name: 'HelloWorld',
component: HelloWorld,
meta: { title: 'Hello World' }
},
{
path: '/terms-of-service',
name: 'TermsOfService',
component: TermsOfService,
meta: { title: 'Vionow 服务条款' }
},
{
path: '/user-agreement',
name: 'UserAgreement',
component: UserAgreement,
meta: { title: '用户协议' }
},
{
path: '/privacy-policy',
name: 'PrivacyPolicy',
component: PrivacyPolicy,
meta: { title: '隐私政策' }
},
{
path: '/change-password',
name: 'ChangePassword',
component: ChangePassword,
meta: { title: '修改密码', requiresAuth: true }
},
{
path: '/set-password',
name: 'SetPassword',
component: SetPassword,
meta: { title: '设置密码', requiresAuth: true }
},
]
const router = createRouter({
history: createWebHistory(),
routes,
// 添加路由缓存配置
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { top: 0 }
}
}
})
// 路由守卫
router.beforeEach(async (to, from, next) => {
try {
const userStore = useUserStore()
// 检查localStorage中的token是否被清除例如JWT过期后被request.js清除
// 如果token被清除但store中仍有用户信息则同步清除store
const storedToken = localStorage.getItem('token')
if (!storedToken && userStore.isAuthenticated) {
userStore.clearUserData()
}
// 优化:只在首次访问时初始化用户状态
if (!userStore.initialized) {
await userStore.init()
}
// 处理根路径:如果已登录,重定向到个人主页;否则重定向到欢迎页面
if (to.path === '/' || to.path === '/welcome') {
if (userStore.isAuthenticated && to.path === '/') {
next('/profile')
return
}
// 未登录用户访问欢迎页面,允许访问
if (!userStore.isAuthenticated && to.path === '/welcome') {
next()
return
}
}
// 检查是否需要认证
if (to.meta.requiresAuth) {
if (!userStore.isAuthenticated) {
// 未登录,跳转到登录页
next({
path: '/login',
query: { redirect: to.fullPath }
})
return
}
// 检查管理员权限
if (to.meta.requiresAdmin && !userStore.isAdmin) {
// 权限不足,跳转到个人主页并显示警告
ElMessage.warning('权限不足,只有管理员才能访问此页面')
next('/profile')
return
}
}
// 已登录用户访问登录页,重定向到个人主页
if (to.meta.guest && userStore.isAuthenticated) {
next('/profile')
return
}
// 设置页面标题
if (to.meta.title) {
document.title = `${to.meta.title} - AIGC Demo`
}
next()
} catch (error) {
console.error('路由守卫错误:', error)
// 发生错误时,允许访问但显示错误信息
next()
}
})
export default router