// 管理后台JavaScript功能 - 增强版 // 页面加载完成后执行 document.addEventListener('DOMContentLoaded', function() { // 初始化所有工具提示 initTooltips(); // 初始化确认对话框 initConfirmDialogs(); // 初始化表格排序 initTableSorting(); // 初始化状态更新 initStatusUpdates(); // 初始化图片上传 initImageUpload(); // 初始化主题切换 initThemeToggle(); // 初始化动画效果 initAnimations(); }); // 初始化主题切换 function initThemeToggle() { const themeToggle = document.getElementById('themeToggle'); // 检查本地存储的主题设置 const savedTheme = localStorage.getItem('adminTheme') || 'default'; applyTheme(savedTheme); // 设置切换按钮图标 updateThemeToggleIcon(savedTheme); if (themeToggle) { themeToggle.addEventListener('click', function() { const currentTheme = document.body.classList.contains('christmas-theme') ? 'christmas' : 'default'; const newTheme = currentTheme === 'christmas' ? 'default' : 'christmas'; applyTheme(newTheme); localStorage.setItem('adminTheme', newTheme); updateThemeToggleIcon(newTheme); // 添加切换动画 document.body.style.transition = 'all 0.5s ease'; // 显示主题切换提示 const themeName = newTheme === 'christmas' ? '圣诞节主题' : '默认主题'; showAlert(`已切换至${themeName}`, 'success'); }); } } // 应用主题 function applyTheme(theme) { if (theme === 'christmas') { document.body.classList.add('christmas-theme'); } else { document.body.classList.remove('christmas-theme'); } } // 更新主题切换按钮图标 function updateThemeToggleIcon(theme) { const themeToggle = document.getElementById('themeToggle'); if (themeToggle) { const icon = themeToggle.querySelector('i'); if (icon) { if (theme === 'christmas') { icon.className = 'fas fa-snowflake'; } else { icon.className = 'fas fa-palette'; } } } } // 初始化动画效果 function initAnimations() { // 添加滚动动画 const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver(function(entries) { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('animate-in'); observer.unobserve(entry.target); } }); }, observerOptions); // 观察所有卡片 const cards = document.querySelectorAll('.card'); cards.forEach(card => { card.classList.add('animate-prep'); observer.observe(card); }); } // 初始化工具提示 function initTooltips() { const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')); tooltipTriggerList.map(function (tooltipTriggerEl) { return new bootstrap.Tooltip(tooltipTriggerEl); }); } // 初始化确认对话框 function initConfirmDialogs() { // 为所有带有data-confirm属性的按钮添加确认对话框 const confirmButtons = document.querySelectorAll('[data-confirm]'); confirmButtons.forEach(button => { button.addEventListener('click', function(e) { const message = this.getAttribute('data-confirm'); if (!confirm(message)) { e.preventDefault(); return false; } }); }); } // 初始化表格排序 function initTableSorting() { const sortableTables = document.querySelectorAll('.table-sortable'); sortableTables.forEach(table => { const headers = table.querySelectorAll('th[data-sort]'); headers.forEach(header => { header.style.cursor = 'pointer'; header.addEventListener('click', function() { sortTable(table, this.getAttribute('data-sort')); }); }); }); } // 表格排序函数 function sortTable(table, column) { const tbody = table.querySelector('tbody'); const rows = Array.from(tbody.querySelectorAll('tr')); const isAsc = table.getAttribute('data-sort-order') !== 'asc'; rows.sort((a, b) => { const aValue = a.querySelector(`td[data-column="${column}"]`).textContent.trim(); const bValue = b.querySelector(`td[data-column="${column}"]`).textContent.trim(); if (isAsc) { return aValue.localeCompare(bValue); } else { return bValue.localeCompare(aValue); } }); // 清空表格并重新添加排序后的行 tbody.innerHTML = ''; rows.forEach(row => tbody.appendChild(row)); // 更新排序状态 table.setAttribute('data-sort-order', isAsc ? 'asc' : 'desc'); // 更新排序图标 const headers = table.querySelectorAll('th[data-sort]'); headers.forEach(header => { const icon = header.querySelector('.sort-icon'); if (icon) icon.remove(); }); const currentHeader = table.querySelector(`th[data-sort="${column}"]`); const icon = document.createElement('i'); icon.className = `sort-icon fas fa-sort-${isAsc ? 'up' : 'down'} ms-1`; currentHeader.appendChild(icon); } // 初始化状态更新 function initStatusUpdates() { // 定期更新设备状态 const deviceStatusElements = document.querySelectorAll('.device-status'); if (deviceStatusElements.length > 0) { setInterval(updateDeviceStatus, 30000); // 每30秒更新一次 } } // 更新设备状态 function updateDeviceStatus() { const deviceStatusElements = document.querySelectorAll('.device-status[data-device-id]'); deviceStatusElements.forEach(element => { const deviceId = element.getAttribute('data-device-id'); fetch(`/api/devices/${deviceId}/status`) .then(response => response.json()) .then(data => { if (data.online) { element.innerHTML = '在线'; } else { element.innerHTML = '离线'; } }) .catch(error => { console.error('Error updating device status:', error); }); }); } // 初始化图片上传 function initImageUpload() { const uploadArea = document.querySelector('.upload-area'); const fileInput = document.querySelector('#image'); if (uploadArea && fileInput) { // 点击上传区域触发文件选择 uploadArea.addEventListener('click', function() { fileInput.click(); }); // 拖拽上传 ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { uploadArea.addEventListener(eventName, preventDefaults, false); }); function preventDefaults(e) { e.preventDefault(); e.stopPropagation(); } ['dragenter', 'dragover'].forEach(eventName => { uploadArea.addEventListener(eventName, highlight, false); }); ['dragleave', 'drop'].forEach(eventName => { uploadArea.addEventListener(eventName, unhighlight, false); }); function highlight() { uploadArea.classList.add('dragover'); } function unhighlight() { uploadArea.classList.remove('dragover'); } uploadArea.addEventListener('drop', handleDrop, false); function handleDrop(e) { const dt = e.dataTransfer; const files = dt.files; if (files.length) { fileInput.files = files; handleFiles(files); } } fileInput.addEventListener('change', function() { handleFiles(this.files); }); function handleFiles(files) { if (files.length) { const file = files[0]; // 验证文件类型 if (!file.type.startsWith('image/')) { showAlert('请选择图片文件', 'danger'); return; } // 验证文件大小(限制为10MB) if (file.size > 10 * 1024 * 1024) { showAlert('图片文件大小不能超过10MB', 'danger'); return; } // 显示图片预览 const reader = new FileReader(); reader.onload = function(e) { const preview = document.querySelector('#imagePreview'); const previewImg = document.querySelector('#previewImg'); if (preview && previewImg) { previewImg.src = e.target.result; preview.style.display = 'block'; } }; reader.readAsDataURL(file); } } } } // 显示提示消息 function showAlert(message, type = 'info') { const alertContainer = document.querySelector('.alert-container') || createAlertContainer(); const alertElement = document.createElement('div'); alertElement.className = `alert alert-${type} alert-dismissible fade show`; alertElement.setAttribute('role', 'alert'); alertElement.innerHTML = ` ${message} `; alertContainer.appendChild(alertElement); // 自动关闭提示 setTimeout(() => { alertElement.classList.remove('show'); setTimeout(() => { alertElement.remove(); }, 300); }, 5000); } // 创建提示消息容器 function createAlertContainer() { const container = document.createElement('div'); container.className = 'alert-container position-fixed top-0 end-0 p-3'; container.style.zIndex = '1050'; document.body.appendChild(container); return container; } // 推送内容到设备 function pushContent(deviceId, version) { if (confirm('确定要推送此内容到设备吗?')) { const btn = event.target; const originalText = btn.innerHTML; // 显示加载状态 btn.disabled = true; btn.innerHTML = ' 推送中...'; fetch(`/api/devices/${deviceId}/update`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ version: version }) }) .then(response => response.json()) .then(data => { showAlert('内容推送成功', 'success'); }) .catch(error => { console.error('Error:', error); showAlert('内容推送失败', 'danger'); }) .finally(() => { // 恢复按钮状态 btn.disabled = false; btn.innerHTML = originalText; }); } } // 刷新设备状态 function refreshDevice(deviceId) { const btn = event.target; const originalText = btn.innerHTML; // 显示加载状态 btn.disabled = true; btn.innerHTML = ' 刷新中...'; fetch(`/api/devices/${deviceId}/status`) .then(response => response.json()) .then(data => { if (data.online) { showAlert('设备在线', 'success'); } else { showAlert('设备离线', 'warning'); } location.reload(); }) .catch(error => { console.error('Error:', error); showAlert('获取设备状态失败', 'danger'); }) .finally(() => { // 恢复按钮状态 btn.disabled = false; btn.innerHTML = originalText; }); } // 删除设备 function deleteDevice(deviceId) { if (confirm('确定要删除此设备吗?此操作不可恢复!')) { const btn = event.target; const originalText = btn.innerHTML; // 显示加载状态 btn.disabled = true; btn.innerHTML = ' 删除中...'; fetch(`/api/devices/${deviceId}`, { method: 'DELETE' }) .then(response => { if (response.ok) { showAlert('设备删除成功', 'success'); setTimeout(() => { window.location.href = '/admin/devices'; }, 1000); } else { throw new Error('删除失败'); } }) .catch(error => { console.error('Error:', error); showAlert('设备删除失败', 'danger'); }) .finally(() => { // 恢复按钮状态 btn.disabled = false; btn.innerHTML = originalText; }); } } // 删除内容 function deleteContent(deviceId, version) { if (confirm('确定要删除此内容吗?此操作不可恢复!')) { const btn = event.target; const originalText = btn.innerHTML; // 显示加载状态 btn.disabled = true; btn.innerHTML = ' 删除中...'; fetch(`/api/contents/${deviceId}/${version}`, { method: 'DELETE' }) .then(response => { if (response.ok) { showAlert('内容删除成功', 'success'); setTimeout(() => { window.location.href = `/admin/devices/${deviceId}`; }, 1000); } else { throw new Error('删除失败'); } }) .catch(error => { console.error('Error:', error); showAlert('内容删除失败', 'danger'); }) .finally(() => { // 恢复按钮状态 btn.disabled = false; btn.innerHTML = originalText; }); } } // 格式化日期时间 function formatDateTime(dateString) { const date = new Date(dateString); return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }); } // 格式化文件大小 function formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } // 复制文本到剪贴板 function copyToClipboard(text) { const textarea = document.createElement('textarea'); textarea.value = text; document.body.appendChild(textarea); textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); showAlert('已复制到剪贴板', 'success'); } // 添加动画样式 const style = document.createElement('style'); style.textContent = ` .animate-prep { opacity: 0; transform: translateY(20px); transition: opacity 0.6s ease, transform 0.6s ease; } .animate-in { opacity: 1; transform: translateY(0); } `; document.head.appendChild(style);