Files
NianAIGC/lib/client/billing-price-catalog.ts
T
2026-09-23 15:46:21 +08:00

51 lines
1.8 KiB
TypeScript

import type { BillingParameterDimension, BillingParameterTier, BillingPriceRule } from "@/lib/types";
export type PriceEditTarget = {
dimensionKey?: string;
tierValue?: string;
label: string;
markupMultiplier: number;
};
export function priceCatalogBulkTarget(rules: BillingPriceRule[]) {
const modelKeys = new Set<string>();
const ruleIds: string[] = [];
const multipliers: number[] = [];
let tierCount = 0;
for (const rule of rules) {
ruleIds.push(rule.id);
modelKeys.add([rule.provider, rule.capability, rule.reqKey || ""].join("\u0000"));
multipliers.push(rule.markupMultiplier);
const tiers = rule.parameterDimensions?.flatMap((dimension) => dimension.tiers) || [];
tierCount += tiers.length || 1;
multipliers.push(...tiers.map((tier) => tier.markupMultiplier));
}
return {
ruleIds,
modelCount: modelKeys.size,
tierCount,
currentMultiplier: multipliers.length && multipliers.every((value) => value === multipliers[0]) ? multipliers[0] : null
};
}
export function groupedPriceRuleSections(rules: BillingPriceRule[]) {
return rules.map((rule, index) => ({
rule,
label: rule.provider === "seedream" && rule.capability === "image.generate"
? rule.conditions?.layerDecomposition === true ? "图层拆分" : "基础生图"
: rule.variantKey || `规则 ${index + 1}`,
dimensions: rule.parameterDimensions?.filter((dimension) => dimension.tiers.length > 0) || []
}));
}
export function priceTierEditTarget(dimension: BillingParameterDimension, tier: BillingParameterTier, businessLabel?: string): PriceEditTarget {
return {
dimensionKey: dimension.key,
tierValue: String(tier.value),
label: [businessLabel, dimension.label || dimension.key, tier.label || String(tier.value)].filter(Boolean).join(" · "),
markupMultiplier: tier.markupMultiplier
};
}