// 路由配置文件:定义应用的所有路由及导航守卫 import { createRouter, createWebHistory } from 'vue-router' import { useUserStore } from '../store/user' import { useDatabaseStore } from '../store/database' import { useRegistrationStore } from '../store/registration' // 创建路由实例,使用 HTML5 History 模式 const router = createRouter({ history: createWebHistory(), routes: [ { path: '/database-setup', name: 'DatabaseSetup', component: () => import('../views/DatabaseSettings.vue'), // 首次数据库配置引导页(无需登录) }, { path: '/login', name: 'Login', component: () => import('../views/Login.vue'), // 登录页 }, { path: '/register', name: 'Register', component: () => import('../views/Register.vue'), // 注册页 }, { path: '/bill-import', name: 'BillImport', component: () => import('../views/BillImport.vue'), // 账单导入(独立页,无侧边栏) }, { path: '/', component: () => import('../views/Layout.vue'), // 主布局(带侧边栏) redirect: '/dashboard', // 默认跳转到统计面板 children: [ { path: 'dashboard', name: 'Dashboard', component: () => import('../views/Dashboard.vue'), // 统计面板 }, { path: 'transactions', name: 'Transactions', component: () => import('../views/TransactionList.vue'), // 收支记录 }, { path: 'categories', name: 'Categories', component: () => import('../views/CategoryManage.vue'), // 分类管理 }, { path: 'tags', name: 'Tags', component: () => import('../views/TagManage.vue'), // 标签管理 }, { path: 'rules', name: 'Rules', component: () => import('../views/RuleManage.vue'), // 规则管理(自定义分类与标签规则) }, { path: 'email-bills', // 跳转到上次访问的标签页,无记录时默认邮箱配置 redirect: () => { const tabs = ['configs', 'senderRules', 'messages'] const saved = typeof localStorage !== 'undefined' ? localStorage.getItem('emailBill.tab') : null return `/email-bills/${saved && tabs.includes(saved) ? saved : 'configs'}` }, }, { path: 'email-bills/:tab(configs|senderRules|messages)', name: 'EmailBills', component: () => import('../views/EmailBillManage.vue'), // 邮箱账单(邮箱配置/发件人规则/待处理账单) }, { path: 'settings', name: 'Settings', component: () => import('../views/Settings.vue'), // 系统设置(数据库 + AI 模型) }, { path: 'ai-usage', name: 'AiUsage', component: () => import('../views/AiUsage.vue'), // 模型使用情况 }, { path: 'logs', // 跳转到上次访问的日志标签页,无记录时默认访问日志 redirect: () => { const tabs = ['http', 'login', 'app'] const saved = typeof localStorage !== 'undefined' ? localStorage.getItem('logs.tab') : null return `/logs/${saved && tabs.includes(saved) ? saved : 'http'}` }, }, { path: 'logs/:tab(http|login|app)', name: 'Logs', component: () => import('../views/Logs.vue'), // 系统日志(访问日志/登录日志/运行日志) }, ], }, ], }) // 全局前置守卫:优先校验数据库配置,再校验登录状态 router.beforeEach(async (to, _from, next) => { const databaseStore = useDatabaseStore() // 首次进入时从后端加载数据库配置状态 if (!databaseStore.loaded) { await databaseStore.load() } // 数据库未配置:强制引导到配置页,避免用户卡在无法登录的状态 if (!databaseStore.configured) { if (to.path === '/database-setup') { next() } else { next('/database-setup') } return } // 已配置数据库:配置引导页不再需要,跳转到登录或首页 if (to.path === '/database-setup') { const userStore = useUserStore() next(userStore.token ? '/dashboard' : '/login') return } // 注册功能关闭且已有用户时,不允许访问注册页 if (to.path === '/register') { const registrationStore = useRegistrationStore() if (!registrationStore.loaded) { await registrationStore.load() } if (!registrationStore.status?.allowed) { next('/login') return } } const userStore = useUserStore() // 如果目标页面不是登录/注册页,且没有 token,则重定向到登录页并记录来源,登录后可回跳 if (to.path !== '/login' && to.path !== '/register' && !userStore.token) { next({ path: '/login', query: { redirect: to.fullPath } }) } else { next() } }) export default router