From e96ba3c26faa82baec558019c3979cfd49b14c7d Mon Sep 17 00:00:00 2001 From: wangshun <932054296@qq.com> Date: Tue, 2 Sep 2025 14:46:18 +0800 Subject: [PATCH] =?UTF-8?q?1.=E8=BF=BD=E5=8A=A0=EF=BC=9A=E6=8A=95=E7=A5=A8?= =?UTF-8?q?=E7=BB=93=E6=9D=9F=E6=9F=A5=E7=9C=8B=E5=80=92=E8=AE=A1=E6=97=B6?= =?UTF-8?q?=E6=97=B6=E9=97=B4=202.=E4=BF=AE=E6=94=B9=EF=BC=9A=E5=80=92?= =?UTF-8?q?=E8=AE=A1=E6=97=B6=E6=A0=B7=E5=BC=8F=203.=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E6=8A=BD=E5=A5=96=E5=92=8C=E6=8A=95=E7=A5=A8=E5=80=92?= =?UTF-8?q?=E8=AE=A1=E6=97=B6=E4=BB=A3=E7=A0=81=E7=BB=9F=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend_nuxt/components/PostLottery.vue | 49 +++----------------- frontend_nuxt/components/PostPoll.vue | 55 +++++------------------ frontend_nuxt/composables/useCountdown.ts | 51 +++++++++++++++++++++ 3 files changed, 66 insertions(+), 89 deletions(-) create mode 100644 frontend_nuxt/composables/useCountdown.ts diff --git a/frontend_nuxt/components/PostLottery.vue b/frontend_nuxt/components/PostLottery.vue index 29d487685..125d04ab7 100644 --- a/frontend_nuxt/components/PostLottery.vue +++ b/frontend_nuxt/components/PostLottery.vue @@ -16,7 +16,7 @@
x {{ lottery.prizeCount }}
-
离结束还有
+
距离结束还有
{{ countdown }}
authState.loggedIn) const lotteryParticipants = computed(() => props.lottery?.participants || []) const lotteryWinners = computed(() => props.lottery?.winners || []) -const lotteryEnded = computed(() => { - if (!props.lottery || !props.lottery.endTime) return false - return new Date(props.lottery.endTime).getTime() <= Date.now() -}) +// 倒计时和结束flg +const { countdown, isEnded } = useCountdown(props.lottery?.endTime) +const lotteryEnded = computed(() => isEnded.value) const hasJoined = computed(() => { if (!loggedIn.value) return false return lotteryParticipants.value.some((p) => p.id === Number(authState.userId)) }) -const countdown = ref('00:00:00') -let timer = null -const updateCountdown = () => { - if (!props.lottery || !props.lottery.endTime) { - countdown.value = '00:00:00' - return - } - const diff = new Date(props.lottery.endTime).getTime() - Date.now() - if (diff <= 0) { - countdown.value = '00:00:00' - if (timer) { - clearInterval(timer) - timer = null - } - return - } - const h = String(Math.floor(diff / 3600000)).padStart(2, '0') - const m = String(Math.floor((diff % 3600000) / 60000)).padStart(2, '0') - const s = String(Math.floor((diff % 60000) / 1000)).padStart(2, '0') - countdown.value = `${h}:${m}:${s}` -} -const startCountdown = () => { - updateCountdown() - if (timer) clearInterval(timer) - timer = setInterval(updateCountdown, 1000) -} -watch( - () => props.lottery?.endTime, - () => { - if (props.lottery && props.lottery.endTime) startCountdown() - }, -) -onMounted(() => { - if (props.lottery && props.lottery.endTime) startCountdown() -}) -onBeforeUnmount(() => { - if (timer) clearInterval(timer) -}) - const gotoUser = (id) => navigateTo(`/users/${id}`, { replace: true }) const config = useRuntimeConfig() diff --git a/frontend_nuxt/components/PostPoll.vue b/frontend_nuxt/components/PostPoll.vue index fdfc7cc07..29bc4b687 100644 --- a/frontend_nuxt/components/PostPoll.vue +++ b/frontend_nuxt/components/PostPoll.vue @@ -34,7 +34,7 @@
单选
-
离结束还有
+
距离结束还有
{{ countdown }}
@@ -107,7 +107,11 @@ 投票已结束
- 您已投票,等待结束查看结果 +
您已投票,等待结束查看结果
+
+
距离结束还有
+
{{ countdown }}
+
@@ -118,6 +122,7 @@ import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue' import { getToken, authState } from '~/utils/auth' import { toast } from '~/main' import { useRuntimeConfig } from '#imports' +import { useCountdown } from '~/composables/useCountdown' const props = defineProps({ poll: { type: Object, required: true }, @@ -140,10 +145,9 @@ const pollPercentages = computed(() => }) : [], ) -const pollEnded = computed(() => { - if (!props.poll || !props.poll.endTime) return false - return new Date(props.poll.endTime).getTime() <= Date.now() -}) +// 倒计时 +const { countdown, isEnded } = useCountdown(props.poll?.endTime) +const pollEnded = computed(() => isEnded.value) const hasVoted = computed(() => { if (!loggedIn.value) return false return pollParticipants.value.some((p) => p.id === Number(authState.userId)) @@ -152,45 +156,6 @@ watch([hasVoted, pollEnded], ([voted, ended]) => { if (voted || ended) showPollResult.value = true }) -const countdown = ref('00:00:00') -let timer = null -const updateCountdown = () => { - if (!props.poll || !props.poll.endTime) { - countdown.value = '00:00:00' - return - } - const diff = new Date(props.poll.endTime).getTime() - Date.now() - if (diff <= 0) { - countdown.value = '00:00:00' - if (timer) { - clearInterval(timer) - timer = null - } - return - } - const h = String(Math.floor(diff / 3600000)).padStart(2, '0') - const m = String(Math.floor((diff % 3600000) / 60000)).padStart(2, '0') - const s = String(Math.floor((diff % 60000) / 1000)).padStart(2, '0') - countdown.value = `${h}:${m}:${s}` -} -const startCountdown = () => { - updateCountdown() - if (timer) clearInterval(timer) - timer = setInterval(updateCountdown, 1000) -} -watch( - () => props.poll?.endTime, - () => { - if (props.poll && props.poll.endTime) startCountdown() - }, -) -onMounted(() => { - if (props.poll && props.poll.endTime) startCountdown() -}) -onBeforeUnmount(() => { - if (timer) clearInterval(timer) -}) - const gotoUser = (id) => navigateTo(`/users/${id}`, { replace: true }) const config = useRuntimeConfig() diff --git a/frontend_nuxt/composables/useCountdown.ts b/frontend_nuxt/composables/useCountdown.ts new file mode 100644 index 000000000..9873499eb --- /dev/null +++ b/frontend_nuxt/composables/useCountdown.ts @@ -0,0 +1,51 @@ +import { ref, onMounted, onBeforeUnmount } from 'vue' + +/** + * 通用倒计时 composable + * @param endTime 截止时间字符串或 Date 对象 + * @returns { countdown, isEnded } + */ +export function useCountdown(endTime?: string | Date) { + const countdown = ref('') + const isEnded = ref(false) + let timer: ReturnType | null = null + + const update = () => { + if (!endTime) { + countdown.value = '' + isEnded.value = true + return + } + const diff = new Date(endTime).getTime() - Date.now() + if (diff <= 0) { + countdown.value = '已结束' + isEnded.value = true + if (timer) clearInterval(timer) + return + } + // 计算天、时、分、秒 + const days = Math.floor(diff / (24 * 3600 * 1000)) + const hours = Math.floor((diff % (24 * 3600 * 1000)) / 3600000) + const minutes = Math.floor((diff % 3600000) / 60000) + const seconds = Math.floor((diff % 60000) / 1000) + + if (days > 0) { + countdown.value = `${days}天 ${hours}小时 ${minutes}分 ${seconds}秒` + } else if (hours > 0) { + countdown.value = `${hours}小时 ${minutes}分 ${seconds}秒` + } else { + countdown.value = `${minutes}分 ${seconds}秒` + } + } + + onMounted(() => { + update() + timer = setInterval(update, 1000) + }) + + onBeforeUnmount(() => { + if (timer) clearInterval(timer) + }) + + return { countdown, isEnded } +}