mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
feat: 引入 status_snapshot 统一 provider key 状态管理
- 新增 StatusSnapshot 模型,聚合 OAuth / 账号 / 配额三维状态 - 新增 StatusSnapshotStore 负责快照的持久化与查询 - 重构 response_builder / endpoint_models,基于 snapshot 输出状态字段 - 前端抽取 providerKeyStatus / oauthRefreshFeedback 工具函数, 统一 PoolManagement、ProviderDetailDrawer、BatchDialog 的状态展示 - errorParser 增加已知 OAuth 错误的友好提示 - refresher 适配 snapshot 写入,account_state 扩展状态分类 - 新增 alembic 迁移及存量数据回填脚本 - 补充前后端单元测试
This commit is contained in:
@@ -278,8 +278,13 @@ import {
|
||||
import { exportKey, refreshProviderQuota } from '@/api/endpoints/keys'
|
||||
import { refreshProviderOAuth } from '@/api/endpoints/provider_oauth'
|
||||
import { useProxyNodesStore } from '@/stores/proxy-nodes'
|
||||
import { classifyAccountBlockLabel, cleanAccountBlockReason, isAccountLevelBlockReason, isRefreshFailedReason } from '@/utils/accountBlock'
|
||||
import { getOAuthOrgBadge } from '@/utils/oauthIdentity'
|
||||
import {
|
||||
getAccountStatusDisplay,
|
||||
getAccountStatusTitle,
|
||||
getOAuthStatusDisplay,
|
||||
getOAuthStatusTitle,
|
||||
} from '@/utils/providerKeyStatus'
|
||||
|
||||
type QuickSelectorValue =
|
||||
| 'banned'
|
||||
@@ -423,21 +428,12 @@ function normalizeAuthTypeLabel(authType: string): string {
|
||||
}
|
||||
|
||||
function getStatusBadgeLabel(key: PoolKeyDetail): string | null {
|
||||
const explicitLabel = String(key.account_status_label || '').trim()
|
||||
if (explicitLabel) return explicitLabel
|
||||
const account = getAccountStatusDisplay(key)
|
||||
if (account.blocked && account.label) return account.label
|
||||
|
||||
const reason = String(key.oauth_invalid_reason || '').trim()
|
||||
if (isAccountLevelBlockReason(reason)) {
|
||||
const cleaned = cleanAccountBlockReason(reason)
|
||||
return classifyAccountBlockLabel(cleaned || reason)
|
||||
}
|
||||
|
||||
if (normalizeText(key.auth_type) !== 'oauth') return null
|
||||
if (isRefreshFailedReason(reason)) return '续期失败'
|
||||
if (key.oauth_invalid_at != null || normalizeText(reason)) return 'Token 失效'
|
||||
if (typeof key.oauth_expires_at === 'number' && key.oauth_expires_at > 0) {
|
||||
return key.oauth_expires_at * 1000 <= Date.now() ? 'Token 过期' : null
|
||||
}
|
||||
const oauth = getOAuthStatusDisplay(key, 0)
|
||||
if (oauth?.isInvalid) return 'Token 失效'
|
||||
if (oauth?.isExpired) return 'Token 过期'
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -445,20 +441,11 @@ function getStatusBadgeTitle(key: PoolKeyDetail): string {
|
||||
const label = getStatusBadgeLabel(key)
|
||||
if (!label) return ''
|
||||
|
||||
const explicitReason = String(key.account_status_reason || '').trim()
|
||||
if (explicitReason) return `${label}: ${explicitReason}`
|
||||
const accountTitle = getAccountStatusTitle(key)
|
||||
if (accountTitle) return accountTitle
|
||||
|
||||
const reason = String(key.oauth_invalid_reason || '').trim()
|
||||
if (!reason) return label
|
||||
if (isAccountLevelBlockReason(reason)) {
|
||||
const cleaned = cleanAccountBlockReason(reason)
|
||||
return cleaned ? `${label}: ${cleaned}` : label
|
||||
}
|
||||
if (isRefreshFailedReason(reason)) {
|
||||
const cleaned = reason.replace(/^\[REFRESH_FAILED\]\s*/i, '').trim()
|
||||
return cleaned ? `${label}: ${cleaned}` : label
|
||||
}
|
||||
return `${label}: ${reason}`
|
||||
const oauthTitle = getOAuthStatusTitle(key, 0)
|
||||
return oauthTitle || label
|
||||
}
|
||||
|
||||
function formatRelativeTime(value: string): string {
|
||||
|
||||
Reference in New Issue
Block a user