2025-10-21 16:50:33 +08:00
|
|
|
import { createRouter, createWebHistory } from 'vue-router'
|
|
|
|
|
import { useUserStore } from '@/stores/user'
|
2025-10-23 09:59:54 +08:00
|
|
|
import { ElMessage } from 'element-plus'
|
2025-10-21 16:50:33 +08:00
|
|
|
|
2025-10-23 09:59:54 +08:00
|
|
|
// 路由组件 - 使用懒加载优化性能
|
|
|
|
|
const Home = () => import('@/views/Home.vue')
|
|
|
|
|
const Login = () => import('@/views/Login.vue')
|
|
|
|
|
const Register = () => import('@/views/Register.vue')
|
|
|
|
|
const Orders = () => import('@/views/Orders.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 Dashboard = () => import('@/views/Dashboard.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')
|
2025-11-07 19:09:50 +08:00
|
|
|
const ImageToVideoDetail = () => import('@/views/ImageToVideoDetail.vue')
|
2025-10-23 09:59:54 +08:00
|
|
|
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')
|
2025-10-27 10:46:49 +08:00
|
|
|
const TaskStatusPage = () => import('@/views/TaskStatusPage.vue')
|
2025-11-13 17:01:39 +08:00
|
|
|
const TermsOfService = () => import('@/views/TermsOfService.vue')
|
2025-10-21 16:50:33 +08:00
|
|
|
|
|
|
|
|
const routes = [
|
|
|
|
|
{
|
|
|
|
|
path: '/works',
|
|
|
|
|
name: 'MyWorks',
|
|
|
|
|
component: MyWorks,
|
2025-10-23 09:59:54 +08:00
|
|
|
meta: { title: '我的作品', requiresAuth: true, keepAlive: true }
|
2025-10-21 16:50:33 +08:00
|
|
|
},
|
2025-10-27 10:46:49 +08:00
|
|
|
{
|
|
|
|
|
path: '/task-status',
|
|
|
|
|
name: 'TaskStatus',
|
|
|
|
|
component: TaskStatusPage,
|
|
|
|
|
meta: { title: '任务状态', requiresAuth: true }
|
|
|
|
|
},
|
2025-10-21 16:50:33 +08:00
|
|
|
{
|
|
|
|
|
path: '/video/:id',
|
|
|
|
|
name: 'VideoDetail',
|
|
|
|
|
component: VideoDetail,
|
|
|
|
|
meta: { title: '视频详情', requiresAuth: true }
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: '/text-to-video',
|
|
|
|
|
name: 'TextToVideo',
|
|
|
|
|
component: TextToVideo,
|
2025-10-23 09:59:54 +08:00
|
|
|
meta: { title: '文生视频', requiresAuth: true, keepAlive: true }
|
2025-10-21 16:50:33 +08:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: '/text-to-video/create',
|
|
|
|
|
name: 'TextToVideoCreate',
|
|
|
|
|
component: TextToVideoCreate,
|
2025-11-13 17:01:39 +08:00
|
|
|
meta: { title: '文生视频创作' }
|
2025-10-21 16:50:33 +08:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: '/image-to-video',
|
|
|
|
|
name: 'ImageToVideo',
|
|
|
|
|
component: ImageToVideo,
|
2025-10-23 09:59:54 +08:00
|
|
|
meta: { title: '图生视频', requiresAuth: true, keepAlive: true }
|
2025-10-21 16:50:33 +08:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: '/image-to-video/create',
|
|
|
|
|
name: 'ImageToVideoCreate',
|
|
|
|
|
component: ImageToVideoCreate,
|
2025-11-13 17:01:39 +08:00
|
|
|
meta: { title: '图生视频创作' }
|
2025-10-21 16:50:33 +08:00
|
|
|
},
|
2025-11-07 19:09:50 +08:00
|
|
|
{
|
|
|
|
|
path: '/image-to-video/detail/:taskId',
|
|
|
|
|
name: 'ImageToVideoDetail',
|
|
|
|
|
component: ImageToVideoDetail,
|
|
|
|
|
meta: { title: '图生视频详情', requiresAuth: true }
|
|
|
|
|
},
|
2025-10-21 16:50:33 +08:00
|
|
|
{
|
|
|
|
|
path: '/storyboard-video',
|
|
|
|
|
name: 'StoryboardVideo',
|
|
|
|
|
component: StoryboardVideo,
|
2025-10-23 09:59:54 +08:00
|
|
|
meta: { title: '分镜视频', requiresAuth: true, keepAlive: true }
|
2025-10-21 16:50:33 +08:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: '/storyboard-video/create',
|
|
|
|
|
name: 'StoryboardVideoCreate',
|
|
|
|
|
component: StoryboardVideoCreate,
|
2025-11-13 17:01:39 +08:00
|
|
|
meta: { title: '分镜视频创作' }
|
2025-10-21 16:50:33 +08:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: '/',
|
2025-11-05 18:18:53 +08:00
|
|
|
name: 'Root',
|
|
|
|
|
redirect: '/welcome' // 默认重定向到欢迎页面
|
2025-10-21 16:50:33 +08:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: '/welcome',
|
|
|
|
|
name: 'Welcome',
|
|
|
|
|
component: Welcome,
|
|
|
|
|
meta: { title: '欢迎', guest: true }
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: '/home',
|
|
|
|
|
name: 'Home',
|
|
|
|
|
component: Home,
|
|
|
|
|
meta: { title: '首页', requiresAuth: 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',
|
|
|
|
|
name: 'Orders',
|
|
|
|
|
component: Orders,
|
|
|
|
|
meta: { title: '订单管理', requiresAuth: 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 }
|
2025-10-22 09:37:59 +08:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
path: '/member-management',
|
|
|
|
|
name: 'MemberManagement',
|
|
|
|
|
component: MemberManagement,
|
|
|
|
|
meta: { title: '会员管理', requiresAuth: true, requiresAdmin: true }
|
2025-10-23 09:59:54 +08:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
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: '/hello',
|
|
|
|
|
name: 'HelloWorld',
|
|
|
|
|
component: HelloWorld,
|
|
|
|
|
meta: { title: 'Hello World' }
|
|
|
|
|
},
|
2025-11-13 17:01:39 +08:00
|
|
|
{
|
|
|
|
|
path: '/terms-of-service',
|
|
|
|
|
name: 'TermsOfService',
|
|
|
|
|
component: TermsOfService,
|
|
|
|
|
meta: { title: 'Vionow 服务条款' }
|
|
|
|
|
},
|
2025-10-21 16:50:33 +08:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
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()
|
|
|
|
|
|
2025-10-23 09:59:54 +08:00
|
|
|
// 优化:只在首次访问时初始化用户状态
|
2025-10-21 16:50:33 +08:00
|
|
|
if (!userStore.initialized) {
|
|
|
|
|
await userStore.init()
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-05 18:18:53 +08:00
|
|
|
// 处理根路径:如果已登录,重定向到个人主页;否则重定向到欢迎页面
|
|
|
|
|
if (to.path === '/' || to.path === '/welcome') {
|
|
|
|
|
if (userStore.isAuthenticated && to.path === '/') {
|
|
|
|
|
next('/profile')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// 未登录用户访问欢迎页面,允许访问
|
|
|
|
|
if (!userStore.isAuthenticated && to.path === '/welcome') {
|
|
|
|
|
next()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-21 16:50:33 +08:00
|
|
|
// 检查是否需要认证
|
|
|
|
|
if (to.meta.requiresAuth) {
|
|
|
|
|
if (!userStore.isAuthenticated) {
|
|
|
|
|
// 未登录,跳转到登录页
|
|
|
|
|
next({
|
|
|
|
|
path: '/login',
|
|
|
|
|
query: { redirect: to.fullPath }
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查管理员权限
|
|
|
|
|
if (to.meta.requiresAdmin && !userStore.isAdmin) {
|
2025-10-23 09:59:54 +08:00
|
|
|
// 权限不足,跳转到个人主页并显示警告
|
|
|
|
|
ElMessage.warning('权限不足,只有管理员才能访问此页面')
|
|
|
|
|
next('/profile')
|
2025-10-21 16:50:33 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-27 10:46:49 +08:00
|
|
|
// 已登录用户访问登录页,重定向到个人主页
|
2025-10-21 16:50:33 +08:00
|
|
|
if (to.meta.guest && userStore.isAuthenticated) {
|
2025-10-27 10:46:49 +08:00
|
|
|
next('/profile')
|
2025-10-21 16:50:33 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置页面标题
|
|
|
|
|
if (to.meta.title) {
|
|
|
|
|
document.title = `${to.meta.title} - AIGC Demo`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
next()
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('路由守卫错误:', error)
|
|
|
|
|
// 发生错误时,允许访问但显示错误信息
|
|
|
|
|
next()
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
export default router
|