import { createRouter, createWebHistory } from "vue-router"; import { useAuthStore } from "../stores/auth"; const routes = [ { path: "/login", name: "login", component: () => import("../views/LoginView.vue") }, { path: "/", component: () => import("../layout/MainLayout.vue"), meta: { requiresAuth: true }, children: [ { path: "", name: "home", component: () => import("../views/HomeView.vue"), meta: { roles: ["SYS_ADMIN", "DEVELOPER"] }, }, { path: "customers", name: "customers", component: () => import("../views/CustomersView.vue"), meta: { roles: ["SYS_ADMIN", "DEVELOPER"] }, }, { path: "projects", name: "projects", component: () => import("../views/ProjectsView.vue"), meta: { roles: ["SYS_ADMIN", "DEVELOPER"] }, }, { path: "contracts/new", name: "contract-new", component: () => import("../views/ContractWizardView.vue"), meta: { roles: ["SYS_ADMIN", "DEVELOPER"], title: "新建合同" }, }, { path: "contracts/:id", name: "contract-detail", component: () => import("../views/ContractDetailView.vue"), meta: { roles: ["SYS_ADMIN", "DEVELOPER"], title: "合同详情" }, }, { path: "contracts", name: "contracts", component: () => import("../views/ContractsView.vue"), meta: { roles: ["SYS_ADMIN", "DEVELOPER"], title: "合同管理" }, }, ], }, { path: "/403", name: "forbidden", component: () => import("../views/ForbiddenView.vue") }, { path: "/:pathMatch(.*)*", name: "notfound", component: () => import("../views/NotFoundView.vue") }, ]; const router = createRouter({ history: createWebHistory(), routes, }); function hasRoleAccess(metaRoles, userRoles) { if (!metaRoles || metaRoles.length === 0) return true; const set = new Set(userRoles || []); return metaRoles.some((r) => set.has(r)); } router.beforeEach((to) => { const auth = useAuthStore(); if (to.meta.requiresAuth && !auth.token) { return { name: "login", query: { redirect: to.fullPath } }; } if (to.meta.requiresAuth && to.meta.roles && !hasRoleAccess(to.meta.roles, auth.roles)) { return { name: "forbidden" }; } return true; }); export default router;