topfans/frontend/pages/square/composables/useBanner.js

86 lines
2.3 KiB
JavaScript

import { ref } from 'vue'
import { getActivityListApi, getMintingActivitiesApi } from '@/utils/api.js'
import { getPreloadApi } from '@/utils/preloadApi/index'
// 默认 banner(接口失败/无数据时兜底)
const FALLBACK_BANNER = [
{
image_url: '/static/sucai/image-05.png',
title: '这河非遇美学宇宙联名',
link_type: 'activity',
link_value: '1'
}
]
/**
* 模块级共享状态(单例)
*/
const bannerActivities = ref([])
const banners = ref([])
// 内部:优先走预拉缓存,未命中/过期则手动 fetch
async function _tryPreloadThenFetch(key, fallbackFetch, processFn) {
const api = getPreloadApi()
if (api) {
try {
const cached = await api.get(key)
if (cached && cached.code === 0) {
processFn(cached)
return
}
} catch (e) { /* 未命中/过期,走手动 fetch */ }
}
const res = await fallbackFetch()
if (res && res.code === 0) processFn(res)
}
const loadBannerActivities = async () => {
try {
await _tryPreloadThenFetch('banner.activities',
() => getActivityListApi(uni.getStorageSync('star_id') || null, 1, 10),
(res) => {
if (res.data?.activities) {
bannerActivities.value = res.data.activities.filter(item => item.status !== 'expired')
}
}
)
} catch (e) {
console.error('[useBanner] 加载 banner 活动失败', e?.message ?? e)
}
}
const loadBanners = async () => {
try {
await _tryPreloadThenFetch('banner.minting',
() => getMintingActivitiesApi(null, 1, 10),
(res) => {
if (res.data?.activities) {
banners.value = res.data.activities.map(activity => ({
id: activity.id,
image_url: activity.cover_image,
title: activity.title,
link_type: 'activity',
link_value: String(activity.id),
description: activity.description,
route: activity.route,
params: activity.params
}))
}
if (banners.value.length === 0) banners.value = [...FALLBACK_BANNER]
}
)
} catch (e) {
console.error('[useBanner] 加载运营 banner 失败', e?.message ?? e)
banners.value = [...FALLBACK_BANNER]
}
}
export function useBanner() {
return {
bannerActivities,
banners,
loadBannerActivities,
loadBanners
}
}