diff --git a/admin/src/views/display/LadderSummary.vue b/admin/src/views/display/LadderSummary.vue index fa19e538..132d20c4 100644 --- a/admin/src/views/display/LadderSummary.vue +++ b/admin/src/views/display/LadderSummary.vue @@ -196,7 +196,7 @@
@@ -230,7 +230,6 @@ const loadingBoards = ref(false); const loadingMatches = ref(false); let timer = null; -let refreshTimer = null; let handleWindowClick = null; let boardsRaf = null; let matchesRaf = null; @@ -243,6 +242,15 @@ const matchesGroup1 = ref(null); const boardsScrollY = ref(0); const matchesScrollY = ref(0); +const REFRESH_COOLDOWN_MS = 3000; +let lastRefreshAt = 0; + +const onScrollEndRefresh = () => { + if (Date.now() - lastRefreshAt < REFRESH_COOLDOWN_MS) return; + lastRefreshAt = Date.now(); + refreshAll(); +}; + const updateTime = () => { currentTime.value = dayjs().format("YYYY-MM-DD HH:mm:ss"); }; @@ -373,6 +381,7 @@ const startBoardsScroll = () => { boardsScrollY.value -= 0.35; if (Math.abs(boardsScrollY.value) >= h) { boardsScrollY.value = 0; + onScrollEndRefresh(); } boardsRaf = requestAnimationFrame(tick); }; @@ -406,6 +415,7 @@ const startMatchesScroll = () => { matchesScrollY.value -= 0.4; if (Math.abs(matchesScrollY.value) >= h) { matchesScrollY.value = 0; + onScrollEndRefresh(); } matchesRaf = requestAnimationFrame(tick); }; @@ -430,7 +440,6 @@ onMounted(async () => { await refreshAll(); timer = setInterval(updateTime, 1000); - refreshTimer = setInterval(refreshAll, 30 * 1000); handleWindowClick = () => { showStoreMenu.value = false; @@ -445,7 +454,6 @@ onMounted(async () => { onUnmounted(() => { if (timer) clearInterval(timer); - if (refreshTimer) clearInterval(refreshTimer); stopAutoScroll(); if (handleWindowClick) window.removeEventListener("click", handleWindowClick); }); diff --git a/admin/src/views/display/LadderSummaryOrange.vue b/admin/src/views/display/LadderSummaryOrange.vue index 349f44a1..720068d6 100644 --- a/admin/src/views/display/LadderSummaryOrange.vue +++ b/admin/src/views/display/LadderSummaryOrange.vue @@ -196,7 +196,7 @@ @@ -230,7 +230,6 @@ const loadingBoards = ref(false); const loadingMatches = ref(false); let timer = null; -let refreshTimer = null; let handleWindowClick = null; let boardsRaf = null; let matchesRaf = null; @@ -243,6 +242,15 @@ const matchesGroup1 = ref(null); const boardsScrollY = ref(0); const matchesScrollY = ref(0); +const REFRESH_COOLDOWN_MS = 3000; +let lastRefreshAt = 0; + +const onScrollEndRefresh = () => { + if (Date.now() - lastRefreshAt < REFRESH_COOLDOWN_MS) return; + lastRefreshAt = Date.now(); + refreshAll(); +}; + const updateTime = () => { currentTime.value = dayjs().format("YYYY-MM-DD HH:mm:ss"); }; @@ -373,6 +381,7 @@ const startBoardsScroll = () => { boardsScrollY.value -= 0.35; if (Math.abs(boardsScrollY.value) >= h) { boardsScrollY.value = 0; + onScrollEndRefresh(); } boardsRaf = requestAnimationFrame(tick); }; @@ -406,6 +415,7 @@ const startMatchesScroll = () => { matchesScrollY.value -= 0.4; if (Math.abs(matchesScrollY.value) >= h) { matchesScrollY.value = 0; + onScrollEndRefresh(); } matchesRaf = requestAnimationFrame(tick); }; @@ -430,7 +440,6 @@ onMounted(async () => { await refreshAll(); timer = setInterval(updateTime, 1000); - refreshTimer = setInterval(refreshAll, 30 * 1000); handleWindowClick = () => { showStoreMenu.value = false; @@ -445,7 +454,6 @@ onMounted(async () => { onUnmounted(() => { if (timer) clearInterval(timer); - if (refreshTimer) clearInterval(refreshTimer); stopAutoScroll(); if (handleWindowClick) window.removeEventListener("click", handleWindowClick); }); diff --git a/admin/src/views/display/RankingBoard.vue b/admin/src/views/display/RankingBoard.vue index 948af438..131c9da8 100644 --- a/admin/src/views/display/RankingBoard.vue +++ b/admin/src/views/display/RankingBoard.vue @@ -465,7 +465,7 @@ @@ -492,7 +492,6 @@ const scrollContainer = ref(null); const isRefreshing = ref(false); let timer = null; - let refreshTimer = null; let handleWindowClick = null; const scrollReqIdAll = ref(null); const scrollReqIdMale = ref(null); @@ -500,12 +499,21 @@ const scrollYAll = ref(0); const scrollYMale = ref(0); const scrollYFemale = ref(0); + const REFRESH_COOLDOWN_MS = 3000; + let lastRefreshAt = 0; // 更新时间 const updateTime = () => { currentTime.value = dayjs().format("YYYY-MM-DD HH:mm:ss"); }; + // 滚动到底部时刷新一次(带冷却,避免短列表时刷新过频) + const onScrollEndRefresh = () => { + if (Date.now() - lastRefreshAt < REFRESH_COOLDOWN_MS) return; + lastRefreshAt = Date.now(); + fetchRanking(); + }; + // 连续无缝滚动逻辑 (使用 Transform 性能更好) const startContinuousScroll = (listRef, scrollYRef, reqIdRef) => { if (reqIdRef.value) cancelAnimationFrame(reqIdRef.value); @@ -522,9 +530,10 @@ // 计算单份数据的高度:100条 * (90px行高 + 12px间距) const singleSetHeight = listRef.value.length * 102; - // 如果滚完了一整套数据,瞬间重置回 0 + // 如果滚完了一整套数据,瞬间重置回 0,并触发一次刷新 if (Math.abs(scrollYRef.value) >= singleSetHeight) { scrollYRef.value = 0; + onScrollEndRefresh(); } reqIdRef.value = requestAnimationFrame(scroll); @@ -663,7 +672,6 @@ onMounted(() => { fetchStores(); timer = setInterval(updateTime, 1000); - refreshTimer = setInterval(fetchRanking, 30 * 1000); // 30秒刷新一次,避免过于频繁影响滚动感 // 点击外部关闭菜单 handleWindowClick = () => { @@ -674,7 +682,6 @@ onUnmounted(() => { if (timer) clearInterval(timer); - if (refreshTimer) clearInterval(refreshTimer); if (scrollReqIdAll.value) cancelAnimationFrame(scrollReqIdAll.value); if (scrollReqIdMale.value) cancelAnimationFrame(scrollReqIdMale.value); if (scrollReqIdFemale.value) cancelAnimationFrame(scrollReqIdFemale.value); diff --git a/admin/src/views/display/RankingBoardOrange.vue b/admin/src/views/display/RankingBoardOrange.vue index db567c41..b989c2c3 100644 --- a/admin/src/views/display/RankingBoardOrange.vue +++ b/admin/src/views/display/RankingBoardOrange.vue @@ -511,7 +511,7 @@ @@ -538,7 +538,6 @@ const scrollContainer = ref(null); const isRefreshing = ref(false); let timer = null; - let refreshTimer = null; let handleWindowClick = null; const group1 = ref(null); const scrollReqId = ref(null); @@ -549,11 +548,19 @@ const scrollReqIdFemale = ref(null); const scrollYMale = ref(0); const scrollYFemale = ref(0); + const REFRESH_COOLDOWN_MS = 3000; + let lastRefreshAt = 0; const updateTime = () => { currentTime.value = dayjs().format("HH:mm:ss"); }; + const onScrollEndRefresh = () => { + if (Date.now() - lastRefreshAt < REFRESH_COOLDOWN_MS) return; + lastRefreshAt = Date.now(); + fetchRanking(); + }; + const startContinuousScroll = (listRef, scrollYRef, reqIdRef, groupRef) => { if (reqIdRef.value) cancelAnimationFrame(reqIdRef.value); @@ -569,6 +576,7 @@ if (Math.abs(scrollYRef.value) >= singleSetHeight) { scrollYRef.value = 0; + onScrollEndRefresh(); } reqIdRef.value = requestAnimationFrame(scroll); @@ -693,7 +701,6 @@ onMounted(() => { fetchStores(); timer = setInterval(updateTime, 1000); - refreshTimer = setInterval(fetchRanking, 30 * 1000); handleWindowClick = () => { showStoreMenu.value = false; }; @@ -702,7 +709,6 @@ onUnmounted(() => { if (timer) clearInterval(timer); - if (refreshTimer) clearInterval(refreshTimer); if (scrollReqId.value) cancelAnimationFrame(scrollReqId.value); if (scrollReqIdMale.value) cancelAnimationFrame(scrollReqIdMale.value); if (scrollReqIdFemale.value) cancelAnimationFrame(scrollReqIdFemale.value);