diff --git a/controller/channel_pricing.go b/controller/channel_pricing.go
index 16bcf0e..f904205 100644
--- a/controller/channel_pricing.go
+++ b/controller/channel_pricing.go
@@ -258,6 +258,26 @@ type ChannelPricingWithTags struct {
Tags []*model.PricingTag `json:"tags"`
}
+// GetChannelPricingByModelWithChannelInfo 获取指定模型的渠道定价(带渠道信息,所有用户可访问)
+func GetChannelPricingByModelWithChannelInfo(c *gin.Context) {
+ // 使用通配符路由时,参数包含前导斜杠,需要去除
+ modelName := c.Param("name")
+ if modelName == "" {
+ common.ApiErrorMsg(c, "model name is required")
+ return
+ }
+ // 去除前导斜杠(路由是 /channel-pricing/model/*name,name 会是 "/deepseek-ai/xxx")
+ modelName = strings.TrimPrefix(modelName, "/")
+
+ list, err := model.GetChannelPricingByModelWithChannelInfo(modelName)
+ if err != nil {
+ common.ApiError(c, err)
+ return
+ }
+
+ common.ApiSuccess(c, list)
+}
+
// GetChannelPricingWithTags 获取渠道定价(带标签详情)
func GetChannelPricingWithTags(c *gin.Context) {
page, _ := strconv.Atoi(c.DefaultQuery("p", "1"))
diff --git a/model/channel_pricing.go b/model/channel_pricing.go
index e1f82eb..a7004f8 100644
--- a/model/channel_pricing.go
+++ b/model/channel_pricing.go
@@ -6,6 +6,7 @@ import (
"time"
"github.com/QuantumNous/new-api/common"
+ "github.com/QuantumNous/new-api/setting/ratio_setting"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
@@ -205,3 +206,63 @@ func InvalidateChannelPricingCache() {
channelPricingCache = make(map[string]*ChannelPricing)
channelPricingCacheTime = time.Time{} // 重置为零值
}
+
+// ChannelPricingWithChannel 带渠道信息的定价响应
+type ChannelPricingWithChannel struct {
+ Id int `json:"id"`
+ ChannelId int `json:"channel_id"`
+ ChannelName string `json:"channel_name"`
+ ChannelType int `json:"channel_type"`
+ QuotaType int `json:"quota_type"` // 0=按量, 1=按次
+ ModelRatio float64 `json:"model_ratio"`
+ CompletionRatio float64 `json:"completion_ratio"`
+ ModelPrice float64 `json:"model_price"`
+ HasCustomPricing bool `json:"has_custom_pricing"` // 是否有自定义定价
+}
+
+// GetChannelPricingByModelWithChannelInfo 获取指定模型的渠道定价(带渠道信息)
+// 返回所有支持该模型的渠道,对于没有渠道定价的渠道使用全局默认价格
+func GetChannelPricingByModelWithChannelInfo(modelName string) ([]*ChannelPricingWithChannel, error) {
+ var results []*ChannelPricingWithChannel
+
+ // 获取全局默认价格
+ globalModelRatio, hasRatio, _ := ratio_setting.GetModelRatio(modelName)
+ globalModelPrice, hasPrice := ratio_setting.GetModelPrice(modelName, false)
+ globalCompletionRatio := ratio_setting.GetCompletionRatio(modelName)
+
+ // 确定默认计费类型
+ var defaultQuotaType int
+ if hasPrice {
+ defaultQuotaType = QuotaTypeByCall
+ } else {
+ defaultQuotaType = QuotaTypeByTokens
+ }
+
+ // 如果没有全局价格,设置默认值
+ if !hasRatio {
+ globalModelRatio = 0
+ }
+ if !hasPrice {
+ globalModelPrice = 0
+ }
+
+ // 查询所有支持该模型的渠道,左连接渠道定价表
+ err := DB.Table("abilities").
+ Select(`abilities.channel_id, channels.name as channel_name, channels.type as channel_type,
+ COALESCE(channel_pricings.quota_type, ?) as quota_type,
+ COALESCE(channel_pricings.model_ratio, ?) as model_ratio,
+ COALESCE(channel_pricings.completion_ratio, ?) as completion_ratio,
+ COALESCE(channel_pricings.model_price, ?) as model_price,
+ channel_pricings.id as id,
+ (channel_pricings.id IS NOT NULL) as has_custom_pricing`,
+ defaultQuotaType, globalModelRatio, globalCompletionRatio, globalModelPrice).
+ Joins("LEFT JOIN channels ON abilities.channel_id = channels.id").
+ Joins("LEFT JOIN channel_pricings ON abilities.channel_id = channel_pricings.channel_id AND channel_pricings.model_name = ? AND channel_pricings.deleted_at IS NULL", modelName).
+ Where("abilities.model = ?", modelName).
+ Where("abilities.enabled = ?", true).
+ Where("channels.status = ?", 1). // 只显示启用的渠道
+ Group("abilities.channel_id"). // 去重(同一渠道可能有多个分组)
+ Scan(&results).Error
+
+ return results, err
+}
diff --git a/router/api-router.go b/router/api-router.go
index b5b6e8c..278c070 100644
--- a/router/api-router.go
+++ b/router/api-router.go
@@ -30,6 +30,7 @@ func SetApiRouter(router *gin.Engine) {
//apiRouter.GET("/midjourney", controller.GetMidjourney)
apiRouter.GET("/home_page_content", controller.GetHomePageContent)
apiRouter.GET("/pricing", middleware.TryUserAuth(), controller.GetPricing)
+ apiRouter.GET("/channel-pricing/model/*name", middleware.TryUserAuth(), controller.GetChannelPricingByModelWithChannelInfo)
apiRouter.GET("/verification", middleware.EmailVerificationRateLimit(), middleware.TurnstileCheck(), controller.SendEmailVerification)
apiRouter.GET("/reset_password", middleware.CriticalRateLimit(), middleware.TurnstileCheck(), controller.SendPasswordResetEmail)
apiRouter.POST("/user/reset", middleware.CriticalRateLimit(), controller.ResetPassword)
diff --git a/web/src/components/common/ui/HorizontalFilterRow.jsx b/web/src/components/common/ui/HorizontalFilterRow.jsx
index b98cce6..376d9b4 100644
--- a/web/src/components/common/ui/HorizontalFilterRow.jsx
+++ b/web/src/components/common/ui/HorizontalFilterRow.jsx
@@ -17,13 +17,12 @@ along with this program. If not, see