/** * Vue Router 配置 —— 替代旧 app.js 中 activePage + v-if 模式 * * 使用 Hash 模式(#/path),无需后端 SPA fallback 配置。 */ import { createRouter, createWebHashHistory, type RouteRecordRaw } from 'vue-router' import { useAuthStore } from '@/stores/auth' import { useCategoryStore } from '@/stores/category' import { useDocumentStore } from '@/stores/document' const routes: RouteRecordRaw[] = [ { path: '/', redirect: '/chat' }, // ==================== 智能客服 ==================== { path: '/chat', name: 'Chat', component: () => import('@/views/ChatPanel.vue') }, // ==================== 知识库 ==================== { path: '/knowledge/stats', name: 'DocStats', component: () => import('@/views/DocStats.vue') }, { path: '/knowledge/document', name: 'DocList', component: () => import('@/views/DocList.vue') }, { path: '/knowledge/upload', name: 'DocUpload', component: () => import('@/views/DocUpload.vue') }, { path: '/knowledge/category', name: 'Category', component: () => import('@/views/CategoryManager.vue') }, { path: '/knowledge/search', name: 'DocSearch', component: () => import('@/views/DocSearch.vue') }, { path: '/knowledge/faq', name: 'FaqManager', component: () => import('@/views/FaqManager.vue') }, { path: '/knowledge/feedback-ops', name: 'FeedbackOps', component: () => import('@/views/FeedbackOps.vue') }, // ==================== 会话管理 ==================== { path: '/conversation', name: 'Conversation', component: () => import('@/views/ConversationManager.vue') }, // ==================== 运营看板 ==================== { path: '/dashboard', name: 'Dashboard', component: () => import('@/views/DashboardPanel.vue') }, // ==================== 系统设置 ==================== { path: '/settings/role', name: 'RoleManager', component: () => import('@/views/RoleManager.vue') }, { path: '/settings/model-config', name: 'ModelConfig', component: () => import('@/views/ModelConfigManager.vue') }, { path: '/settings/sensitive', name: 'SensitiveWord', component: () => import('@/views/SensitiveWordManager.vue') }, { path: '/settings/audit-log', name: 'AuditLog', component: () => import('@/views/AuditLogManager.vue') }, { path: '/settings/user', name: 'UserManager', component: () => import('@/views/UserManager.vue') }, { path: '/settings/api-key', name: 'ApiKey', component: () => import('@/views/ApiKeyManager.vue') }, { path: '/settings/webhook', name: 'Webhook', component: () => import('@/views/WebhookManager.vue') }, { path: '/settings/mcp-server', name: 'McpServer', component: () => import('@/views/McpServerManager.vue') }, { path: '/settings/pipeline-flow', name: 'PipelineFlow', component: () => import('@/views/PipelineFlow.vue') }, { path: '/settings/system-config', name: 'SystemConfig', component: () => import('@/views/SystemConfigManager.vue') }, { path: '/settings/log-viewer', name: 'LogViewer', component: () => import('@/views/LogViewer.vue') }, // ==================== 兜底 ==================== { path: '/:pathMatch(.*)*', redirect: '/chat' }, ] const router = createRouter({ history: createWebHashHistory(), routes, }) /** 路由守卫:登录校验 + 页面数据预加载(替代旧 _onPageEnter) */ router.beforeEach(async (to, _from, next) => { // 页面数据预加载钩子 const pageId = to.name as string const categoryStore = useCategoryStore() const documentStore = useDocumentStore() switch (pageId) { case 'DocStats': case 'DocList': case 'DocSearch': case 'DocUpload': try { await Promise.all([ categoryStore.loadCategories(), documentStore.loadStats(), documentStore.loadTags(), ]) } catch { /* 预加载失败不阻塞导航 */ } break case 'Category': case 'FaqManager': case 'FeedbackOps': try { await categoryStore.loadCategories() } catch { /* */ } break case 'RoleManager': try { await categoryStore.loadCategories() } catch { /* */ } break } next() }) export default router