152 lines
6.0 KiB
JavaScript
152 lines
6.0 KiB
JavaScript
// Filename: frontend/js/components/BatchActions.js
|
|
import { apiFetchJson } from '../../services/api.js';
|
|
|
|
// 存储对 LogsPage 实例的引用
|
|
let logsPageInstance = null;
|
|
|
|
// 存储对 DOM 元素的引用
|
|
const elements = {
|
|
batchActionsBtn: null,
|
|
batchActionsMenu: null,
|
|
deleteSelectedLogsBtn: null,
|
|
clearAllLogsBtn: null,
|
|
};
|
|
|
|
// 用于处理页面点击以关闭菜单的绑定函数
|
|
const handleDocumentClick = (event) => {
|
|
if (!elements.batchActionsMenu.contains(event.target) && !elements.batchActionsBtn.contains(event.target)) {
|
|
closeBatchActionsMenu();
|
|
}
|
|
};
|
|
|
|
// 关闭菜单的逻辑
|
|
function closeBatchActionsMenu() {
|
|
if (elements.batchActionsMenu && !elements.batchActionsMenu.classList.contains('hidden')) {
|
|
elements.batchActionsMenu.classList.remove('opacity-100', 'scale-100');
|
|
elements.batchActionsMenu.classList.add('opacity-0', 'scale-95');
|
|
setTimeout(() => {
|
|
elements.batchActionsMenu.classList.add('hidden');
|
|
}, 100);
|
|
document.removeEventListener('click', handleDocumentClick);
|
|
}
|
|
}
|
|
|
|
// 切换菜单显示/隐藏
|
|
function handleBatchActionsToggle(event) {
|
|
event.stopPropagation();
|
|
const isHidden = elements.batchActionsMenu.classList.contains('hidden');
|
|
if (isHidden) {
|
|
elements.batchActionsMenu.classList.remove('hidden', 'opacity-0', 'scale-95');
|
|
elements.batchActionsMenu.classList.add('opacity-100', 'scale-100');
|
|
document.addEventListener('click', handleDocumentClick);
|
|
} else {
|
|
closeBatchActionsMenu();
|
|
}
|
|
}
|
|
|
|
// 处理删除选中日志的逻辑
|
|
async function handleDeleteSelectedLogs() {
|
|
closeBatchActionsMenu();
|
|
const selectedIds = Array.from(logsPageInstance.state.selectedLogIds);
|
|
if (selectedIds.length === 0) return;
|
|
|
|
Swal.fire({
|
|
width: '20rem',
|
|
backdrop: `rgba(0,0,0,0.5)`,
|
|
heightAuto: false,
|
|
customClass: { popup: `swal2-custom-style ${document.documentElement.classList.contains('dark') ? 'swal2-dark' : ''}` },
|
|
title: '确认删除',
|
|
text: `您确定要删除选定的 ${selectedIds.length} 条日志吗?此操作不可撤销。`,
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonText: '确认删除',
|
|
cancelButtonText: '取消',
|
|
reverseButtons: false,
|
|
confirmButtonColor: '#ef4444',
|
|
cancelButtonColor: '#6b7280',
|
|
focusCancel: true,
|
|
target: '#main-content-wrapper',
|
|
}).then(async (result) => {
|
|
if (result.isConfirmed) {
|
|
try {
|
|
const idsQueryString = selectedIds.join(',');
|
|
const url = `/admin/logs?ids=${idsQueryString}`;
|
|
const { success, message } = await apiFetchJson(url, { method: 'DELETE' });
|
|
if (success) {
|
|
Swal.fire({ toast: true, position: 'top-end', icon: 'success', title: '删除成功', showConfirmButton: false, timer: 2000, timerProgressBar: true });
|
|
logsPageInstance.loadAndRenderLogs(); // 使用实例刷新列表
|
|
} else {
|
|
throw new Error(message || '删除失败,请稍后重试。');
|
|
}
|
|
} catch (error) {
|
|
Swal.fire({ icon: 'error', title: '操作失败', text: error.message, target: '#main-content-wrapper' });
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// [NEW] 处理清空所有日志的逻辑
|
|
async function handleClearAllLogs() {
|
|
closeBatchActionsMenu();
|
|
|
|
Swal.fire({
|
|
width: '20rem',
|
|
backdrop: `rgba(0,0,0,0.5)`,
|
|
heightAuto: false,
|
|
customClass: { popup: `swal2-custom-style ${document.documentElement.classList.contains('dark') ? 'swal2-dark' : ''}` },
|
|
title: '危险操作确认',
|
|
html: `您确定要<strong class="text-red-500">清空全部</strong>日志吗?<br>此操作不可撤销!`,
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonText: '确认清空',
|
|
cancelButtonText: '取消',
|
|
reverseButtons: false,
|
|
confirmButtonColor: '#ef4444',
|
|
cancelButtonColor: '#6b7280',
|
|
focusCancel: true,
|
|
target: '#main-content-wrapper',
|
|
}).then(async (result) => {
|
|
if (result.isConfirmed) {
|
|
try {
|
|
const url = `/admin/logs/all`; // 后端清空所有日志的接口
|
|
const { success, message } = await apiFetchJson(url, { method: 'DELETE' });
|
|
if (success) {
|
|
Swal.fire({ toast: true, position: 'top-end', icon: 'success', title: '清空成功', showConfirmButton: false, timer: 2000, timerProgressBar: true });
|
|
logsPageInstance.loadAndRenderLogs(); // 刷新列表
|
|
} else {
|
|
throw new Error(message || '清空失败,请稍后重试。');
|
|
}
|
|
} catch (error) {
|
|
Swal.fire({ icon: 'error', title: '操作失败', text: error.message, target: '#main-content-wrapper' });
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
/**
|
|
* 初始化批量操作模块
|
|
* @param {object} logsPage - LogsPage 类的实例
|
|
*/
|
|
export function initBatchActions(logsPage) {
|
|
logsPageInstance = logsPage;
|
|
|
|
// 查询所有需要的 DOM 元素
|
|
elements.batchActionsBtn = document.getElementById('batch-actions-btn');
|
|
elements.batchActionsMenu = document.getElementById('batch-actions-menu');
|
|
elements.deleteSelectedLogsBtn = document.getElementById('delete-selected-logs-btn');
|
|
elements.clearAllLogsBtn = document.getElementById('clear-all-logs-btn'); // [NEW] 查询新按钮
|
|
|
|
if (!elements.batchActionsBtn) return; // 如果找不到主按钮,则不进行任何操作
|
|
|
|
// 绑定事件监听器
|
|
elements.batchActionsBtn.addEventListener('click', handleBatchActionsToggle);
|
|
if (elements.deleteSelectedLogsBtn) {
|
|
elements.deleteSelectedLogsBtn.addEventListener('click', handleDeleteSelectedLogs);
|
|
}
|
|
if (elements.clearAllLogsBtn) { // [NEW] 绑定新按钮的事件
|
|
elements.clearAllLogsBtn.addEventListener('click', handleClearAllLogs);
|
|
}
|
|
}
|
|
// [NEW] - END
|