export type ProductNameSourceSuffixItem = { /** 来源标识,如 91kaquan */ source: string /** 括号内的后缀文字,如 91卡券 */ suffix: string /** 未启用(false)的配置不参与展示;缺省按启用处理,兼容打手端精简数据 */ enabled?: boolean } /** 后缀只保留括号内的文字:填了外层全角/半角括号时自动剥离。 */ export function normalizeProductNameSuffixText(value: unknown): string { let text = String(value ?? '').trim() if (!text) return '' const wrappedFullWidth = text.startsWith('(') && text.endsWith(')') const wrappedHalfWidth = text.startsWith('(') && text.endsWith(')') if ((wrappedFullWidth || wrappedHalfWidth) && text.length >= 2) { text = text.slice(1, -1).trim() } return text } /** * 按来源取后缀:来源精确匹配、不区分大小写,空来源或空后缀不命中。 * 同一来源配置多条时以第一条有效配置为准。 */ export function resolveProductNameSourceSuffix( items: ProductNameSourceSuffixItem[] | null | undefined, provider: unknown, ): string { const normalizedProvider = String(provider ?? '') .trim() .toLowerCase() if (!normalizedProvider) return '' for (const item of items ?? []) { if (item?.enabled === false) continue const source = String(item?.source ?? '') .trim() .toLowerCase() if (!source || source !== normalizedProvider) continue const suffix = normalizeProductNameSuffixText(item?.suffix) if (suffix) return suffix } return '' } /** * 在商品名后追加「(后缀)」;没有后缀时原样返回。 * 商品名已以相同后缀结尾(全角/半角括号均可)时不重复追加。 */ export function appendProductNameSourceSuffix(productName: unknown, suffix: unknown): string { const name = String(productName ?? '').trim() const normalizedSuffix = normalizeProductNameSuffixText(suffix) if (!name || !normalizedSuffix) return name if (name.endsWith(`(${normalizedSuffix})`) || name.endsWith(`(${normalizedSuffix})`)) { return name } return `${name}(${normalizedSuffix})` } /** 展示用:按来源匹配后一次性完成后缀追加;无匹配时返回原商品名。 */ export function applyProductNameSourceSuffix( productName: unknown, provider: unknown, items: ProductNameSourceSuffixItem[] | null | undefined, ): string { return appendProductNameSourceSuffix(productName, resolveProductNameSourceSuffix(items, provider)) }