From 36d9ce5a4ce908e1bada16c55ae1bbb5a563aaad Mon Sep 17 00:00:00 2001 From: hzj <1304805162@qq.com> Date: Mon, 19 Jan 2026 22:44:42 +0800 Subject: [PATCH] =?UTF-8?q?feat(cp=E6=8E=92=E8=A1=8C=E6=A6=9C):=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=9C=88=E5=BA=A6=E5=80=92=E8=AE=A1=E6=97=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/Ranking/Couple/Ranking.vue | 223 ++++++++++++++++++++++++++- 1 file changed, 222 insertions(+), 1 deletion(-) diff --git a/src/views/Ranking/Couple/Ranking.vue b/src/views/Ranking/Couple/Ranking.vue index a315173..433f9e8 100644 --- a/src/views/Ranking/Couple/Ranking.vue +++ b/src/views/Ranking/Couple/Ranking.vue @@ -49,6 +49,31 @@ + +
+
+
{{ WDays }}D
+
+
{{ WHours }}
+
:
+
{{ WMinutes }}
+
:
+
{{ WSeconds }}
+
+
+
+
+
{{ MDays }}D
+
+
{{ MHours }}
+
:
+
{{ MMinutes }}
+
:
+
{{ MSeconds }}
+
+
+
+
@@ -226,6 +251,151 @@ const { myRanking, // 我的排名 } = storeToRefs(coupleStore) +// 倒计时相关数据 +const WDays = ref(0) +const WHours = ref(0) +const WMinutes = ref(0) +const WSeconds = ref(0) +let countdownTimer = null + +const MDays = ref(0) +const MHours = ref(0) +const MMinutes = ref(0) +const MSeconds = ref(0) +let monthlyCountdownTimer = null // 月度倒计时定时器 + +// 获取对应的时间戳 +const getNextMondayInBeijing = () => { + const now = new Date() + const targetDate = new Date(now.getTime()) // 创建一个基于当前时间的新日期对象 + + // 转换为北京时间来判断星期几 + const utcTime = now.getTime() + now.getTimezoneOffset() * 60000 + const beijingTime = new Date(utcTime + 8 * 3600000) // UTC+8 + + const beijingDay = beijingTime.getDay() // 0=周日, 1=周一, ..., 6=周六 + const beijingHour = beijingTime.getHours() + + // 转换为 0=周一, 1=周二, ..., 6=周日 + const normalizedDay = beijingDay === 0 ? 6 : beijingDay - 1 + + let daysToAdd + if (normalizedDay === 0) { + // 今天是周一 + if (beijingHour >= 5) { + daysToAdd = 7 // 超过5点,计算到下周一的所需时间 + } else { + daysToAdd = 0 // 今天 + } + } else { + daysToAdd = 7 - normalizedDay // 到下周一的天数 + } + + // 正确地添加天数 + targetDate.setDate(targetDate.getDate() + daysToAdd) // 添加天数到下周一的当前时间 + targetDate.setHours(5, 0, 0, 0) // 将时间重新设置为早上5点,作为目标时间戳 + + return targetDate.getTime() +} + +const targetTime = ref(getNextMondayInBeijing()) // 闭包保存目标时间 (核心修正) + +// 格式化时间 +const formatTime = (value) => { + return value < 10 ? `0${value}` : value +} + +// 倒计时 +const getCountdown = () => { + const now = Date.now() + let diff = targetTime.value - now + + if (diff <= 0) { + // 初始化数据 + initData() + + targetTime.value += 7 * 86400000 // +7天 (更新闭包变量) + diff = targetTime.value - now + } + + const totalSeconds = Math.floor(diff / 1000) + WDays.value = Math.floor(totalSeconds / (24 * 3600)) + WHours.value = formatTime(Math.floor((totalSeconds % (24 * 3600)) / 3600)) + WMinutes.value = formatTime(Math.floor((totalSeconds % 3600) / 60)) + WSeconds.value = formatTime(Math.floor(totalSeconds % 60)) +} + +// 启动倒计时 +const startCountdown = () => { + getCountdown() // 立即执行一次周倒计时 + getMonthlyCountdown() // 立即执行一次月倒计时 + countdownTimer = setInterval(getCountdown, 1000) + monthlyCountdownTimer = setInterval(getMonthlyCountdown, 1000) +} + +// 获取下个月1号早上5点的北京时间 +const getNextMonthFirstInBeijing = () => { + const now = new Date() + + // 获取当前的北京时间 + const beijingTime = new Date(now.getTime() + 8 * 60 * 60 * 1000) + const year = beijingTime.getUTCFullYear() + const month = beijingTime.getUTCMonth() + const date = beijingTime.getUTCDate() + const hour = beijingTime.getUTCHours() + + // 确定目标月份 + let targetYear = year + let targetMonth = month + + if (date === 1 && hour < 5) { + // 如果今天是1号且还没过5点,目标就是本月1号5点 + } else { + // 否则目标是下个月1号 + targetMonth = month + 1 + if (targetMonth > 11) { + targetMonth = 0 + targetYear++ + } + } + + // 创建代表北京时间的UTC时间戳 + // 使用Date.UTC创建代表"北京时间"的时间戳 + const targetDateAsBeijing = Date.UTC(targetYear, targetMonth, 1, 5, 0, 0) - 8 * 60 * 60 * 1000 + + return targetDateAsBeijing +} + +// 月度倒计时 +const getMonthlyCountdown = () => { + const now = Date.now() + let diff = targetMonthTime.value - now + + if (diff <= 0) { + // 如果时间已过,重新计算下一个月 + targetMonthTime.value = getNextMonthFirstInBeijing() + diff = targetMonthTime.value - now + } + + const totalSeconds = Math.floor(diff / 1000) + + // 计算天数(这里需要考虑月份跨越的情况,使用总天数) + const totalDays = Math.floor(totalSeconds / (24 * 3600)) + MDays.value = totalDays + + const remainingHours = Math.floor((totalSeconds % (24 * 3600)) / 3600) + MHours.value = formatTime(remainingHours) + + const remainingMinutes = Math.floor((totalSeconds % 3600) / 60) + MMinutes.value = formatTime(remainingMinutes) + + const remainingSeconds = totalSeconds % 60 + MSeconds.value = formatTime(remainingSeconds) +} + +// 添加月度倒计时的目标时间 +const targetMonthTime = ref(getNextMonthFirstInBeijing()) + const weeklyShow = ref(true) //本周数据 const seasonShow = ref(false) //季度数据 @@ -415,6 +585,7 @@ const connectToAppHandler = async () => { // 组件挂载时检测环境 onMounted(() => { + startCountdown() //开启倒计时 connectToAppHandler() // 监听加载模块 if (RankingLoadmore.value) { @@ -422,6 +593,56 @@ onMounted(() => { observer.observe(RankingLoadmore.value) } }) + +onUnmounted(() => { + // 销毁计时器 + if (countdownTimer) { + clearInterval(countdownTimer) + countdownTimer = null + } + if (monthlyCountdownTimer) { + clearInterval(monthlyCountdownTimer) + monthlyCountdownTimer = null + } +}) - +