You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

64 lines
1.8 KiB

1 week ago
  1. import { getTime, setTime } from 'apis/system'
  2. import { formatDateTime } from 'libs/utils'
  3. import { onMounted, onUnmounted, ref } from 'vue'
  4. export function useServerTime() {
  5. const serverTime = ref<number | undefined>() // 初始服务器时间戳
  6. const clientFetchTime = ref<number | null>(null) // 获取服务器时间时的客户端时间戳
  7. const currentTime = ref<string>('0001-00-00 00:00:00')
  8. const editVisible = ref(false)
  9. let interval: number | null = null
  10. onMounted(async () => {
  11. try {
  12. await getDateTime()
  13. }
  14. catch (error) {
  15. // currentTime.value = formatDateTime(undefined, new Date())
  16. console.error('获取服务器时间失败')
  17. }
  18. })
  19. const openDialog = () => {
  20. editVisible.value = true
  21. }
  22. const closeDialog = () => {
  23. editVisible.value = false
  24. }
  25. const getDateTime = async () => {
  26. serverTime.value = (await getTime())?.epochMilli
  27. clientFetchTime.value = Date.now()
  28. let num = 0
  29. if (interval)
  30. clearInterval(interval)
  31. interval = window.setInterval(async () => {
  32. if (num > 60) {
  33. serverTime.value = (await getTime())?.epochMilli
  34. clientFetchTime.value = Date.now()
  35. num = 0
  36. }
  37. if (serverTime.value && clientFetchTime.value) {
  38. const elapsed = Date.now() - clientFetchTime.value
  39. const currentServerTime = serverTime.value + elapsed
  40. currentTime.value = formatDateTime(undefined, new Date(currentServerTime))
  41. num++
  42. }
  43. }, 1000)
  44. }
  45. const setDateTime = async (time: number) => {
  46. await setTime({ epochMilli: time })
  47. await getDateTime()
  48. }
  49. onUnmounted(() => {
  50. if (interval)
  51. clearInterval(interval)
  52. })
  53. return { currentTime, serverTime, editVisible, setDateTime, openDialog, closeDialog }
  54. }