feat(codex): 增强 OAuth 导入解析与账号信息提取,优化维护调度器线程模型

Codex OAuth:
- 导入解析支持附加账号字段(account_id/plan_type/user_id/email)
- enrich_codex 扩展从 access_token 和直接字段提取账号信息
- parse_codex_id_token 支持 JWT/JSON 字符串/dict 三种输入格式
- request patching 新增 openai:compact 格式支持
- codex_usage_parser 新增 credits_unlimited 字段解析

维护调度器:
- 同步 DB 操作迁移到线程池执行,避免阻塞事件循环
- 新增 request_candidates 定期清理任务
- 新增每周 VACUUM ANALYZE 数据库表维护任务
- 新增 enable_db_maintenance 配置项

前端:
- ElapsedTimeText 从 setInterval 改为 requestAnimationFrame
- 时间线过滤 available/unused 占位记录
- Usage 页面默认关闭全局自动刷新
- 移除号池管理中的配额更新时间显示
This commit is contained in:
fawney19
2026-03-04 10:00:38 +08:00
parent e181329a81
commit 82a9fb3c39
17 changed files with 822 additions and 317 deletions
@@ -10,20 +10,18 @@ const props = withDefaults(defineProps<{
status?: string | null
responseTimeMs?: number | null
precision?: number
intervalMs?: number
}>(), {
createdAt: null,
status: null,
responseTimeMs: null,
precision: 2,
intervalMs: 200
})
const now = ref(Date.now())
const precision = computed(() => Math.max(0, props.precision))
const isActive = computed(() => props.status === 'pending' || props.status === 'streaming')
let timer: ReturnType<typeof setInterval> | null = null
let rafId: number | null = null
function parseCreatedAtMs(value: string | null | undefined): number {
if (!value) return Number.NaN
@@ -32,31 +30,33 @@ function parseCreatedAtMs(value: string | null | undefined): number {
return new Date(normalized).getTime()
}
function stopTimer() {
if (!timer) return
clearInterval(timer)
timer = null
function stopRaf() {
if (rafId == null) return
cancelAnimationFrame(rafId)
rafId = null
}
function startTimer() {
stopTimer()
const intervalMs = Math.max(100, props.intervalMs)
timer = setInterval(() => {
now.value = Date.now()
}, intervalMs)
function tick() {
now.value = Date.now()
rafId = requestAnimationFrame(tick)
}
watch([isActive, () => props.intervalMs], ([active]) => {
function startRaf() {
stopRaf()
now.value = Date.now()
rafId = requestAnimationFrame(tick)
}
watch(isActive, (active) => {
if (active) {
now.value = Date.now()
startTimer()
startRaf()
} else {
stopTimer()
stopRaf()
}
}, { immediate: true })
onUnmounted(() => {
stopTimer()
stopRaf()
})
const displayText = computed(() => {