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. 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 | null>(null) // 初始服务器时间戳
  6. const clientFetchTime = ref<number | null>(null) // 获取服务器时间时的客户端时间戳
  7. const currentTime = ref<string>('0000-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. // eslint-disable-next-line unused-imports/no-unused-vars
  15. catch (error) {
  16. // currentTime.value = formatDateTime(undefined, new Date())
  17. console.error('获取服务器时间失败')
  18. }
  19. })
  20. const openDialog = () => {
  21. editVisible.value = true
  22. }
  23. const closeDialog = () => {
  24. editVisible.value = false
  25. }
  26. const getDateTime = async () => {
  27. serverTime.value = (await getTime())?.epochMilli
  28. clientFetchTime.value = Date.now()
  29. let num = 0
  30. if (interval)
  31. clearInterval(interval)
  32. interval = window.setInterval(async () => {
  33. if (num > 60) {
  34. serverTime.value = (await getTime())?.epochMilli
  35. clientFetchTime.value = Date.now()
  36. num = 0
  37. }
  38. if (serverTime.value && clientFetchTime.value) {
  39. const elapsed = Date.now() - clientFetchTime.value
  40. const currentServerTime = serverTime.value + elapsed
  41. currentTime.value = formatDateTime(undefined, new Date(currentServerTime))
  42. num++
  43. }
  44. }, 1000)
  45. }
  46. const setDateTime = async (time: number) => {
  47. await setTime(time)
  48. await getDateTime()
  49. }
  50. onUnmounted(() => {
  51. if (interval)
  52. clearInterval(interval)
  53. })
  54. return { currentTime, serverTime, editVisible, setDateTime, openDialog, closeDialog }
  55. }