refactor: 将访问令牌功能迁移至模块系统

- 新增 management_tokens 模块定义,支持通过环境变量控制可用性
- 从静态路由中移除 management-tokens,改由模块动态注册
- 前端路由添加模块激活检查,未激活时重定向到仪表盘
- 认证服务添加模块激活检查,未激活时禁止令牌认证
- 导航菜单中移除访问令牌入口(保留直接 URL 访问)
- 修复 alembic 迁移脚本格式和错误处理
This commit is contained in:
fawney19
2026-02-05 16:32:27 +08:00
parent 440721368f
commit 5be7813ab8
8 changed files with 210 additions and 77 deletions

View File

@@ -493,7 +493,6 @@ const navigation = computed(() => {
items: [
{ name: '模型目录', href: '/dashboard/models', icon: Box },
{ name: 'API 密钥', href: '/dashboard/api-keys', icon: Key },
{ name: '访问令牌', href: '/dashboard/management-tokens', icon: KeyRound },
]
},
{
@@ -517,6 +516,7 @@ const navigation = computed(() => {
// 图标映射
const iconMap: Record<string, LucideIcon> = {
Key,
KeyRound,
FileUp,
Shield,
Puzzle,
@@ -556,7 +556,6 @@ const navigation = computed(() => {
{ name: '提供商', href: '/admin/providers', icon: FolderTree },
{ name: '模型管理', href: '/admin/models', icon: Layers },
{ name: '独立密钥', href: '/admin/keys', icon: Key },
{ name: '访问令牌', href: '/admin/management-tokens', icon: KeyRound },
{ name: '异步任务', href: '/admin/async-tasks', icon: Zap },
{ name: '使用记录', href: '/admin/usage', icon: BarChart3 },
]

View File

@@ -87,7 +87,8 @@ const routes: RouteRecordRaw[] = [
{
path: 'management-tokens',
name: 'ManagementTokens',
component: () => importWithRetry(() => import('@/views/user/ManagementTokens.vue'))
component: () => importWithRetry(() => import('@/views/user/ManagementTokens.vue')),
meta: { module: 'management_tokens' }
},
{
path: 'announcements',
@@ -139,7 +140,8 @@ const routes: RouteRecordRaw[] = [
{
path: 'management-tokens',
name: 'AdminManagementTokens',
component: () => importWithRetry(() => import('@/views/user/ManagementTokens.vue'))
component: () => importWithRetry(() => import('@/views/user/ManagementTokens.vue')),
meta: { module: 'management_tokens' }
},
{
path: 'providers',
@@ -329,6 +331,26 @@ router.beforeEach(async (to, from, next) => {
}
next()
}
} 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('/dashboard')
return
}
}
// 用户侧需要检查模块是否激活active而不仅仅是可用available
if (!moduleStore.isActive(moduleName)) {
log.warn(`Module ${moduleName} is not active, redirecting to user dashboard`)
next('/dashboard')
return
}
next()
} else {
next()
}