wanshenmean
2026-03-13 d216edd0e9931d71664f33e625cff6d8131a0fad
Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Web/wwwroot/js/site.js
@@ -1,4 +1,200 @@
// 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.
// Write your JavaScript code.
// 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 = `
        <div id="${toastId}" class="toast align-items-center text-white ${bgClass} border-0" role="alert" aria-live="assertive" aria-atomic="true">
            <div class="d-flex">
                <div class="toast-body">
                    ${message}
                </div>
                <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
            </div>
        </div>
    `;
    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 = `
        <div class="spinner-border text-light" style="width: 3rem; height: 3rem;" role="status">
            <span class="visually-hidden">Loading...</span>
        </div>
    `;
    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();
});