feat(cp排行榜): 新增月度倒计时

This commit is contained in:
hzj 2026-01-19 22:44:42 +08:00
parent 3951680afc
commit 36d9ce5a4c

View File

@ -49,6 +49,31 @@
</div>
</div>
<itemCenter :imgUrl="imageUrl(`timeBg`)" :contentStyle="`inset:0 0 4vw;`">
<div v-show="weeklyShow" style="display: flex; justify-content: center; align-items: center">
<div class="timeBox">
<div class="timeText" style="">{{ WDays }}D</div>
<div class="timeText timeGap"></div>
<div class="timeText" style="">{{ WHours }}</div>
<div class="timeText timeGap">:</div>
<div class="timeText" style="">{{ WMinutes }}</div>
<div class="timeText timeGap">:</div>
<div class="timeText" style="">{{ WSeconds }}</div>
</div>
</div>
<div v-show="seasonShow" style="display: flex; justify-content: center; align-items: center">
<div class="timeBox">
<div class="timeText" style="">{{ MDays }}D</div>
<div class="timeText timeGap"></div>
<div class="timeText" style="">{{ MHours }}</div>
<div class="timeText timeGap">:</div>
<div class="timeText" style="">{{ MMinutes }}</div>
<div class="timeText timeGap">:</div>
<div class="timeText" style="">{{ MSeconds }}</div>
</div>
</div>
</itemCenter>
<!-- 排行榜 -->
<div style="position: relative; display: flex; flex-direction: column; gap: 2vw">
<!-- 取消按钮 -->
@ -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)
}
// 15
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) {
// 1515
} 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
}
})
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.timeBox {
width: 50vw;
display: flex;
justify-content: center;
}
.timeText {
color: #fff;
font-weight: 590;
font-size: 2em;
margin-top: 1vw;
background: linear-gradient(
180deg,
#ffdf6b 31.61%,
#ffe562 36.73%,
#fff 52.37%,
#ffe562 58.67%,
#ffa615 72.2%
);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.timeGap {
width: 6px;
align-self: stretch;
display: flex;
justify-content: center;
align-items: center;
}
[dir='rtl'] .timeBox {
flex-direction: row-reverse;
}
</style>