feat: OAuth 重复账号失效时允许覆盖更新,优化前端分页与刷新体验

- OAuth 去重逻辑改为:已失效的重复账号自动覆盖更新而非拒绝,
  适用于单个导入、批量导入、Kiro 导入等所有入口
- 新增 _update_existing_oauth_key 函数统一处理覆盖更新逻辑
- useSmartPagination 新增 fixedHeight 属性防止翻页时容器高度跳动
- ProviderDetailDrawer OAuth 刷新后仅重载 keys 数据避免整表刷新
This commit is contained in:
fawney19
2026-02-11 10:01:28 +08:00
parent 5cfae4f8f0
commit 11b0026995
3 changed files with 227 additions and 104 deletions

View File

@@ -39,6 +39,12 @@ export function useSmartPagination<T>(
return Math.ceil(items.value.length / itemsPerPage.value)
})
/** 分页激活时的固定高度px用于防止翻页时容器高度跳动 */
const fixedHeight = computed(() => {
if (!shouldPaginate.value || cachedAvgItemHeight.value <= 0) return undefined
return itemsPerPage.value * cachedAvgItemHeight.value
})
/** 将当前页内的局部索引转换为全局索引 */
function getGlobalIndex(localIdx: number): number {
if (!shouldPaginate.value) return localIdx
@@ -165,6 +171,7 @@ export function useSmartPagination<T>(
totalPages,
shouldPaginate,
paginatedItems,
fixedHeight,
getGlobalIndex,
detect,
reset,

View File

@@ -208,6 +208,7 @@
v-if="allKeys.length > 0"
ref="keysListRef"
class="divide-y divide-border/40"
:style="keysFixedHeight ? { minHeight: keysFixedHeight + 'px' } : undefined"
>
<div
v-for="({ key, endpoint }, localIdx) in paginatedKeys"
@@ -1227,6 +1228,7 @@ const {
totalPages: totalKeyPages,
shouldPaginate: shouldPaginateKeys,
paginatedItems: paginatedKeys,
fixedHeight: keysFixedHeight,
getGlobalIndex: getGlobalKeyIndex,
reset: resetKeysPagination,
} = useSmartPagination(allKeys, keysListRef)
@@ -1494,8 +1496,13 @@ async function handleRefreshOAuth(key: EndpointAPIKey) {
if (keyInList) {
keyInList.oauth_expires_at = result.expires_at
}
// 重新加载 key 数据token 刷新可能补上了 project_id 等信息)
await loadEndpoints()
// 重新加载 keys 数据,避免整个表格刷新
if (props.providerId) {
const freshKeys = await getProviderKeys(props.providerId).catch(() => null)
if (freshKeys) {
providerKeys.value = freshKeys
}
}
// Antigravitytoken 刷新后可能完成了账号激活,触发配额获取
// (不 emit('refresh'),避免触发全局 provider 余额刷新)
void autoRefreshQuotaInBackground()