Files
workspace/code/email/Email-Vue/src/hooks/useEmailListManager.ts
T
2025-06-10 21:27:20 +08:00

123 lines
3.3 KiB
TypeScript

import { ref, reactive } from "vue";
import type { EmailSummary } from "@/types/email";
import type { GetEmailSummaryPageParams } from "@/service/email";
import { getEmailSummaryPageApi } from "@/service/email";
const queryParams = reactive<GetEmailSummaryPageParams>({
folderId: "",
page: 1,
pageSize: 10
});
const loading = ref(false);
const emailList = ref<EmailSummary[]>([]);
const total = ref(0);
const prefetchCache = ref<{
page: number | null;
data: EmailSummary[];
used: boolean; // ✅ 用于标记是否已经部分使用
}>({
page: null,
data: [],
used: false
});
export function useEmailListManager() {
const fetchData = async () => {
if (!queryParams.folderId) return;
const { page, pageSize, folderId } = queryParams;
// ✅ 判断是否可以安全使用缓存
const canUseCache = prefetchCache.value.page === page && prefetchCache.value.data.length > 0 && !prefetchCache.value.used;
if (canUseCache) {
console.log(`Using cached data for page ${page}`);
emailList.value = [...prefetchCache.value.data];
} else {
loading.value = true;
try {
const res = await getEmailSummaryPageApi({ folderId, page, pageSize });
const pageData = res.data;
emailList.value = pageData.record;
total.value = pageData.total;
} finally {
loading.value = false;
}
}
// ✅ 预取下一页(如果有)
const maxPage = Math.ceil(total.value / pageSize);
const nextPage = page + 1;
if (nextPage <= maxPage) {
prefetchPageData(nextPage, folderId, pageSize);
} else {
clearPrefetch();
}
};
const prefetchPageData = async (page: number, folderId: string, pageSize: number) => {
try {
const res = await getEmailSummaryPageApi({ folderId, page, pageSize });
prefetchCache.value = {
page,
data: res.data.record,
used: false
};
} catch {
clearPrefetch();
}
};
const clearPrefetch = () => {
prefetchCache.value = {
page: null,
data: [],
used: false
};
};
const removeAndFill = async (idsToRemove: string[]) => {
idsToRemove.forEach((id) => {
const idx = emailList.value.findIndex((item) => item.id === id);
if (idx !== -1) {
emailList.value.splice(idx, 1);
total.value = Math.max(0, total.value - 1);
}
});
// ✅ 从预取数据补足当前页
while (emailList.value.length < queryParams.pageSize && prefetchCache.value.data.length > 0) {
emailList.value.push(prefetchCache.value.data.shift()!);
prefetchCache.value.used = true; // ✅ 标记:缓存被用过
}
// ✅ 如果仍不足,尝试翻页请求新数据
const maxPage = Math.ceil(total.value / queryParams.pageSize);
if (emailList.value.length < queryParams.pageSize && queryParams.page < maxPage) {
queryParams.page++;
await fetchData(); // 内部已判断是否重新请求
}
};
const resetData = () => {
queryParams.page = 1;
queryParams.pageSize = 10;
total.value = 0;
emailList.value = [];
clearPrefetch();
};
return {
queryParams,
emailList,
loading,
total,
fetchData,
removeAndFill,
resetData,
cacheEmailList: prefetchCache // 👈 新增这一行
};
}