83 lines
2.6 KiB
JavaScript
83 lines
2.6 KiB
JavaScript
import { ref } from 'vue'
|
||
import { getActivityListApi, getMintingActivitiesApi } from '@/utils/api.js'
|
||
|
||
// 默认 banner(接口失败/无数据时兜底)
|
||
const FALLBACK_BANNER = [
|
||
{
|
||
image_url: '/static/sucai/image-05.png',
|
||
title: '这河非遇美学宇宙联名',
|
||
link_type: 'activity',
|
||
link_value: '1'
|
||
}
|
||
]
|
||
|
||
/**
|
||
* 模块级共享状态(单例)
|
||
*
|
||
* 背景:square.vue 和 pages/components/Header.vue 都会调 useBanner(),
|
||
* 旧实现每次调用都 new ref,导致两个组件各持一份独立的 bannerActivities,
|
||
* 状态可能不一致。
|
||
*
|
||
* 改单例后:所有调用 useBanner() 的地方拿到的是同一对 ref,
|
||
* 任一处调 loadBannerActivities() / loadBanners() 都会同步刷新所有订阅者。
|
||
*
|
||
* 不会把数据搬到 Vuex,原因是 banner 数据目前只有这两个使用方,没必要全局 store 化。
|
||
*/
|
||
const bannerActivities = ref([])
|
||
const banners = ref([])
|
||
|
||
const loadBannerActivities = async () => {
|
||
try {
|
||
const starId = uni.getStorageSync('star_id') || null
|
||
const res = await getActivityListApi(starId, 1, 10)
|
||
|
||
if (res.code === 0 && res.data?.activities) {
|
||
const activities = res.data.activities
|
||
// 过滤掉已过期的活动
|
||
bannerActivities.value = activities.filter(item => item.status !== 'expired')
|
||
}
|
||
} catch (e) {
|
||
console.error('[useBanner] 加载 banner 活动失败', e?.message ?? e)
|
||
}
|
||
}
|
||
|
||
// 加载运营 banner(铸造活动)
|
||
const loadBanners = async () => {
|
||
try {
|
||
const res = await getMintingActivitiesApi(null, 1, 10)
|
||
|
||
if (res.code === 0 && res.data?.activities) {
|
||
// 将后端数据映射为 BannerCarousel 约定的字段
|
||
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,
|
||
// 后端路由参数 JSON 字符串,前端在 handleBannerClick 中拼到 url 上
|
||
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() {
|
||
// 返回模块级单例的引用(API 不变,调用方零改动)
|
||
return {
|
||
bannerActivities,
|
||
banners,
|
||
loadBannerActivities,
|
||
loadBanners
|
||
}
|
||
}
|