From bdf125e001ad3b5baeefbc73d30d0a29c17feed5 Mon Sep 17 00:00:00 2001 From: KevinLiao Date: Sun, 27 Jul 2025 19:51:37 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20APIKey=E6=9F=A5=E8=AF=A2=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E6=95=B0=E6=8D=AE=E4=B8=8D=E6=AD=A3=E7=A1=AE=E7=9A=84?= =?UTF-8?q?=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/routes/apiStats.js | 1 - src/routes/web.js | 2 - src/services/apiKeyService.js | 3 + web/apiStats/app.js | 28 ++++++++++ web/apiStats/index.html | 102 +++++++++++++++++++++++++++++++++- 5 files changed, 131 insertions(+), 5 deletions(-) diff --git a/src/routes/apiStats.js b/src/routes/apiStats.js index e496b9ab..d144162e 100644 --- a/src/routes/apiStats.js +++ b/src/routes/apiStats.js @@ -97,7 +97,6 @@ router.post('/api/user-stats', async (req, res) => { try { const client = redis.getClientSafe(); - const currentMonth = `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, '0')}`; // 获取所有月度模型统计(与model-stats接口相同的逻辑) const allModelKeys = await client.keys(`usage:${fullKeyData.id}:model:monthly:*:*`); diff --git a/src/routes/web.js b/src/routes/web.js index eac99038..7aacae26 100644 --- a/src/routes/web.js +++ b/src/routes/web.js @@ -6,8 +6,6 @@ const fs = require('fs'); const redis = require('../models/redis'); const logger = require('../utils/logger'); const config = require('../../config/config'); -const apiKeyService = require('../services/apiKeyService'); -const CostCalculator = require('../utils/costCalculator'); const router = express.Router(); diff --git a/src/services/apiKeyService.js b/src/services/apiKeyService.js index ae78cd99..f7a1797b 100644 --- a/src/services/apiKeyService.js +++ b/src/services/apiKeyService.js @@ -147,6 +147,9 @@ class ApiKeyService { keyData: { id: keyData.id, name: keyData.name, + description: keyData.description, + createdAt: keyData.createdAt, + expiresAt: keyData.expiresAt, claudeAccountId: keyData.claudeAccountId, geminiAccountId: keyData.geminiAccountId, permissions: keyData.permissions || 'all', diff --git a/web/apiStats/app.js b/web/apiStats/app.js index 134cd8bb..b61de143 100644 --- a/web/apiStats/app.js +++ b/web/apiStats/app.js @@ -226,6 +226,34 @@ const app = createApp({ } }, + // 📅 格式化过期日期 + formatExpireDate(dateString) { + if (!dateString) return ''; + const date = new Date(dateString); + return date.toLocaleString('zh-CN', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit' + }); + }, + + // 🔍 检查 API Key 是否已过期 + isApiKeyExpired(expiresAt) { + if (!expiresAt) return false; + return new Date(expiresAt) < new Date(); + }, + + // ⏰ 检查 API Key 是否即将过期(7天内) + isApiKeyExpiringSoon(expiresAt) { + if (!expiresAt) return false; + const expireDate = new Date(expiresAt); + const now = new Date(); + const daysUntilExpire = (expireDate - now) / (1000 * 60 * 60 * 24); + return daysUntilExpire > 0 && daysUntilExpire <= 7; + }, + // 🔢 格式化数字 formatNumber(num) { if (typeof num !== 'number') { diff --git a/web/apiStats/index.html b/web/apiStats/index.html index a185f38d..c238effc 100644 --- a/web/apiStats/index.html +++ b/web/apiStats/index.html @@ -169,9 +169,25 @@ 创建时间 {{ formatDate(statsData.createdAt) }} -
+
过期时间 - {{ formatDate(statsData.expiresAt) }} +
+
+ + 已过期 +
+
+ + {{ formatExpireDate(statsData.expiresAt) }} +
+
+ {{ formatExpireDate(statsData.expiresAt) }} +
+
+
+ + 永不过期 +
@@ -276,6 +292,88 @@ 每日费用限制 {{ statsData.limits.dailyCostLimit > 0 ? '$' + statsData.limits.dailyCostLimit : '无限制' }} +
+ 模型限制 + + + + 限制 {{ statsData.restrictions.restrictedModels.length }} 个模型 + + + + 允许所有模型 + + +
+
+ 客户端限制 + + + + 限制 {{ statsData.restrictions.allowedClients.length }} 个客户端 + + + + 允许所有客户端 + + +
+ + + + + +
+

+ + 详细限制信息 +

+ +
+ +
+

+ + 受限模型列表 +

+
+
+ + {{ model }} +
+
+

+ + 此 API Key 不能访问以上列出的模型 +

+
+ + +
+

+ + 允许的客户端 +

+
+
+ + {{ client }} +
+
+

+ + 此 API Key 只能被以上列出的客户端使用 +