9 changed files with 240 additions and 85 deletions
-
1src/apis/system.ts
-
105src/components/common/Countdown.vue
-
24src/components/home/Tube/index.vue
-
43src/hooks/useServerTime.ts
-
15src/layouts/default.vue
-
4src/libs/utils.ts
-
5src/stores/systemStore.ts
-
1src/types/system.d.ts
-
117src/views/debug/index.vue
@ -0,0 +1,105 @@ |
|||
<script setup lang="ts"> |
|||
import { useSystemStore } from 'stores/systemStore' |
|||
import { onBeforeUnmount, onMounted, ref, watch } from 'vue' |
|||
|
|||
const props = defineProps<{ |
|||
current: number |
|||
startTime: number |
|||
duration: number // 秒 |
|||
}>() |
|||
|
|||
const systemStore = useSystemStore() |
|||
|
|||
const remaining = ref(0) |
|||
let timer: number | null = null |
|||
|
|||
const calculateRemaining = () => { |
|||
// const now = new Date() |
|||
// // 计算时间差(考虑网络延迟) |
|||
// const timeDiff = now.getTime() - props.current |
|||
// 计算结束时间 |
|||
console.log(props) |
|||
const endTime = props.startTime + props.duration * 1000 |
|||
// 剩余时间 = 结束时间 - 当前时间 - 网络延迟 |
|||
remaining.value = Math.max(0, endTime - new Date(systemStore.currentTime).getTime()) |
|||
console.log('remaining', remaining.value) |
|||
} |
|||
|
|||
const updateCountdown = () => { |
|||
if (remaining.value <= 0) { |
|||
stopTimer() |
|||
return |
|||
} |
|||
remaining.value -= 1000 |
|||
} |
|||
|
|||
const startTimer = () => { |
|||
updateCountdown() // 立即执行一次 |
|||
timer = window.setInterval(() => { |
|||
calculateRemaining() |
|||
updateCountdown() |
|||
}, 1000) |
|||
} |
|||
|
|||
const stopTimer = () => { |
|||
if (timer) { |
|||
console.log(111) |
|||
clearInterval(timer) |
|||
timer = null |
|||
} |
|||
} |
|||
|
|||
onMounted(() => { |
|||
startTimer() |
|||
}) |
|||
|
|||
onBeforeUnmount(() => { |
|||
stopTimer() |
|||
}) |
|||
|
|||
// 时间分割计算 |
|||
const days = ref(0) |
|||
const hours = ref('00') |
|||
const minutes = ref('00') |
|||
const seconds = ref('00') |
|||
|
|||
// 监听剩余时间变化 |
|||
watch( |
|||
() => remaining.value, |
|||
(newVal) => { |
|||
if (newVal <= 0 || !newVal) { |
|||
days.value = 0 |
|||
hours.value = '00' |
|||
minutes.value = '00' |
|||
seconds.value = '00' |
|||
return |
|||
} |
|||
|
|||
days.value = Math.floor(newVal / (1000 * 60 * 60 * 24)) |
|||
|
|||
const hoursNum = Math.floor((newVal % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) |
|||
hours.value = hoursNum.toString().padStart(2, '0') |
|||
|
|||
const minutesNum = Math.floor((newVal % (1000 * 60 * 60)) / (1000 * 60)) |
|||
minutes.value = minutesNum.toString().padStart(2, '0') |
|||
|
|||
const secondsNum = Math.floor((newVal % (1000 * 60)) / 1000) |
|||
seconds.value = secondsNum.toString().padStart(2, '0') |
|||
}, |
|||
) |
|||
</script> |
|||
|
|||
<template> |
|||
<div class="countdown"> |
|||
<span v-if="days">{{ days }}天</span> |
|||
{{ hours }}:{{ minutes }}:{{ seconds }} |
|||
</div> |
|||
</template> |
|||
|
|||
<style scoped> |
|||
.countdown { |
|||
text-align: center; |
|||
font-size: 12px; |
|||
color: #FF4500; |
|||
} |
|||
</style> |
@ -0,0 +1,43 @@ |
|||
import { getTime } from 'apis/system' |
|||
import { formatDateTime } from 'libs/utils' |
|||
import { onMounted, onUnmounted, ref } from 'vue' |
|||
|
|||
export function useServerTime() { |
|||
const serverTime = ref<number | null>(null) // 初始服务器时间戳
|
|||
const clientFetchTime = ref<number | null>(null) // 获取服务器时间时的客户端时间戳
|
|||
const currentTime = ref<string>('0000-00-00 00:00:00') |
|||
|
|||
let interval: number | null = null |
|||
|
|||
onMounted(async () => { |
|||
try { |
|||
serverTime.value = await getTime() |
|||
clientFetchTime.value = Date.now() |
|||
let num = 0 |
|||
interval = window.setInterval(async () => { |
|||
if (num > 10) { |
|||
serverTime.value = await getTime() |
|||
clientFetchTime.value = Date.now() |
|||
num = 0 |
|||
} |
|||
if (serverTime.value && clientFetchTime.value) { |
|||
const elapsed = Date.now() - clientFetchTime.value |
|||
const currentServerTime = serverTime.value + elapsed |
|||
currentTime.value = formatDateTime(undefined, new Date(currentServerTime)) |
|||
num++ |
|||
} |
|||
}, 1000) |
|||
} |
|||
// eslint-disable-next-line unused-imports/no-unused-vars
|
|||
catch (error) { |
|||
console.error('获取服务器时间失败') |
|||
} |
|||
}) |
|||
|
|||
onUnmounted(() => { |
|||
if (interval) |
|||
clearInterval(interval) |
|||
}) |
|||
|
|||
return { currentTime } |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue