2025-04-02 14:29:57 +08:00

165 lines
4.8 KiB
JavaScript

/**
* 通用工具函数库
*/
// 格式化日期时间
function formatDateTime(dateString, format = 'YYYY-MM-DD HH:mm:ss') {
const date = new Date(dateString);
if (isNaN(date.getTime())) return '';
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return format
.replace('YYYY', year)
.replace('MM', month)
.replace('DD', day)
.replace('HH', hours)
.replace('mm', minutes)
.replace('ss', seconds);
}
// 时间距离现在
function timeAgo(dateString) {
const date = new Date(dateString);
if (isNaN(date.getTime())) return '';
const now = new Date();
const secondsAgo = Math.floor((now - date) / 1000);
if (secondsAgo < 60) {
return '刚刚';
} else if (secondsAgo < 3600) {
const minutes = Math.floor(secondsAgo / 60);
return `${minutes}分钟前`;
} else if (secondsAgo < 86400) {
const hours = Math.floor(secondsAgo / 3600);
return `${hours}小时前`;
} else if (secondsAgo < 2592000) {
const days = Math.floor(secondsAgo / 86400);
return `${days}天前`;
} else if (secondsAgo < 31536000) {
const months = Math.floor(secondsAgo / 2592000);
return `${months}个月前`;
} else {
const years = Math.floor(secondsAgo / 31536000);
return `${years}年前`;
}
}
// 格式化状态标签
function formatStatus(status, labels = {}) {
const defaultLabels = {
online: { text: '在线', class: 'bg-green-100 text-green-800' },
offline: { text: '离线', class: 'bg-gray-100 text-gray-800' },
error: { text: '错误', class: 'bg-red-100 text-red-800' },
pending: { text: '待处理', class: 'bg-yellow-100 text-yellow-800' },
success: { text: '成功', class: 'bg-green-100 text-green-800' },
failure: { text: '失败', class: 'bg-red-100 text-red-800' },
};
const statusLabel = { ...defaultLabels, ...labels }[status] || { text: status, class: 'bg-gray-100 text-gray-800' };
return `<span class="px-2 py-1 text-xs rounded-full ${statusLabel.class}">${statusLabel.text}</span>`;
}
// 格式化文件大小
function formatFileSize(bytes) {
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];
}
// 复制文本到剪贴板
function copyToClipboard(text) {
return new Promise((resolve, reject) => {
if (!navigator.clipboard) {
fallbackCopyToClipboard(text);
resolve(true);
return;
}
navigator.clipboard.writeText(text)
.then(() => resolve(true))
.catch(err => {
fallbackCopyToClipboard(text);
resolve(true);
});
});
}
// 复制文本到剪贴板的后备方案
function fallbackCopyToClipboard(text) {
const textArea = document.createElement('textarea');
textArea.value = text;
// 设置样式使文本域不可见
textArea.style.position = 'fixed';
textArea.style.top = '-9999px';
textArea.style.left = '-9999px';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
document.execCommand('copy');
} catch (err) {
console.error('无法复制文本: ', err);
}
document.body.removeChild(textArea);
}
// 防抖函数
function debounce(func, wait = 300) {
let timeout;
return function(...args) {
const context = this;
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args);
}, wait);
};
}
// 节流函数
function throttle(func, limit = 300) {
let inThrottle;
return function(...args) {
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => {
inThrottle = false;
}, limit);
}
};
}
// 从URL获取查询参数
function getQueryParam(name, url = window.location.href) {
name = name.replace(/[\[\]]/g, '\\$&');
const regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)');
const results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, ' '));
}