feat: add SingleRecordMnt component for student record maintenance with search, add, edit, view, and delete functionalities
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
// 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)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user