8 changed files with 309 additions and 4 deletions
-
3src/apis/system.ts
-
104src/assets/styles/element.scss
-
108src/components/home/DateTime/index.vue
-
64src/hooks/useServerTime.ts
-
6src/libs/http.ts
-
13src/libs/utils.ts
-
1src/stores/useSystemStore.ts
-
14src/views/main/index.vue
@ -0,0 +1,108 @@ |
|||||
|
<script setup lang="ts"> |
||||
|
import FtDialog from 'components/common/FTDialog/index.vue' |
||||
|
import { useServerTime } from 'hooks/useServerTime' |
||||
|
import { FtMessage } from 'libs/message' |
||||
|
import { ref, watch } from 'vue' |
||||
|
|
||||
|
const emits = defineEmits(['ok', 'cancel']) |
||||
|
|
||||
|
const { serverTime, setDateTime, closeDialog } = useServerTime() |
||||
|
console.log('serverTime', serverTime.value) |
||||
|
|
||||
|
let onceFlag = false |
||||
|
watch(() => serverTime.value, () => { |
||||
|
if (!onceFlag) { |
||||
|
onceFlag = true |
||||
|
form.value.epochMilli = serverTime.value |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
const form = ref({ epochMilli: serverTime.value }) |
||||
|
console.log(form.value) |
||||
|
|
||||
|
const formRef = ref() |
||||
|
|
||||
|
const okLoading = ref(false) |
||||
|
const okHandle = () => { |
||||
|
formRef.value.validate(async (valid: any) => { |
||||
|
if (!valid) { |
||||
|
return |
||||
|
} |
||||
|
console.log(form.value) |
||||
|
okLoading.value = true |
||||
|
await setDateTime(form.value.epochMilli as number) |
||||
|
setTimeout(() => { |
||||
|
okLoading.value = false |
||||
|
FtMessage.success('保存成功') |
||||
|
closeDialog() |
||||
|
}, 300) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const cancel = () => { |
||||
|
emits('cancel') |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<FtDialog visible title="调整日期与时间" width="40%" :ok-handle="okHandle" @cancel="cancel"> |
||||
|
<div class="dialog-content"> |
||||
|
<el-form ref="formRef" label-width="120" :model="form"> |
||||
|
<el-form-item |
||||
|
label="日期与时间" prop="epochMilli" :rules="[ |
||||
|
{ |
||||
|
required: true, |
||||
|
message: '请选择日期和时间', |
||||
|
trigger: 'change', |
||||
|
}, |
||||
|
]" |
||||
|
> |
||||
|
<el-date-picker |
||||
|
v-model="form.epochMilli" |
||||
|
:editable="false" |
||||
|
:show-now="false" |
||||
|
style="width: 100%" |
||||
|
type="datetime" |
||||
|
format="YYYY/MM/DD HH:mm:ss" |
||||
|
value-format="x" |
||||
|
placeholder="请选择日期和时间" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
</div> |
||||
|
</FtDialog> |
||||
|
</template> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
:deep(.el-form-item__error) { |
||||
|
font-size: 40px; |
||||
|
} |
||||
|
.dialog-content { |
||||
|
display: flex; |
||||
|
align-items: center; /* 垂直居中 */ |
||||
|
justify-content: center; /* 水平居中 */ |
||||
|
height: 400px; /* 确保容器高度撑开 */ |
||||
|
} |
||||
|
.el-select { |
||||
|
width: 80%; |
||||
|
} |
||||
|
.el-input { |
||||
|
width: 80%; |
||||
|
} |
||||
|
.unit-text { |
||||
|
font-size: 40px; |
||||
|
color: #0349A8; |
||||
|
font-weight: 500; |
||||
|
margin-left: 20px; |
||||
|
} |
||||
|
.select-box { |
||||
|
display: flex; |
||||
|
margin: 40px; |
||||
|
} |
||||
|
.route-img { |
||||
|
display: flex; |
||||
|
img { |
||||
|
width: 70px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,64 @@ |
|||||
|
import { getTime, setTime } 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') |
||||
|
const editVisible = ref(false) |
||||
|
|
||||
|
let interval: number | null = null |
||||
|
|
||||
|
onMounted(async () => { |
||||
|
try { |
||||
|
await getDateTime() |
||||
|
} |
||||
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
||||
|
catch (error) { |
||||
|
// currentTime.value = formatDateTime(undefined, new Date())
|
||||
|
console.error('获取服务器时间失败') |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
const openDialog = () => { |
||||
|
editVisible.value = true |
||||
|
} |
||||
|
|
||||
|
const closeDialog = () => { |
||||
|
editVisible.value = false |
||||
|
} |
||||
|
|
||||
|
const getDateTime = async () => { |
||||
|
serverTime.value = (await getTime())?.epochMilli |
||||
|
clientFetchTime.value = Date.now() |
||||
|
let num = 0 |
||||
|
if (interval) |
||||
|
clearInterval(interval) |
||||
|
interval = window.setInterval(async () => { |
||||
|
if (num > 60) { |
||||
|
serverTime.value = (await getTime())?.epochMilli |
||||
|
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) |
||||
|
} |
||||
|
|
||||
|
const setDateTime = async (time: number) => { |
||||
|
await setTime(time) |
||||
|
await getDateTime() |
||||
|
} |
||||
|
|
||||
|
onUnmounted(() => { |
||||
|
if (interval) |
||||
|
clearInterval(interval) |
||||
|
}) |
||||
|
|
||||
|
return { currentTime, serverTime, editVisible, setDateTime, openDialog, closeDialog } |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue