diff --git a/apps/api/internal/httpapi/model_catalog.go b/apps/api/internal/httpapi/model_catalog.go index 470b0bb..5bbbcb1 100644 --- a/apps/api/internal/httpapi/model_catalog.go +++ b/apps/api/internal/httpapi/model_catalog.go @@ -202,6 +202,9 @@ func buildModelCatalog( sourceCount := 0 for _, model := range models { platform := platformMap[model.PlatformID] + if !catalogSourceEnabled(model, platform) { + continue + } baseModel := baseModelMap[model.BaseModelID] providerKey := modelProviderKey(model, baseModel, platform) provider := providerMap[providerKey] @@ -271,6 +274,10 @@ func buildModelCatalog( } } +func catalogSourceEnabled(model store.PlatformModel, platform store.Platform) bool { + return model.Enabled && platform.ID != "" && platform.Status == "enabled" +} + func modelCatalogItem(group *catalogGroup, accessRuleGroups map[string]accessRuleGroup) ModelCatalogItem { sources := sortedCatalogSources(group.sources) primary := sources[0] diff --git a/apps/api/internal/httpapi/model_catalog_test.go b/apps/api/internal/httpapi/model_catalog_test.go index fa191be..4a76a97 100644 --- a/apps/api/internal/httpapi/model_catalog_test.go +++ b/apps/api/internal/httpapi/model_catalog_test.go @@ -168,6 +168,71 @@ func TestBuildModelCatalogUsesBaseModelProviderForProviderFilters(t *testing.T) } } +func TestBuildModelCatalogOnlyUsesEnabledPlatformModels(t *testing.T) { + models := []store.PlatformModel{ + { + ID: "enabled-source", + PlatformID: "platform-enabled", + BaseModelID: "base-deepseek", + ModelName: "deepseek-chat", + ModelAlias: "DeepSeek Chat", + ModelType: store.StringList{"text_generate"}, + DisplayName: "DeepSeek Chat", + Enabled: true, + }, + { + ID: "disabled-model", + PlatformID: "platform-enabled", + BaseModelID: "base-deepseek", + ModelName: "deepseek-chat", + ModelAlias: "DeepSeek Chat", + ModelType: store.StringList{"text_generate"}, + DisplayName: "DeepSeek Chat", + Enabled: false, + }, + { + ID: "disabled-platform", + PlatformID: "platform-disabled", + BaseModelID: "base-deepseek", + ModelName: "deepseek-chat", + ModelAlias: "DeepSeek Chat", + ModelType: store.StringList{"text_generate"}, + DisplayName: "DeepSeek Chat", + Enabled: true, + }, + } + platforms := []store.Platform{ + {ID: "platform-enabled", Provider: "aliyun-bailian-openai", Name: "阿里云百炼(OpenAI兼容)", Status: "enabled"}, + {ID: "platform-disabled", Provider: "silicon-flow-openai", Name: "硅基流动", Status: "disabled"}, + } + providers := []store.CatalogProvider{ + {ProviderKey: "deepseek-openai", DisplayName: "DeepSeek"}, + {ProviderKey: "aliyun-bailian-openai", DisplayName: "阿里云百炼(OpenAI兼容)"}, + {ProviderKey: "silicon-flow-openai", DisplayName: "硅基流动"}, + } + baseModels := []store.BaseModel{ + {ID: "base-deepseek", ProviderKey: "deepseek-openai", ProviderModelName: "deepseek-chat", ModelAlias: "DeepSeek Chat"}, + } + + response := buildModelCatalog(models, platforms, providers, nil, nil, nil, baseModels) + if response.Summary.ModelCount != 1 || response.Summary.SourceCount != 1 { + t.Fatalf("expected only one enabled source, got %+v", response.Summary) + } + item := response.Items[0] + if item.SourceCount != 1 || len(item.Sources) != 1 || item.Sources[0].ID != "enabled-source" { + t.Fatalf("expected only enabled source in item, got sourceCount=%d sources=%+v", item.SourceCount, item.Sources) + } + if len(item.ProviderKeys) != 1 || item.ProviderKeys[0] != "deepseek-openai" { + t.Fatalf("expected base model provider deepseek-openai, got %+v", item.ProviderKeys) + } + if !hasFilterCount(response.Filters.Providers, "deepseek-openai", 1) { + t.Fatalf("expected DeepSeek provider filter, got %+v", response.Filters.Providers) + } + if hasFilterCount(response.Filters.Providers, "aliyun-bailian-openai", 1) || hasFilterCount(response.Filters.Providers, "silicon-flow-openai", 1) { + t.Fatalf("did not expect platform provider filters: %+v", response.Filters.Providers) + } +} + func TestBillingConfigLinesShowsTextInputAndOutputPricing(t *testing.T) { lines := billingConfigLines(map[string]any{ "text_total": map[string]any{ diff --git a/apps/web/src/pages/ModelsPage.tsx b/apps/web/src/pages/ModelsPage.tsx index 3c8981f..91d214b 100644 --- a/apps/web/src/pages/ModelsPage.tsx +++ b/apps/web/src/pages/ModelsPage.tsx @@ -60,7 +60,6 @@ export function ModelsPage(props: { data: ConsoleData }) {
-

共 {catalog.summary.sourceCount} 个源,按别名合并为 {catalog.summary.modelCount} 个模型,当前显示 {filteredModels.length} 个

setQuery(event.target.value)} placeholder="模型名称、能力或厂商" /> diff --git a/apps/web/src/styles/pages.css b/apps/web/src/styles/pages.css index ed1be88..108d899 100644 --- a/apps/web/src/styles/pages.css +++ b/apps/web/src/styles/pages.css @@ -36,6 +36,7 @@ top: 88px; display: grid; gap: 22px; + padding-left: 14px; padding-right: 18px; border-right: 1px solid var(--border); } @@ -125,12 +126,6 @@ gap: 16px; } -.modelsToolbar p { - margin-right: auto; - color: var(--text-soft); - font-size: var(--font-size-base); -} - .searchField { display: grid; width: min(420px, 100%); @@ -2127,6 +2122,12 @@ position: static; } + .modelFilters { + padding-left: 0; + padding-right: 0; + border-right: 0; + } + .modelCards, .providerCatalogGrid, .baseModelGrid,