feat: OAuth 账户管理、维护调度、端点健康检查增强及前端优化

- 新增 OAuth 账户管理对话框和提供商详情抽屉中的 OAuth 信息展示
- 新增维护调度器(maintenance_scheduler)支持定时清理和健康检查
- 增强端点健康检查器,支持更多检测策略
- 重构 codex 服务为 metadata_collectors 模块
- 优化 OpenAI CLI normalizer 代码结构
- 前端: 改进使用量表格、统计图表、指南页面和异步任务管理
- 扩展多个数据库字符串列为 TEXT 类型
- 新增倒计时 composable 和 provider OAuth API 端点
This commit is contained in:
fawney19
2026-02-04 23:59:45 +08:00
parent 24c9105628
commit 4d6e7c094f
64 changed files with 3885 additions and 930 deletions

View File

@@ -67,3 +67,70 @@ export function getProbeCountdown(nextProbeAt: string | null | undefined, _tick:
}
return '探测中'
}
/**
* OAuth Token 状态信息
*/
export interface OAuthStatusInfo {
text: string
isExpired: boolean
isExpiringSoon: boolean
isInvalid: boolean // Token 已失效(账号被封、授权撤销等)
invalidReason?: string // 失效原因
}
/**
* 格式化 OAuth Token 过期倒计时
* @param expiresAt Unix 时间戳(秒)
* @param _tick 响应式触发器(传入 tick.value 以触发响应式更新)
* @param invalidAt 失效时间戳(秒),可选
* @param invalidReason 失效原因,可选
* @returns 状态信息对象
*/
export function getOAuthExpiresCountdown(
expiresAt: number | null | undefined,
_tick: number,
invalidAt?: number | null,
invalidReason?: string | null
): OAuthStatusInfo | null {
void _tick
// 优先检查失效状态(失效比过期更严重)
if (invalidAt != null) {
return {
text: '已失效',
isExpired: false,
isExpiringSoon: false,
isInvalid: true,
invalidReason: invalidReason || undefined
}
}
if (expiresAt == null) return null
const now = Math.floor(Date.now() / 1000)
const diffSeconds = expiresAt - now
if (diffSeconds <= 0) {
return { text: '已过期', isExpired: true, isExpiringSoon: false, isInvalid: false }
}
// 24 小时内过期视为即将过期
const isExpiringSoon = diffSeconds < 24 * 3600
// 格式化时间
const days = Math.floor(diffSeconds / 86400)
const hours = Math.floor((diffSeconds % 86400) / 3600)
const minutes = Math.floor((diffSeconds % 3600) / 60)
let text: string
if (days > 0) {
text = `${days}${hours}`
} else if (hours > 0) {
text = `${hours}${minutes}`
} else {
text = `${minutes}分钟`
}
return { text, isExpired: false, isExpiringSoon, isInvalid: false }
}