// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification // for details on configuring this project to bundle and minify static web assets. // API Base URL (configured server-side) const API_BASE_URL = window.API_BASE_URL || '/api'; // Show toast notification function showToast(message, type = 'info') { const toastContainer = document.getElementById('toastContainer') || createToastContainer(); const toastId = 'toast-' + Date.now(); const bgClass = { 'success': 'bg-success', 'danger': 'bg-danger', 'warning': 'bg-warning', 'info': 'bg-info', 'error': 'bg-danger' }[type] || 'bg-info'; const toastHtml = ` `; toastContainer.insertAdjacentHTML('beforeend', toastHtml); const toastElement = document.getElementById(toastId); const toast = new bootstrap.Toast(toastElement, { delay: 3000 }); toast.show(); toastElement.addEventListener('hidden.bs.toast', () => { toastElement.remove(); }); } function createToastContainer() { const container = document.createElement('div'); container.id = 'toastContainer'; container.className = 'toast-container'; document.body.appendChild(container); return container; } // Show loading spinner function showLoading() { const existingOverlay = document.getElementById('loadingOverlay'); if (existingOverlay) return; const overlay = document.createElement('div'); overlay.id = 'loadingOverlay'; overlay.className = 'spinner-overlay'; overlay.innerHTML = `
Loading...
`; document.body.appendChild(overlay); } // Hide loading spinner function hideLoading() { const overlay = document.getElementById('loadingOverlay'); if (overlay) { overlay.remove(); } } // API call helper async function apiCall(url, options = {}) { const { silent = false, ...fetchOptions } = options; try { if (!silent) { showLoading(); } const response = await fetch(url, { ...fetchOptions, headers: { 'Content-Type': 'application/json', ...fetchOptions.headers } }); if (!response.ok) { const errorData = await response.json().catch(() => ({ error: response.statusText })); throw new Error(errorData.error || `HTTP ${response.status}: ${response.statusText}`); } return await response.json(); } catch (error) { if (!silent) { showToast(error.message, 'error'); } throw error; } finally { if (!silent) { hideLoading(); } } } // Format date function formatDate(dateString) { if (!dateString) return '-'; const date = new Date(dateString); return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }); } // Get status badge class function getStatusBadgeClass(status) { const statusMap = { 'Stopped': 'status-stopped', 'Starting': 'status-starting', 'Running': 'status-running', 'Stopping': 'status-stopping', 'Error': 'status-error' }; return statusMap[status] || 'bg-secondary'; } // Get status text function getStatusText(status) { const statusMap = { 'Stopped': '已停止', 'Starting': '启动中', 'Running': '运行中', 'Stopping': '停止中', 'Error': '错误' }; return statusMap[status] || status; } // Get PLC type text function getPlcTypeText(plcType) { const plcTypeMap = { 'S7200Smart': 'S7-200 Smart', 'S71200': 'S7-1200', 'S71500': 'S7-1500', 'S7300': 'S7-300', 'S7400': 'S7-400' }; return plcTypeMap[plcType] || plcType; } // Confirm action function confirmAction(message, callback) { if (confirm(message)) { callback(); } } // Redirect with delay function redirectWithDelay(url, delay = 1500) { setTimeout(() => { window.location.href = url; }, delay); } // Format bytes function formatBytes(bytes, decimals = 2) { if (bytes === 0) return '0 Bytes'; const k = 1024; const dm = decimals < 0 ? 0 : decimals; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; } // Auto-refresh interval handler let refreshInterval = null; function startAutoRefresh(callback, intervalMs = 5000) { stopAutoRefresh(); callback(); // Initial call refreshInterval = setInterval(callback, intervalMs); } function stopAutoRefresh() { if (refreshInterval) { clearInterval(refreshInterval); refreshInterval = null; } } // Page unload handler window.addEventListener('beforeunload', () => { stopAutoRefresh(); });