新增相对时间工具函数和RelativeTime组件(Wave3-T11遗漏提交)

main
haoliang 1 month ago
parent 0909d9926c
commit b5c92dbd30

@ -0,0 +1,65 @@
<template>
<el-tooltip :content="fullTime" placement="top" :disabled="!fullTime || fullTime === '--'">
<span class="relative-time">{{ displayText }}</span>
</el-tooltip>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import { formatRelativeTime } from '@/utils/time'
const props = defineProps<{
/** 时间字符串、Date对象或时间戳 */
time: string | Date | number | null | undefined
}>()
const displayText = ref('--')
const fullTime = ref('--')
let refreshTimer: number | undefined
function updateTime() {
if (!props.time) {
displayText.value = '--'
fullTime.value = '--'
return
}
const result = formatRelativeTime(props.time)
displayText.value = result.displayText
fullTime.value = result.fullTime
// 30
if (result.needRefresh) {
clearTimer()
refreshTimer = window.setTimeout(() => {
updateTime()
}, 30000)
}
}
function clearTimer() {
if (refreshTimer !== undefined) {
clearTimeout(refreshTimer)
refreshTimer = undefined
}
}
watch(() => props.time, () => {
updateTime()
})
onMounted(() => {
updateTime()
})
onBeforeUnmount(() => {
clearTimer()
})
</script>
<style scoped>
.relative-time {
font-size: 13px;
color: #909399;
cursor: default;
}
</style>

@ -0,0 +1,110 @@
/**
*
*
*/
export interface RelativeTimeResult {
/** 相对时间显示文本 */
displayText: string
/** 完整时间字符串hover显示 */
fullTime: string
/** 是否需要自动刷新10分钟内 */
needRefresh: boolean
}
/**
*
* @param timeStr 'yyyy-MM-dd HH:mm:ss' | Date | number()
* @returns
*/
export function formatRelativeTime(timeStr: string | Date | number | null | undefined): RelativeTimeResult {
if (!timeStr) {
return { displayText: '--', fullTime: '--', needRefresh: false }
}
let date: Date
if (timeStr instanceof Date) {
date = timeStr
} else if (typeof timeStr === 'number') {
date = new Date(timeStr)
} else {
date = new Date(timeStr.replace(/-/g, '/')) // 兼容iOS Safari的日期解析
}
if (isNaN(date.getTime())) {
return { displayText: '--', fullTime: String(timeStr), needRefresh: false }
}
const now = Date.now()
const diff = now - date.getTime()
const absDiff = Math.abs(diff)
// 完整时间
const fullTime = formatFullTime(date)
// 未来时间直接返回完整时间
if (diff < -60000) {
return { displayText: fullTime, fullTime, needRefresh: false }
}
// 10秒内
if (absDiff < 10 * 1000) {
return { displayText: '刚刚', fullTime, needRefresh: true }
}
// 1分钟内
if (absDiff < 60 * 1000) {
const seconds = Math.floor(absDiff / 1000)
return { displayText: `${seconds}秒前`, fullTime, needRefresh: true }
}
// 1小时内
if (absDiff < 60 * 60 * 1000) {
const minutes = Math.floor(absDiff / (60 * 1000))
return { displayText: `${minutes}分钟前`, fullTime, needRefresh: true }
}
// 24小时内
if (absDiff < 24 * 60 * 60 * 1000) {
const hours = Math.floor(absDiff / (60 * 60 * 1000))
const minutes = Math.floor((absDiff % (60 * 60 * 1000)) / (60 * 1000))
if (minutes > 0) {
return { displayText: `${hours}小时${minutes}分钟前`, fullTime, needRefresh: true }
}
return { displayText: `${hours}小时前`, fullTime, needRefresh: true }
}
// 2天内昨天/前天)
if (absDiff < 2 * 24 * 60 * 60 * 1000) {
return { displayText: '1天前', fullTime, needRefresh: false }
}
// 7天内
if (absDiff < 7 * 24 * 60 * 60 * 1000) {
const days = Math.floor(absDiff / (24 * 60 * 60 * 1000))
return { displayText: `${days}天前`, fullTime, needRefresh: false }
}
// 超过7天显示 MM-DD HH:mm
return { displayText: formatShortDate(date), fullTime, needRefresh: false }
}
/** 格式化完整时间 yyyy-MM-dd HH:mm:ss */
function formatFullTime(date: Date): string {
const y = date.getFullYear()
const m = String(date.getMonth() + 1).padStart(2, '0')
const d = String(date.getDate()).padStart(2, '0')
const h = String(date.getHours()).padStart(2, '0')
const min = String(date.getMinutes()).padStart(2, '0')
const s = String(date.getSeconds()).padStart(2, '0')
return `${y}-${m}-${d} ${h}:${min}:${s}`
}
/** 格式化短日期 MM-DD HH:mm */
function formatShortDate(date: Date): string {
const m = String(date.getMonth() + 1).padStart(2, '0')
const d = String(date.getDate()).padStart(2, '0')
const h = String(date.getHours()).padStart(2, '0')
const min = String(date.getMinutes()).padStart(2, '0')
return `${m}-${d} ${h}:${min}`
}
Loading…
Cancel
Save