添加工具类模块

- 实现通用辅助函数
This commit is contained in:
Leo 2025-10-20 14:04:50 +08:00
parent 3db624e274
commit 7707522c08

170
src/utils/helpers.js Normal file
View File

@ -0,0 +1,170 @@
/**
* 工具函数
*/
/**
* 格式化文件大小
* @param {number} bytes 字节数
* @returns {string} 格式化的文件大小
*/
export const formatFileSize = (bytes) => {
// 类型检查和安全转换
if (bytes === null || bytes === undefined) return '0 Bytes';
const numBytes = Number(bytes);
if (isNaN(numBytes) || numBytes < 0) return '0 Bytes';
if (numBytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(numBytes) / Math.log(k));
return parseFloat((numBytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};
/**
* 格式化时间
* @param {string} dateString 日期字符串
* @returns {string} 格式化的时间
*/
export const formatDateTime = (dateString) => {
if (!dateString) return '-';
const date = new Date(dateString);
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
};
/**
* 格式化转换时间
* @param {number} seconds 秒数
* @returns {string} 格式化的转换时间
*/
export const formatConversionTime = (seconds) => {
// 类型检查和安全转换
if (seconds === null || seconds === undefined) return '-';
// 尝试转换为数字
const numSeconds = Number(seconds);
// 如果不是有效数字,返回默认值
if (isNaN(numSeconds) || numSeconds < 0) return '-';
if (numSeconds < 1) {
return `${Math.round(numSeconds * 1000)}ms`;
} else if (numSeconds < 60) {
return `${numSeconds.toFixed(2)}s`;
} else {
const minutes = Math.floor(numSeconds / 60);
const remainingSeconds = (numSeconds % 60).toFixed(2);
return `${minutes}m ${remainingSeconds}s`;
}
};
/**
* 获取转换状态的颜色
* @param {string} status 状态
* @returns {string} 颜色
*/
export const getStatusColor = (status) => {
const colors = {
processing: '#1890ff',
success: '#52c41a',
failed: '#ff4d4f',
};
return colors[status] || '#d9d9d9';
};
/**
* 获取转换状态的文本
* @param {string} status 状态
* @returns {string} 状态文本
*/
export const getStatusText = (status) => {
const texts = {
processing: '转换中',
success: '转换成功',
failed: '转换失败',
};
return texts[status] || '未知状态';
};
/**
* 验证文件类型
* @param {File} file 文件对象
* @returns {boolean} 是否为有效的SQL文件
*/
export const validateSQLFile = (file) => {
if (!file) return false;
const allowedExtensions = ['.sql'];
const fileName = file.name.toLowerCase();
return allowedExtensions.some(ext => fileName.endsWith(ext));
};
/**
* 下载文件
* @param {Blob} blob 文件blob
* @param {string} filename 文件名
*/
export const downloadFile = (blob, filename) => {
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
};
/**
* 复制文本到剪贴板
* @param {string} text 要复制的文本
* @returns {Promise<boolean>} 是否复制成功
*/
export const copyToClipboard = async (text) => {
try {
await navigator.clipboard.writeText(text);
return true;
} catch (err) {
// 回退方案
try {
const textArea = document.createElement('textarea');
textArea.value = text;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
return true;
} catch (fallbackErr) {
console.error('复制失败:', fallbackErr);
return false;
}
}
};
/**
* 防抖函数
* @param {Function} func 要防抖的函数
* @param {number} wait 等待时间
* @returns {Function} 防抖后的函数
*/
export const debounce = (func, wait) => {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};