import { getAdvertList } from '@/common/server/interface/advert' import { noticeInfo as getNoticeInfo } from '@/common/server/interface/notice'; import { getAllCategories } from '@/common/server/interface/good'; import { ref } from 'vue'; // 响应式数据定义 // 首页核心数据(banner + 通知) export const homeData = ref(null); // 全局加载状态 export const isLoading = ref(false); // 错误信息 export const error = ref(null); // 分页列表数据 export const listData = ref([]); //分页信息 export const pagination = ref({ page: 1, pageSize: 10, hasMore: true, }); // 缓存控制(防重复请求) const CACHE_TIMEOUT = 5 * 60 * 1000; // 5分钟缓存 let lastLoadTime = 0; /** * 预加载首页核心数据(banner + 通知+分类) */ export const preloadHomeData = async () => { if (shouldUseCache()) return; isLoading.value = true; error.value = null; try { const res = await Promise.all([ getAdvertList("TplIndexBanner1").catch(() => null), getNoticeInfo(9).catch(() => null), getAllCategories().catch(() => null), getAdvertList("TplIndexBanner2").catch(() => null), ]); let [advertList, noticeInfoData, categories, recAdvertList] = res; // 获取滚动字幕文字 let noticeInfo = ""; if (noticeInfoData && noticeInfoData.contentBody) { noticeInfo = extractTextFromHTML(noticeInfoData.contentBody); } // 删除 banner 数据源 createTime和updateTime if (advertList) { advertList = advertList.map(it => { let _it = { ...it }; delete _it.createTime; delete _it.updateTime; return _it; }); } //删除 推荐位数据源 if (recAdvertList) { recAdvertList = recAdvertList.map(it => { let _it = { ...it }; delete _it.createTime; delete _it.updateTime; return _it; }); } if (!categories) { categories = []; } categories.unshift({ name: "全部", id: 0 }) homeData.value = { advertList, noticeInfo: noticeInfo, categories, recList: recAdvertList }; console.log("首页数据源", homeData.value); lastLoadTime = Date.now(); } catch (err) { error.value = err; console.error('首页数据预加载失败:', err); } finally { isLoading.value = false; } }; /** * 强制刷新首页核心数据 */ export const refreshHomeData = async () => { lastLoadTime = 0; // 清除缓存 await preloadHomeData(); }; /** * 加载分页列表数据 */ export const loadListData = async (isRefresh = false) => { if (isLoading.value || (!isRefresh && !pagination.value.hasMore)) return; isLoading.value = true; try { const { page, pageSize } = pagination.value; const newData = await fetchListData(page, pageSize); // 替换为实际API if (isRefresh) { listData.value = newData; // 刷新时替换全部数据 pagination.value.page = 2; // 重置页码 } else { listData.value.push(...newData); // 加载更多时追加数据 pagination.value.page++; } pagination.value.hasMore = newData.length >= pageSize; } catch (err) { error.value = err; console.error('列表加载失败:', err); } finally { isLoading.value = false; } }; /** * 刷新列表数据(重置页码) */ export const refreshListData = async () => { pagination.value.page = 1; await loadListData(true); }; // 私有工具函数 const shouldUseCache = () => { return homeData.value && Date.now() - lastLoadTime < CACHE_TIMEOUT; }; const extractTextFromHTML = (htmlString) => { return htmlString.replace(/<[^>]*>/g, ''); } const fetchListData = async (page, pageSize) => { // 替换为实际的分页API调用,例如: // return await getArticleList({ page, pageSize }); return mockFetchList(page, pageSize); }; // 模拟分页API const mockFetchList = (page, pageSize) => { return new Promise(resolve => { setTimeout(() => { const mockData = Array.from({ length: pageSize }, (_, i) => ({ id: (page - 1) * pageSize + i, title: `Item ${(page - 1) * pageSize + i + 1}`, })); resolve(page >= 3 ? [] : mockData); // 模拟第3页无数据 }, 500); }); };