165 lines
4.8 KiB
JavaScript
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, ' '));
|
|
}
|