import { ref, onUnmounted } from 'vue' import dayjs from 'dayjs' export function useCountDown(startTime, endTime, onFinished) { if (!startTime || !endTime) { throw new Error('startTime and endTime are required') } const remaining = ref(0) const formatted = ref('00:00:00') let timer = null const toTimestamp = (t) => dayjs(t).valueOf() let startTs = toTimestamp(startTime) let endTs = toTimestamp(endTime) const calc = () => { const now = dayjs().valueOf() if (now < startTs) { remaining.value = startTs - now } else if (now >= startTs && now < endTs) { remaining.value = endTs - now } else { remaining.value = 0 clearInterval(timer) timer = null onFinished && onFinished() } format() } const format = () => { let left = remaining.value let totalSeconds = Math.floor(left / 1000) const days = Math.floor(totalSeconds / 86400) totalSeconds %= 86400 const h = String(Math.floor(totalSeconds / 3600)).padStart(2, '0') const m = String(Math.floor((totalSeconds % 3600) / 60)).padStart(2, '0') const s = String(totalSeconds % 60).padStart(2, '0') formatted.value = days > 0 ? `${days}天 ${h}:${m}:${s}` : `${h}:${m}:${s}` } const start = () => { // 如果已有计时器,先清掉 if (timer) clearInterval(timer) startTs = toTimestamp(startTime) endTs = toTimestamp(endTime) calc() timer = setInterval(calc, 1000) } const reset = (newStart, newEnd) => { startTime = newStart endTime = newEnd start() } onUnmounted(() => { if (timer) clearInterval(timer) }) return { formatted, remaining, start, reset } }