From 7ba98c1e916989f474f0a059f9c3660718a75765 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Sun, 23 Nov 2025 21:06:16 +0800 Subject: [PATCH] feat: enhance provider display with grouped categorization and improved filtering --- dashboard/src/views/ProviderPage.vue | 142 +++++++++++++++++++++------ 1 file changed, 111 insertions(+), 31 deletions(-) diff --git a/dashboard/src/views/ProviderPage.vue b/dashboard/src/views/ProviderPage.vue index 2b736585..321cb2d7 100644 --- a/dashboard/src/views/ProviderPage.vue +++ b/dashboard/src/views/ProviderPage.vue @@ -52,30 +52,62 @@ - - - mdi-api-off - {{ getEmptyText() }} - - - - - - - - - {{ tm('availability.test') }} - - - - - - - + + + + mdi-api-off + {{ getEmptyText() }} + + + + + {{ group.label }} + + + + + + {{ tm('availability.test') }} + + + + + + + + + + + + + + mdi-api-off + {{ getEmptyText() }} + + + + + + + + {{ tm('availability.test') }} + + + + + + + + @@ -368,6 +400,52 @@ export default { }; }, + groupedProviders() { + if (!this.config_data.provider) { + return []; + } + + const typeOrder = [ + 'chat_completion', + 'agent_runner', + 'speech_to_text', + 'text_to_speech', + 'embedding', + 'rerank', + ]; + + const assigned = new Set(); + const groups = typeOrder + .map((typeKey) => { + const items = this.config_data.provider.filter((provider) => { + const resolved = this.getProviderType(provider); + if (resolved === typeKey) { + assigned.add(provider.id); + return true; + } + return false; + }); + return { + typeKey, + label: this.messages.tabTypes[typeKey] || typeKey, + items, + }; + }) + .filter((group) => group.items.length > 0); + + const remaining = this.config_data.provider.filter( + (provider) => !assigned.has(provider.id), + ); + if (remaining.length > 0) { + groups.push({ + typeKey: 'others', + label: this.tm('providers.tabs.all'), + items: remaining, + }); + } + return groups; + }, + // 根据选择的标签过滤提供商列表 filteredProviders() { if (!this.config_data.provider || this.activeProviderTypeTab === 'all') { @@ -376,13 +454,7 @@ export default { return this.config_data.provider.filter(provider => { // 如果provider.provider_type已经存在,直接使用它 - if (provider.provider_type) { - return provider.provider_type === this.activeProviderTypeTab; - } - - // 否则使用映射关系 - const mappedType = this.oldVersionProviderTypeMapping[provider.type]; - return mappedType === this.activeProviderTypeTab; + return this.getProviderType(provider) === this.activeProviderTypeTab; }); } }, @@ -392,6 +464,14 @@ export default { }, methods: { + getProviderType(provider) { + if (!provider) return undefined; + if (provider.provider_type) { + return provider.provider_type; + } + return this.oldVersionProviderTypeMapping[provider.type]; + }, + getConfig() { axios.get('/api/config/get').then((res) => { this.config_data = res.data.data.config;
{{ getEmptyText() }}