import {ProductItem} from '@/actions/product' import {PurchaseKind, PurchaseMode} from './resource' export type PurchaseSkuItem = { code: string mode: PurchaseMode live: string expire: string price: string count_min: number } export type PurchaseSkuData = { items: PurchaseSkuItem[] priceMap: Map countMinMap: Map modeList: PurchaseMode[] liveList: string[] expireList: string[] } export function parsePurchaseSkuList(kind: PurchaseKind, skuList: ProductItem['skus']): PurchaseSkuData { if (!skuList?.length) { return { items: [], priceMap: new Map(), countMinMap: new Map(), modeList: [], liveList: [], expireList: [], } } const items: PurchaseSkuItem[] = [] const priceMap = new Map() const countMinMap = new Map() const modeSet = new Set() const liveSet = new Set() const expireSet = new Set() for (const sku of skuList) { const params = new URLSearchParams(sku.code) const mode = parsePurchaseSkuMode(params.get('mode')) const live = Number(params.get('live') || '0') const expire = Number(params.get('expire') || '0') if (!mode || live <= 0) { continue } const liveValue = String(live) const expireValue = mode === '1' ? String(expire || '0') : '0' const code = getPurchaseSkuKey({ mode, live: liveValue, expire: expireValue, }) const countMin = typeof sku.count_min === 'number' ? sku.count_min : Number(sku.count_min) || 0 countMinMap.set(code, countMin) items.push({ code, mode, live: liveValue, expire: expireValue, price: sku.price, count_min: countMin, }) priceMap.set(code, sku.price) modeSet.add(mode) liveSet.add(live) if (kind === 'short') { if (mode === '1' && expire > 0) { expireSet.add(expire) } } else if (expire > 0) { expireSet.add(expire) } } if (items.length === 0) { return { items: [], priceMap, countMinMap, modeList: [], liveList: [], expireList: [], } } return { items, priceMap, countMinMap, modeList: (['2', '1'] as const).filter(mode => modeSet.has(mode)), liveList: sortNumericValues(liveSet), expireList: sortNumericValues(expireSet), } } function parsePurchaseSkuMode(mode: string | null): PurchaseMode | null { if (mode === 'time') { return '1' } if (mode === 'quota') { return '2' } return null } function sortNumericValues(values: Iterable) { return Array.from(values).sort((a, b) => a - b).map(String) } export function getPurchaseSkuKey(props: { mode: PurchaseMode live: string expire: string }) { const params = new URLSearchParams() params.set('mode', props.mode === '1' ? 'time' : 'quota') params.set('live', props.live || '0') params.set('expire', props.mode === '1' ? props.expire || '0' : '0') return params.toString() } export function getAvailablePurchaseLives(skuData: PurchaseSkuData, props: { mode: PurchaseMode expire?: string }) { return sortNumericValues(new Set( skuData.items .filter(item => item.mode === props.mode) .filter(item => !props.expire || item.expire === props.expire) .map(item => Number(item.live)), )) } export function getAvailablePurchaseExpires(skuData: PurchaseSkuData, props: { mode: PurchaseMode live?: string }) { return sortNumericValues(new Set( skuData.items .filter(item => item.mode === props.mode) .filter(item => !props.live || item.live === props.live) .filter(item => item.expire !== '0') .map(item => Number(item.expire)), )) } export function hasPurchaseSku(skuData: PurchaseSkuData, props: { mode: PurchaseMode live: string expire: string }) { return skuData.priceMap.has(getPurchaseSkuKey(props)) } export function getPurchaseSkuPrice(priceMap: Map, props: { mode: PurchaseMode live: string expire: string }) { return priceMap.get(getPurchaseSkuKey(props)) } export function formatPurchaseLiveLabel(live: string, kind: PurchaseKind) { const minutes = Number(live) if (kind === 'long') { return `${minutes / 60} 小时` } if (minutes % 60 === 0) { return `${minutes / 60} 小时` } return `${minutes} 分钟` } export function getPurchaseSkuCountMin( skuData: PurchaseSkuData, props: {mode: PurchaseMode, live: string, expire: string}, ): number { const key = getPurchaseSkuKey(props) return skuData.countMinMap.get(key) ?? 0 }