241 lines
8.8 KiB
JavaScript
241 lines
8.8 KiB
JavaScript
document.addEventListener('DOMContentLoaded', function() {
|
||
// 日期范围选择器逻辑
|
||
const dateRangeSelect = document.getElementById('date_range');
|
||
const dateRangeInputs = document.querySelector('.date-range-inputs');
|
||
|
||
if (dateRangeSelect && dateRangeInputs) {
|
||
dateRangeSelect.addEventListener('change', function() {
|
||
if (this.value === 'custom') {
|
||
dateRangeInputs.style.display = 'flex';
|
||
} else {
|
||
dateRangeInputs.style.display = 'none';
|
||
}
|
||
});
|
||
}
|
||
|
||
// 导出日志功能
|
||
const btnExport = document.getElementById('btnExport');
|
||
const exportModal = new bootstrap.Modal(document.getElementById('exportLogModal'));
|
||
const confirmExport = document.getElementById('confirmExport');
|
||
|
||
if (btnExport) {
|
||
btnExport.addEventListener('click', function() {
|
||
exportModal.show();
|
||
});
|
||
}
|
||
|
||
if (confirmExport) {
|
||
confirmExport.addEventListener('click', function() {
|
||
// 获取导出格式
|
||
const exportFormat = document.getElementById('exportFormat').value;
|
||
|
||
// 获取当前筛选条件
|
||
const userId = document.getElementById('user_id').value;
|
||
const action = document.getElementById('action').value;
|
||
const targetType = document.getElementById('target_type').value;
|
||
let startDate = '';
|
||
let endDate = '';
|
||
|
||
const dateRange = document.getElementById('date_range').value;
|
||
if (dateRange === 'custom') {
|
||
startDate = document.getElementById('start_date').value;
|
||
endDate = document.getElementById('end_date').value;
|
||
} else {
|
||
// 根据选择的日期范围计算日期
|
||
const today = new Date();
|
||
endDate = formatDate(today);
|
||
|
||
if (dateRange === '1') {
|
||
const yesterday = new Date(today);
|
||
yesterday.setDate(yesterday.getDate() - 1);
|
||
startDate = formatDate(yesterday);
|
||
} else if (dateRange === '7') {
|
||
const lastWeek = new Date(today);
|
||
lastWeek.setDate(lastWeek.getDate() - 7);
|
||
startDate = formatDate(lastWeek);
|
||
} else if (dateRange === '30') {
|
||
const lastMonth = new Date(today);
|
||
lastMonth.setDate(lastMonth.getDate() - 30);
|
||
startDate = formatDate(lastMonth);
|
||
}
|
||
}
|
||
|
||
// 显示加载提示
|
||
showAlert('info', '正在生成导出文件,请稍候...');
|
||
|
||
// 发送导出请求
|
||
fetch('/log/api/export', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
user_id: userId || null,
|
||
action: action || null,
|
||
target_type: targetType || null,
|
||
start_date: startDate || null,
|
||
end_date: endDate || null,
|
||
format: exportFormat
|
||
})
|
||
})
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
exportModal.hide();
|
||
|
||
if (data.success) {
|
||
showAlert('success', data.message);
|
||
|
||
// 处理文件下载
|
||
if (data.filedata && data.filename) {
|
||
// 解码Base64数据
|
||
const binaryData = atob(data.filedata);
|
||
|
||
// 转换为Blob
|
||
const blob = new Blob([new Uint8Array([...binaryData].map(char => char.charCodeAt(0)))],
|
||
{ type: data.filetype });
|
||
|
||
// 创建下载链接
|
||
const url = window.URL.createObjectURL(blob);
|
||
const a = document.createElement('a');
|
||
a.style.display = 'none';
|
||
a.href = url;
|
||
a.download = data.filename;
|
||
|
||
// 触发下载
|
||
document.body.appendChild(a);
|
||
a.click();
|
||
|
||
// 清理
|
||
window.URL.revokeObjectURL(url);
|
||
document.body.removeChild(a);
|
||
}
|
||
} else {
|
||
showAlert('danger', data.message || '导出失败');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
exportModal.hide();
|
||
showAlert('danger', '导出失败: ' + error.message);
|
||
});
|
||
});
|
||
}
|
||
|
||
// 清除日志功能
|
||
const btnClear = document.getElementById('btnClear');
|
||
const clearModal = new bootstrap.Modal(document.getElementById('clearLogModal'));
|
||
const confirmClear = document.getElementById('confirmClear');
|
||
|
||
if (btnClear) {
|
||
btnClear.addEventListener('click', function() {
|
||
clearModal.show();
|
||
});
|
||
}
|
||
|
||
if (confirmClear) {
|
||
confirmClear.addEventListener('click', function() {
|
||
const days = parseInt(document.getElementById('clearDays').value);
|
||
|
||
fetch('/log/api/clear', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({ days: days })
|
||
})
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
clearModal.hide();
|
||
|
||
if (data.success) {
|
||
showAlert('success', data.message);
|
||
// 2秒后刷新页面
|
||
setTimeout(() => {
|
||
window.location.reload();
|
||
}, 2000);
|
||
} else {
|
||
showAlert('danger', data.message);
|
||
}
|
||
})
|
||
.catch(error => {
|
||
clearModal.hide();
|
||
showAlert('danger', '操作失败: ' + error.message);
|
||
});
|
||
});
|
||
}
|
||
|
||
// 辅助函数 - 格式化日期为 YYYY-MM-DD
|
||
function formatDate(date) {
|
||
const year = date.getFullYear();
|
||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||
const day = String(date.getDate()).padStart(2, '0');
|
||
return `${year}-${month}-${day}`;
|
||
}
|
||
|
||
// 辅助函数 - 显示提示框
|
||
function showAlert(type, message) {
|
||
// 移除之前的所有alert
|
||
const existingAlerts = document.querySelectorAll('.alert-floating');
|
||
existingAlerts.forEach(alert => alert.remove());
|
||
|
||
const alertDiv = document.createElement('div');
|
||
alertDiv.className = `alert alert-${type} alert-dismissible fade show alert-floating`;
|
||
alertDiv.innerHTML = `
|
||
<i class="fas fa-${type === 'success' ? 'check-circle' :
|
||
type === 'danger' ? 'exclamation-circle' :
|
||
type === 'info' ? 'info-circle' : 'bell'}"></i>
|
||
${message}
|
||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||
<span aria-hidden="true">×</span>
|
||
</button>
|
||
`;
|
||
|
||
document.body.appendChild(alertDiv);
|
||
|
||
// 添加CSS,如果还没有添加
|
||
if (!document.getElementById('alert-floating-style')) {
|
||
const style = document.createElement('style');
|
||
style.id = 'alert-floating-style';
|
||
style.textContent = `
|
||
.alert-floating {
|
||
position: fixed;
|
||
top: 20px;
|
||
right: 20px;
|
||
z-index: 9999;
|
||
min-width: 300px;
|
||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||
border-left: 4px solid;
|
||
animation: slideIn 0.3s ease-out forwards;
|
||
}
|
||
@keyframes slideIn {
|
||
from { transform: translateX(100%); opacity: 0; }
|
||
to { transform: translateX(0); opacity: 1; }
|
||
}
|
||
.alert-floating i {
|
||
margin-right: 8px;
|
||
}
|
||
.alert-floating .close {
|
||
padding: 0.75rem;
|
||
}
|
||
`;
|
||
document.head.appendChild(style);
|
||
}
|
||
|
||
// 5秒后自动关闭
|
||
setTimeout(() => {
|
||
if (alertDiv.parentNode) {
|
||
alertDiv.classList.add('fade');
|
||
setTimeout(() => alertDiv.remove(), 300);
|
||
}
|
||
}, 5000);
|
||
|
||
// 点击关闭按钮关闭
|
||
const closeButton = alertDiv.querySelector('.close');
|
||
if (closeButton) {
|
||
closeButton.addEventListener('click', function() {
|
||
alertDiv.classList.add('fade');
|
||
setTimeout(() => alertDiv.remove(), 300);
|
||
});
|
||
}
|
||
}
|
||
});
|