96 lines
2.8 KiB
TypeScript
96 lines
2.8 KiB
TypeScript
import { apiClient } from './client'
|
|
import type { ApiResponse } from './types'
|
|
import {
|
|
mergeListingPublishOptions,
|
|
type ListingPublishOptions,
|
|
} from './listingOptions'
|
|
|
|
export interface HomeBannerSlide {
|
|
eyebrow: string
|
|
title: string
|
|
badge: string
|
|
pill: string
|
|
tone: string
|
|
image_url?: string
|
|
}
|
|
|
|
export interface MobileHomeConfig {
|
|
announcements: string[]
|
|
banners: HomeBannerSlide[]
|
|
publish_options: ListingPublishOptions
|
|
}
|
|
|
|
export const defaultHomeAnnouncements = [
|
|
'平台担保交易,拒绝私下转账/共享验证码,交接全程留痕。',
|
|
'优先推荐同地区账号,减少异地登录保护触发。',
|
|
'下单前请核对哈夫币、保险、体力负重和截图信息。',
|
|
]
|
|
|
|
export const defaultHomeBanners: HomeBannerSlide[] = [
|
|
{
|
|
eyebrow: '三角洲行动账号专区',
|
|
title: '高哈夫币 · 安全交接 · 随租随玩',
|
|
badge: 'HOT',
|
|
pill: '新人领券最高减 20 元',
|
|
tone: 'blue',
|
|
image_url: '',
|
|
},
|
|
{
|
|
eyebrow: '平台担保交易',
|
|
title: '交接全程留痕,拒绝私下转账',
|
|
badge: 'SAFE',
|
|
pill: '租号前先验实名与资料',
|
|
tone: 'green',
|
|
image_url: '',
|
|
},
|
|
{
|
|
eyebrow: '高效筛选',
|
|
title: '按区服、段位、哈夫币快速找号',
|
|
badge: 'FAST',
|
|
pill: '支持扫码号与账密号',
|
|
tone: 'orange',
|
|
image_url: '',
|
|
},
|
|
]
|
|
|
|
export async function fetchMobileHomeConfig() {
|
|
const { data } = await apiClient.get<ApiResponse<MobileHomeConfig>>('/mobile-home-config')
|
|
return mergeHomeConfig(data.data)
|
|
}
|
|
|
|
export function mergeHomeConfig(config?: Partial<MobileHomeConfig>): MobileHomeConfig {
|
|
const announcements =
|
|
config?.announcements
|
|
?.map((item) => (typeof item === 'string' ? item.trim() : ''))
|
|
.filter(Boolean) || []
|
|
const banners =
|
|
config?.banners
|
|
?.map((item) => {
|
|
const banner = isBannerLike(item) ? item : ({} as Partial<HomeBannerSlide>)
|
|
return {
|
|
eyebrow: banner.eyebrow?.trim() || '',
|
|
title: banner.title?.trim() || '',
|
|
badge: banner.badge?.trim() || '',
|
|
pill: banner.pill?.trim() || '',
|
|
tone: normalizeBannerTone(banner.tone),
|
|
image_url: banner.image_url?.trim() || '',
|
|
}
|
|
})
|
|
.filter((item) => item.title || item.image_url) || []
|
|
|
|
return {
|
|
announcements: announcements.length ? announcements : defaultHomeAnnouncements,
|
|
banners: banners.length ? banners : defaultHomeBanners,
|
|
publish_options: mergeListingPublishOptions(config?.publish_options),
|
|
}
|
|
}
|
|
|
|
function isBannerLike(value: unknown): value is Partial<HomeBannerSlide> {
|
|
return typeof value === 'object' && value !== null
|
|
}
|
|
|
|
function normalizeBannerTone(tone?: string) {
|
|
if (tone === 'green' || tone === 'orange') return tone
|
|
return 'blue'
|
|
}
|