From 4509f303e6fe0e6db59fff709248c8efa2d3d414 Mon Sep 17 00:00:00 2001 From: Feng Yue <2525275@gmail.com> Date: Thu, 14 Aug 2025 15:25:22 +0800 Subject: [PATCH] feat: enhance user API keys view and fix admin cost display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add deleted API keys display to user's My API Keys view - Show deleted status with gray indicator and "Deleted" badge - Display deletion date and hide delete button for deleted keys - Fix cost calculation in admin deleted API keys tab - Add getCostStats call to properly populate cost data - Support includeDeleted parameter in user API keys endpoint 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/routes/userRoutes.js | 3 +- src/services/apiKeyService.js | 8 +++++ .../components/user/UserApiKeysManager.vue | 30 +++++++++++++++---- web/admin-spa/src/stores/user.js | 8 +++-- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/routes/userRoutes.js b/src/routes/userRoutes.js index 13e5626e..c7379590 100644 --- a/src/routes/userRoutes.js +++ b/src/routes/userRoutes.js @@ -130,7 +130,8 @@ router.get('/profile', authenticateUser, async (req, res) => { // 🔑 获取用户的API Keys router.get('/api-keys', authenticateUser, async (req, res) => { try { - const apiKeys = await apiKeyService.getUserApiKeys(req.user.id) + const { includeDeleted = 'false' } = req.query + const apiKeys = await apiKeyService.getUserApiKeys(req.user.id, includeDeleted === 'true') // 移除敏感信息并格式化usage数据 const safeApiKeys = apiKeys.map((key) => { diff --git a/src/services/apiKeyService.js b/src/services/apiKeyService.js index 6a042ab0..feea7f8c 100644 --- a/src/services/apiKeyService.js +++ b/src/services/apiKeyService.js @@ -208,6 +208,14 @@ class ApiKeyService { // 为每个key添加使用统计和当前并发数 for (const key of apiKeys) { key.usage = await redis.getUsageStats(key.id) + const costStats = await redis.getCostStats(key.id) + // Add cost information to usage object for frontend compatibility + if (key.usage && costStats) { + key.usage.total = key.usage.total || {} + key.usage.total.cost = costStats.total + key.usage.totalCost = costStats.total + } + key.totalCost = costStats ? costStats.total : 0 key.tokenLimit = parseInt(key.tokenLimit) key.concurrencyLimit = parseInt(key.concurrencyLimit || 0) key.rateLimitWindow = parseInt(key.rateLimitWindow || 0) diff --git a/web/admin-spa/src/components/user/UserApiKeysManager.vue b/web/admin-spa/src/components/user/UserApiKeysManager.vue index c856467b..cc3f0d29 100644 --- a/web/admin-spa/src/components/user/UserApiKeysManager.vue +++ b/web/admin-spa/src/components/user/UserApiKeysManager.vue @@ -83,14 +83,27 @@

{{ apiKey.name }}

+ Deleted + + Disabled @@ -100,11 +113,17 @@

{{ apiKey.description || 'No description' }}

Created: {{ formatDate(apiKey.createdAt) }} - Deleted: {{ formatDate(apiKey.deletedAt) }} + Last used: {{ formatDate(apiKey.lastUsedAt) }} Never used - Expires: {{ formatDate(apiKey.expiresAt) }} + Expires: {{ formatDate(apiKey.expiresAt) }}
@@ -140,6 +159,7 @@