添加工具类模块
- 实现通用辅助函数
This commit is contained in:
parent
3db624e274
commit
7707522c08
170
src/utils/helpers.js
Normal file
170
src/utils/helpers.js
Normal 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);
|
||||
};
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user