diff --git a/src/routes/admin.js b/src/routes/admin.js index 36adfa73..954d2f98 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -24,6 +24,50 @@ const ProxyHelper = require('../utils/proxyHelper') const router = express.Router() +// 👥 用户管理 + +// 获取所有用户列表(用于API Key分配) +router.get('/users', authenticateAdmin, async (req, res) => { + try { + const userService = require('../services/userService') + const allUsers = await userService.getAllUsers() + + // 只返回活跃用户,并包含管理员选项 + const activeUsers = allUsers + .filter((user) => user.isActive) + .map((user) => ({ + id: user.id, + username: user.username, + displayName: user.displayName || user.username, + email: user.email, + role: user.role + })) + + // 添加Admin选项作为第一个 + const usersWithAdmin = [ + { + id: 'admin', + username: 'admin', + displayName: 'Admin', + email: '', + role: 'admin' + }, + ...activeUsers + ] + + return res.json({ + success: true, + data: usersWithAdmin + }) + } catch (error) { + logger.error('❌ Failed to get users list:', error) + return res.status(500).json({ + error: 'Failed to get users list', + message: error.message + }) + } +}) + // 🔑 API Keys 管理 // 调试:获取API Key费用详情 @@ -844,7 +888,8 @@ router.put('/api-keys/:keyId', authenticateAdmin, async (req, res) => { expiresAt, dailyCostLimit, weeklyOpusCostLimit, - tags + tags, + ownerId // 新增:所有者ID字段 } = req.body // 只允许更新指定字段 @@ -1014,6 +1059,45 @@ router.put('/api-keys/:keyId', authenticateAdmin, async (req, res) => { updates.isActive = isActive } + // 处理所有者变更 + if (ownerId !== undefined) { + const userService = require('../services/userService') + + if (ownerId === 'admin') { + // 分配给Admin + updates.userId = '' + updates.userUsername = '' + updates.createdBy = 'admin' + } else if (ownerId) { + // 分配给用户 + try { + const user = await userService.getUserById(ownerId, false) + if (!user) { + return res.status(400).json({ error: 'Invalid owner: User not found' }) + } + if (!user.isActive) { + return res.status(400).json({ error: 'Cannot assign to inactive user' }) + } + + // 设置新的所有者信息 + updates.userId = ownerId + updates.userUsername = user.username + updates.createdBy = user.username + + // 管理员重新分配时,不检查用户的API Key数量限制 + logger.info(`🔄 Admin reassigning API key ${keyId} to user ${user.username}`) + } catch (error) { + logger.error('Error fetching user for owner reassignment:', error) + return res.status(400).json({ error: 'Invalid owner ID' }) + } + } else { + // 清空所有者(分配给Admin) + updates.userId = '' + updates.userUsername = '' + updates.createdBy = 'admin' + } + } + await apiKeyService.updateApiKey(keyId, updates) logger.success(`📝 Admin updated API key: ${keyId}`) diff --git a/web/admin-spa/src/components/apikeys/EditApiKeyModal.vue b/web/admin-spa/src/components/apikeys/EditApiKeyModal.vue index f74b25f8..82e27447 100644 --- a/web/admin-spa/src/components/apikeys/EditApiKeyModal.vue +++ b/web/admin-spa/src/components/apikeys/EditApiKeyModal.vue @@ -41,6 +41,26 @@

名称不可修改

+ +
+ + +

+ 分配此 API Key 给指定用户或管理员,管理员分配时不受用户 API Key 数量限制 +

+
+