From 85ef87df11069939ac4818ee65033558f2f4b369 Mon Sep 17 00:00:00 2001 From: wood chen Date: Thu, 1 May 2025 01:57:55 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=B7=E6=A0=BC=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E9=80=BB=E8=BE=91=EF=BC=8C=E6=96=B0=E5=A2=9E=E6=89=A9?= =?UTF-8?q?=E5=B1=95=E4=BB=B7=E6=A0=BC=E5=AD=97=E6=AE=B5=E7=9A=84=E7=9B=B8?= =?UTF-8?q?=E5=AF=B9=E5=9F=BA=E5=87=86=E6=98=A0=E5=B0=84=EF=BC=8C=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E5=89=8D=E7=AB=AF=E5=B1=95=E7=A4=BA=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E6=8F=90=E5=8D=87=E7=94=A8=E6=88=B7=E4=BD=93=E9=AA=8C?= =?UTF-8?q?=E5=92=8C=E4=BB=A3=E7=A0=81=E5=8F=AF=E7=BB=B4=E6=8A=A4=E6=80=A7?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/handlers/one_hub/price_rates.go | 354 +++++++++++++++++------- frontend/src/views/Prices.vue | 251 +++++++++-------- 2 files changed, 378 insertions(+), 227 deletions(-) diff --git a/backend/handlers/one_hub/price_rates.go b/backend/handlers/one_hub/price_rates.go index e994eb5..feed783 100644 --- a/backend/handlers/one_hub/price_rates.go +++ b/backend/handlers/one_hub/price_rates.go @@ -35,6 +35,20 @@ type PriceRate struct { ExtraRatios *ExtraRatios `json:"extra_ratios,omitempty"` } +// 定义扩展价格字段是否相对于input的映射 +var extraRelativeToInput = map[string]bool{ + "cached_tokens": true, + "cached_write_tokens": true, + "cached_read_tokens": true, + "input_audio_tokens": true, + "output_audio_tokens": false, + "reasoning_tokens": false, + "input_text_tokens": true, + "output_text_tokens": false, + "input_image_tokens": true, + "output_image_tokens": false, +} + // GetPriceRates 获取价格倍率 func GetPriceRates(c *gin.Context) { cacheKey := "one_hub_price_rates" @@ -87,103 +101,173 @@ func GetPriceRates(c *gin.Context) { // 计算各扩展价格字段的倍率 if price.InputAudioTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.InputAudioTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["input_audio_tokens"] { + baseRate = inputRate } else { - rate = round(*price.InputAudioTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.InputAudioTokens/2, 4) / baseRate + extraRatios.InputAudioTokens = &rate + } else { + rate := round(*price.InputAudioTokens/14, 4) / baseRate + extraRatios.InputAudioTokens = &rate } - extraRatios.InputAudioTokens = &rate } if price.OutputAudioTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.OutputAudioTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["output_audio_tokens"] { + baseRate = inputRate } else { - rate = round(*price.OutputAudioTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.OutputAudioTokens/2, 4) / baseRate + extraRatios.OutputAudioTokens = &rate + } else { + rate := round(*price.OutputAudioTokens/14, 4) / baseRate + extraRatios.OutputAudioTokens = &rate } - extraRatios.OutputAudioTokens = &rate } if price.CachedTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.CachedTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["cached_tokens"] { + baseRate = inputRate } else { - rate = round(*price.CachedTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.CachedTokens/2, 4) / baseRate + extraRatios.CachedTokens = &rate + } else { + rate := round(*price.CachedTokens/14, 4) / baseRate + extraRatios.CachedTokens = &rate } - extraRatios.CachedTokens = &rate } if price.CachedReadTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.CachedReadTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["cached_read_tokens"] { + baseRate = inputRate } else { - rate = round(*price.CachedReadTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.CachedReadTokens/2, 4) / baseRate + extraRatios.CachedReadTokens = &rate + } else { + rate := round(*price.CachedReadTokens/14, 4) / baseRate + extraRatios.CachedReadTokens = &rate } - extraRatios.CachedReadTokens = &rate } if price.CachedWriteTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.CachedWriteTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["cached_write_tokens"] { + baseRate = inputRate } else { - rate = round(*price.CachedWriteTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.CachedWriteTokens/2, 4) / baseRate + extraRatios.CachedWriteTokens = &rate + } else { + rate := round(*price.CachedWriteTokens/14, 4) / baseRate + extraRatios.CachedWriteTokens = &rate } - extraRatios.CachedWriteTokens = &rate } if price.ReasoningTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.ReasoningTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["reasoning_tokens"] { + baseRate = inputRate } else { - rate = round(*price.ReasoningTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.ReasoningTokens/2, 4) / baseRate + extraRatios.ReasoningTokens = &rate + } else { + rate := round(*price.ReasoningTokens/14, 4) / baseRate + extraRatios.ReasoningTokens = &rate } - extraRatios.ReasoningTokens = &rate } if price.InputTextTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.InputTextTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["input_text_tokens"] { + baseRate = inputRate } else { - rate = round(*price.InputTextTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.InputTextTokens/2, 4) / baseRate + extraRatios.InputTextTokens = &rate + } else { + rate := round(*price.InputTextTokens/14, 4) / baseRate + extraRatios.InputTextTokens = &rate } - extraRatios.InputTextTokens = &rate } if price.OutputTextTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.OutputTextTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["output_text_tokens"] { + baseRate = inputRate } else { - rate = round(*price.OutputTextTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.OutputTextTokens/2, 4) / baseRate + extraRatios.OutputTextTokens = &rate + } else { + rate := round(*price.OutputTextTokens/14, 4) / baseRate + extraRatios.OutputTextTokens = &rate } - extraRatios.OutputTextTokens = &rate } if price.InputImageTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.InputImageTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["input_image_tokens"] { + baseRate = inputRate } else { - rate = round(*price.InputImageTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.InputImageTokens/2, 4) / baseRate + extraRatios.InputImageTokens = &rate + } else { + rate := round(*price.InputImageTokens/14, 4) / baseRate + extraRatios.InputImageTokens = &rate } - extraRatios.InputImageTokens = &rate } if price.OutputImageTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.OutputImageTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["output_image_tokens"] { + baseRate = inputRate } else { - rate = round(*price.OutputImageTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.OutputImageTokens/2, 4) / baseRate + extraRatios.OutputImageTokens = &rate + } else { + rate := round(*price.OutputImageTokens/14, 4) / baseRate + extraRatios.OutputImageTokens = &rate } - extraRatios.OutputImageTokens = &rate } } @@ -285,103 +369,173 @@ func GetOfficialPriceRates(c *gin.Context) { // 计算各扩展价格字段的倍率 if price.InputAudioTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.InputAudioTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["input_audio_tokens"] { + baseRate = inputRate } else { - rate = round(*price.InputAudioTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.InputAudioTokens/2, 4) / baseRate + extraRatios.InputAudioTokens = &rate + } else { + rate := round(*price.InputAudioTokens/14, 4) / baseRate + extraRatios.InputAudioTokens = &rate } - extraRatios.InputAudioTokens = &rate } if price.OutputAudioTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.OutputAudioTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["output_audio_tokens"] { + baseRate = inputRate } else { - rate = round(*price.OutputAudioTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.OutputAudioTokens/2, 4) / baseRate + extraRatios.OutputAudioTokens = &rate + } else { + rate := round(*price.OutputAudioTokens/14, 4) / baseRate + extraRatios.OutputAudioTokens = &rate } - extraRatios.OutputAudioTokens = &rate } if price.CachedTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.CachedTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["cached_tokens"] { + baseRate = inputRate } else { - rate = round(*price.CachedTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.CachedTokens/2, 4) / baseRate + extraRatios.CachedTokens = &rate + } else { + rate := round(*price.CachedTokens/14, 4) / baseRate + extraRatios.CachedTokens = &rate } - extraRatios.CachedTokens = &rate } if price.CachedReadTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.CachedReadTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["cached_read_tokens"] { + baseRate = inputRate } else { - rate = round(*price.CachedReadTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.CachedReadTokens/2, 4) / baseRate + extraRatios.CachedReadTokens = &rate + } else { + rate := round(*price.CachedReadTokens/14, 4) / baseRate + extraRatios.CachedReadTokens = &rate } - extraRatios.CachedReadTokens = &rate } if price.CachedWriteTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.CachedWriteTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["cached_write_tokens"] { + baseRate = inputRate } else { - rate = round(*price.CachedWriteTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.CachedWriteTokens/2, 4) / baseRate + extraRatios.CachedWriteTokens = &rate + } else { + rate := round(*price.CachedWriteTokens/14, 4) / baseRate + extraRatios.CachedWriteTokens = &rate } - extraRatios.CachedWriteTokens = &rate } if price.ReasoningTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.ReasoningTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["reasoning_tokens"] { + baseRate = inputRate } else { - rate = round(*price.ReasoningTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.ReasoningTokens/2, 4) / baseRate + extraRatios.ReasoningTokens = &rate + } else { + rate := round(*price.ReasoningTokens/14, 4) / baseRate + extraRatios.ReasoningTokens = &rate } - extraRatios.ReasoningTokens = &rate } if price.InputTextTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.InputTextTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["input_text_tokens"] { + baseRate = inputRate } else { - rate = round(*price.InputTextTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.InputTextTokens/2, 4) / baseRate + extraRatios.InputTextTokens = &rate + } else { + rate := round(*price.InputTextTokens/14, 4) / baseRate + extraRatios.InputTextTokens = &rate } - extraRatios.InputTextTokens = &rate } if price.OutputTextTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.OutputTextTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["output_text_tokens"] { + baseRate = inputRate } else { - rate = round(*price.OutputTextTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.OutputTextTokens/2, 4) / baseRate + extraRatios.OutputTextTokens = &rate + } else { + rate := round(*price.OutputTextTokens/14, 4) / baseRate + extraRatios.OutputTextTokens = &rate } - extraRatios.OutputTextTokens = &rate } if price.InputImageTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.InputImageTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["input_image_tokens"] { + baseRate = inputRate } else { - rate = round(*price.InputImageTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.InputImageTokens/2, 4) / baseRate + extraRatios.InputImageTokens = &rate + } else { + rate := round(*price.InputImageTokens/14, 4) / baseRate + extraRatios.InputImageTokens = &rate } - extraRatios.InputImageTokens = &rate } if price.OutputImageTokens != nil { - var rate float64 - if price.Currency == "USD" { - rate = round(*price.OutputImageTokens/2, 4) + var baseRate float64 + if extraRelativeToInput["output_image_tokens"] { + baseRate = inputRate } else { - rate = round(*price.OutputImageTokens/14, 4) + baseRate = outputRate + } + + if price.Currency == "USD" { + rate := round(*price.OutputImageTokens/2, 4) / baseRate + extraRatios.OutputImageTokens = &rate + } else { + rate := round(*price.OutputImageTokens/14, 4) / baseRate + extraRatios.OutputImageTokens = &rate } - extraRatios.OutputImageTokens = &rate } } diff --git a/frontend/src/views/Prices.vue b/frontend/src/views/Prices.vue index d5e01dc..bef6aa6 100644 --- a/frontend/src/views/Prices.vue +++ b/frontend/src/views/Prices.vue @@ -134,98 +134,80 @@
-
扩展价格
+
+ 扩展价格 +
- - - - - - - - - - +
+ 音频输入 + {{ price.input_audio_tokens }} + + {{ price.temp_input_audio_tokens }} + +
+
+ 音频输出 + {{ price.output_audio_tokens }} + + {{ price.temp_output_audio_tokens }} + +
+
+ 缓存读取 + {{ price.cached_read_tokens }} + + {{ price.temp_cached_read_tokens }} + +
+
+ 缓存写入 + {{ price.cached_write_tokens }} + + {{ price.temp_cached_write_tokens }} + +
+
+ 推理 + {{ price.reasoning_tokens }} + + {{ price.temp_reasoning_tokens }} + +
+
+ 文本输入 + {{ price.input_text_tokens }} + + {{ price.temp_input_text_tokens }} + +
+
+ 文本输出 + {{ price.output_text_tokens }} + + {{ price.temp_output_text_tokens }} + +
+
+ 图片输入 + {{ price.input_image_tokens }} + + {{ price.temp_input_image_tokens }} + +
+
+ 图片输出 + {{ price.output_image_tokens }} + + {{ price.temp_output_image_tokens }} + +
+
+ 缓存 + {{ price.cached_tokens }} + + {{ price.temp_cached_tokens }} + +
@@ -1630,9 +1612,8 @@ onMounted(() => { } } -.skeleton-row { - padding: 10px; - border-bottom: 1px solid #EBEEF5; +.skeleton { + min-height: 240px; } .pagination-container { @@ -1736,24 +1717,24 @@ onMounted(() => { .price-cards-container { display: grid; - grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); - gap: 1.2rem; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 1rem; padding: 1rem 0; } .price-card { background: #fff; - border-radius: 12px; - padding: 1.5rem; - box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); + border-radius: 8px; + padding: 1rem; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); display: flex; flex-direction: column; - gap: 1rem; + gap: 0.8rem; transition: all 0.3s ease; position: relative; overflow: hidden; height: auto; - min-height: 280px; + min-height: 240px; } .price-card:hover { @@ -1767,7 +1748,7 @@ onMounted(() => { top: 0; left: 0; width: 100%; - height: 6px; + height: 4px; background: linear-gradient(to right, #36d1dc, #5b86e5); } @@ -1836,14 +1817,15 @@ onMounted(() => { } .model-name { - font-size: 1.35rem; + font-size: 1.1rem; font-weight: 600; color: #1f2937; - margin: 0 0 0.75rem 0; + margin: 0 0 0.5rem 0; display: flex; align-items: center; + flex-wrap: wrap; gap: 0.5rem; - line-height: 1.3; + line-height: 1.2; } .model-meta { @@ -1856,11 +1838,11 @@ onMounted(() => { .price-info { display: flex; flex-direction: column; - gap: 0.7rem; - margin-top: 0.75rem; - padding: 0.75rem; + gap: 0.5rem; + padding: 0.5rem; + margin-top: 0.5rem; background-color: #f9fafc; - border-radius: 8px; + border-radius: 6px; } .price-row { @@ -1882,49 +1864,52 @@ onMounted(() => { .extended-prices { border-top: 1px solid #f0f0f0; - padding-top: 1rem; - margin-top: 0.5rem; + padding-top: 0.5rem; + margin-top: 0.3rem; } .section-title { font-weight: 600; color: #606266; - margin-bottom: 0.75rem; - font-size: 0.95rem; + font-size: 0.85rem; + margin-bottom: 0.5rem; + display: flex; + align-items: center; } .extended-price-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); - gap: 0.75rem; + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: 0.5rem; } .extended-price-item { - display: flex; - flex-direction: column; - gap: 0.25rem; - padding: 0.75rem; + font-size: 0.7rem; + display: inline-flex; + align-items: center; + padding: 0.35rem 0.5rem; background: #f9fafb; - border-radius: 8px; + border-radius: 4px; border: 1px solid #f0f0f0; transition: all 0.2s ease; + max-width: fit-content; } .extended-price-item:hover { background: #f0f2f5; - box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05); } .ext-price-label { - font-size: 0.8rem; + font-size: 0.7rem; color: #606266; - font-weight: 500; + margin-right: 0.2rem; } .ext-price-value { - font-weight: 600; + font-weight: 500; color: #303133; - font-size: 0.95rem; + font-size: 0.7rem; } .price-card-footer { @@ -1958,7 +1943,7 @@ onMounted(() => { } .skeleton { - min-height: 300px; + min-height: 240px; } :deep(.el-tag) { @@ -2094,6 +2079,18 @@ onMounted(() => { color: #C0C4CC; cursor: not-allowed; } + +.ext-price-label::after { + content: ": "; +} + +.temp-tag { + margin-left: 4px; + font-size: 0.65rem !important; + height: 18px; + line-height: 16px; + padding: 0 4px; +}