From 62aea5a4a8c8b5a10109b65b2459a41902b9eb5d Mon Sep 17 00:00:00 2001 From: shaw Date: Tue, 14 Oct 2025 19:19:33 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DtokenExpiresAt?= =?UTF-8?q?=E6=B7=B7=E6=B7=86=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/routes/admin.js | 31 +++++++++++++++++++++------- src/services/geminiAccountService.js | 10 ++++++++- src/services/openaiAccountService.js | 10 ++++++++- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/routes/admin.js b/src/routes/admin.js index ee85ee5d..0206c6c1 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -32,6 +32,18 @@ const ProxyHelper = require('../utils/proxyHelper') const router = express.Router() +// 🛠️ 工具函数:处理可为空的时间字段 +function normalizeNullableDate(value) { + if (value === undefined || value === null) { + return null + } + if (typeof value === 'string') { + const trimmed = value.trim() + return trimmed === '' ? null : trimmed + } + return value +} + // 🛠️ 工具函数:映射前端字段名到后端字段名 /** * 映射前端的 expiresAt 字段到后端的 subscriptionExpiresAt 字段 @@ -64,17 +76,22 @@ function formatAccountExpiry(account) { return account } - // 保存原始的 OAuth token 过期时间 - const tokenExpiresAt = account.expiresAt || null + const rawSubscription = Object.prototype.hasOwnProperty.call(account, 'subscriptionExpiresAt') + ? account.subscriptionExpiresAt + : null - // 将订阅过期时间映射到 expiresAt(前端使用) - const subscriptionExpiresAt = account.subscriptionExpiresAt || null + const rawToken = Object.prototype.hasOwnProperty.call(account, 'tokenExpiresAt') + ? account.tokenExpiresAt + : account.expiresAt + + const subscriptionExpiresAt = normalizeNullableDate(rawSubscription) + const tokenExpiresAt = normalizeNullableDate(rawToken) return { ...account, - expiresAt: subscriptionExpiresAt, // 前端显示订阅过期时间 - tokenExpiresAt, // 保留 OAuth token 过期时间 - subscriptionExpiresAt // 保留原始字段 + subscriptionExpiresAt, + tokenExpiresAt, + expiresAt: subscriptionExpiresAt } } diff --git a/src/services/geminiAccountService.js b/src/services/geminiAccountService.js index 287cf392..134600ec 100644 --- a/src/services/geminiAccountService.js +++ b/src/services/geminiAccountService.js @@ -654,6 +654,12 @@ async function getAllAccounts() { // 转换 schedulable 字符串为布尔值(与 getAccount 保持一致) accountData.schedulable = accountData.schedulable !== 'false' // 默认为true,只有明确设置为'false'才为false + const tokenExpiresAt = accountData.expiresAt || null + const subscriptionExpiresAt = + accountData.subscriptionExpiresAt && accountData.subscriptionExpiresAt !== '' + ? accountData.subscriptionExpiresAt + : null + // 不解密敏感字段,只返回基本信息 accounts.push({ ...accountData, @@ -663,7 +669,9 @@ async function getAllAccounts() { // ✅ 前端显示订阅过期时间(业务字段) // 注意:前端看到的 expiresAt 实际上是 subscriptionExpiresAt - expiresAt: accountData.subscriptionExpiresAt || null, + tokenExpiresAt, + subscriptionExpiresAt, + expiresAt: subscriptionExpiresAt, // 添加 scopes 字段用于判断认证方式 // 处理空字符串和默认值的情况 diff --git a/src/services/openaiAccountService.js b/src/services/openaiAccountService.js index 00ed88cd..cf045e9c 100644 --- a/src/services/openaiAccountService.js +++ b/src/services/openaiAccountService.js @@ -793,6 +793,12 @@ async function getAllAccounts() { } } + const tokenExpiresAt = accountData.expiresAt || null + const subscriptionExpiresAt = + accountData.subscriptionExpiresAt && accountData.subscriptionExpiresAt !== '' + ? accountData.subscriptionExpiresAt + : null + // 不解密敏感字段,只返回基本信息 accounts.push({ ...accountData, @@ -803,7 +809,9 @@ async function getAllAccounts() { refreshToken: maskedRefreshToken, // ✅ 前端显示订阅过期时间(业务字段) - expiresAt: accountData.subscriptionExpiresAt || null, + tokenExpiresAt, + subscriptionExpiresAt, + expiresAt: subscriptionExpiresAt, // 添加 scopes 字段用于判断认证方式 // 处理空字符串的情况