1
This commit is contained in:
373
src/apis/mall-app/normalize.ts
Normal file
373
src/apis/mall-app/normalize.ts
Normal file
@@ -0,0 +1,373 @@
|
||||
import type {
|
||||
AppCartListResponse,
|
||||
AppGoodsDetailResponse,
|
||||
AppGoodsPageResponse,
|
||||
AppHomeMerchantGoodsResponse,
|
||||
AppHomeResponse,
|
||||
AppRecentNewGoodsResponse,
|
||||
AppOrderDetailResponse,
|
||||
AppOrderPageResponse,
|
||||
CartItemInfo,
|
||||
GoodsDetailInfo,
|
||||
GoodsSkuInfo,
|
||||
GoodsSummary,
|
||||
AppTradePreviewResponse,
|
||||
HomeMerchantGoodsBlock,
|
||||
MerchantId,
|
||||
MerchantInfo,
|
||||
OrderDetailInfo,
|
||||
OrderSummary,
|
||||
RecommendMerchantInfo,
|
||||
RecentNewGoodsItem,
|
||||
TradePreviewInfo,
|
||||
TradePreviewStoreInfo,
|
||||
} from '@/types/mall'
|
||||
|
||||
type MaybeMallUidPayload = {
|
||||
uid?: number
|
||||
memberId?: number
|
||||
}
|
||||
|
||||
type MaybeMallMerchantPayload = {
|
||||
merchantId?: MerchantId | number
|
||||
storeId?: number | string
|
||||
}
|
||||
|
||||
type RawRecommendMerchantPayload = Partial<RecommendMerchantInfo> & {
|
||||
id?: RecommendMerchantInfo['id']
|
||||
merchantId?: MerchantId | number | string
|
||||
merchantName?: string
|
||||
logo?: string
|
||||
notice?: string
|
||||
status?: string
|
||||
rankScore?: number | string
|
||||
goodsCount?: number | string
|
||||
recentNewGoodsCount?: number | string
|
||||
orderCount?: number | string
|
||||
}
|
||||
|
||||
type RawMerchantEntityPayload = Partial<MerchantInfo> & {
|
||||
id?: MerchantInfo['id'] | string
|
||||
merchantId?: MerchantId | number | string
|
||||
merchantName?: string
|
||||
logo?: string
|
||||
notice?: string
|
||||
status?: string
|
||||
}
|
||||
|
||||
type RawGoodsSummaryPayload = Partial<GoodsSummary> & {
|
||||
merchantId?: MerchantId | number | string
|
||||
createdAt?: GoodsSummary['createdAt'] | string | null
|
||||
updatedAt?: GoodsSummary['updatedAt'] | string | null
|
||||
createAt?: number | string | null
|
||||
updateAt?: number | string | null
|
||||
created_at?: number | string | null
|
||||
updated_at?: number | string | null
|
||||
createTime?: number | string | null
|
||||
updateTime?: number | string | null
|
||||
create_time?: number | string | null
|
||||
update_time?: number | string | null
|
||||
}
|
||||
|
||||
const toMerchantId = (value: MerchantId | number | string | null | undefined): MerchantId =>
|
||||
value == null ? '' : String(value)
|
||||
|
||||
const toNumber = (value: number | string | null | undefined): number => {
|
||||
const parsed = Number(value)
|
||||
return Number.isFinite(parsed) ? parsed : 0
|
||||
}
|
||||
|
||||
const pickText = (...values: Array<string | null | undefined>): string => {
|
||||
for (const value of values) {
|
||||
if (typeof value === 'string' && value.trim()) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
return ''
|
||||
}
|
||||
|
||||
const toUnixTime = (value: number | string | null | undefined): number => {
|
||||
if (typeof value === 'number' && Number.isFinite(value)) {
|
||||
return value > 1_000_000_000_000 ? Math.floor(value / 1000) : value
|
||||
}
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
return 0
|
||||
}
|
||||
|
||||
const text = value.trim()
|
||||
if (!text) {
|
||||
return 0
|
||||
}
|
||||
|
||||
const numeric = Number(text)
|
||||
if (Number.isFinite(numeric)) {
|
||||
return numeric > 1_000_000_000_000 ? Math.floor(numeric / 1000) : numeric
|
||||
}
|
||||
|
||||
const parsed = Date.parse(text.replace(/-/g, '/'))
|
||||
return Number.isFinite(parsed) ? Math.floor(parsed / 1000) : 0
|
||||
}
|
||||
|
||||
export const normalizeMallAppPayload = <TPayload extends object>(payload: TPayload): TPayload => {
|
||||
const normalized = { ...payload } as TPayload & MaybeMallUidPayload & MaybeMallMerchantPayload
|
||||
|
||||
if (normalized.uid == null && normalized.memberId != null) {
|
||||
normalized.uid = normalized.memberId
|
||||
}
|
||||
delete normalized.memberId
|
||||
|
||||
if (normalized.merchantId != null) {
|
||||
normalized.merchantId = toMerchantId(normalized.merchantId)
|
||||
}
|
||||
if (normalized.merchantId == null && normalized.storeId != null) {
|
||||
normalized.merchantId = toMerchantId(normalized.storeId)
|
||||
}
|
||||
delete normalized.storeId
|
||||
|
||||
return normalized as TPayload
|
||||
}
|
||||
|
||||
const normalizeGoodsSku = (sku: GoodsSkuInfo): GoodsSkuInfo => ({
|
||||
...sku,
|
||||
merchantId: toMerchantId(sku.merchantId),
|
||||
})
|
||||
|
||||
const normalizeGoodsSummary = (goods: RawGoodsSummaryPayload): GoodsSummary => {
|
||||
const normalized = goods as GoodsSummary
|
||||
|
||||
return {
|
||||
...normalized,
|
||||
merchantId: toMerchantId(goods.merchantId),
|
||||
merchantName: pickText(goods.merchantName),
|
||||
merchantLogo: pickText(goods.merchantLogo),
|
||||
createdAt: toUnixTime(goods.createdAt ?? goods.createAt ?? goods.created_at ?? goods.createTime ?? goods.create_time),
|
||||
updatedAt: toUnixTime(goods.updatedAt ?? goods.updateAt ?? goods.updated_at ?? goods.updateTime ?? goods.update_time),
|
||||
}
|
||||
}
|
||||
|
||||
const normalizeRecentNewGoodsItem = (goods: RecentNewGoodsItem): RecentNewGoodsItem => ({
|
||||
...goods,
|
||||
merchantId: goods.merchantId == null ? undefined : toMerchantId(goods.merchantId),
|
||||
merchantName: pickText(goods.merchantName, goods.storeName),
|
||||
merchantLogo: goods.merchantLogo?.trim(),
|
||||
storeName: pickText(goods.storeName, goods.merchantName),
|
||||
spuId: String(goods.spuId),
|
||||
createdAt: toUnixTime(goods.createdAt),
|
||||
})
|
||||
|
||||
const normalizeGoodsDetailInfo = (detail: GoodsDetailInfo): GoodsDetailInfo => ({
|
||||
...detail,
|
||||
merchantId: toMerchantId(detail.merchantId),
|
||||
createdAt: toUnixTime(detail.createdAt),
|
||||
updatedAt: toUnixTime(detail.updatedAt),
|
||||
skus: (detail.skus ?? []).map(normalizeGoodsSku),
|
||||
})
|
||||
|
||||
const normalizeCartItem = (item: CartItemInfo): CartItemInfo => ({
|
||||
...item,
|
||||
merchantId: toMerchantId(item.merchantId),
|
||||
})
|
||||
|
||||
const normalizeTradePreviewGroup = (group: TradePreviewStoreInfo): TradePreviewStoreInfo => ({
|
||||
...group,
|
||||
merchantId: toMerchantId(group.merchantId),
|
||||
})
|
||||
|
||||
const normalizeOrderSummary = (order: OrderSummary): OrderSummary => ({
|
||||
...order,
|
||||
merchantId: toMerchantId(order.merchantId),
|
||||
})
|
||||
|
||||
const normalizeOrderDetailInfo = (order: OrderDetailInfo): OrderDetailInfo => ({
|
||||
...order,
|
||||
merchantId: toMerchantId(order.merchantId),
|
||||
})
|
||||
|
||||
const normalizeRecommendMerchant = (
|
||||
merchant: RawRecommendMerchantPayload | null | undefined
|
||||
): RecommendMerchantInfo | undefined => {
|
||||
if (!merchant) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return {
|
||||
...(merchant as RecommendMerchantInfo),
|
||||
merchantId: toMerchantId(merchant.merchantId ?? merchant.id),
|
||||
storeName: pickText(merchant.storeName, merchant.merchantName),
|
||||
storeLogo: pickText(merchant.storeLogo, merchant.logo),
|
||||
storeNotice: pickText(merchant.storeNotice, merchant.notice),
|
||||
storeStatus: (merchant.storeStatus ?? merchant.status ?? 'enabled') as RecommendMerchantInfo['storeStatus'],
|
||||
rankScore: toNumber(merchant.rankScore),
|
||||
goodsCount: toNumber(merchant.goodsCount),
|
||||
recentNewGoodsCount: toNumber(merchant.recentNewGoodsCount),
|
||||
orderCount: toNumber(merchant.orderCount),
|
||||
}
|
||||
}
|
||||
|
||||
const normalizeMerchantEntity = (
|
||||
merchant: RawMerchantEntityPayload | null | undefined
|
||||
): MerchantInfo | undefined => {
|
||||
if (!merchant) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return {
|
||||
...(merchant as MerchantInfo),
|
||||
merchantId: toMerchantId(merchant.merchantId ?? merchant.id),
|
||||
storeName: pickText(merchant.storeName, merchant.merchantName),
|
||||
storeLogo: pickText(merchant.storeLogo, merchant.logo),
|
||||
storeNotice: pickText(merchant.storeNotice, merchant.notice),
|
||||
storeStatus: (merchant.storeStatus ?? merchant.status ?? 'enabled') as MerchantInfo['storeStatus'],
|
||||
}
|
||||
}
|
||||
|
||||
const normalizeHomeMerchantGoodsBlock = (
|
||||
block: HomeMerchantGoodsBlock | undefined
|
||||
): HomeMerchantGoodsBlock | undefined => {
|
||||
if (!block) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const merchant = normalizeRecommendMerchant(block.merchant ?? block.store)
|
||||
if (!merchant) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return {
|
||||
...block,
|
||||
merchant,
|
||||
goods: block.goods.map(normalizeGoodsSummary),
|
||||
store: merchant,
|
||||
}
|
||||
}
|
||||
|
||||
export const normalizeAppGoodsPageResponse = (
|
||||
payload: AppGoodsPageResponse
|
||||
): AppGoodsPageResponse => ({
|
||||
...payload,
|
||||
list: payload.list.map(normalizeGoodsSummary),
|
||||
})
|
||||
|
||||
export const normalizeAppRecentNewGoodsResponse = (
|
||||
payload: AppRecentNewGoodsResponse
|
||||
): AppRecentNewGoodsResponse => ({
|
||||
...payload,
|
||||
total: payload.total ?? 0,
|
||||
list: (payload.list ?? []).map(normalizeRecentNewGoodsItem),
|
||||
})
|
||||
|
||||
export const normalizeAppCartListResponse = (
|
||||
payload: AppCartListResponse
|
||||
): AppCartListResponse => ({
|
||||
...payload,
|
||||
list: payload.list.map(normalizeCartItem),
|
||||
})
|
||||
|
||||
export const normalizeAppOrderPageResponse = (
|
||||
payload: AppOrderPageResponse
|
||||
): AppOrderPageResponse => ({
|
||||
...payload,
|
||||
list: payload.list.map(normalizeOrderSummary),
|
||||
})
|
||||
|
||||
export const normalizeAppOrderDetailResponse = (
|
||||
payload: AppOrderDetailResponse
|
||||
): AppOrderDetailResponse => ({
|
||||
...payload,
|
||||
data: normalizeOrderDetailInfo(payload.data),
|
||||
})
|
||||
|
||||
export const normalizeAppHomeResponse = (payload: AppHomeResponse): AppHomeResponse => {
|
||||
const recommendMerchants = (payload.recommendMerchants ?? payload.recommendStores ?? [])
|
||||
.map(normalizeRecommendMerchant)
|
||||
.filter(Boolean) as RecommendMerchantInfo[]
|
||||
const featuredMerchants = (payload.featuredMerchants ?? payload.featuredStores ?? [])
|
||||
.map(normalizeRecommendMerchant)
|
||||
.filter(Boolean) as RecommendMerchantInfo[]
|
||||
|
||||
return {
|
||||
...payload,
|
||||
recommendGoods: payload.recommendGoods.map(normalizeGoodsSummary),
|
||||
recommendMerchants,
|
||||
featuredMerchants,
|
||||
recommendStores: recommendMerchants,
|
||||
featuredStores: featuredMerchants,
|
||||
}
|
||||
}
|
||||
|
||||
export const normalizeAppHomeMerchantGoodsResponse = (
|
||||
payload: AppHomeMerchantGoodsResponse
|
||||
): AppHomeMerchantGoodsResponse => ({
|
||||
...payload,
|
||||
data:
|
||||
normalizeHomeMerchantGoodsBlock(payload.data) ??
|
||||
({
|
||||
merchant: {
|
||||
id: 0,
|
||||
merchantId: '0',
|
||||
storeName: '',
|
||||
storeLogo: '',
|
||||
storeNotice: '',
|
||||
storeStatus: 'disabled',
|
||||
mainCategoryName: '',
|
||||
recommendReason: '',
|
||||
rankScore: 0,
|
||||
goodsCount: 0,
|
||||
recentNewGoodsCount: 0,
|
||||
orderCount: 0,
|
||||
},
|
||||
store: {
|
||||
id: 0,
|
||||
merchantId: '0',
|
||||
storeName: '',
|
||||
storeLogo: '',
|
||||
storeNotice: '',
|
||||
storeStatus: 'disabled',
|
||||
mainCategoryName: '',
|
||||
recommendReason: '',
|
||||
rankScore: 0,
|
||||
goodsCount: 0,
|
||||
recentNewGoodsCount: 0,
|
||||
orderCount: 0,
|
||||
},
|
||||
goods: [],
|
||||
} satisfies HomeMerchantGoodsBlock),
|
||||
})
|
||||
|
||||
export const normalizeAppGoodsDetailResponse = (
|
||||
payload: AppGoodsDetailResponse
|
||||
): AppGoodsDetailResponse => {
|
||||
const merchant = normalizeMerchantEntity(payload.merchant ?? payload.store)
|
||||
|
||||
return {
|
||||
...payload,
|
||||
data: normalizeGoodsDetailInfo(payload.data),
|
||||
merchant: merchant ?? payload.store!,
|
||||
store: merchant ?? payload.store,
|
||||
}
|
||||
}
|
||||
|
||||
export const normalizeAppTradePreviewResponse = (
|
||||
payload: AppTradePreviewResponse
|
||||
): AppTradePreviewResponse => {
|
||||
const data = payload.data as TradePreviewInfo & {
|
||||
uid?: number
|
||||
memberId?: number
|
||||
merchantGroups?: TradePreviewInfo['merchantGroups']
|
||||
storeGroups?: TradePreviewInfo['merchantGroups']
|
||||
}
|
||||
const merchantGroups = data.merchantGroups ?? data.storeGroups ?? []
|
||||
|
||||
return {
|
||||
...payload,
|
||||
data: {
|
||||
...data,
|
||||
uid: data.uid ?? data.memberId ?? 0,
|
||||
memberId: data.memberId ?? data.uid,
|
||||
merchantGroups: merchantGroups.map(normalizeTradePreviewGroup),
|
||||
storeGroups: merchantGroups.map(normalizeTradePreviewGroup),
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user