Files
omniai-ds-code-package/src/features/ecommerce/utils/platformRules.ts
T

94 lines
5.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { formatAspectRatio, normalizeRatioToken } from "./ratioUtils";
import { getPlatformRules } from "../../../api/platformRulesClient";
export type ProductSetOutputKey = "set" | "detail" | "model" | "video";
export type CloneOutputKey = ProductSetOutputKey | "hot";
export type PlatformRatioModeKey = ProductSetOutputKey | "hot";
export interface PlatformRatioGroup {
ratios: string[];
defaultRatio: string;
}
export interface EcommercePlatformSpec {
label: string;
ratios: string[];
defaultRatio: string;
ratioGroups?: Partial<Record<PlatformRatioModeKey, PlatformRatioGroup>>;
specs: string[];
tip?: string;
aliases?: string[];
}
// 业务数据由后端 API 下发(AGENTS.md 规则4),见 src/api/platformRulesClient.ts。
// 启动 gating 保证本模块求值时(随 EcommercePage chunk 加载)缓存已填充。
// 顶层读取一次:gating 后 getPlatformRules() 返回 API 数据;未就绪则返回 fallback。
const rules = getPlatformRules();
export const platformSpecOptions: EcommercePlatformSpec[] = rules.platformSpecOptions;
export const platformOptions = platformSpecOptions.map((option) => option.label);
export const marketLanguageOptions: Array<{ country: string; languages: string[] }> =
rules.marketLanguageOptions;
export const marketOptions = marketLanguageOptions.map((option) => option.country);
export const languageOptions = Array.from(new Set(marketLanguageOptions.flatMap((option) => option.languages)));
export const languageAliases: Record<string, string> = rules.languageAliases;
export const defaultPlatformSpec = platformSpecOptions[0]!;
export const getPlatformSpec = (value: string) =>
platformSpecOptions.find((option) => option.label === value || option.aliases?.includes(value)) ?? defaultPlatformSpec;
export const legacyPlatformAliases: Record<string, string> = rules.legacyPlatformAliases;
export const normalizePlatform = (value: string) => getPlatformSpec(legacyPlatformAliases[value] ?? value).label;
export const domesticPlatformLabels = new Set(rules.domesticPlatformLabels);
export const domesticPlatformLanguages = rules.domesticPlatformLanguages;
export const isDomesticPlatform = (platformValue: string) => domesticPlatformLabels.has(normalizePlatform(platformValue));
export const getPlatformRatioGroup = (value: string, mode?: PlatformRatioModeKey): PlatformRatioGroup => {
const platformSpec = getPlatformSpec(value);
return (mode ? platformSpec.ratioGroups?.[mode] : null) ?? {
ratios: platformSpec.ratios,
defaultRatio: platformSpec.defaultRatio,
};
};
export const getPlatformRatioOptions = (value: string, mode?: PlatformRatioModeKey) => getPlatformRatioGroup(value, mode).ratios;
export const getPlatformDefaultRatio = (value: string, mode?: PlatformRatioModeKey) => getPlatformRatioGroup(value, mode).defaultRatio;
export const getUniqueRatioOptions = (ratios: string[]) => Array.from(new Set(ratios));
export const normalizeRatioForPlatform = (platformValue: string, ratioValue: string, mode?: PlatformRatioModeKey) => {
const platformRatios = getPlatformRatioOptions(platformValue, mode);
if (platformRatios.includes(ratioValue)) return ratioValue;
const normalizedRatio = normalizeRatioToken(ratioValue);
const matchedRatio = platformRatios.find((option) => normalizeRatioToken(option).includes(normalizedRatio));
return matchedRatio ?? getPlatformDefaultRatio(platformValue, mode);
};
export const defaultMarketLanguageOption = marketLanguageOptions[0]!;
export const normalizeMarket = (value: string) =>
marketLanguageOptions.some((option) => option.country === value) ? value : defaultMarketLanguageOption.country;
export const normalizeLanguage = (value: string) => languageAliases[value] ?? value;
export const uniqueLanguages = (languages: string[]) => Array.from(new Set(languages));
export const appendEnglish = (languages: string[]) => Array.from(new Set([...languages, "英文"]));
export const getMarketLanguageOptions = (marketValue: string) =>
appendEnglish((marketLanguageOptions.find((option) => option.country === marketValue) ?? defaultMarketLanguageOption).languages);
export const getPlatformLanguageOptions = (platformValue: string, marketValue: string) => {
const marketLanguages = getMarketLanguageOptions(marketValue);
if (!isDomesticPlatform(platformValue)) return marketLanguages;
const localLanguages = marketLanguages.filter((item) => item !== "英文");
return uniqueLanguages([...localLanguages, ...domesticPlatformLanguages, "英文"]);
};
export const getPlatformDefaultLanguage = (platformValue: string, marketValue: string) =>
isDomesticPlatform(platformValue) ? "中文" : (getPlatformLanguageOptions(platformValue, marketValue)[0] ?? languageOptions[0] ?? "英文");
export const normalizeLanguageForPlatform = (platformValue: string, marketValue: string, languageValue: string) => {
const normalizedLanguage = normalizeLanguage(languageValue);
const platformLanguages = getPlatformLanguageOptions(platformValue, marketValue);
return platformLanguages.includes(normalizedLanguage) ? normalizedLanguage : getPlatformDefaultLanguage(platformValue, marketValue);
};
export const defaultEcommercePlatform = rules.defaultEcommercePlatform;
export const defaultProductSetOutput: ProductSetOutputKey = "set";
export const defaultCloneOutput: CloneOutputKey = "set";
export const formatUploadedImageRatio = (image?: { width?: number; height?: number; format?: string }) => {
if (!image) return null;
const format = image.format ? `\u00a0\u00a0\u00a0${image.format}` : "";
if (!image.width || !image.height) return `上传图片\u00a0\u00a0\u00a0原图比例${format}`;
return `上传图片 ${image.width}×${image.height}px\u00a0\u00a0\u00a0${formatAspectRatio(image.width, image.height)}${format}`;
};