// src/router/guards.ts import type { Router } from 'vue-router' import { useAuthStore } from '@/stores/auth' function hasAll(required: string[], owned: string[]) { return required.every((x) => owned.includes(x)) } export function registerGuards(router: Router) { router.beforeEach(async (to) => { const skipLogin = import.meta.env.VITE_SKIP_LOGIN === 'true' if (skipLogin) { if (to.name === 'login' || to.meta.guestOnly) { return { name: 'home' } } return true } const auth = useAuthStore() // Requires auth:未登入導去 login,附 redirect if (to.meta.requiresAuth && !auth.isAuthenticated) { if (to.name === 'login') return true return { name: 'login', query: { redirect: to.fullPath } } } // Role-based access control (RBAC) if (to.meta.roles?.length && !hasAll(to.meta.roles, auth.roles)) { return { name: 'forbidden' } } return true }) router.beforeResolve(() => { // 適合放:進頁前最後一步的「輕量」工作(例如開始進度條) // NProgress.start() 之類 return true }) router.afterEach((to) => { // 1) Document title const base = 'Demo App' document.title = to.meta.title ? `${to.meta.title} - ${base}` : base // 2) 追蹤(Analytics)可放這裡:pageview // 3) NProgress.done() }) router.onError((err) => { // Chunk load 失敗、動態 import 失敗等 // 可考慮:router.replace(current) 或導到錯誤頁 console.error('Router error:', err) }) }