refactor(ui): 统一图像与文本模型的测试连接逻辑至 composable 层

- 将图像模型的 canTestConnection、canRefreshModels、isConnectionConfigured 逻辑统一迁移至 useImageModelManager
- 文本模型新增模式支持测试连接功能,行为与图像模型保持一致
- 统一连接可用性判断逻辑,修改 canTestFormConnection 依赖 modelId 而非 name 进行校验
- 移除图像模型中冗余的 v-if="selectedProvider" 条件,由 manager 层统一控制状态
- 组件层职责收敛为纯 UI 展示,业务逻辑全部收拢至 manager 层管理
- 架构调整后,文本与图像模型的连接管理逻辑保持一致,提升代码可维护性
This commit is contained in:
linshen committed 2025-11-29 22:32:11 +08:00
1 parent b8bd391a0b
commit 31bcdaf5e6
3 files changed
+38 -39

No files matched your search

@@ -149,7 +149,7 @@
<template #action>
<NSpace justify="space-between" align="center" style="width: 100%;">
<!-- 左侧:连接测试 -->
<NSpace align="center" v-if="selectedProvider">
<NSpace align="center">
<NButton
@click="handleTestConnection"
:loading="isTestingConnection"
@@ -262,7 +262,9 @@ const {
selectedProvider,
selectedModel,
currentParameterDefinitions,
// (use local computed for UI gates)
isConnectionConfigured,
canTestConnection,
canRefreshModels,
// methods
onProviderChange: handleProviderChange,
@@ -340,23 +342,6 @@ const connectionFields = computed(() => {
return fields
})
const isConnectionConfigured = computed(() => {
if (!selectedProvider.value?.connectionSchema) return true
const schema = selectedProvider.value.connectionSchema
const config = configForm.value.connectionConfig || {}
return schema.required.every(field => config[field])
})
const canTestConnection = computed(() => {
return selectedProvider.value && isConnectionConfigured.value
})
const canRefreshModels = computed(() => {
return selectedProvider.value?.supportsDynamicModels && isConnectionConfigured.value
})
const refreshButtonTooltip = computed(() => {
if (canRefreshModels.value) {
return t('image.model.refreshTooltip')
@@ -152,6 +152,19 @@ export function useImageModelManager() {
supportsDynamicModels.value && isConnectionConfigured.value && !isLoadingDynamicModels.value
)
const canTestConnection = computed(() => {
// 测试期间禁用
if (isTestingConnection.value) return false
// 必须有必需的连接配置
if (!isConnectionConfigured.value) return false
// 必须有模型 ID(发送请求所需)
if (!configForm.value.modelId?.trim()) return false
// 必须有 provider
if (!configForm.value.providerId) return false
return true
})
// 初始化数据加载
const loadProviders = async () => {
isLoadingProviders.value = true
@@ -696,6 +709,7 @@ export function useImageModelManager() {
supportsDynamicModels,
isConnectionConfigured,
canRefreshModels,
canTestConnection,
currentParameterDefinitions,
currentParamOverrides,
availableParameterCount,
@@ -153,14 +153,14 @@ export function useTextModelManager() {
})
const canTestFormConnection = computed(() => {
// 必须在编辑模式下
if (!editingModelId.value) return false
// 测试期间禁用
if (isTestingFormConnection.value) return false
// 必须有必需的连接配置
if (!isConnectionConfigured.value) return false
// 必须有模型名称
if (!form.value.name?.trim()) return false
// 必须有模型 ID(发送请求所需)
if (!form.value.modelId?.trim()) return false
// 必须有 provider
if (!form.value.providerId) return false
return true
})
@@ -614,34 +614,32 @@ export function useTextModelManager() {
formConnectionStatus.value = { type: 'info', message: t('modelManager.testing') }
try {
const existingConfig = editingModelId.value ? await modelManager.getModel(editingModelId.value) : undefined
if (!existingConfig) {
throw new Error('模型配置不存在')
}
if (!form.value.providerId || !form.value.modelId) {
throw new Error('模型未选择')
}
const providerMeta = ensureProviderMeta(form.value.providerId, existingConfig.providerMeta)
const modelMeta = ensureModelMeta(form.value.providerId, form.value.modelId, existingConfig.modelMeta)
// 编辑模式下获取现有配置,新增模式下为 undefined
const existingConfig = editingModelId.value ? await modelManager.getModel(editingModelId.value) : undefined
const providerMeta = ensureProviderMeta(form.value.providerId, existingConfig?.providerMeta)
const modelMeta = ensureModelMeta(form.value.providerId, form.value.modelId, existingConfig?.modelMeta)
const baseURL = typeof form.value.connectionConfig?.baseURL === 'string'
? form.value.connectionConfig.baseURL.trim()
: undefined
const connectionConfig: TextConnectionConfig = {
baseURL: baseURL || existingConfig.connectionConfig?.baseURL,
...existingConfig.connectionConfig,
baseURL: baseURL || existingConfig?.connectionConfig?.baseURL,
...existingConfig?.connectionConfig,
...form.value.connectionConfig,
apiKey: form.value.displayMaskedKey && form.value.originalApiKey
? form.value.originalApiKey
: (form.value.connectionConfig.apiKey || existingConfig.connectionConfig?.apiKey)
: (form.value.connectionConfig.apiKey || existingConfig?.connectionConfig?.apiKey)
}
const tempConfig = {
id: `temp-test-${editingModelId.value}-${Date.now()}`,
name: form.value.name,
id: `temp-test-${editingModelId.value || 'new'}-${Date.now()}`,
name: form.value.name || form.value.modelId,
enabled: form.value.enabled,
providerMeta,
modelMeta,
@@ -654,8 +652,9 @@ export function useTextModelManager() {
try {
// 测试临时模型
await llmService.testConnection(tempConfig.id)
formConnectionStatus.value = { type: 'success', message: t('modelManager.testSuccess', { provider: form.value.name }) }
toast.success(t('modelManager.testSuccess', { provider: form.value.name }))
const displayName = form.value.name || form.value.modelId
formConnectionStatus.value = { type: 'success', message: t('modelManager.testSuccess', { provider: displayName }) }
toast.success(t('modelManager.testSuccess', { provider: displayName }))
} finally {
// 清理临时模型
try {
@@ -667,11 +666,12 @@ export function useTextModelManager() {
} catch (error) {
console.error('连接测试失败:', error)
const displayName = form.value.name || form.value.modelId
formConnectionStatus.value = {
type: 'error',
message: t('modelManager.testFailed', { provider: form.value.name, error: error instanceof Error ? error.message : 'Unknown error' || 'Unknown error' })
message: t('modelManager.testFailed', { provider: displayName, error: error instanceof Error ? error.message : 'Unknown error' })
}
toast.error(t('modelManager.testFailed', { provider: form.value.name, error: error instanceof Error ? error.message : 'Unknown error' || 'Unknown error' }))
toast.error(t('modelManager.testFailed', { provider: displayName, error: error instanceof Error ? error.message : 'Unknown error' }))
} finally {
isTestingFormConnection.value = false
}