flnxi-Wu/app/admin/_utils/formatters.ts
2025-11-22 17:56:24 +08:00

184 lines
5.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 格式化工具函数
*
* 统一管理各种格式化逻辑(日期、时间、数字等)
* 包括:日期时间格式化、文件大小格式化、数字格式化、百分比格式化等
* 确保整个应用的格式化一致性
*
* @created 2025-01-XX(从各组件提取)
* @utils
*/
import { format } from 'date-fns'
/**
* 格式化日期时间(完整格式)
* @param date - 日期对象或时间戳字符串
* @param formatStr - 格式化字符串,默认为 'yyyy-MM-dd HH:mm:ss'
* @returns 格式化后的日期时间字符串
*/
export function formatDateTime(date: Date | string | number, formatStr: string = 'yyyy-MM-dd HH:mm:ss'): string {
try {
const dateObj = typeof date === 'string' || typeof date === 'number' ? new Date(date) : date
if (isNaN(dateObj.getTime())) {
return '无效日期'
}
return format(dateObj, formatStr)
} catch (error) {
console.error('Date formatting error:', error)
return '无效日期'
}
}
/**
* 格式化日期(仅日期部分)
* @param date - 日期对象或时间戳字符串
* @returns 格式化后的日期字符串(yyyy-MM-dd)
*/
export function formatDate(date: Date | string | number): string {
return formatDateTime(date, 'yyyy-MM-dd')
}
/**
* 格式化时间(仅时间部分)
* @param date - 日期对象或时间戳字符串
* @returns 格式化后的时间字符串(HH:mm:ss)
*/
export function formatTime(date: Date | string | number): string {
return formatDateTime(date, 'HH:mm:ss')
}
/**
* 格式化日期时间(简短格式,不含秒)
* @param date - 日期对象或时间戳字符串
* @returns 格式化后的日期时间字符串(yyyy-MM-dd HH:mm)
*/
export function formatDateTimeShort(date: Date | string | number): string {
return formatDateTime(date, 'yyyy-MM-dd HH:mm')
}
/**
* 使用本地化格式格式化日期时间
* @param date - 日期对象或时间戳字符串
* @param locale - 语言环境,默认为 'zh-CN'
* @param options - Intl.DateTimeFormat 选项
* @returns 格式化后的日期时间字符串
*/
export function formatDateTimeLocale(
date: Date | string | number,
locale: string = 'zh-CN',
options?: Intl.DateTimeFormatOptions
): string {
try {
const dateObj = typeof date === 'string' || typeof date === 'number' ? new Date(date) : date
if (isNaN(dateObj.getTime())) {
return '无效日期'
}
const defaultOptions: Intl.DateTimeFormatOptions = {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
}
return new Intl.DateTimeFormat(locale, options || defaultOptions).format(dateObj)
} catch (error) {
console.error('Date formatting error:', error)
return '无效日期'
}
}
/**
* 格式化相对时间(如:2小时前、3天前)
* @param date - 日期对象或时间戳字符串
* @returns 相对时间字符串
*/
export function formatRelativeTime(date: Date | string | number): string {
try {
const dateObj = typeof date === 'string' || typeof date === 'number' ? new Date(date) : date
if (isNaN(dateObj.getTime())) {
return '无效日期'
}
const now = new Date()
const diffMs = now.getTime() - dateObj.getTime()
const diffSeconds = Math.floor(diffMs / 1000)
const diffMinutes = Math.floor(diffSeconds / 60)
const diffHours = Math.floor(diffMinutes / 60)
const diffDays = Math.floor(diffHours / 24)
if (diffSeconds < 60) {
return '刚刚'
} else if (diffMinutes < 60) {
return `${diffMinutes}分钟前`
} else if (diffHours < 24) {
return `${diffHours}小时前`
} else if (diffDays < 7) {
return `${diffDays}天前`
} else {
return formatDateTimeShort(dateObj)
}
} catch (error) {
console.error('Relative time formatting error:', error)
return '无效日期'
}
}
/**
* 格式化文件大小
* @param bytes - 字节数
* @param decimals - 小数位数,默认为 2
* @returns 格式化后的文件大小字符串
*/
export function formatFileSize(bytes: number, decimals: number = 2): string {
if (bytes === 0) return '0 Bytes'
const k = 1024
const dm = decimals < 0 ? 0 : decimals
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
}
/**
* 格式化数字(添加千位分隔符)
* @param num - 数字
* @param decimals - 小数位数,默认为 0
* @returns 格式化后的数字字符串
*/
export function formatNumber(num: number, decimals: number = 0): string {
try {
return num.toLocaleString('zh-CN', {
minimumFractionDigits: decimals,
maximumFractionDigits: decimals,
})
} catch (error) {
console.error('Number formatting error:', error)
return String(num)
}
}
/**
* 格式化百分比
* @param value - 数值(0-1 或 0-100)
* @param isDecimal - 是否为小数格式(0-1),默认为 false(0-100)
* @param decimals - 小数位数,默认为 1
* @returns 格式化后的百分比字符串
*/
export function formatPercent(value: number, isDecimal: boolean = false, decimals: number = 1): string {
try {
const percent = isDecimal ? value * 100 : value
return `${percent.toFixed(decimals)}%`
} catch (error) {
console.error('Percent formatting error:', error)
return '0%'
}
}