Luxx/dashboard/src/utils/useFormatters.js

71 lines
2.0 KiB
JavaScript

/**
* 格式化工具函数
*/
// 相对时间映射
const RELATIVE = (diff) => {
if (diff < 60000) return '刚刚'
if (diff < 3600000) return `${Math.floor(diff / 60000)} 分钟前`
if (diff < 86400000) return `${Math.floor(diff / 3600000)} 小时前`
return `${Math.floor(diff / 86400000)} 天前`
}
/**
* 格式化日期 (MMDDHHMM)
* @param {string|Date} date - 日期
* @param {string} format - 格式 ('short', 'long', 'relative')
*/
export const formatDate = (date, format = 'short') => {
if (!date) return '未知时间'
const d = new Date(date)
if (isNaN(d.getTime())) return '无效日期'
if (format === 'relative') return RELATIVE(new Date() - d)
const pad = (n) => String(n).padStart(2, '0')
return `${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`
}
/**
* 格式化数字
* @param {number} num - 数字
* @param {Object} options - 配置
*/
export const formatNumber = (num, options = {}) => {
if (typeof num !== 'number') return num
const { decimals = 0, thousands = true, suffix = '' } = options
return new Intl.NumberFormat('zh-CN', {
minimumFractionDigits: decimals,
maximumFractionDigits: decimals,
useGrouping: thousands
}).format(num) + suffix
}
/**
* 截断文本
*/
export const truncate = (text, maxLength = 50, suffix = '...') =>
!text || text.length <= maxLength ? text : text.slice(0, maxLength - suffix.length) + suffix
/**
* 格式化文件大小
*/
export const formatFileSize = (bytes) => {
if (!bytes) return '0 B'
const k = 1024, sizes = ['B', 'KB', 'MB', 'GB', 'TB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`
}
/**
* 首字母大写
*/
export const capitalize = (str) => str ? str.replace(/^./, c => c.toUpperCase()) : ''
/**
* 格式化令牌数
*/
export const formatTokens = (tokens) =>
tokens >= 1e6 ? `${(tokens / 1e6).toFixed(1)}M`
: tokens >= 1e3 ? `${(tokens / 1e3).toFixed(1)}K`
: String(tokens)