guyu/common/server/home.js
2025-07-23 20:52:57 +08:00

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