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:
109
frontend/src/stores/modules.ts
Normal file
109
frontend/src/stores/modules.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import { modulesApi, type ModuleStatus } from '@/api/modules'
|
||||
import { log } from '@/utils/logger'
|
||||
|
||||
export const useModuleStore = defineStore('modules', () => {
|
||||
const modules = ref<Record<string, ModuleStatus>>({})
|
||||
const loaded = ref(false)
|
||||
const loading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
|
||||
/**
|
||||
* 获取所有模块状态
|
||||
*/
|
||||
async function fetchModules() {
|
||||
if (loading.value) return
|
||||
|
||||
loading.value = true
|
||||
error.value = null
|
||||
|
||||
try {
|
||||
modules.value = await modulesApi.getAllStatus()
|
||||
loaded.value = true
|
||||
} catch (err: any) {
|
||||
log.error('Failed to fetch modules status', err)
|
||||
error.value = err.response?.data?.detail || '获取模块状态失败'
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查模块是否部署可用
|
||||
*/
|
||||
function isAvailable(moduleName: string): boolean {
|
||||
return modules.value[moduleName]?.available ?? false
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查模块是否运行启用
|
||||
*/
|
||||
function isEnabled(moduleName: string): boolean {
|
||||
return modules.value[moduleName]?.enabled ?? false
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查模块是否最终激活
|
||||
*/
|
||||
function isActive(moduleName: string): boolean {
|
||||
return modules.value[moduleName]?.active ?? false
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置模块启用状态
|
||||
*/
|
||||
async function setEnabled(moduleName: string, enabled: boolean) {
|
||||
try {
|
||||
await modulesApi.setEnabled(moduleName, enabled)
|
||||
// 刷新所有模块状态,确保依赖模块的 active 状态同步更新
|
||||
await fetchModules()
|
||||
return true
|
||||
} catch (err: any) {
|
||||
log.error(`Failed to set module ${moduleName} enabled=${enabled}`, err)
|
||||
error.value = err.response?.data?.detail || '设置模块状态失败'
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可用的管理菜单项(available 即显示)
|
||||
*/
|
||||
const availableAdminMenuItems = computed(() => {
|
||||
return Object.values(modules.value)
|
||||
.filter((m) => m.available && m.admin_route)
|
||||
.sort((a, b) => a.admin_menu_order - b.admin_menu_order)
|
||||
})
|
||||
|
||||
/**
|
||||
* 按分组获取可用的管理菜单项
|
||||
*/
|
||||
const availableAdminMenuItemsByGroup = computed(() => {
|
||||
const items = availableAdminMenuItems.value
|
||||
const groups: Record<string, ModuleStatus[]> = {}
|
||||
|
||||
for (const item of items) {
|
||||
const group = item.admin_menu_group || 'other'
|
||||
if (!groups[group]) {
|
||||
groups[group] = []
|
||||
}
|
||||
groups[group].push(item)
|
||||
}
|
||||
|
||||
return groups
|
||||
})
|
||||
|
||||
return {
|
||||
modules,
|
||||
loaded,
|
||||
loading,
|
||||
error,
|
||||
fetchModules,
|
||||
isAvailable,
|
||||
isEnabled,
|
||||
isActive,
|
||||
setEnabled,
|
||||
availableAdminMenuItems,
|
||||
availableAdminMenuItemsByGroup,
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user