feat: 添加模型白名单选择器组件,同步 new-api 模型列表
- 新增 ModelWhitelistSelector.vue 支持模型白名单多选 - 新增 ModelIcon.vue 显示品牌图标(基于 @lobehub/icons) - 新增 useModelWhitelist.ts 硬编码各平台模型列表 - 更新账号编辑表单支持模型白名单配置 - 支持 Claude/OpenAI/Gemini/智谱/百度/讯飞等主流平台 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -114,15 +114,15 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
|
||||
gitHubReleaseClient := repository.NewGitHubReleaseClient()
|
||||
serviceBuildInfo := provideServiceBuildInfo(buildInfo)
|
||||
updateService := service.ProvideUpdateService(updateCache, gitHubReleaseClient, serviceBuildInfo)
|
||||
systemHandler := handler.ProvideSystemHandler(updateService)
|
||||
adminSubscriptionHandler := admin.NewSubscriptionHandler(subscriptionService)
|
||||
adminUsageHandler := admin.NewUsageHandler(usageService, apiKeyService, adminService)
|
||||
adminHandlers := handler.ProvideAdminHandlers(dashboardHandler, adminUserHandler, groupHandler, accountHandler, oAuthHandler, openAIOAuthHandler, geminiOAuthHandler, antigravityOAuthHandler, proxyHandler, adminRedeemHandler, settingHandler, systemHandler, adminSubscriptionHandler, adminUsageHandler)
|
||||
pricingRemoteClient := repository.NewPricingRemoteClient()
|
||||
pricingService, err := service.ProvidePricingService(configConfig, pricingRemoteClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
systemHandler := handler.ProvideSystemHandler(updateService)
|
||||
adminSubscriptionHandler := admin.NewSubscriptionHandler(subscriptionService)
|
||||
adminUsageHandler := admin.NewUsageHandler(usageService, apiKeyService, adminService)
|
||||
adminHandlers := handler.ProvideAdminHandlers(dashboardHandler, adminUserHandler, groupHandler, accountHandler, oAuthHandler, openAIOAuthHandler, geminiOAuthHandler, antigravityOAuthHandler, proxyHandler, adminRedeemHandler, settingHandler, systemHandler, adminSubscriptionHandler, adminUsageHandler)
|
||||
billingService := service.NewBillingService(configConfig, pricingService)
|
||||
identityCache := repository.NewIdentityCache(redisClient)
|
||||
identityService := service.NewIdentityService(identityCache)
|
||||
|
||||
@@ -300,12 +300,42 @@ func (h *GatewayHandler) Messages(c *gin.Context) {
|
||||
|
||||
// Models handles listing available models
|
||||
// GET /v1/models
|
||||
// Returns different model lists based on the API key's group platform
|
||||
// Returns models based on account configurations (model_mapping whitelist)
|
||||
// Falls back to default models if no whitelist is configured
|
||||
func (h *GatewayHandler) Models(c *gin.Context) {
|
||||
apiKey, _ := middleware2.GetApiKeyFromContext(c)
|
||||
|
||||
// Return OpenAI models for OpenAI platform groups
|
||||
if apiKey != nil && apiKey.Group != nil && apiKey.Group.Platform == "openai" {
|
||||
var groupID *int64
|
||||
var platform string
|
||||
|
||||
if apiKey != nil && apiKey.Group != nil {
|
||||
groupID = &apiKey.Group.ID
|
||||
platform = apiKey.Group.Platform
|
||||
}
|
||||
|
||||
// Get available models from account configurations (without platform filter)
|
||||
availableModels := h.gatewayService.GetAvailableModels(c.Request.Context(), groupID, "")
|
||||
|
||||
if len(availableModels) > 0 {
|
||||
// Build model list from whitelist
|
||||
models := make([]claude.Model, 0, len(availableModels))
|
||||
for _, modelID := range availableModels {
|
||||
models = append(models, claude.Model{
|
||||
ID: modelID,
|
||||
Type: "model",
|
||||
DisplayName: modelID,
|
||||
CreatedAt: "2024-01-01T00:00:00Z",
|
||||
})
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"object": "list",
|
||||
"data": models,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Fallback to default models
|
||||
if platform == "openai" {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"object": "list",
|
||||
"data": openai.DefaultModels,
|
||||
@@ -313,7 +343,6 @@ func (h *GatewayHandler) Models(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Default: Claude models
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"object": "list",
|
||||
"data": claude.DefaultModels,
|
||||
|
||||
@@ -1440,3 +1440,58 @@ func (s *GatewayService) countTokensError(c *gin.Context, status int, errType, m
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// GetAvailableModels returns the list of models available for a group
|
||||
// It aggregates model_mapping keys from all schedulable accounts in the group
|
||||
func (s *GatewayService) GetAvailableModels(ctx context.Context, groupID *int64, platform string) []string {
|
||||
var accounts []Account
|
||||
var err error
|
||||
|
||||
if groupID != nil {
|
||||
accounts, err = s.accountRepo.ListSchedulableByGroupID(ctx, *groupID)
|
||||
} else {
|
||||
accounts, err = s.accountRepo.ListSchedulable(ctx)
|
||||
}
|
||||
|
||||
if err != nil || len(accounts) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Filter by platform if specified
|
||||
if platform != "" {
|
||||
filtered := make([]Account, 0)
|
||||
for _, acc := range accounts {
|
||||
if acc.Platform == platform {
|
||||
filtered = append(filtered, acc)
|
||||
}
|
||||
}
|
||||
accounts = filtered
|
||||
}
|
||||
|
||||
// Collect unique models from all accounts
|
||||
modelSet := make(map[string]struct{})
|
||||
hasAnyMapping := false
|
||||
|
||||
for _, acc := range accounts {
|
||||
mapping := acc.GetModelMapping()
|
||||
if len(mapping) > 0 {
|
||||
hasAnyMapping = true
|
||||
for model := range mapping {
|
||||
modelSet[model] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no account has model_mapping, return nil (use default)
|
||||
if !hasAnyMapping {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert to slice
|
||||
models := make([]string, 0, len(modelSet))
|
||||
for model := range modelSet {
|
||||
models = append(models, model)
|
||||
}
|
||||
|
||||
return models
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user