Files
012-kaopeilian/frontend/src/router/index.ts
yuliang_guo 8500308919
All checks were successful
continuous-integration/drone/push Build is passing
feat: 添加功能开关机制
- 添加环境变量配置 VITE_FEATURE_DUO_PRACTICE 等
- env.ts 新增 isFeatureEnabled 方法
- 菜单根据功能开关动态显示/隐藏
- 路由守卫拦截未启用功能的直接访问
- 开发环境默认开启双人对练,生产环境默认关闭
2026-01-31 14:26:52 +08:00

363 lines
11 KiB
TypeScript

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import Layout from '@/layout/index.vue'
import { setupRouterGuard } from './guard'
/**
* 路由配置
*/
const routes: RouteRecordRaw[] = [
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [
{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index.vue'),
meta: { title: '首页概览', icon: 'HomeFilled', roles: ['admin', 'manager', 'trainee'] }
}
]
},
{
path: '/trainee',
component: Layout,
redirect: '/trainee/course-center',
meta: { title: '学员中心', icon: 'Reading', roles: ['admin', 'manager', 'trainee'] },
children: [
{
path: 'growth-path',
name: 'GrowthPath',
component: () => import('@/views/trainee/growth-path.vue'),
meta: { title: '我的成长路径', icon: 'TrendCharts' }
},
{
path: 'leaderboard',
name: 'Leaderboard',
component: () => import('@/views/trainee/leaderboard.vue'),
meta: { title: '等级排行榜', icon: 'Trophy' }
},
{
path: 'my-certificates',
name: 'MyCertificates',
component: () => import('@/views/trainee/my-certificates.vue'),
meta: { title: '我的证书', icon: 'Medal' }
},
{
path: 'course-center',
name: 'CourseCenter',
component: () => import('@/views/trainee/course-center.vue'),
meta: { title: '课程中心', icon: 'Collection' }
},
{
path: 'course-detail',
name: 'CourseDetail',
component: () => import('@/views/trainee/course-detail.vue'),
meta: { title: '课程详情', hidden: true }
},
{
path: 'audio-player',
name: 'AudioPlayer',
component: () => import('@/views/trainee/audio-player.vue'),
meta: { title: '音频播放', hidden: true }
},
{
path: 'broadcast-course',
name: 'BroadcastCourse',
component: () => import('@/views/trainee/broadcast-course.vue'),
meta: { title: '播课', hidden: true }
},
{
path: 'exam',
name: 'TraineeExam',
component: () => import('@/views/exam/practice.vue'),
meta: { title: '动态考试', icon: 'Edit', hidden: true }
},
{
path: 'ai-practice-center',
name: 'AIPracticeCenter',
component: () => import('@/views/trainee/ai-practice-center.vue'),
meta: { title: '陪练中心', icon: 'Microphone' }
},
{
path: 'score-query',
name: 'TraineeScoreQuery',
component: () => import('@/views/trainee/score-query.vue'),
meta: { title: '查分中心', icon: 'Document' }
},
{
path: 'score-report',
name: 'TraineeScoreReport',
component: () => import('@/views/analysis/report.vue'),
meta: { title: '成绩报告', icon: 'Document' }
},
{
path: 'mistakes',
name: 'TraineeMistakes',
component: () => import('@/views/analysis/mistakes.vue'),
meta: { title: '错题分析', icon: 'Warning' }
},
{
path: 'practice-records',
name: 'PracticeRecords',
component: () => import('@/views/trainee/practice-records.vue'),
meta: { title: '陪练记录', icon: 'DocumentCopy' }
},
{
path: 'exam-result',
name: 'ExamResult',
component: () => import('@/views/trainee/exam-result.vue'),
meta: { title: '考试结果', hidden: true }
},
{
path: 'ai-practice',
name: 'AIPractice',
component: () => import('@/views/trainee/ai-practice.vue'),
meta: { title: 'AI陪练', hidden: true }
},
{
path: 'practice-report/:id?',
name: 'PracticeReport',
component: () => import('@/views/trainee/practice-report.vue'),
meta: { title: '陪练分析报告', hidden: true }
},
{
path: 'chat-course',
name: 'ChatCourse',
component: () => import('@/views/trainee/chat-course.vue'),
meta: { title: '与课程对话', hidden: true }
},
{
path: 'ai-practice-coze',
name: 'AIPracticeCoze',
component: () => import('@/views/trainee/ai-practice-coze.vue'),
meta: { title: 'AI陪练会话', hidden: true }
},
{
path: 'duo-practice',
name: 'DuoPractice',
component: () => import('@/views/trainee/duo-practice.vue'),
meta: { title: '双人对练', icon: 'Connection', feature: 'duo-practice' }
},
{
path: 'duo-practice/room/:code',
name: 'DuoPracticeRoom',
component: () => import('@/views/trainee/duo-practice-room.vue'),
meta: { title: '对练房间', hidden: true, feature: 'duo-practice' }
},
{
path: 'duo-practice/join/:code',
name: 'DuoPracticeJoin',
component: () => import('@/views/trainee/duo-practice-room.vue'),
meta: { title: '加入对练', hidden: true, feature: 'duo-practice' }
},
{
path: 'duo-practice/report/:id',
name: 'DuoPracticeReport',
component: () => import('@/views/trainee/duo-practice-report.vue'),
meta: { title: '对练报告', hidden: true, feature: 'duo-practice' }
}
]
},
{
path: '/manager',
component: Layout,
redirect: '/manager/team-dashboard',
meta: { title: '管理者视图', icon: 'DataBoard', roles: ['admin', 'manager'] },
children: [
{
path: 'team-dashboard',
name: 'TeamDashboard',
component: () => import('@/views/manager/team-dashboard.vue'),
meta: { title: '团队看板', icon: 'DataLine' }
},
{
path: 'data-dashboard',
name: 'DataDashboard',
component: () => import('@/views/admin/data-dashboard.vue'),
meta: { title: '数据大屏', icon: 'Monitor' }
},
{
path: 'team-management',
name: 'TeamManagement',
component: () => import('@/views/manager/team-management.vue'),
meta: { title: '团队成员管理', icon: 'UserFilled' }
},
{
path: 'assignment-center',
name: 'AssignmentCenter',
component: () => import('@/views/manager/assignment-center.vue'),
meta: { title: '任务中心', icon: 'Tickets' }
},
{
path: 'growth-path-management',
name: 'GrowthPathManagement',
component: () => import('@/views/manager/growth-path-management.vue'),
meta: { title: '成长路径管理', icon: 'Finished' }
},
{
path: 'course-management',
name: 'CourseManagement',
component: () => import('@/views/manager/course-management.vue'),
meta: { title: '课程管理', icon: 'Document' }
},
{
path: 'create-course',
name: 'CreateCourse',
component: () => import('@/views/manager/edit-course.vue'),
meta: { title: '创建课程', hidden: true }
},
{
path: 'edit-course/:id',
name: 'EditCourse',
component: () => import('@/views/manager/edit-course.vue'),
meta: { title: '编辑课程', hidden: true }
},
{
path: 'practice-scene-management',
name: 'PracticeSceneManagement',
component: () => import('@/views/manager/practice-scene-management.vue'),
meta: { title: '陪练场景管理', icon: 'Microphone' }
},
{
path: 'student-scores',
name: 'StudentScores',
component: () => import('@/views/manager/student-scores.vue'),
meta: { title: '学员考试成绩', icon: 'DataAnalysis' }
},
{
path: 'student-practice',
name: 'StudentPractice',
component: () => import('@/views/manager/student-practice.vue'),
meta: { title: '学员陪练记录', icon: 'ChatLineRound' }
}
]
},
{
path: '/admin',
component: Layout,
redirect: '/admin/dashboard',
meta: { title: '系统管理', icon: 'Setting', roles: ['admin'] },
children: [
{
path: 'dashboard',
name: 'AdminDashboard',
component: () => import('@/views/admin/dashboard.vue'),
meta: { title: '管理员仪表盘', icon: 'Monitor' }
},
{
path: 'user-management',
name: 'UserManagement',
component: () => import('@/views/admin/user-management.vue'),
meta: { title: '用户管理', icon: 'User' }
},
{
path: 'position-management',
name: 'PositionManagement',
component: () => import('@/views/admin/position-management.vue'),
meta: { title: '岗位管理', icon: 'Stamp' }
},
{
path: 'logs',
name: 'AdminLogs',
component: () => import('@/views/admin/logs.vue'),
meta: { title: '系统日志', icon: 'Files' }
},
{
path: 'settings',
name: 'SystemSettings',
component: () => import('@/views/admin/system-settings.vue'),
meta: { title: '系统设置', icon: 'Setting' }
}
]
},
{
path: '/analysis',
component: Layout,
redirect: '/analysis/statistics',
meta: { title: '数据分析', icon: 'DataAnalysis', roles: ['admin', 'manager'] },
children: [
{
path: 'statistics',
name: 'Statistics',
component: () => import('@/views/analysis/statistics.vue'),
meta: { title: '统计分析', icon: 'PieChart' }
}
]
},
{
path: '/exam',
component: Layout,
redirect: '/exam/practice',
meta: { title: '考试练习', icon: 'Edit' },
children: [
{
path: 'practice',
name: 'ExamPractice',
component: () => import('@/views/exam/practice.vue'),
meta: { title: '动态考试', icon: 'EditPen' }
}
]
},
{
path: '/user',
component: Layout,
redirect: '/user/profile',
meta: { title: '用户中心', icon: 'User', roles: ['admin', 'manager', 'trainee'] },
children: [
{
path: 'profile',
name: 'Profile',
component: () => import('@/views/user/profile.vue'),
meta: { title: '个人信息', icon: 'UserFilled' }
},
{
path: 'settings',
name: 'Settings',
component: () => import('@/views/user/settings.vue'),
meta: { title: '系统设置', icon: 'Setting' }
},
{
path: 'change-password',
name: 'ChangePassword',
component: () => import('@/views/user/change-password.vue'),
meta: { title: '修改密码', hidden: true }
},
{
path: 'notifications',
name: 'Notifications',
component: () => import('@/views/user/notifications.vue'),
meta: { title: '消息中心', icon: 'Bell' }
}
]
},
{
path: '/login',
name: 'Login',
component: () => import('@/views/login/index.vue'),
meta: { hidden: true }
},
{
path: '/register',
name: 'Register',
component: () => import('@/views/register/index.vue'),
meta: { hidden: true }
},
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: () => import('@/views/error/404.vue'),
meta: { hidden: true }
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
// 设置路由守卫
setupRouterGuard(router)
export default router