taibai_shopping/app/static/js/admin_logs.js
2025-07-09 05:22:28 +08:00

351 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 操作日志页面JavaScript
document.addEventListener('DOMContentLoaded', function() {
// 初始化
initializeLogManagement();
});
// 初始化日志管理功能
function initializeLogManagement() {
// 添加事件监听器
setupEventListeners();
// 初始化工具提示
initializeTooltips();
// 初始化表格
initializeTable();
}
// 设置事件监听器
function setupEventListeners() {
// 搜索表单提交
const searchForm = document.querySelector('form[method="GET"]');
if (searchForm) {
searchForm.addEventListener('submit', function(e) {
// 可以在这里添加搜索前的验证
});
}
// 用户类型筛选变更
const userTypeSelect = document.getElementById('user_type');
if (userTypeSelect) {
userTypeSelect.addEventListener('change', function() {
// 自动提交表单
this.form.submit();
});
}
// 操作类型输入框
const actionInput = document.getElementById('action');
if (actionInput) {
// 添加防抖搜索
let searchTimer;
actionInput.addEventListener('input', function() {
clearTimeout(searchTimer);
searchTimer = setTimeout(() => {
// 可以实现实时搜索
}, 500);
});
}
}
// 初始化工具提示
function initializeTooltips() {
// 为用户代理字段添加工具提示
const userAgentElements = document.querySelectorAll('.user-agent');
userAgentElements.forEach(element => {
if (element.title) {
// 使用Bootstrap的tooltip
new bootstrap.Tooltip(element);
}
});
}
// 初始化表格
function initializeTable() {
// 添加表格行点击事件
const tableRows = document.querySelectorAll('.table tbody tr');
tableRows.forEach(row => {
row.addEventListener('click', function(e) {
// 如果点击的是按钮,不触发行点击事件
if (e.target.tagName === 'BUTTON' || e.target.closest('button')) {
return;
}
// 高亮选中行
tableRows.forEach(r => r.classList.remove('table-active'));
this.classList.add('table-active');
});
});
}
// 查看日志详情
function viewLogDetail(logId) {
// 发送AJAX请求获取日志详情
fetch(`/admin/logs/${logId}/detail`)
.then(response => response.json())
.then(data => {
if (data.success) {
showLogDetailModal(data.log);
} else {
showError('获取日志详情失败: ' + data.message);
}
})
.catch(error => {
console.error('Error:', error);
showError('网络错误,请重试');
});
}
// 显示日志详情模态框
function showLogDetailModal(log) {
const modalHtml = `
<div class="modal fade" id="logDetailModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">操作日志详情</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="log-detail">
<div class="row">
<div class="col-md-6">
<div class="log-info-item">
<span class="log-info-label">日志ID:</span>
<span class="log-info-value">#${log.id}</span>
</div>
<div class="log-info-item">
<span class="log-info-label">操作者:</span>
<span class="log-info-value">
<span class="badge bg-${log.user_type === 2 ? 'warning' : 'info'}">
${log.user_type === 2 ? '管理员' : '用户'}
</span>
#${log.user_id || '未知'}
</span>
</div>
<div class="log-info-item">
<span class="log-info-label">操作类型:</span>
<span class="log-info-value operation-action">${log.action}</span>
</div>
<div class="log-info-item">
<span class="log-info-label">操作对象:</span>
<span class="log-info-value">
${log.resource_type || '无'}
${log.resource_id ? `#${log.resource_id}` : ''}
</span>
</div>
</div>
<div class="col-md-6">
<div class="log-info-item">
<span class="log-info-label">IP地址:</span>
<span class="log-info-value"><code>${log.ip_address || '未知'}</code></span>
</div>
<div class="log-info-item">
<span class="log-info-label">操作时间:</span>
<span class="log-info-value">${formatDateTime(log.created_at)}</span>
</div>
</div>
</div>
${log.user_agent ? `
<div class="mt-3">
<h6>用户代理信息:</h6>
<div class="user-agent-detail">
<code>${log.user_agent}</code>
</div>
</div>
` : ''}
${log.request_data ? `
<div class="mt-3">
<h6>请求数据:</h6>
<pre class="request-data"><code>${JSON.stringify(log.request_data, null, 2)}</code></pre>
</div>
` : ''}
</div>
</div>
</div>
</div>
</div>
`;
// 移除现有的模态框
const existingModal = document.getElementById('logDetailModal');
if (existingModal) {
existingModal.remove();
}
// 添加新的模态框
document.body.insertAdjacentHTML('beforeend', modalHtml);
// 显示模态框
const modal = new bootstrap.Modal(document.getElementById('logDetailModal'));
modal.show();
}
// 导出日志
function exportLogs() {
// 获取当前筛选条件
const userType = document.getElementById('user_type').value;
const action = document.getElementById('action').value;
// 构建导出URL
const params = new URLSearchParams();
if (userType) params.append('user_type', userType);
if (action) params.append('action', action);
const exportUrl = `/admin/logs/export?${params.toString()}`;
// 下载文件
window.location.href = exportUrl;
}
// 清理日志
function clearLogs() {
if (!confirm('确定要清理历史日志吗?此操作不可逆!')) {
return;
}
const daysToKeep = prompt('请输入要保留的天数例如30:', '30');
if (!daysToKeep || isNaN(daysToKeep) || daysToKeep <= 0) {
showError('请输入有效的天数');
return;
}
// 显示加载状态
showLoading();
// 发送AJAX请求
fetch('/admin/logs/clear', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
days_to_keep: parseInt(daysToKeep)
})
})
.then(response => response.json())
.then(data => {
hideLoading();
if (data.success) {
showSuccess(data.message);
// 刷新页面
setTimeout(() => {
location.reload();
}, 1000);
} else {
showError(data.message);
}
})
.catch(error => {
hideLoading();
console.error('Error:', error);
showError('网络错误,请重试');
});
}
// 搜索日志
function searchLogs() {
const searchForm = document.querySelector('form[method="GET"]');
if (searchForm) {
searchForm.submit();
}
}
// 重置搜索
function resetSearch() {
window.location.href = '/admin/logs';
}
// 格式化日期时间
function formatDateTime(dateTimeString) {
if (!dateTimeString) return '未知';
const date = new Date(dateTimeString);
return date.toLocaleString('zh-CN');
}
// 显示成功消息
function showSuccess(message) {
showAlert(message, 'success');
}
// 显示错误消息
function showError(message) {
showAlert(message, 'danger');
}
// 显示提示消息
function showAlert(message, type) {
const alertDiv = document.createElement('div');
alertDiv.className = `alert alert-${type} alert-dismissible fade show`;
alertDiv.innerHTML = `
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
`;
// 插入到页面顶部
const container = document.querySelector('.admin-content');
container.insertBefore(alertDiv, container.firstChild);
// 3秒后自动关闭
setTimeout(() => {
alertDiv.remove();
}, 3000);
}
// 显示加载状态
function showLoading() {
const loadingDiv = document.createElement('div');
loadingDiv.id = 'loading-overlay';
loadingDiv.innerHTML = `
<div class="loading-spinner">
<i class="bi bi-hourglass-split"></i>
<div>处理中...</div>
</div>
`;
loadingDiv.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
color: white;
`;
document.body.appendChild(loadingDiv);
}
// 隐藏加载状态
function hideLoading() {
const loadingDiv = document.getElementById('loading-overlay');
if (loadingDiv) {
loadingDiv.remove();
}
}
// 表格排序功能
function sortTable(column) {
// 实现表格排序功能
console.log('Sort by:', column);
}
// 批量操作功能(可选)
function bulkOperation() {
// 实现批量操作功能
const selectedLogs = document.querySelectorAll('input[type="checkbox"]:checked');
if (selectedLogs.length === 0) {
showError('请选择要操作的日志');
return;
}
// 实现批量操作逻辑
}