feat(channels): 模型定价支持一键同步最新模型

从 LiteLLM 定价目录中读取指定平台的最新模型列表,
将尚未录入的模型以新定价条目(价格留空)的形式追加,
管理员只需点击同步最新模型按钮即可完成操作。

- backend/service: PricingService 新增 ListModelNamesByProvider
- backend/handler: ChannelHandler 新增 SyncPricingModels (GET /api/v1/admin/channels/pricing/sync-models)
- backend/routes: 注册新路由(在 /:id 通配符之前)
- backend/wire_gen: 手动更新 NewChannelHandler 调用
- frontend/api: channels.ts 新增 syncPricingModels
- frontend/i18n: zh.ts / en.ts 新增 5 个 key
- frontend/view: ChannelsView 定价区域标题行新增「同步最新模型」按钮
- tests: pricing_service_test + channel_handler_test 新增单元测试
This commit is contained in:
wucm667
2026-05-19 20:32:32 +08:00
parent 8927ab091e
commit 92ad68a314
10 changed files with 252 additions and 12 deletions
@@ -17,11 +17,12 @@ import (
type ChannelHandler struct {
channelService *service.ChannelService
billingService *service.BillingService
pricingService *service.PricingService
}
// NewChannelHandler creates a new admin channel handler
func NewChannelHandler(channelService *service.ChannelService, billingService *service.BillingService) *ChannelHandler {
return &ChannelHandler{channelService: channelService, billingService: billingService}
func NewChannelHandler(channelService *service.ChannelService, billingService *service.BillingService, pricingService *service.PricingService) *ChannelHandler {
return &ChannelHandler{channelService: channelService, billingService: billingService, pricingService: pricingService}
}
// --- Request / Response types ---
@@ -500,3 +501,34 @@ func (h *ChannelHandler) GetModelDefaultPricing(c *gin.Context) {
"image_output_price": pricing.ImageOutputPricePerToken,
})
}
// platformToLiteLLMProvider maps a channel platform name to the corresponding
// LiteLLM provider string used as the key in the pricing catalog.
var platformToLiteLLMProvider = map[string]string{
service.PlatformAnthropic: "anthropic",
service.PlatformOpenAI: "openai",
service.PlatformGemini: "google",
service.PlatformAntigravity: "anthropic",
}
// SyncPricingModels 返回 LiteLLM 定价目录中指定平台的最新模型列表
// GET /api/v1/admin/channels/pricing/sync-models?platform=anthropic
func (h *ChannelHandler) SyncPricingModels(c *gin.Context) {
platform := strings.ToLower(strings.TrimSpace(c.Query("platform")))
if platform == "" {
response.ErrorFrom(c, infraerrors.BadRequest("MISSING_PARAMETER", "platform parameter is required").
WithMetadata(map[string]string{"param": "platform"}))
return
}
provider, ok := platformToLiteLLMProvider[platform]
if !ok {
response.ErrorFrom(c, infraerrors.BadRequest("UNSUPPORTED_PLATFORM",
fmt.Sprintf("unsupported platform: %s", platform)).
WithMetadata(map[string]string{"param": "platform"}))
return
}
models := h.pricingService.ListModelNamesByProvider(provider)
response.Success(c, gin.H{"models": models})
}