From 4a7aeeed8cafe4f2853a1893271fd06f9c291a53 Mon Sep 17 00:00:00 2001 From: jianzhichu Date: Sat, 28 Mar 2026 13:55:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=BD=E5=B1=89=E6=BB=9A=E5=8A=A8=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E4=B8=8D=E8=A7=A6=E5=8F=91=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/pages/cok/CookieTable.vue | 133 +++++++++++++++++++++--------- 1 file changed, 95 insertions(+), 38 deletions(-) diff --git a/app/src/pages/cok/CookieTable.vue b/app/src/pages/cok/CookieTable.vue index eafd326..171ee83 100644 --- a/app/src/pages/cok/CookieTable.vue +++ b/app/src/pages/cok/CookieTable.vue @@ -378,53 +378,101 @@ const openSeriesDownSetModal = () => { openCommonDrawer(); }; -// ========== 公用抽屉打开逻辑 ========== +// ========== 公用抽屉打开逻辑(替换原来的) ========== const openCommonDrawer = () => { // 重置抽屉状态 drawerDataList.value = []; drawerPagination.current = 1; drawerPagination.total = 0; drawerPagination.hasMore = true; - // 显示抽屉 showDrawer.value = true; - // 加载第一页数据 - loadDrawerData(); - // 监听滚动触底(延迟绑定,确保DOM已渲染) - nextTick(() => { - bindDrawerScrollEvent(); - }); -}; + // 确保DOM渲染后再加载 + 绑定事件 + nextTick() + .then(() => { + loadDrawerData(); + bindDrawerScrollEvent(); + }) + .catch(() => {}); +}; // ========== 绑定抽屉滚动触底事件 ========== +// const bindDrawerScrollEvent = () => { +// const scrollContainer = drawerScrollRef.value; +// if (!scrollContainer) return; + +// // 先移除原有事件,避免重复绑定 +// scrollContainer.removeEventListener('scroll', handleDrawerScroll); +// // 添加滚动事件 +// scrollContainer.addEventListener('scroll', handleDrawerScroll); +// }; +// ========== 绑定抽屉滚动触底事件(替换原来的) ========== const bindDrawerScrollEvent = () => { const scrollContainer = drawerScrollRef.value; - if (!scrollContainer) return; + if (!scrollContainer) { + // 延迟重试绑定,确保DOM渲染完成 + setTimeout(() => { + bindDrawerScrollEvent(); + }, 100); + return; + } - // 先移除原有事件,避免重复绑定 + // 先清除所有旧事件 scrollContainer.removeEventListener('scroll', handleDrawerScroll); - // 添加滚动事件 + // 重新绑定 scrollContainer.addEventListener('scroll', handleDrawerScroll); + + // 额外:首次加载如果内容不足一屏,自动加载下一页 + setTimeout(() => { + handleDrawerScroll(); + }, 200); }; - // ========== 滚动触底处理逻辑 ========== -const handleDrawerScroll = () => { - const scrollContainer = drawerScrollRef.value; - if (!scrollContainer || drawerPagination.loading || !drawerPagination.hasMore) return; +// const handleDrawerScroll = () => { +// const scrollContainer = drawerScrollRef.value; +// if (!scrollContainer || drawerPagination.loading || !drawerPagination.hasMore) return; - // 计算滚动位置(触底阈值20px,避免精准触底才触发) - const { scrollTop, clientHeight, scrollHeight } = scrollContainer; - const isBottom = scrollTop + clientHeight >= scrollHeight - 20; +// // 计算滚动位置(触底阈值20px,避免精准触底才触发) +// const { scrollTop, clientHeight, scrollHeight } = scrollContainer; +// const isBottom = scrollTop + clientHeight >= scrollHeight - 20; + +// if (isBottom) { +// // 加载下一页 +// drawerPagination.current += 1; +// loadDrawerData(); +// } +// }; + +// 防抖函数(防止滚动触发太频繁) +const debounce = (func: Function, delay = 100) => { + let timeoutId: any; + return (...args: any[]) => { + clearTimeout(timeoutId); + timeoutId = setTimeout(() => func.apply(this, args), delay); + }; +}; +// ========== 滚动触底处理逻辑(替换原来的) ========== +const handleDrawerScroll = debounce(() => { + const scrollContainer = drawerScrollRef.value; + if (!scrollContainer) return; + if (drawerPagination.loading || !drawerPagination.hasMore) return; + + const { scrollTop, scrollHeight, clientHeight } = scrollContainer; + // 兼容所有设备的触底判断(距离底部 50px 就触发) + const isBottom = scrollTop + clientHeight + 50 >= scrollHeight; if (isBottom) { - // 加载下一页 + console.log('✅ 触底加载触发'); drawerPagination.current += 1; loadDrawerData(); } -}; +}, 100); // 100ms 防抖 -// ========== 加载抽屉数据( +// ========== 加载抽屉数据(替换原来的) ========== const loadDrawerData = () => { - if (drawerPagination.loading || !drawerPagination.hasMore) return; + if (drawerPagination.loading || !drawerPagination.hasMore) { + console.log('🚫 阻止重复加载'); + return; + } drawerPagination.loading = true; useApiStore() @@ -436,17 +484,24 @@ const loadDrawerData = () => { }) .then((res) => { if (res.code === 0) { - drawerDataList.value = [...drawerDataList.value, ...res.data.data]; - drawerPagination.loading = false; - // 更新分页状态 - drawerPagination.total = res.data.total; - drawerPagination.loading = false; - // 判断是否还有更多数据 + const newData = res.data.data || []; + drawerDataList.value = [...drawerDataList.value, ...newData]; + + drawerPagination.total = res.data.total || 0; + // 判断是否还有更多 drawerPagination.hasMore = drawerDataList.value.length < drawerPagination.total; + + // 加载完成后立刻检查是否需要继续加载(适配大屏) + setTimeout(() => { + handleDrawerScroll(); + }, 100); } else { - message.error(res.message); + message.error(res.message || '加载失败'); } }) + .catch(() => { + message.error('网络异常,加载失败'); + }) .finally(() => { drawerPagination.loading = false; }); @@ -1117,13 +1172,17 @@ html.dark-mode .drawer-card-container.grid-container .drawer-card-grid .ant-inpu // 抽屉滚动容器样式(核心修复) .drawer-scroll-container { width: 100%; - height: calc(100vh - 120px); // 关键:固定高度,确保能滚动 - overflow-y: auto; // 开启垂直滚动 - overflow-x: hidden; // 隐藏水平滚动 + /* 固定抽屉内部高度,强制出现滚动区域 */ + height: calc(100vh - 130px) !important; + min-height: 300px !important; + overflow-y: auto !important; + overflow-x: hidden !important; padding: 0 8px; box-sizing: border-box; + position: relative; + z-index: 1; - // 滚动条样式优化(可选) + /* 优化滚动条 */ &::-webkit-scrollbar { width: 6px; } @@ -1131,13 +1190,11 @@ html.dark-mode .drawer-card-container.grid-container .drawer-card-grid .ant-inpu background: transparent; } &::-webkit-scrollbar-thumb { - background: rgba(0, 0, 0, 0.1); + background: rgba(0, 0, 0, 0.15); border-radius: 3px; } - - // 黑暗模式滚动条 html.dark-mode &::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.1); + background: rgba(255, 255, 255, 0.2); } }