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 navConfig = [ { group: '功能', order: 1, items: [ { name: '对标分析', path: 'content-style/benchmark', icon: 'grid', component: () => import('../views/content-style/Benchmark.vue') }, { name: '文案创作', path: 'content-style/copywriting', icon: 'text', component: () => import('../views/content-style/Copywriting.vue') }, { name: '热点趋势', path: 'trends/forecast', icon: 'text', component: () => import('../views/trends/Forecast.vue') }, { name: '智能体', path: 'agents', icon: 'robot', component: () => import('../views/agents/Agents.vue') }, ] }, { group: '数字人', order: 2, items: [ { name: '数字人', path: 'digital-human/kling', icon: 'user', component: () => import('../views/kling/IdentifyFace.vue') }, { name: '人声克隆', path: 'digital-human/voice-copy', icon: 'mic', component: () => import('../views/dh/VoiceCopy.vue') }, ] }, { group: '素材库', order: 3, items: [ { name: '素材列表', path: 'material/list', icon: 'grid', component: () => import('../views/material/MaterialListNew.vue') }, { name: '智能混剪', path: 'material/mix', icon: 'scissors', component: () => import('../views/material/Mix.vue') }, { name: '任务中心', path: 'system/task-management/:type', icon: 'video', component: () => import('../views/system/task-management/layout/TaskLayout.vue'), requiresAuth: true, params: { type: 'mix-task' } }, ] }, { group: '系统', order: 4, requiresAuth: true, items: [ { name: '风格设置', path: 'system/style-settings', icon: 'text', component: () => import('../views/system/style-settings/index.vue') }, ] } ] // 导航图标定义 const navIcons = { home: '', grid: '', text: '', mic: '', wave: '', user: '', video: '', folder: '', scissors: '', robot: '' } // ============ 辅助函数 ============ function findOrCreateParentRoute(routes, parentPath) { let parentRoute = routes.find(r => r.path === parentPath) if (!parentRoute) { parentRoute = { path: parentPath, children: [], meta: {} } routes.push(parentRoute) } return parentRoute } function addChildRoute(parentRoute, path, name, component, meta) { parentRoute.children.push({ path, name, component, meta }) } function setDefaultRedirect(parentRoute, redirectPath) { if (!parentRoute.children.some(c => c.path === '')) { parentRoute.children.unshift({ path: '', redirect: redirectPath }) } } // ============ 从导航配置生成路由 ============ function buildRoutesFromNav(config) { const parentRoutes = [] config.forEach(group => { group.items.forEach(item => { const [parentPath, ...childSegments] = item.path.split('/') const childPath = childSegments.join('/') || '' const parentRoute = findOrCreateParentRoute(parentRoutes, parentPath) parentRoute.meta.navGroup = group.group parentRoute.meta.navGroupOrder = group.order if (group.requiresAuth) { parentRoute.meta.requiresAuth = true } addChildRoute(parentRoute, childPath, item.name, item.component, { navIcon: item.icon, navLabel: item.name, requiresAuth: item.requiresAuth }) setDefaultRedirect(parentRoute, `/${item.path}`) }) }) const hiddenRoutes = [ { path: 'trends/heat', name: '热度分析', component: () => import('../views/trends/Heat.vue'), meta: { hidden: true } }, { path: 'material/mix-task', name: '混剪任务', component: () => import('../views/material/MixTaskList.vue'), meta: { hidden: true } }, { path: 'material/group', name: '素材分组', component: () => import('../views/material/MaterialGroup.vue'), meta: { hidden: true } }, { path: 'user/profile', name: '个人中心', component: () => import('../views/user/Profile.vue'), meta: { hidden: true } } ] hiddenRoutes.forEach(route => { const [parentPath, childPath] = route.path.split('/') const parentRoute = findOrCreateParentRoute(parentRoutes, parentPath) addChildRoute(parentRoute, childPath, route.name, route.component, route.meta) }) return parentRoutes } const routes = [ // 登录页面 { path: '/login', name: '登录', component: () => import('../views/auth/Login.vue'), meta: { requiresAuth: false } }, // 主布局 { path: '/', component: MainLayout, redirect: '/content-style/benchmark', children: buildRoutesFromNav(navConfig), meta: { requiresAuth: true } }, ] // 导出配置供 SidebarNav 使用 export { navConfig, navIcons } const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes, }) // 路由守卫 router.beforeEach(async (to, from, next) => { const userStore = useUserStore() const authenToken = tokenManager.getAccessToken() 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 } if (authenToken && !userStore.isLoggedIn) { userStore.fetchUserInfo() } next() }) export default router