优化首页公告与轮播图
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import { apiClient } from './client'
|
||||
import {
|
||||
defaultListingPublishOptions,
|
||||
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
|
||||
}
|
||||
|
||||
interface ApiResponse<T> {
|
||||
code: string
|
||||
message: string
|
||||
data: T
|
||||
}
|
||||
|
||||
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 || defaultListingPublishOptions),
|
||||
}
|
||||
}
|
||||
|
||||
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'
|
||||
}
|
||||
Reference in New Issue
Block a user