Files
Henry_Du 4ce4649aaf
Build VoiceHub FPK / build-fpk (push) Failing after 56m5s
Build and Push Docker Image / build-and-push (push) Canceled after 1h9m35s
初次提交
2026-09-06 08:19:02 +08:00

200 lines
5.7 KiB
TypeScript

import { apiKeyPermissions, apiKeys, db, users } from '~/drizzle/db'
import { and, count, desc, eq, inArray, sql } from 'drizzle-orm'
/**
* 获取API Key列表
* GET /api/admin/api-keys
*/
export default defineEventHandler(async (event) => {
// 检查用户权限 - 只有超级管理员可以管理API Key
const user = event.context.user
if (!user || user.role !== 'SUPER_ADMIN') {
throw createError({
statusCode: 403,
statusMessage: '只有超级管理员可以管理API Key'
})
}
const query = getQuery(event)
const page = parseInt(query.page as string) || 1
const limit = parseInt(query.limit as string) || 20
const search = (query.search as string) || ''
const status = query.status as string // 'active', 'inactive', 'expired'
const offset = (page - 1) * limit
try {
// 构建查询条件
const whereConditions = []
if (search) {
whereConditions.push(
sql`${apiKeys.name} ILIKE ${`%${search}%`} OR ${apiKeys.description} ILIKE ${`%${search}%`}`
)
}
if (status === 'active') {
whereConditions.push(
and(
eq(apiKeys.isActive, true),
sql`(${apiKeys.expiresAt} IS NULL OR ${apiKeys.expiresAt} > NOW())`
)
)
} else if (status === 'inactive') {
whereConditions.push(eq(apiKeys.isActive, false))
} else if (status === 'expired') {
whereConditions.push(
and(
eq(apiKeys.isActive, true),
sql`${apiKeys.expiresAt} IS NOT NULL AND ${apiKeys.expiresAt} <= NOW()`
)
)
}
const whereClause =
whereConditions.length > 0
? whereConditions.length === 1
? whereConditions[0]
: and(...whereConditions)
: undefined
// 获取API Key列表
const apiKeysList = await db
.select({
id: apiKeys.id,
name: apiKeys.name,
description: apiKeys.description,
keyPrefix: apiKeys.keyPrefix,
isActive: apiKeys.isActive,
expiresAt: apiKeys.expiresAt,
usageCount: apiKeys.usageCount,
lastUsedAt: apiKeys.lastUsedAt,
createdAt: apiKeys.createdAt,
updatedAt: apiKeys.updatedAt,
createdByUserId: apiKeys.createdByUserId,
creatorName: users.name
})
.from(apiKeys)
.leftJoin(users, eq(apiKeys.createdByUserId, users.id))
.where(whereClause)
.orderBy(desc(apiKeys.createdAt))
.limit(limit)
.offset(offset)
// 获取总数
const totalResult = await db.select({ count: count() }).from(apiKeys).where(whereClause)
const total = totalResult[0]?.count || 0
// 获取每个API Key的权限
const apiKeyIds = apiKeysList.map((key) => key.id).filter((id) => id != null)
let permissions = []
if (apiKeyIds.length > 0) {
try {
permissions = await db
.select({
apiKeyId: apiKeyPermissions.apiKeyId,
permission: apiKeyPermissions.permission
})
.from(apiKeyPermissions)
.where(inArray(apiKeyPermissions.apiKeyId, apiKeyIds))
// 确保permissions是数组
if (!Array.isArray(permissions)) {
permissions = []
}
} catch (permError) {
console.error('获取权限数据失败:', permError)
permissions = []
}
}
// 组织权限数据
const permissionsMap: Record<string, string[]> = {}
try {
if (permissions && Array.isArray(permissions) && permissions.length > 0) {
for (const perm of permissions) {
if (
perm &&
typeof perm === 'object' &&
perm.hasOwnProperty('apiKeyId') &&
perm.hasOwnProperty('permission') &&
perm.apiKeyId != null &&
perm.permission != null
) {
const apiKeyId = String(perm.apiKeyId)
const permission = String(perm.permission)
if (apiKeyId && permission) {
if (!permissionsMap[apiKeyId]) {
permissionsMap[apiKeyId] = []
}
permissionsMap[apiKeyId].push(permission)
}
}
}
}
} catch (mapError) {
console.error('组织权限数据失败:', mapError)
// permissionsMap已经初始化为空对象,继续执行
}
// 组合结果
let result = []
try {
if (Array.isArray(apiKeysList)) {
result = apiKeysList
.map((key) => {
// 确保key对象存在且有必要的属性
if (!key || typeof key !== 'object' || key.id == null) {
return null
}
try {
const keyId = String(key.id)
const expiresAt = key.expiresAt ? new Date(key.expiresAt) : null
const now = new Date()
return {
...key,
permissions: permissionsMap[keyId] || [],
isExpired: expiresAt ? now > expiresAt : false,
status: !key.isActive
? 'inactive'
: expiresAt && now > expiresAt
? 'expired'
: 'active'
}
} catch (keyError) {
console.error('处理API Key数据失败:', keyError, key)
return null
}
})
.filter(Boolean) // 过滤掉null值
}
} catch (resultError) {
console.error('组合结果失败:', resultError)
result = []
}
return {
success: true,
data: {
items: result,
pagination: {
page,
limit,
total,
totalPages: Math.ceil(total / limit)
}
}
}
} catch (error: any) {
throw createError({
statusCode: 500,
statusMessage: `获取API Key列表失败: ${error.message}`
})
}
})