topfans/frontend/pages/square/composables/useBanner.js
2026-06-16 15:19:53 +08:00

83 lines
2.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}