重构价格倍率相关逻辑,将原有的 rates 处理替换为 one_hub 处理,更新相关路由和缓存清除逻辑,提升代码结构和可维护性。同时,前端接口地址也进行了相应调整,以支持新的 one_hub 路由。

This commit is contained in:
wood chen 2025-04-17 20:53:35 +08:00
parent 9b4cee8e0f
commit e6c405a130
6 changed files with 120 additions and 13 deletions

View File

@ -11,7 +11,7 @@ import (
"aimodels-prices/database"
"aimodels-prices/handlers"
"aimodels-prices/handlers/rates"
"aimodels-prices/handlers/one_hub"
"aimodels-prices/models"
)
@ -233,7 +233,7 @@ func UpdateOtherPrices() error {
log.Printf("其他厂商价格数据处理完成,成功处理: %d, 跳过: %d", processedCount, skippedCount)
// 清除倍率缓存
rates.ClearRatesCache()
one_hub.ClearRatesCache()
log.Println("倍率缓存已清除")
return nil
}

View File

@ -14,7 +14,7 @@ import (
"aimodels-prices/database"
"aimodels-prices/handlers"
"aimodels-prices/handlers/rates"
"aimodels-prices/handlers/one_hub"
"aimodels-prices/models"
"gorm.io/gorm"
@ -220,7 +220,7 @@ func UpdateSiliconFlowPrices() error {
log.Printf("SiliconFlow价格数据处理完成成功处理: %d, 跳过: %d", processedCount, skippedCount)
// 清除倍率缓存
rates.ClearRatesCache()
one_hub.ClearRatesCache()
log.Println("倍率缓存已清除")
return nil
}

View File

@ -1,4 +1,4 @@
package rates
package one_hub
import (
"net/http"
@ -22,7 +22,7 @@ type PriceRate struct {
// GetPriceRates 获取价格倍率
func GetPriceRates(c *gin.Context) {
cacheKey := "price_rates"
cacheKey := "one_hub_price_rates"
// 尝试从缓存获取
if cachedData, found := database.GlobalCache.Get(cacheKey); found {
@ -100,9 +100,94 @@ func GetPriceRates(c *gin.Context) {
c.JSON(http.StatusOK, rates)
}
// GetOfficialPriceRates 获取官方厂商ID小于1000的价格倍率
func GetOfficialPriceRates(c *gin.Context) {
cacheKey := "one_hub_official_price_rates"
// 尝试从缓存获取
if cachedData, found := database.GlobalCache.Get(cacheKey); found {
if rates, ok := cachedData.([]PriceRate); ok {
c.JSON(http.StatusOK, rates)
return
}
}
// 使用索引优化查询只查询需要的字段并添加厂商ID筛选条件
var prices []models.Price
result := database.DB.Model(&models.Price{}).
Select("model", "billing_type", "channel_type", "input_price", "output_price", "currency", "status").
Where(&models.Price{Status: "approved"}).
Where("channel_type < ?", 1000).
Find(&prices)
if result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch prices"})
return
}
// 创建map用于存储模型及其对应的最高倍率
modelRateMap := make(map[string]PriceRate)
// 计算倍率
for _, price := range prices {
// 根据货币类型计算倍率
var inputRate, outputRate float64
if price.Currency == "USD" {
// 如果是美元除以2
inputRate = round(price.InputPrice/2, 4)
outputRate = round(price.OutputPrice/2, 4)
} else {
// 如果是人民币或其他货币除以14
inputRate = round(price.InputPrice/14, 4)
outputRate = round(price.OutputPrice/14, 4)
}
// 创建当前价格的PriceRate
currentRate := PriceRate{
Model: price.Model,
Type: price.BillingType,
ChannelType: price.ChannelType,
Input: inputRate,
Output: outputRate,
}
// 转换为小写以实现不区分大小写比较
modelLower := strings.ToLower(price.Model)
// 检查是否已存在相同模型名称(不区分大小写)
if existingRate, exists := modelRateMap[modelLower]; exists {
// 比较倍率,保留较高的那个
// 这里我们以输入和输出倍率的总和作为比较标准
existingTotal := existingRate.Input + existingRate.Output
currentTotal := inputRate + outputRate
if currentTotal > existingTotal {
// 当前倍率更高,替换已存在的
modelRateMap[modelLower] = currentRate
}
} else {
// 不存在相同模型名称,直接添加
modelRateMap[modelLower] = currentRate
}
}
// 从map中提取结果到slice
rates := make([]PriceRate, 0, len(modelRateMap))
for _, rate := range modelRateMap {
rates = append(rates, rate)
}
// 存入缓存有效期24小时
database.GlobalCache.Set(cacheKey, rates, 24*time.Hour)
c.JSON(http.StatusOK, rates)
}
// ClearRatesCache 清除价格倍率缓存
func ClearRatesCache() {
database.GlobalCache.Delete("price_rates")
database.GlobalCache.Delete("one_hub_price_rates")
database.GlobalCache.Delete("one_hub_official_price_rates")
}
// round 四舍五入到指定小数位

View File

@ -10,7 +10,7 @@ import (
"github.com/gin-gonic/gin"
"aimodels-prices/database"
"aimodels-prices/handlers/rates"
"aimodels-prices/handlers/one_hub"
"aimodels-prices/models"
)
@ -628,5 +628,5 @@ func clearPriceCache() {
database.GlobalCache.Clear()
// 同时清除价格倍率缓存
rates.ClearRatesCache()
one_hub.ClearRatesCache()
}

View File

@ -10,7 +10,7 @@ import (
"aimodels-prices/cron"
"aimodels-prices/database"
"aimodels-prices/handlers"
"aimodels-prices/handlers/rates"
one_hub_handlers "aimodels-prices/handlers/one_hub"
initTasks "aimodels-prices/init"
"aimodels-prices/middleware"
)
@ -66,7 +66,9 @@ func main() {
prices := api.Group("/prices")
{
prices.GET("", handlers.GetPrices)
prices.GET("/rates", rates.GetPriceRates)
prices.GET("/rates", one_hub_handlers.GetPriceRates) //one_hub 价格倍率, 旧接口
prices.POST("", middleware.AuthRequired(), handlers.CreatePrice)
prices.PUT("/:id", middleware.AuthRequired(), handlers.UpdatePrice)
prices.DELETE("/:id", middleware.AuthRequired(), handlers.DeletePrice)
@ -74,6 +76,13 @@ func main() {
prices.PUT("/approve-all", middleware.AuthRequired(), middleware.AdminRequired(), handlers.ApproveAllPrices)
}
//one_hub 路由
one_hub := api.Group("/one_hub")
{
one_hub.GET("/rates", one_hub_handlers.GetPriceRates)
one_hub.GET("/official-rates", one_hub_handlers.GetOfficialPriceRates)
}
// 模型厂商相关路由
providers := api.Group("/providers")
{

View File

@ -34,8 +34,8 @@
<div class="api-url">
<span class="method">GET</span>
<el-tooltip content="点击复制" placement="top">
<span class="url" @click="copyToClipboard(origin + '/api/prices/rates')">
{{ origin }}/api/prices/rates
<span class="url" @click="copyToClipboard(origin + '/api/one_hub/rates')">
{{ origin }}/api/one_hub/rates
</span>
</el-tooltip>
</div>
@ -62,6 +62,19 @@
</div>
</el-collapse-item>
<el-collapse-item title="One-Hub 官方价格倍率(ID小于1000)">
<div class="api-doc">
<div class="api-url">
<span class="method">GET</span>
<el-tooltip content="点击复制" placement="top">
<span class="url" @click="copyToClipboard(origin + '/api/one_hub/official-rates')">
{{ origin }}/api/one_hub/official-rates
</span>
</el-tooltip>
</div>
</div>
</el-collapse-item>
<el-collapse-item title="获取价格列表">
<div class="api-doc">
<div class="api-url">