import { compareUiTierSortOrder } from "@/lib/constants/quote"; import { RpaDataInvalidError } from "@/modules/quote/types"; type QuoteTierKey = { service_level: string; rate_option: string; }; function tierKey(serviceLevel: string, rateOption: string): string { return `${serviceLevel}/${rateOption}`; } /** 保留 MotherShip 实际返回的全部档位,仅去重 + 排序(不作固定 3+2 白名单过滤) */ export function normalizeToFourTiers( quotes: T[], ): T[] { const map = new Map(); for (const quote of quotes) { map.set(tierKey(quote.service_level, quote.rate_option), quote); } if (!map.has("standard/lowest")) { throw new RpaDataInvalidError("缺少必选报价档位:standard/lowest"); } return [...map.values()].sort((a, b) => compareUiTierSortOrder( a.service_level, a.rate_option, b.service_level, b.rate_option, ), ); } /** 至少含 standard/lowest;档位数随 MotherShip 实际返回 */ export function assertFourTiers(quotes: QuoteTierKey[]): void { const normalized = normalizeToFourTiers(quotes); if (normalized.length < 1) { throw new RpaDataInvalidError("报价档位数不足"); } if ( !normalized.some( (item) => item.service_level === "standard" && item.rate_option === "lowest", ) ) { throw new RpaDataInvalidError("缺少报价档位:standard/lowest"); } }