Files
sionrui/frontend/app/web-gold/src/router/index.js
2025-12-15 23:33:02 +08:00

136 lines
4.8 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 tokenManager from '@gold/utils/token-manager'
import MainLayout from '@/layouts/MainLayout.vue'
const routes = [
// 登录页面 - 独立渲染不使用Layout
{
path: '/login',
name: '登录',
component: () => import('../views/auth/Login.vue'),
meta: {
requiresAuth: false
}
},
// 主布局路由 - 所有需要Layout的页面都在这里
{
path: '/',
component: MainLayout,
redirect: '/content-style/benchmark',
children: [
{
path: 'content-style',
name: '内容风格分析',
children: [
{ path: '', redirect: '/content-style/benchmark' },
{ path: 'benchmark', name: '对标分析', component: () => import('../views/content-style/Benchmark.vue') },
{ path: 'copywriting', name: '文案创作', component: () => import('../views/content-style/Copywriting.vue') },
]
},
{
path: 'trends',
name: '热点趋势分析',
children: [
{ path: '', redirect: '/trends/heat' },
{ path: 'heat', name: '热度分析', component: () => import('../views/trends/Heat.vue') },
{ path: 'forecast', name: '热点预测', component: () => import('../views/trends/Forecast.vue') },
{ path: 'copywriting', name: '趋势文案创作', component: () => import('../views/trends/Copywriting.vue') },
]
},
{
path: 'digital-human',
name: '数字人',
children: [
{ path: '', redirect: '/digital-human/voice-copy' },
{ path: 'kling', name: '可灵数字人', component: () => import('../views/kling/IdentifyFace.vue') },
{ path: 'voice-copy', name: '人声克隆', component: () => import('../views/dh/VoiceCopy.vue') },
{ path: 'avatar', name: '生成数字人', component: () => import('../views/dh/Avatar.vue') },
{ path: 'video', name: '数字人视频', component: () => import('../views/dh/Video.vue') },
]
},
{
path: 'material',
name: '素材库',
children: [
{ path: '', redirect: '/material/list' },
{ path: 'list', name: '素材列表', component: () => import('../views/material/MaterialList.vue') },
{ path: 'mix', name: '智能混剪', component: () => import('../views/material/Mix.vue') },
{ path: 'mix-task', name: '混剪任务', component: () => import('../views/material/MixTaskList.vue') },
{ path: 'group', name: '素材分组', component: () => import('../views/material/MaterialGroup.vue') },
]
},
{
path: 'system',
name: '系统',
children: [
{ path: '', redirect: '/system/style-settings' },
{ path: 'style-settings', name: '风格设置', component: () => import('../views/system/StyleSettings.vue') },
],
meta: {
requiresAuth: true
}
},
{ path: 'realtime-hot', name: '实时热点推送', component: () => import('../views/realtime/RealtimeHot.vue') },
{ path: 'capcut-import', name: '剪映导入', component: () => import('../views/capcut/CapcutImport.vue') },
{ path: 'help', name: '帮助', component: () => import('../views/misc/Help.vue') },
{ path: 'download', name: '下载', component: () => import('../views/misc/Download.vue') },
{ path: 'settings/theme', name: '主题设置', component: () => import('../views/misc/Theme.vue') },
],
meta: {
requiresAuth: true
}
},
]
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes,
})
// 路由守卫
router.beforeEach(async (to, from, next) => {
const userStore = useUserStore()
// 等待 Pinia store 恢复完成(最多等待 500ms
if (to.meta.requiresAuth) {
let waitCount = 0
while (!userStore.isHydrated && waitCount < 50) {
await new Promise(resolve => setTimeout(resolve, 10))
waitCount++
}
}
// 检查是否已登录(通过 token 是否有效)
const authenToken = tokenManager.getToken()
// 路由访问控制
if (to.meta.requiresAuth && !authenToken) {
// 需要认证但未登录,跳转到登录页并记录当前路径
next({
path: '/login',
query: { redirect: to.fullPath }
})
return
}
// 已登录用户访问登录页,重定向到首页
if (to.path === '/login' && authenToken) {
next({ path: '/content-style/benchmark', replace: true })
return
}
// 首次访问且已登录时,同步用户信息到 store
if (authenToken) {
userStore.isLoggedIn = true
userStore.fetchUserInfo().catch(error => {
console.error('初始化用户信息失败:', error)
})
}
next()
})
export default router