149 lines
4.5 KiB
JavaScript
149 lines
4.5 KiB
JavaScript
|
||
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);
|
||
});
|
||
}; |