feat(oauth): 账号封禁前置 OAuth 验证、抽取 provider_context、完善账号状态分类

- 新增 verify_oauth_before_account_block:在标记账号封禁前先尝试刷新 token,
  区分 OAuth 过期与真正的账号级封禁,避免误标
- 抽取 provider_context.py 统一解析 provider_type,解决 ORM detached 访问问题
- account_state 新增 workspace_deactivated 分类和 auto-removable 状态集合,
  补充中文验证关键词匹配
- OAuth refresh 成功后仅清除可恢复的 token 错误,不再自动清除账号级 block
- deploy.sh 依赖指纹改用纯 shell 实现,移除对 Python tomllib 的依赖
- 前端 Pool 管理页面新增筛选和批量操作优化
- 补充对应测试用例
This commit is contained in:
fawney19
2026-03-20 16:50:59 +08:00
parent aa83b4a7a7
commit 25d38ae632
44 changed files with 1527 additions and 370 deletions

View File

@@ -1158,7 +1158,7 @@ const emit = defineEmits<{
(e: 'refresh'): void
}>()
const { error: showError, success: showSuccess } = useToast()
const { error: showError, success: showSuccess, warning: showWarning } = useToast()
const { confirm } = useConfirm()
const { copyToClipboard } = useClipboard()
const { tick: countdownTick, start: startCountdownTimer, stop: stopCountdownTimer } = useCountdownTimer()
@@ -1643,7 +1643,15 @@ async function handleRefreshOAuth(key: EndpointAPIKey) {
refreshingOAuthKeyId.value = key.id
try {
const result = await refreshProviderOAuth(key.id)
showSuccess('Token 刷新成功')
if (result.account_state_recheck_attempted) {
if (result.account_state_recheck_error) {
showWarning('Token 刷新成功,但账号状态复检失败')
} else {
showSuccess('Token 刷新成功,已复检账号状态')
}
} else {
showSuccess('Token 刷新成功')
}
// 更新本地数据
const keyInList = providerKeys.value.find(k => k.id === key.id)
if (keyInList) {
@@ -1678,7 +1686,7 @@ async function handleClearOAuthInvalid(key: EndpointAPIKey) {
const confirmed = await confirm({
title: '清除账号异常标记',
message: `确认账号 "${key.name || key.id.slice(0, 8)}" 已手动完成验证?清除后该 Key 将恢复正常调度。`,
message: `确认账号 "${key.name || key.id.slice(0, 8)}" 已手动完成验证?清除后系统会按当前手动开关和调度状态重新评估该 Key。`,
confirmText: '确认清除',
variant: 'default',
})
@@ -1687,13 +1695,12 @@ async function handleClearOAuthInvalid(key: EndpointAPIKey) {
clearingOAuthInvalidKeyId.value = key.id
try {
await clearOAuthInvalid(key.id)
showSuccess('已清除 OAuth 异常标记Key 已自动启用')
showSuccess('已清除 OAuth 异常标记')
// 更新本地数据
const keyInList = providerKeys.value.find(k => k.id === key.id)
if (keyInList) {
keyInList.oauth_invalid_at = null
keyInList.oauth_invalid_reason = null
keyInList.is_active = true
}
await loadEndpoints()
} catch (err: unknown) {