mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-10 11:19:50 +08:00
fix(providers): 修复 Key 表单状态同步与 streaming 候选状态码处理
前端: - KeyAllowedModelsEditDialog 同时监听 open 和 apiKey 变化,避免切换 key 时状态未刷新 - KeyFormDialog 新增 api_formats 过滤与默认值逻辑,可用格式变化时自动同步表单 - ProviderDetailDrawer 合并 provider 和 endpoint 的 api_formats 传递给 Key 表单, 数据刷新后同步 currentEndpoint 和 editingKey 引用 后端: - mark_candidate_streaming 移除 status_code 参数,streaming 阶段不再提前写入状态码 - 简化 active_requests 中 streaming 请求的完成判断,不再依赖 status_code 条件
This commit is contained in:
@@ -936,7 +936,7 @@
|
||||
:editing-key="editingKey"
|
||||
:provider-id="provider ? provider.id : null"
|
||||
:provider-type="provider?.provider_type || null"
|
||||
:available-api-formats="provider?.api_formats || []"
|
||||
:available-api-formats="availableKeyApiFormats"
|
||||
@close="keyFormDialogOpen = false"
|
||||
@saved="handleKeyChanged"
|
||||
/>
|
||||
@@ -1258,6 +1258,65 @@ const allKeys = computed(() => {
|
||||
return result
|
||||
})
|
||||
|
||||
const availableKeyApiFormats = computed(() => {
|
||||
const formatSet = new Set<string>()
|
||||
|
||||
for (const format of provider.value?.api_formats || []) {
|
||||
if (format) {
|
||||
formatSet.add(format)
|
||||
}
|
||||
}
|
||||
|
||||
for (const endpoint of endpoints.value) {
|
||||
if (endpoint.api_format) {
|
||||
formatSet.add(endpoint.api_format)
|
||||
}
|
||||
}
|
||||
|
||||
return sortApiFormats([...formatSet])
|
||||
})
|
||||
|
||||
function syncCurrentSelections(
|
||||
nextEndpoints: ProviderEndpointWithKeys[] = endpoints.value,
|
||||
nextProviderKeys: EndpointAPIKey[] = providerKeys.value
|
||||
) {
|
||||
if (currentEndpoint.value) {
|
||||
currentEndpoint.value = nextEndpoints.find(endpoint => endpoint.id === currentEndpoint.value?.id) ?? null
|
||||
}
|
||||
|
||||
if (!editingKey.value) {
|
||||
return
|
||||
}
|
||||
|
||||
const latestKeys: EndpointAPIKey[] = []
|
||||
const seenKeyIds = new Set<string>()
|
||||
|
||||
for (const key of nextProviderKeys) {
|
||||
if (!seenKeyIds.has(key.id)) {
|
||||
seenKeyIds.add(key.id)
|
||||
latestKeys.push(key)
|
||||
}
|
||||
}
|
||||
|
||||
for (const endpoint of nextEndpoints) {
|
||||
for (const key of endpoint.keys || []) {
|
||||
if (!seenKeyIds.has(key.id)) {
|
||||
seenKeyIds.add(key.id)
|
||||
latestKeys.push(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const latestEditingKey = latestKeys.find(key => key.id === editingKey.value?.id) || null
|
||||
editingKey.value = latestEditingKey
|
||||
|
||||
if (!latestEditingKey) {
|
||||
keyFormDialogOpen.value = false
|
||||
keyPermissionsDialogOpen.value = false
|
||||
oauthKeyEditDialogOpen.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 账号列表智能分页 =====
|
||||
const keysListRef = ref<HTMLElement | null>(null)
|
||||
const {
|
||||
@@ -1558,6 +1617,7 @@ async function handleRefreshOAuth(key: EndpointAPIKey) {
|
||||
const freshKeys = await getProviderKeys(props.providerId).catch(() => null)
|
||||
if (freshKeys) {
|
||||
providerKeys.value = freshKeys
|
||||
syncCurrentSelections(endpoints.value, freshKeys)
|
||||
}
|
||||
}
|
||||
// Antigravity:token 刷新后可能完成了账号激活,触发配额获取
|
||||
@@ -2640,7 +2700,7 @@ async function loadEndpoints() {
|
||||
providerKeys.value = providerKeysResult
|
||||
providerModels.value = modelsResult
|
||||
// 按 API 格式排序
|
||||
endpoints.value = endpointsList.sort((a, b) => {
|
||||
const sortedEndpoints = endpointsList.sort((a, b) => {
|
||||
const aIdx = API_FORMAT_ORDER.indexOf(a.api_format)
|
||||
const bIdx = API_FORMAT_ORDER.indexOf(b.api_format)
|
||||
if (aIdx === -1 && bIdx === -1) return 0
|
||||
@@ -2648,6 +2708,8 @@ async function loadEndpoints() {
|
||||
if (bIdx === -1) return -1
|
||||
return aIdx - bIdx
|
||||
})
|
||||
endpoints.value = sortedEndpoints
|
||||
syncCurrentSelections(sortedEndpoints, providerKeysResult)
|
||||
} catch (err: unknown) {
|
||||
if (requestId !== endpointsLoadRequestId) return
|
||||
showError(parseApiError(err, '加载端点失败'), '错误')
|
||||
|
||||
Reference in New Issue
Block a user