refactor(frontend): 优化模型/提供商组件的数据刷新逻辑

- ModelDetailDrawer: 移除 handleMappingsUpdate 中冗余的 refreshRoutingData 调用,路由刷新改由 @refresh 事件统一处理
- ModelMappingsTab: saveMappings 成功后始终 emit update 和 refresh 事件,确保数据一致性
- BatchAssignModelsDialog: 为批量添加/导入操作增加 try-catch 错误处理,部分操作失败时仍通知父组件刷新
- ProviderDetailDrawer: 移除 modelsTabRef 直接调用子组件 reload 的模式,统一通过 emit('refresh') 由父组件协调刷新
This commit is contained in:
AAEE86
2026-02-11 03:09:26 +08:00
parent cd0acf1e6b
commit 0fa15604dc
4 changed files with 35 additions and 28 deletions

View File

@@ -560,9 +560,7 @@ function refreshRoutingData() {
// 处理模型映射更新
function handleMappingsUpdate(_mappings: string[]) {
// 映射已在 ModelMappingsTab 内部保存到服务器
// 刷新路由数据以反映可能的候选变化
refreshRoutingData()
// 通知父组件刷新模型数据
// 路由数据刷新由 @refresh 事件处理,这里只需通知父组件刷新模型数据
emit('refreshModel')
}

View File

@@ -531,12 +531,14 @@ async function saveMappings() {
// 自动关联未关联的提供商
if (unlinkedProviderIds.length > 0) {
toastSuccess(`映射规则已保存,正在关联 ${unlinkedProviderIds.length} 个提供商...`)
// linkProviders 处理完成后会由父组件统一刷新数据,无需再 emit update
emit('linkProviders', unlinkedProviderIds)
} else {
toastSuccess('映射规则已保存')
emit('update', cleanedMappings)
}
// 保存成功后刷新数据
emit('update', cleanedMappings)
emit('refresh')
} catch (err) {
log.error('保存映射规则失败:', err)
toastError('保存失败,请重试')

View File

@@ -511,6 +511,7 @@ async function handleSave() {
if (!hasChanges.value || saving.value) return
saving.value = true
let hasAnyOperation = false
try {
let totalSuccess = 0
const allErrors: string[] = []
@@ -519,6 +520,7 @@ async function handleSave() {
for (const globalModelId of globalModelsToRemove.value) {
const existingModel = existingModels.value.find(m => m.global_model_id === globalModelId)
if (existingModel) {
hasAnyOperation = true
try {
await deleteModel(props.providerId, existingModel.id)
totalSuccess++
@@ -535,6 +537,7 @@ async function handleSave() {
m.provider_model_mappings?.some(mapping => mapping.name === modelId)
)
if (existingModel) {
hasAnyOperation = true
try {
await deleteModel(props.providerId, existingModel.id)
totalSuccess++
@@ -546,19 +549,29 @@ async function handleSave() {
// 添加全局模型
if (globalModelsToAdd.value.length > 0) {
const result = await batchAssignModelsToProvider(props.providerId, globalModelsToAdd.value)
totalSuccess += result.success.length
if (result.errors.length > 0) {
allErrors.push(...result.errors.map(e => e.error))
hasAnyOperation = true
try {
const result = await batchAssignModelsToProvider(props.providerId, globalModelsToAdd.value)
totalSuccess += result.success.length
if (result.errors.length > 0) {
allErrors.push(...result.errors.map(e => e.error))
}
} catch (err: any) {
allErrors.push(parseApiError(err, '批量添加全局模型失败'))
}
}
// 添加上游模型
if (upstreamModelsToAdd.value.length > 0) {
const result = await importModelsFromUpstream(props.providerId, upstreamModelsToAdd.value)
totalSuccess += result.success.length
if (result.errors.length > 0) {
allErrors.push(...result.errors.map(e => e.error))
hasAnyOperation = true
try {
const result = await importModelsFromUpstream(props.providerId, upstreamModelsToAdd.value)
totalSuccess += result.success.length
if (result.errors.length > 0) {
allErrors.push(...result.errors.map(e => e.error))
}
} catch (err: any) {
allErrors.push(parseApiError(err, '导入上游模型失败'))
}
}
@@ -574,6 +587,10 @@ async function handleSave() {
emit('update:open', false)
} catch (err: any) {
showError(parseApiError(err, '保存失败'), '错误')
// 即使出错,如果已执行过操作,也通知父组件刷新数据
if (hasAnyOperation) {
emit('changed')
}
} finally {
saving.value = false
}

View File

@@ -872,7 +872,6 @@
<!-- 模型查看 -->
<ModelsTab
v-if="provider"
ref="modelsTabRef"
:key="`models-${provider.id}`"
:provider="provider"
:endpoints="endpoints"
@@ -1132,7 +1131,6 @@ const revealedKeys = ref<Map<string, string>>(new Map())
const modelFormDialogOpen = ref(false)
const editingModel = ref<Model | null>(null)
const batchAssignDialogOpen = ref(false)
const modelsTabRef = ref<InstanceType<typeof ModelsTab> | null>(null)
const modelMappingTabRef = ref<InstanceType<typeof ModelMappingTab> | null>(null)
// 密钥列表拖拽排序状态
@@ -1466,12 +1464,8 @@ async function confirmDeleteKey() {
try {
await deleteEndpointKey(keyId)
showSuccess('密钥已删除')
// 并行刷新端点列表、模型列表、模型映射(删除 Key 触发自动解除模型关联)
await Promise.all([
loadEndpoints(),
modelsTabRef.value?.reload(),
modelMappingTabRef.value?.reload()
])
// 刷新端点列表及模型数据(删除 Key 触发自动解除模型关联)
await loadEndpoints()
emit('refresh')
} catch (err: any) {
showError(err.response?.data?.detail || '删除密钥失败', '错误')
@@ -1799,11 +1793,6 @@ async function openAntigravityQuotaDialog(key: EndpointAPIKey) {
async function handleKeyChanged() {
await loadEndpoints()
// 并行刷新模型列表和模型映射(因为模型权限会影响正则映射预览)
await Promise.all([
modelsTabRef.value?.reload(),
modelMappingTabRef.value?.reload()
])
emit('refresh')
// 添加/修改 key 后自动获取 Antigravity 配额(新 key 的 upstream_metadata 为空)
void autoRefreshQuotaInBackground()
@@ -1892,19 +1881,20 @@ function handleBatchAssign() {
// 处理批量关联完成
async function handleBatchAssignChanged() {
await loadProvider()
await loadEndpoints()
emit('refresh')
}
// 处理模型映射变更
async function handleModelMappingChanged() {
await loadEndpoints()
emit('refresh')
}
// 处理模型保存完成
async function handleModelSaved() {
editingModel.value = null
await loadProvider()
await loadEndpoints()
emit('refresh')
}