mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
feat: 实现功能模块系统,支持模块的动态注册与启用控制
- 新增 ModuleRegistry 核心,支持模块注册、可用性检查和启用状态管理 - 新增模块管理 API(管理端和公共端),提供模块状态查询和启用控制 - 将 LDAP 功能迁移到模块系统,支持通过环境变量和数据库配置控制 - 前端新增模块管理页面和 store,支持模块启用/禁用操作 - 路由守卫集成模块状态检查,未激活模块的页面自动重定向 - 面包屑导航支持模块配置页面的层级显示 - Switch 组件新增 disabled 属性支持
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import type { RouteRecordRaw } from 'vue-router'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { useModuleStore } from '@/stores/modules'
|
||||
import { importWithRetry } from '@/utils/importRetry'
|
||||
import { log } from '@/utils/logger'
|
||||
|
||||
@@ -116,6 +117,11 @@ const routes: RouteRecordRaw[] = [
|
||||
name: 'SystemSettings',
|
||||
component: () => importWithRetry(() => import('@/views/admin/SystemSettings.vue'))
|
||||
},
|
||||
{
|
||||
path: 'modules',
|
||||
name: 'ModuleManagement',
|
||||
component: () => importWithRetry(() => import('@/views/admin/ModuleManagement.vue'))
|
||||
},
|
||||
{
|
||||
path: 'email',
|
||||
name: 'EmailSettings',
|
||||
@@ -124,7 +130,8 @@ const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: 'ldap',
|
||||
name: 'LdapSettings',
|
||||
component: () => importWithRetry(() => import('@/views/admin/LdapSettings.vue'))
|
||||
component: () => importWithRetry(() => import('@/views/admin/LdapSettings.vue')),
|
||||
meta: { module: 'ldap' }
|
||||
},
|
||||
{
|
||||
path: 'audit-logs',
|
||||
@@ -164,6 +171,7 @@ function isNetworkError(error: any): boolean {
|
||||
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
const authStore = useAuthStore()
|
||||
const moduleStore = useModuleStore()
|
||||
|
||||
try {
|
||||
// 如果有token但没有用户信息,尝试获取用户信息
|
||||
@@ -186,6 +194,7 @@ router.beforeEach(async (to, from, next) => {
|
||||
// 检查整个路由匹配记录链中的 meta
|
||||
const requiresAuth = to.matched.some(record => record.meta.requiresAuth !== false)
|
||||
const requiresAdmin = to.matched.some(record => record.meta.requiresAdmin)
|
||||
const moduleName = to.matched.find(record => record.meta.module)?.meta.module as string | undefined
|
||||
|
||||
// 如果需要认证但没有token,跳转到首页
|
||||
if (requiresAuth && !authStore.token) {
|
||||
@@ -212,6 +221,26 @@ router.beforeEach(async (to, from, next) => {
|
||||
log.warn('Non-admin user attempted to access admin page, redirecting to user dashboard')
|
||||
next('/dashboard')
|
||||
} else {
|
||||
// 检查模块可用性
|
||||
if (moduleName) {
|
||||
// 确保模块状态已加载
|
||||
if (!moduleStore.loaded) {
|
||||
try {
|
||||
await moduleStore.fetchModules()
|
||||
} catch (error) {
|
||||
// fail-close: 获取模块状态失败时拒绝访问
|
||||
log.warn('Failed to fetch modules status, denying access', { error })
|
||||
next('/admin/dashboard')
|
||||
return
|
||||
}
|
||||
}
|
||||
// 如果模块未激活(available && enabled),重定向到管理员首页
|
||||
if (!moduleStore.isActive(moduleName)) {
|
||||
log.warn(`Module ${moduleName} is not active, redirecting to admin dashboard`)
|
||||
next('/admin/dashboard')
|
||||
return
|
||||
}
|
||||
}
|
||||
next()
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user