105 lines
3.2 KiB
TypeScript
105 lines
3.2 KiB
TypeScript
import { getVideoCreditCostFromConfig, type VideoImageGenConfigLike } from "@/lib/ai/video-model-config";
|
|
|
|
export type DiscountableImageGenConfigLike = VideoImageGenConfigLike & {
|
|
creditCostPerImage?: number | null;
|
|
creditDiscountRate?: number | null;
|
|
};
|
|
|
|
function normalizeRoundedCost(value: unknown) {
|
|
const normalized = Number(value);
|
|
if (!Number.isFinite(normalized)) return 0;
|
|
return Math.max(0, Math.round(normalized));
|
|
}
|
|
|
|
export function normalizeImageModelCreditDiscountRate(value: unknown) {
|
|
const normalized = Number(value);
|
|
if (!Number.isFinite(normalized)) return null;
|
|
const rounded = Math.round(normalized * 10) / 10;
|
|
if (rounded <= 0 || rounded >= 10) return null;
|
|
return rounded;
|
|
}
|
|
|
|
export function formatImageModelCreditDiscountLabel(value: unknown) {
|
|
const normalized = normalizeImageModelCreditDiscountRate(value);
|
|
if (normalized === null) return null;
|
|
const displayValue = Number.isInteger(normalized)
|
|
? String(normalized)
|
|
: normalized.toFixed(1).replace(/\.0$/, "");
|
|
return `${displayValue}折`;
|
|
}
|
|
|
|
export function getImageModelCreditDiscountLabel(
|
|
config: DiscountableImageGenConfigLike | null | undefined
|
|
) {
|
|
return formatImageModelCreditDiscountLabel(config?.creditDiscountRate);
|
|
}
|
|
|
|
export function applyImageModelCreditDiscount(
|
|
rawCost: unknown,
|
|
config: DiscountableImageGenConfigLike | null | undefined
|
|
) {
|
|
const baseCost = normalizeRoundedCost(rawCost);
|
|
if (baseCost <= 0) return 0;
|
|
|
|
const normalizedDiscountRate = normalizeImageModelCreditDiscountRate(
|
|
config?.creditDiscountRate
|
|
);
|
|
if (normalizedDiscountRate === null) return baseCost;
|
|
|
|
return Math.max(0, Math.round((baseCost * normalizedDiscountRate) / 10));
|
|
}
|
|
|
|
export function getGenerationCreditCostFromImageGenConfig(
|
|
config: DiscountableImageGenConfigLike | null | undefined,
|
|
target: "image" | "video",
|
|
options?: { duration?: number | null; resolution?: string | null }
|
|
) {
|
|
const sourceValue =
|
|
target === "video"
|
|
? (() => {
|
|
const resolvedVideoCost = getVideoCreditCostFromConfig(
|
|
config,
|
|
options?.duration,
|
|
options?.resolution
|
|
);
|
|
if (resolvedVideoCost > 0) return resolvedVideoCost;
|
|
return config?.creditCostPerVideo ?? config?.creditCostPerImage ?? 0;
|
|
})()
|
|
: config?.creditCostPerImage ?? 0;
|
|
|
|
return applyImageModelCreditDiscount(sourceValue, config);
|
|
}
|
|
|
|
export function getImageCreditCostFromConfig(
|
|
config: DiscountableImageGenConfigLike | null | undefined
|
|
) {
|
|
return getGenerationCreditCostFromImageGenConfig(config, "image");
|
|
}
|
|
|
|
export function getModelGenerationCreditCost(
|
|
modelConfig: { imageGenConfig?: DiscountableImageGenConfigLike | null } | null | undefined,
|
|
target: "image" | "video",
|
|
options?: { duration?: number | null; resolution?: string | null }
|
|
) {
|
|
return getGenerationCreditCostFromImageGenConfig(
|
|
modelConfig?.imageGenConfig,
|
|
target,
|
|
options
|
|
);
|
|
}
|
|
|
|
export function normalizeImageGenPricingConfig<
|
|
T extends DiscountableImageGenConfigLike | null | undefined,
|
|
>(config: T): T {
|
|
if (!config) return config;
|
|
|
|
const normalizedDiscountRate = normalizeImageModelCreditDiscountRate(
|
|
config.creditDiscountRate
|
|
);
|
|
|
|
return {
|
|
...config,
|
|
creditDiscountRate: normalizedDiscountRate ?? undefined,
|
|
} as T;
|
|
}
|