refactor: 统一账户过期时间字段映射和检查逻辑

主要改进:
1. 创建 mapExpiryField() 工具函数统一处理前后端字段映射(expiresAt -> subscriptionExpiresAt)
2. 统一 subscriptionExpiresAt 初始值为 null(替代空字符串)
3. 规范过期检查方法名为 isSubscriptionExpired(),返回 true 表示已过期
4. 优化过期检查条件判断,只检查 null 而非空字符串
5. 补充 OpenAI-Responses 和调度器中缺失的过期检查逻辑
6. 添加代码评审文档记录未修复问题

影响范围:
- 所有 9 种账户服务的过期字段处理
- admin.js 中所有账户更新路由
- 统一调度器的过期账户过滤逻辑

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
mrlitong
2025-10-14 08:04:05 +00:00
parent ba60a2dcbb
commit cbc3a83f11
13 changed files with 410 additions and 82 deletions

View File

@@ -211,6 +211,15 @@ class UnifiedOpenAIScheduler {
error.statusCode = 403 // Forbidden - 调度被禁止
throw error
}
// ⏰ 检查 OpenAI-Responses 专属账户订阅是否过期
if (openaiResponsesAccountService.isSubscriptionExpired(boundAccount)) {
const errorMsg = `Dedicated account ${boundAccount.name} subscription has expired`
logger.warn(`⚠️ ${errorMsg}`)
const error = new Error(errorMsg)
error.statusCode = 403 // Forbidden - 订阅已过期
throw error
}
}
// 专属账户可选的模型检查只有明确配置了supportedModels且不为空才检查
@@ -461,6 +470,14 @@ class UnifiedOpenAIScheduler {
}
}
// ⏰ 检查订阅是否过期
if (openaiResponsesAccountService.isSubscriptionExpired(account)) {
logger.debug(
`⏭️ Skipping OpenAI-Responses account ${account.name} - subscription expired`
)
continue
}
// OpenAI-Responses 账户默认支持所有模型
// 因为它们是第三方兼容 API模型支持由第三方决定
@@ -536,6 +553,11 @@ class UnifiedOpenAIScheduler {
logger.info(`🚫 OpenAI-Responses account ${accountId} is not schedulable`)
return false
}
// ⏰ 检查订阅是否过期
if (openaiResponsesAccountService.isSubscriptionExpired(account)) {
logger.info(`🚫 OpenAI-Responses account ${accountId} subscription expired`)
return false
}
// 检查并清除过期的限流状态
const isRateLimitCleared =
await openaiResponsesAccountService.checkAndClearRateLimit(accountId)