blob: a10d95f87365dbf594babcdcc7da0f1a76bf3fa3 [file] [log] [blame]
import type { RcFile } from 'antd/es/upload';
// 将文件转换为Base64
export const getBase64 = (file: RcFile): Promise<string> =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result as string);
reader.onerror = (error) => reject(error);
});
// 验证图片文件
interface ValidationResult {
valid: boolean;
message?: string;
}
export const validateImageFile = (file: RcFile): ValidationResult => {
const isImage = file.type.startsWith('image/');
if (!isImage) {
return { valid: false, message: '只能上传图片文件!' };
}
const isLt5M = file.size / 1024 / 1024 < 5;
if (!isLt5M) {
return { valid: false, message: '图片大小不能超过 5MB!' };
}
return { valid: true };
};
// 验证种子文件
export const validateSeedFile = (file: RcFile): ValidationResult => {
const isLt100M = file.size / 1024 / 1024 < 100;
if (!isLt100M) {
return { valid: false, message: '种子文件大小不能超过 100MB!' };
}
return { valid: true };
};
// 格式化文件大小
export const 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 const debounce = <T extends (...args: unknown[]) => unknown>(
func: T,
wait: number
): ((...args: Parameters<T>) => void) => {
let timeout: ReturnType<typeof setTimeout>;
return (...args: Parameters<T>) => {
clearTimeout(timeout);
timeout = setTimeout(() => func(...args), wait);
};
};
// 节流函数 - 修复版本
export const throttle = <T extends (...args: unknown[]) => unknown>(
func: T,
limit: number
): ((...args: Parameters<T>) => void) => {
let inThrottle: boolean;
return (...args: Parameters<T>) => {
if (!inThrottle) {
func(...args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
};
// 生成唯一ID
export const generateId = (): string => {
return Date.now().toString(36) + Math.random().toString(36).substr(2);
};
// 安全的JSON解析
export const safeJsonParse = <T>(str: string, defaultValue: T): T => {
try {
return JSON.parse(str) as T;
} catch {
return defaultValue;
}
};
// 检查是否为空值
export const isEmpty = (value: unknown): boolean => {
if (value === null || value === undefined) return true;
if (typeof value === 'string') return value.trim() === '';
if (Array.isArray(value)) return value.length === 0;
if (typeof value === 'object') return Object.keys(value).length === 0;
return false;
};
// URL参数解析
export const parseUrlParams = (url: string): Record<string, string> => {
const params: Record<string, string> = {};
const urlObj = new URL(url);
urlObj.searchParams.forEach((value, key) => {
params[key] = value;
});
return params;
};
// 时间格式化
export const formatDate = (date: Date | string | number, format: string = 'YYYY-MM-DD HH:mm:ss'): string => {
const d = new Date(date);
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
const hours = String(d.getHours()).padStart(2, '0');
const minutes = String(d.getMinutes()).padStart(2, '0');
const seconds = String(d.getSeconds()).padStart(2, '0');
return format
.replace('YYYY', year.toString())
.replace('MM', month)
.replace('DD', day)
.replace('HH', hours)
.replace('mm', minutes)
.replace('ss', seconds);
};
// 相对时间格式化(例如:2小时前)
export const formatRelativeTime = (date: Date | string | number): string => {
const now = new Date();
const target = new Date(date);
const diff = now.getTime() - target.getTime();
const seconds = Math.floor(diff / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
const months = Math.floor(days / 30);
const years = Math.floor(months / 12);
if (years > 0) return `${years}年前`;
if (months > 0) return `${months}个月前`;
if (days > 0) return `${days}天前`;
if (hours > 0) return `${hours}小时前`;
if (minutes > 0) return `${minutes}分钟前`;
return '刚刚';
};