feat(proxy,oauth,pool): H2 头过滤、OAuth 过期分级标记与批量操作进度条

- proxy: 屏蔽 host/content-length 头转发,避免 H2 PROTOCOL_ERROR
- oauth: 区分 [REFRESH_FAILED] 与 [OAUTH_EXPIRED] 标记,token 过期
  自动阻止调度但不停用账号,便于管理员恢复
- pool/account_state: 识别新增的 OAUTH_EXPIRED/REFRESH_FAILED 前缀
- 前端: 批量操作显示实时进度条,倍率编辑 Escape/blur 竞态修复,
  OAuth 刷新失败后自动刷新列表
This commit is contained in:
fawney19
2026-03-06 01:47:09 +08:00
parent fa71cddb60
commit e9c3ac94c6
9 changed files with 134 additions and 16 deletions

View File

@@ -2059,19 +2059,16 @@ function startEditMultiplier(key: EndpointAPIKey, format: string) {
function cancelEditMultiplier() {
editingMultiplierKey.value = null
editingMultiplierFormat.value = null
multiplierSaving.value = false
}
function handleMultiplierKeydown(e: KeyboardEvent, key: EndpointAPIKey, format: string) {
if (e.key === 'Enter') {
e.preventDefault()
e.stopPropagation()
if (!multiplierSaving.value) {
multiplierSaving.value = true
saveMultiplier(key, format)
}
saveMultiplier(key, format)
} else if (e.key === 'Escape') {
e.preventDefault()
multiplierSaving.value = true // 阻止 blur 触发保存
cancelEditMultiplier()
}
}
@@ -2082,7 +2079,7 @@ function handleMultiplierBlur(key: EndpointAPIKey, format: string) {
}
async function saveMultiplier(key: EndpointAPIKey, format: string) {
// 防止重复调用
// 防止重复调用Enter 触发后阻止 blur 再次进入)
if (multiplierSaving.value) return
multiplierSaving.value = true
@@ -2093,6 +2090,7 @@ async function saveMultiplier(key: EndpointAPIKey, format: string) {
if (!keyId || isNaN(newMultiplier)) {
showError('请输入有效的倍率值')
cancelEditMultiplier()
multiplierSaving.value = false
return
}
@@ -2100,6 +2098,7 @@ async function saveMultiplier(key: EndpointAPIKey, format: string) {
if (newMultiplier <= 0 || newMultiplier > 100) {
showError('倍率必须在 0.01 到 100 之间')
cancelEditMultiplier()
multiplierSaving.value = false
return
}
@@ -2107,6 +2106,7 @@ async function saveMultiplier(key: EndpointAPIKey, format: string) {
const currentMultiplier = getKeyRateMultiplier(key, format)
if (Math.abs(currentMultiplier - newMultiplier) < 0.0001) {
cancelEditMultiplier()
multiplierSaving.value = false
return
}