fix(web): 模型价格 - 修复零积分显示为未配置
This commit is contained in:
@@ -4,7 +4,7 @@ import { Popover } from "antd";
|
||||
|
||||
import { canvasThemes, type CanvasTheme } from "@/lib/canvas-theme";
|
||||
import { modelCapabilityConfigFor, videoDurationOptions } from "@/lib/model-capabilities";
|
||||
import { modelQuoteRequest, normalizeTierResolution, priceTiersForCurrentSelection } from "@/lib/model-pricing";
|
||||
import { formatPriceRange, modelQuoteRequest, normalizeTierResolution, priceTierSummaryLabel, priceTiersForCurrentSelection } from "@/lib/model-pricing";
|
||||
import { compatibleModelInGroup, configuredModelDisplayName, groupModelsByDisplayName, modelCompatibilityError, resolveCompatibleModel, type ModelRequirements } from "@/lib/model-selection";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { modelDisplayName, modelIcon, modelOptionName, PUBLIC_MODEL_CATALOG_ID, resolveModelChannel, selectableModelsByCapability, type AiConfig, type ModelCapability } from "@/stores/use-config-store";
|
||||
@@ -400,22 +400,7 @@ function channelTierPriceSummary(
|
||||
visibleTiers: NonNullable<NonNullable<AiConfig["channels"][number]["modelCosts"]>[number]["logicalPriceTiers"]>,
|
||||
allTiers: NonNullable<NonNullable<AiConfig["channels"][number]["modelCosts"]>[number]["logicalPriceTiers"]>,
|
||||
): Extract<ModelMenuPrice, { kind: "tiers" }> {
|
||||
const fixedRequestValues = visibleTiers
|
||||
.filter((tier) => tier.billingMode === "fixed_request")
|
||||
.map((tier) => tier.unitPriceMicrocredits / 1_000_000)
|
||||
.filter((value) => value > 0);
|
||||
const perSecondValues = visibleTiers
|
||||
.filter((tier) => tier.billingMode === "per_second")
|
||||
.map((tier) => tier.unitPriceMicrocredits / 1_000_000)
|
||||
.filter((value) => value > 0);
|
||||
const hasTokenTier = visibleTiers.some((tier) => tier.billingMode === "token");
|
||||
const label = fixedRequestValues.length
|
||||
? formatPriceRange(fixedRequestValues, "积分")
|
||||
: perSecondValues.length
|
||||
? formatPriceRange(perSecondValues, "积分/秒")
|
||||
: hasTokenTier
|
||||
? "按量预估"
|
||||
: "未配置";
|
||||
const label = priceTierSummaryLabel(visibleTiers);
|
||||
return {
|
||||
kind: "tiers",
|
||||
label,
|
||||
@@ -424,12 +409,6 @@ function channelTierPriceSummary(
|
||||
};
|
||||
}
|
||||
|
||||
function formatPriceRange(values: number[], suffix: string) {
|
||||
const unique = Array.from(new Set(values)).sort((left, right) => left - right);
|
||||
const format = (value: number) => value.toLocaleString("zh-CN", { maximumFractionDigits: 3 });
|
||||
return unique.length === 1 ? `${format(unique[0])} ${suffix}` : `${format(unique[0])}-${format(unique[unique.length - 1])} ${suffix}`;
|
||||
}
|
||||
|
||||
function tierResolutionLabel(value: string) {
|
||||
const normalized = normalizeTierResolution(value);
|
||||
return normalized === "*" ? "全部分辨率" : normalized.toUpperCase();
|
||||
|
||||
@@ -51,6 +51,25 @@ export function priceTiersForCurrentSelection(tiers: ModelPriceTier[], capabilit
|
||||
return matched;
|
||||
}
|
||||
|
||||
export function priceTierSummaryLabel(tiers: ModelPriceTier[]) {
|
||||
const unitPrices = (billingMode: ModelPriceTier["billingMode"]) =>
|
||||
tiers
|
||||
.filter((tier) => tier.billingMode === billingMode)
|
||||
.map((tier) => tier.unitPriceMicrocredits / 1_000_000)
|
||||
.filter((value) => Number.isFinite(value) && value >= 0);
|
||||
const fixedRequestValues = unitPrices("fixed_request");
|
||||
const perSecondValues = unitPrices("per_second");
|
||||
if (fixedRequestValues.length) return formatPriceRange(fixedRequestValues, "积分");
|
||||
if (perSecondValues.length) return formatPriceRange(perSecondValues, "积分/秒");
|
||||
return tiers.some((tier) => tier.billingMode === "token") ? "按量预估" : "未配置";
|
||||
}
|
||||
|
||||
export function formatPriceRange(values: number[], suffix: string) {
|
||||
const unique = Array.from(new Set(values)).sort((left, right) => left - right);
|
||||
const format = (value: number) => value.toLocaleString("zh-CN", { maximumFractionDigits: 3 });
|
||||
return unique.length === 1 ? `${format(unique[0])} ${suffix}` : `${format(unique[0])}-${format(unique[unique.length - 1])} ${suffix}`;
|
||||
}
|
||||
|
||||
export function modelQuoteRequest(config: AiConfig, value: string, capability?: ModelCapability, requirements?: ModelRequirements): { logicalModelID: string; intent: ModelRequestIntent } | undefined {
|
||||
if (!capability || !value) return undefined;
|
||||
const channel = resolveModelChannel(config, value);
|
||||
|
||||
Reference in New Issue
Block a user