import { type ClassValue, clsx } from "clsx" import { twMerge } from "tailwind-merge" export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) } export function formatFileSize(bytes: number): string { if (bytes === 0) return '0 Bytes' const k = 1024 const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'] const i = Math.floor(Math.log(bytes) / Math.log(k)) return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i] } export function formatDate(date: string | Date): string { const d = typeof date === 'string' ? new Date(date) : date return d.toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', }) } export function formatDateTime(date: string | Date): string { const d = typeof date === 'string' ? new Date(date) : date return d.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', }) } export function generateSlug(text: string): string { return text .toLowerCase() .trim() .replace(/[^\w\s-]/g, '') // 移除特殊字符 .replace(/[\s_-]+/g, '-') // 替换空格和下划线为连字符 .replace(/^-+|-+$/g, '') // 移除开头和结尾的连字符 } export function truncate(text: string, length: number): string { if (text.length <= length) return text return text.substring(0, length) + '...' } export function debounce any>( func: T, wait: number ): (...args: Parameters) => void { let timeout: ReturnType | null = null return (...args: Parameters) => { if (timeout) clearTimeout(timeout) timeout = setTimeout(() => func(...args), wait) } } export function isImageFile(file: File): boolean { const imageTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp', 'image/bmp'] return imageTypes.includes(file.type) } export function getImageDimensions(file: File): Promise<{ width: number; height: number }> { return new Promise((resolve, reject) => { const img = new Image() const url = URL.createObjectURL(file) img.onload = () => { URL.revokeObjectURL(url) resolve({ width: img.naturalWidth, height: img.naturalHeight }) } img.onerror = () => { URL.revokeObjectURL(url) reject(new Error('Failed to load image')) } img.src = url }) }