fix: 修复5小时限制被停止调度未恢复的问题

This commit is contained in:
shaw
2025-09-28 23:30:41 +08:00
parent aca2b1cccb
commit b4d7ed06c5

View File

@@ -599,6 +599,7 @@ class ClaudeAccountService {
'unifiedClientId'
]
const updatedData = { ...accountData }
let shouldClearAutoStopFields = false
// 检查是否新增了 refresh token
const oldRefreshToken = this._decryptSensitiveData(accountData.refreshToken)
@@ -669,6 +670,7 @@ class ClaudeAccountService {
// 兼容旧的标记(逐步迁移)
delete updatedData.autoStoppedAt
delete updatedData.stoppedReason
shouldClearAutoStopFields = true
// 如果是手动启用调度,记录日志
if (updates.schedulable === true || updates.schedulable === 'true') {
@@ -700,6 +702,18 @@ class ClaudeAccountService {
await redis.setClaudeAccount(accountId, updatedData)
if (shouldClearAutoStopFields) {
const fieldsToRemove = [
'rateLimitAutoStopped',
'fiveHourAutoStopped',
'fiveHourStoppedAt',
'tempErrorAutoStopped',
'autoStoppedAt',
'stoppedReason'
]
await this._removeAccountFields(accountId, fieldsToRemove, 'manual_schedule_update')
}
logger.success(`📝 Updated Claude account: ${accountId}`)
return { success: true }
@@ -1399,6 +1413,9 @@ class ClaudeAccountService {
const now = new Date()
const currentTime = now.getTime()
let shouldClearSessionStatus = false
let shouldClearFiveHourFlags = false
// 检查当前是否有活跃的会话窗口
if (accountData.sessionWindowStart && accountData.sessionWindowEnd) {
const windowEnd = new Date(accountData.sessionWindowEnd).getTime()
@@ -1429,6 +1446,7 @@ class ClaudeAccountService {
if (accountData.sessionWindowStatus) {
delete accountData.sessionWindowStatus
delete accountData.sessionWindowStatusUpdatedAt
shouldClearSessionStatus = true
}
// 如果账户因为5小时限制被自动停止现在恢复调度
@@ -1439,6 +1457,7 @@ class ClaudeAccountService {
accountData.schedulable = 'true'
delete accountData.fiveHourAutoStopped
delete accountData.fiveHourStoppedAt
shouldClearFiveHourFlags = true
// 发送Webhook通知
try {
@@ -1457,6 +1476,17 @@ class ClaudeAccountService {
}
}
if (shouldClearSessionStatus || shouldClearFiveHourFlags) {
const fieldsToRemove = []
if (shouldClearFiveHourFlags) {
fieldsToRemove.push('fiveHourAutoStopped', 'fiveHourStoppedAt')
}
if (shouldClearSessionStatus) {
fieldsToRemove.push('sessionWindowStatus', 'sessionWindowStatusUpdatedAt')
}
await this._removeAccountFields(accountId, fieldsToRemove, 'session_window_refresh')
}
logger.info(
`🕐 Created new session window for account ${accountData.name} (${accountId}): ${windowStart.toISOString()} - ${windowEnd.toISOString()} (from current time)`
)
@@ -2486,6 +2516,12 @@ class ClaudeAccountService {
// 保存更新
await redis.setClaudeAccount(account.id, updatedAccountData)
const fieldsToRemove = ['fiveHourAutoStopped', 'fiveHourStoppedAt']
if (newWindowStart && newWindowEnd) {
fieldsToRemove.push('sessionWindowStatus', 'sessionWindowStatusUpdatedAt')
}
await this._removeAccountFields(account.id, fieldsToRemove, 'five_hour_recovery_task')
result.recovered++
result.accounts.push({
id: latestAccount.id,
@@ -2541,6 +2577,31 @@ class ClaudeAccountService {
throw error
}
}
async _removeAccountFields(accountId, fields = [], context = 'general_cleanup') {
if (!Array.isArray(fields) || fields.length === 0) {
return
}
const filteredFields = fields.filter((field) => typeof field === 'string' && field.trim())
if (filteredFields.length === 0) {
return
}
const accountKey = `claude:account:${accountId}`
try {
await redis.client.hdel(accountKey, ...filteredFields)
logger.debug(
`🧹 已在 ${context} 阶段为账号 ${accountId} 删除字段 [${filteredFields.join(', ')}]`
)
} catch (error) {
logger.error(
`❌ 无法在 ${context} 阶段为账号 ${accountId} 删除字段 [${filteredFields.join(', ')}]:`,
error
)
}
}
}
module.exports = new ClaudeAccountService()