flnxi-Wu/app/admin/_utils/formatters.ts
WuYongJie e4dcb6260a
Some checks failed
CI Check / check (push) Has been cancelled
feat: Admin页面重构 & UI三层架构系统
- 创建统一UI三层架构系统(基础层、颜色层、组合层)
- 拆分Admin页面为独立Tab组件(MonitorTab、UsersTab、DepartmentsTab等)
- 提取公共逻辑到Hooks(useToast、useDataFetch、useUserOperations等)
- 提取工具函数(validators、formatters、api等)
- 创建统一弹窗组件(Modal)和useModal Hook
- 添加错误边界和统一状态组件
- 完善类型定义和可访问性支持
- 更新文档(优化记录、优化计划、更新日志)
2025-11-22 15:17:10 +08:00

178 lines
5.2 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.

/**
* 格式化工具函数
* 统一管理各种格式化逻辑(日期、时间、数字等)
*/
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%'
}
}