// 智慧河道管理平台 - JavaScript 主文件 // 全局变量 let map; let currentTab = 'monitor'; let workorderData = []; let deviceData = []; let warningData = []; let dashboardData = { realTimeStatus: { online: 12, warning: 3, processing: 2 }, waterQuality: { excellent: 8, good: 4, warning: 1 }, efficiency: { daily: 85, weekly: 78, monthly: 82 }, alerts: [ {id: 1, type: 'high', title: '水质异常', desc: '湘江中路段检测到污染物超标', time: '2分钟前'}, {id: 2, type: 'medium', title: '设备故障', desc: '橘子洲头摄像头离线', time: '15分钟前'}, {id: 3, type: 'low', title: '清理完成', desc: '杜甫江阁段垃圾清理完毕', time: '1小时前'} ], envData: { temperature: 24, windSpeed: 3.2, visibility: 8.5 } }; // 初始化应用 document.addEventListener('DOMContentLoaded', function() { // The initializeApp function will be called by onTdtMapApiLoaded }); function initializeApp() { initializeNavigation(); initializeDashboard(); initializeTime(); initializeMap(); initializeCharts(); startRealTimeUpdates(); // 初始化其他模块 initializeWorkorder(); initializeDevice(); initializeWarning(); initializeStatistics(); // 启用大屏模式 enableFullscreenMode(); } function onTdtMapApiLoaded() { window.T = T; // Expose T to the global scope initializeApp(); } // 初始化大屏仪表板 function initializeDashboard() { updateRealTimeStatus(); updateWaterQuality(); updateEfficiencyStats(); updateAlerts(); updateEnvironmentData(); updateWeatherInfo(); } // 导航系统 function initializeNavigation() { const navButtons = document.querySelectorAll('.nav-btn'); const tabContents = document.querySelectorAll('.tab-content'); navButtons.forEach(button => { button.addEventListener('click', function() { const targetTab = this.getAttribute('data-tab'); switchTab(targetTab); }); }); } function switchTab(tabName) { // 如果已经是当前标签页,则不执行任何操作 if (currentTab === tabName) return; // 更新导航按钮状态 document.querySelectorAll('.nav-btn').forEach(btn => { btn.classList.remove('active'); }); document.querySelector(`[data-tab="${tabName}"]`).classList.add('active'); // 更新内容区域 document.querySelectorAll('.tab-content').forEach(content => { content.classList.remove('active'); }); document.getElementById(tabName).classList.add('active'); currentTab = tabName; // 大屏模式控制 if (tabName === 'monitor') { enableFullscreenMode(); } else { disableFullscreenMode(); } // 根据不同标签页执行特定初始化 switch(tabName) { case 'monitor': if (map) { setTimeout(() => map.invalidateSize(), 100); } // 刷新监控管理一张图的图表 refreshMonitorCharts(); break; case 'workorder': refreshWorkorderTable(); break; case 'device': refreshDeviceGrid(); break; case 'warning': refreshWarningData(); break; case 'statistics': refreshCharts(); break; } } // 启用大屏模式 function enableFullscreenMode() { document.body.classList.add('fullscreen-mode'); // 添加ESC键退出大屏模式的监听 document.addEventListener('keydown', handleEscapeKey); } // 禁用大屏模式 function disableFullscreenMode() { document.body.classList.remove('fullscreen-mode'); document.removeEventListener('keydown', handleEscapeKey); } // 处理ESC键退出大屏模式 function handleEscapeKey(event) { if (event.key === 'Escape' && document.body.classList.contains('fullscreen-mode')) { // 切换到统计分析页面 switchTab('statistics'); } } // 添加大屏模式切换按钮功能 function toggleFullscreenMode() { if (document.body.classList.contains('fullscreen-mode')) { disableFullscreenMode(); } else { enableFullscreenMode(); } } // 时间显示 function initializeTime() { updateTime(); setInterval(updateTime, 1000); } function updateTime() { const now = new Date(); const timeString = now.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }); const datetimeElement = document.getElementById('datetime'); if (datetimeElement) { datetimeElement.textContent = timeString; } } // 更新实时状态 function updateRealTimeStatus() { const statusGrid = document.querySelector('.status-grid'); if (!statusGrid) return; const statusData = dashboardData.realTimeStatus; const statusCards = [ {key: 'online', label: '在线设备', value: statusData.online, class: 'online'}, {key: 'warning', label: '告警设备', value: statusData.warning, class: 'warning'}, {key: 'processing', label: '处理中', value: statusData.processing, class: 'processing'} ]; statusGrid.innerHTML = statusCards.map(card => `
${card.value}
${card.label}
`).join(''); } // 更新水质监测 function updateWaterQuality() { const qualityData = dashboardData.waterQuality; const qualityItems = document.querySelectorAll('.quality-item'); const items = [ {element: qualityItems[0], key: 'excellent', label: '优秀', class: 'excellent'}, {element: qualityItems[1], key: 'good', label: '良好', class: 'good'}, {element: qualityItems[2], key: 'warning', label: '预警', class: 'warning'} ]; items.forEach(item => { if (item.element) { item.element.className = `quality-item ${item.class}`; item.element.innerHTML = `
${qualityData[item.key]}
${item.label}
监测点
`; } }); } // 更新清理效率统计 function updateEfficiencyStats() { const efficiencyData = dashboardData.efficiency; const statRows = document.querySelectorAll('.stat-row'); const stats = [ {element: statRows[0], label: '日清理率', value: efficiencyData.daily}, {element: statRows[1], label: '周清理率', value: efficiencyData.weekly}, {element: statRows[2], label: '月清理率', value: efficiencyData.monthly} ]; stats.forEach(stat => { if (stat.element) { stat.element.innerHTML = ` ${stat.label} ${stat.value}% `; } }); } // 更新告警信息 function updateAlerts() { const alertList = document.querySelector('.alert-list'); if (!alertList) return; const alerts = dashboardData.alerts; alertList.innerHTML = alerts.map(alert => `
${alert.title}
${alert.desc}
${alert.time}
`).join(''); } // 更新环境数据 function updateEnvironmentData() { const envData = dashboardData.envData; const envItems = document.querySelectorAll('.env-item'); const items = [ {element: envItems[0], icon: 'thermometer-half', label: '水温', value: envData.temperature, unit: '°C'}, {element: envItems[1], icon: 'wind', label: '风速', value: envData.windSpeed, unit: 'm/s'}, {element: envItems[2], icon: 'eye', label: '能见度', value: envData.visibility, unit: 'km'} ]; items.forEach(item => { if (item.element) { item.element.innerHTML = `
${item.label}
${item.value}${item.unit}
`; } }); } // 更新天气信息 function updateWeatherInfo() { const weatherElement = document.getElementById('weather'); if (weatherElement) { weatherElement.innerHTML = ` 晴 24°C `; } } // 地图系统 function initializeMap() { // 初始化天地图 const mapElement = document.getElementById('map'); if (!mapElement) return; map = new T.Map('map'); const point = new T.LngLat(112.9388, 28.2282); // 长沙坐标 map.centerAndZoom(point, 12); // 启用地图功能 map.enableScrollWheelZoom(); map.addControl(new T.Control.Zoom()); map.addControl(new T.Control.Scale()); map.addControl(new T.Control.MapType()); // 添加湘江河道轮廓 addRiverOverlay(); // 添加设备标记 addDeviceMarkers(); // 添加垃圾污染点 addGarbageMarkers(); // 地图控制事件 const toggleLayerBtn = document.getElementById('toggleLayer'); const fullscreenBtn = document.getElementById('fullscreen'); if (toggleLayerBtn) { toggleLayerBtn.addEventListener('click', toggleMapLayers); } if (fullscreenBtn) { fullscreenBtn.addEventListener('click', toggleFullscreen); } } // 初始化图表 function initializeCharts() { initializeTrendChart(); initializeMonitorCharts(); } // 初始化趋势图表 function initializeTrendChart() { const canvas = document.getElementById('trendChart'); if (!canvas) return; // 销毁已存在的图表实例 destroyChart('trendChart'); const ctx = canvas.getContext('2d'); // 创建渐变 const gradient1 = ctx.createLinearGradient(0, 0, 0, 200); gradient1.addColorStop(0, 'rgba(255, 68, 68, 0.3)'); gradient1.addColorStop(1, 'rgba(255, 68, 68, 0)'); const gradient2 = ctx.createLinearGradient(0, 0, 0, 200); gradient2.addColorStop(0, 'rgba(0, 212, 255, 0.3)'); gradient2.addColorStop(1, 'rgba(0, 212, 255, 0)'); const gradient3 = ctx.createLinearGradient(0, 0, 0, 200); gradient3.addColorStop(0, 'rgba(0, 255, 136, 0.3)'); gradient3.addColorStop(1, 'rgba(0, 255, 136, 0)'); window.chartInstances['trendChart'] = new Chart(ctx, { type: 'line', data: { labels: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00'], datasets: [{ label: '告警数量', data: [12, 8, 15, 6, 10, 4], borderColor: '#ff4444', backgroundColor: gradient1, borderWidth: 2, fill: true, tension: 0.4 }, { label: '处理数量', data: [8, 12, 10, 18, 14, 16], borderColor: '#00d4ff', backgroundColor: gradient2, borderWidth: 2, fill: true, tension: 0.4 }, { label: '完成数量', data: [6, 10, 8, 15, 12, 14], borderColor: '#00ff88', backgroundColor: gradient3, borderWidth: 2, fill: true, tension: 0.4 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } }, scales: { x: { grid: { color: 'rgba(255, 255, 255, 0.1)' }, ticks: { color: '#b0c4de', font: { size: 10 } } }, y: { grid: { color: 'rgba(255, 255, 255, 0.1)' }, ticks: { color: '#b0c4de', font: { size: 10 } } } }, elements: { point: { radius: 3, hoverRadius: 6 } } } }); } // 开始实时更新 function startRealTimeUpdates() { // 每30秒更新一次数据 setInterval(() => { updateDashboardData(); updateChartData(); }, 30000); } // 更新仪表板数据 function updateDashboardData() { // 模拟数据变化 dashboardData.realTimeStatus.online += Math.floor(Math.random() * 3) - 1; dashboardData.realTimeStatus.warning += Math.floor(Math.random() * 2) - 1; dashboardData.realTimeStatus.processing += Math.floor(Math.random() * 2) - 1; // 确保数据在合理范围内 dashboardData.realTimeStatus.online = Math.max(8, Math.min(15, dashboardData.realTimeStatus.online)); dashboardData.realTimeStatus.warning = Math.max(0, Math.min(5, dashboardData.realTimeStatus.warning)); dashboardData.realTimeStatus.processing = Math.max(0, Math.min(5, dashboardData.realTimeStatus.processing)); // 更新环境数据 dashboardData.envData.temperature += (Math.random() - 0.5) * 2; dashboardData.envData.windSpeed += (Math.random() - 0.5) * 1; dashboardData.envData.visibility += (Math.random() - 0.5) * 2; // 确保环境数据在合理范围内 dashboardData.envData.temperature = Math.max(15, Math.min(35, dashboardData.envData.temperature)); dashboardData.envData.windSpeed = Math.max(0, Math.min(10, dashboardData.envData.windSpeed)); dashboardData.envData.visibility = Math.max(3, Math.min(15, dashboardData.envData.visibility)); // 更新界面 updateRealTimeStatus(); updateEnvironmentData(); } // 更新图表数据 function updateChartData() { if (window.chartInstances.trendChart) { const datasets = window.chartInstances.trendChart.data.datasets; datasets.forEach(dataset => { // 移除第一个数据点,添加新的数据点 dataset.data.shift(); dataset.data.push(Math.floor(Math.random() * 20) + 5); }); window.chartInstances.trendChart.update('none'); } } function addRiverOverlay() { // 湘江长沙段轮廓(简化坐标) const riverPoints = [ new T.LngLat(112.9200, 28.3000), new T.LngLat(112.9300, 28.2800), new T.LngLat(112.9400, 28.2600), new T.LngLat(112.9500, 28.2400), new T.LngLat(112.9600, 28.2200), new T.LngLat(112.9700, 28.2000), new T.LngLat(112.9800, 28.1800) ]; const polyline = new T.Polyline(riverPoints, { color: '#3498db', weight: 8, opacity: 0.7 }); map.addOverLay(polyline); // 添加信息窗口 const infoWindow = new T.InfoWindow(); infoWindow.setContent('湘江长沙段'); polyline.addEventListener('click', function() { infoWindow.openInfoWindow(map, riverPoints[Math.floor(riverPoints.length/2)]); }); } function addDeviceMarkers() { // 摄像头标记 const cameras = [ {lat: 28.2282, lng: 112.9388, name: '摄像头01-橘子洲头', status: 'online'}, {lat: 28.2150, lng: 112.9450, name: '摄像头02-杜甫江阁', status: 'online'}, {lat: 28.2400, lng: 112.9300, name: '摄像头03-湘江中路', status: 'warning'}, {lat: 28.2600, lng: 112.9200, name: '摄像头04-猴子石大桥', status: 'online'} ]; cameras.forEach(camera => { const point = new T.LngLat(camera.lng, camera.lat); const marker = new T.Marker(point); // 创建自定义图标 const icon = new T.Icon({ iconUrl: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(` `)}`, iconSize: new T.Point(30, 30) }); marker.setIcon(icon); map.addOverLay(marker); const infoWindow = new T.InfoWindow(); infoWindow.setContent(`${camera.name}
状态: ${getStatusText(camera.status)}`); marker.addEventListener('click', function() { infoWindow.openInfoWindow(map, point); }); }); // 无人船标记 const ships = [ {lat: 28.2200, lng: 112.9400, name: '无人船01', status: 'working'}, {lat: 28.2500, lng: 112.9350, name: '无人船02', status: 'working'}, {lat: 28.2350, lng: 112.9420, name: '无人船03', status: 'idle'} ]; ships.forEach(ship => { const point = new T.LngLat(ship.lng, ship.lat); const marker = new T.Marker(point); const icon = new T.Icon({ iconUrl: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(` `)}`, iconSize: new T.Point(30, 30) }); marker.setIcon(icon); map.addOverLay(marker); const infoWindow = new T.InfoWindow(); infoWindow.setContent(`${ship.name}
状态: ${getStatusText(ship.status)}`); marker.addEventListener('click', function() { infoWindow.openInfoWindow(map, point); }); }); // 无人机标记 const drones = [ {lat: 28.2300, lng: 112.9380, name: '无人机01', status: 'flying'}, {lat: 28.2450, lng: 112.9320, name: '无人机02', status: 'charging'} ]; drones.forEach(drone => { const point = new T.LngLat(drone.lng, drone.lat); const marker = new T.Marker(point); const icon = new T.Icon({ iconUrl: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(` `)}`, iconSize: new T.Point(30, 30) }); marker.setIcon(icon); map.addOverLay(marker); const infoWindow = new T.InfoWindow(); infoWindow.setContent(`${drone.name}
状态: ${getStatusText(drone.status)}`); marker.addEventListener('click', function() { infoWindow.openInfoWindow(map, point); }); }); } function addGarbageMarkers() { const garbagePoints = [ {lat: 28.2250, lng: 112.9410, type: 'water', severity: 'high', description: '大量漂浮垃圾'}, {lat: 28.2180, lng: 112.9460, type: 'beach', severity: 'medium', description: '滩涂堆积物'}, {lat: 28.2420, lng: 112.9330, type: 'water', severity: 'low', description: '少量枯枝'}, {lat: 28.2380, lng: 112.9390, type: 'illegal', severity: 'high', description: '违法倾倒点'} ]; garbagePoints.forEach(point => { const mapPoint = new T.LngLat(point.lng, point.lat); const marker = new T.Marker(mapPoint); const icon = new T.Icon({ iconUrl: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(` `)}`, iconSize: new T.Point(25, 25) }); marker.setIcon(icon); map.addOverLay(marker); const infoWindow = new T.InfoWindow(); infoWindow.setContent(`${point.description}
类型: ${getTypeText(point.type)}
严重程度: ${point.severity}`); marker.addEventListener('click', function() { infoWindow.openInfoWindow(map, mapPoint); }); }); } function getStatusColor(status) { const colors = { 'online': '#2ecc71', 'offline': '#e74c3c', 'warning': '#f39c12', 'working': '#3498db', 'idle': '#95a5a6', 'flying': '#9b59b6', 'charging': '#f1c40f' }; return colors[status] || '#95a5a6'; } function getStatusText(status) { const texts = { 'online': '在线', 'offline': '离线', 'warning': '警告', 'working': '作业中', 'idle': '待机', 'flying': '飞行中', 'charging': '充电中' }; return texts[status] || '未知'; } function getSeverityColor(severity) { const colors = { 'high': '#e74c3c', 'medium': '#f39c12', 'low': '#f1c40f' }; return colors[severity] || '#95a5a6'; } function getTypeText(type) { const texts = { 'water': '水面垃圾', 'beach': '滩涂垃圾', 'illegal': '违法倾倒' }; return texts[type] || '未知'; } function toggleMapLayers() { // 图层切换逻辑 console.log('切换地图图层'); } function toggleFullscreen() { const mapContainer = document.querySelector('.map-container'); if (!document.fullscreenElement) { mapContainer.requestFullscreen().then(() => { setTimeout(() => map.invalidateSize(), 100); }); } else { document.exitFullscreen(); } } // 工单系统 function initializeWorkorderSystem() { // 创建工单按钮 document.getElementById('createWorkorder').addEventListener('click', showCreateWorkorderModal); // 导出数据按钮 document.getElementById('exportWorkorder').addEventListener('click', exportWorkorderData); // 筛选器事件 document.querySelectorAll('.filter-select').forEach(select => { select.addEventListener('change', filterWorkorders); }); // 搜索框事件 document.querySelector('.search-input').addEventListener('input', searchWorkorders); // 初始化工单表格 refreshWorkorderTable(); } function showCreateWorkorderModal() { const modalBody = document.getElementById('modalBody'); modalBody.innerHTML = ` `; document.getElementById('modal').style.display = 'block'; // 表单提交事件 document.getElementById('createWorkorderForm').addEventListener('submit', function(e) { e.preventDefault(); createWorkorder(new FormData(this)); }); } function createWorkorder(formData) { const workorder = { id: 'WO' + Date.now(), type: formData.get('type'), location: formData.get('location'), severity: formData.get('severity'), description: formData.get('description'), status: 'pending', assignee: '待分配', createTime: new Date().toLocaleString('zh-CN'), discoveryMethod: '手动创建' }; workorderData.unshift(workorder); refreshWorkorderTable(); closeModal(); showNotification('工单创建成功', 'success'); } function refreshWorkorderTable() { const tbody = document.getElementById('workorderTableBody'); if (!tbody) return; tbody.innerHTML = ''; workorderData.forEach(workorder => { const row = document.createElement('tr'); row.innerHTML = ` ${workorder.id} ${getTypeText(workorder.type)} ${workorder.location} ${workorder.discoveryMethod} ${getStatusText(workorder.status)} ${workorder.assignee} ${workorder.createTime} `; tbody.appendChild(row); }); } function getStatusBadgeClass(status) { const classes = { 'pending': 'warning', 'processing': 'info', 'completed': 'success', 'cancelled': 'danger' }; return classes[status] || 'secondary'; } function filterWorkorders() { // 筛选逻辑 refreshWorkorderTable(); } function searchWorkorders() { // 搜索逻辑 refreshWorkorderTable(); } function exportWorkorderData() { // 导出数据逻辑 console.log('导出工单数据'); showNotification('数据导出成功', 'success'); } function viewWorkorder(id) { const workorder = workorderData.find(w => w.id === id); if (!workorder) return; const modalBody = document.getElementById('modalBody'); modalBody.innerHTML = `

工单详情 - ${workorder.id}

${getTypeText(workorder.type)}
${workorder.location}
${getStatusText(workorder.status)}
${workorder.assignee}
${workorder.createTime}
${workorder.description || '无'}
`; document.getElementById('modal').style.display = 'block'; } function editWorkorder(id) { // 编辑工单逻辑 console.log('编辑工单:', id); } // 设备管理 function initializeDeviceManagement() { // 添加设备按钮 document.getElementById('addDevice').addEventListener('click', showAddDeviceModal); // 维护计划按钮 document.getElementById('deviceMaintenance').addEventListener('click', showMaintenanceModal); // 设备分类切换 document.querySelectorAll('.category-card').forEach(card => { card.addEventListener('click', function() { document.querySelectorAll('.category-card').forEach(c => c.classList.remove('active')); this.classList.add('active'); filterDevicesByCategory(this.getAttribute('data-category')); }); }); // 初始化设备网格 refreshDeviceGrid(); } function showAddDeviceModal() { const modalBody = document.getElementById('modalBody'); modalBody.innerHTML = ` `; document.getElementById('modal').style.display = 'block'; document.getElementById('addDeviceForm').addEventListener('submit', function(e) { e.preventDefault(); addDevice(new FormData(this)); }); } function addDevice(formData) { const device = { id: 'DEV' + Date.now(), category: formData.get('category'), name: formData.get('name'), model: formData.get('model'), location: formData.get('location'), status: 'online', battery: Math.floor(Math.random() * 100), lastMaintenance: new Date().toLocaleDateString('zh-CN'), installDate: new Date().toLocaleDateString('zh-CN') }; deviceData.push(device); refreshDeviceGrid(); closeModal(); showNotification('设备添加成功', 'success'); } function refreshDeviceGrid() { const grid = document.getElementById('deviceGrid'); if (!grid) return; grid.innerHTML = ''; deviceData.forEach(device => { const card = document.createElement('div'); card.className = 'device-card'; card.innerHTML = `

${device.name}

${device.model}
${getStatusText(device.status)}
位置: ${device.location}
电量: ${device.battery}%
上次维护: ${device.lastMaintenance}
`; grid.appendChild(card); }); } function getDeviceIcon(category) { const icons = { 'camera': 'fa-video', 'ship': 'fa-ship', 'drone': 'fa-helicopter', 'sensor': 'fa-satellite-dish' }; return icons[category] || 'fa-cog'; } function filterDevicesByCategory(category) { // 设备分类筛选逻辑 refreshDeviceGrid(); } function viewDevice(id) { const device = deviceData.find(d => d.id === id); if (!device) return; const modalBody = document.getElementById('modalBody'); modalBody.innerHTML = `

设备详情 - ${device.name}

${device.id}
${getCategoryText(device.category)}
${device.model}
${device.location}
${getStatusText(device.status)}
${device.battery}%
${device.installDate}
${device.lastMaintenance}
`; document.getElementById('modal').style.display = 'block'; } function getCategoryText(category) { const texts = { 'camera': '智能摄像头', 'ship': '无人船', 'drone': '无人机', 'sensor': '传感器' }; return texts[category] || '未知'; } function controlDevice(id) { console.log('控制设备:', id); showNotification('设备控制指令已发送', 'info'); } function maintainDevice(id) { console.log('维护设备:', id); showNotification('维护任务已创建', 'success'); } function showMaintenanceModal() { const modalBody = document.getElementById('modalBody'); modalBody.innerHTML = ` `; document.getElementById('modal').style.display = 'block'; } // 预警系统 function initializeWarningSystem() { // 预警设置按钮 document.getElementById('warningSettings').addEventListener('click', showWarningSettingsModal); // 历史记录按钮 document.getElementById('warningHistory').addEventListener('click', showWarningHistoryModal); // 初始化预警数据 refreshWarningData(); } function refreshWarningData() { // 更新天气信息 updateWeatherInfo(); // 更新垃圾堆积预警 updateGarbageAlerts(); // 更新设备故障预警 updateDeviceAlerts(); } function updateWeatherInfo() { // 模拟天气数据更新 const weatherItems = document.querySelectorAll('.weather-item .weather-value'); if (weatherItems.length >= 3) { weatherItems[0].textContent = '多云 ' + (20 + Math.floor(Math.random() * 10)) + '°C'; weatherItems[1].textContent = Math.floor(Math.random() * 5 + 1) + '级'; weatherItems[2].textContent = Math.floor(Math.random() * 100) + '%'; } } function updateGarbageAlerts() { // 更新垃圾堆积预警数据 console.log('更新垃圾堆积预警'); } function updateDeviceAlerts() { // 更新设备故障预警数据 console.log('更新设备故障预警'); } function showWarningSettingsModal() { const modalBody = document.getElementById('modalBody'); modalBody.innerHTML = ` `; document.getElementById('modal').style.display = 'block'; document.getElementById('warningSettingsForm').addEventListener('submit', function(e) { e.preventDefault(); saveWarningSettings(new FormData(this)); }); } function saveWarningSettings(formData) { // 保存预警设置 console.log('保存预警设置'); closeModal(); showNotification('预警设置已保存', 'success'); } function showWarningHistoryModal() { const modalBody = document.getElementById('modalBody'); modalBody.innerHTML = ` `; document.getElementById('modal').style.display = 'block'; } // 统计分析事件绑定 function bindStatisticsEvents() { // 时间范围选择 const timeRangeSelect = document.querySelector('.time-range'); if (timeRangeSelect) { timeRangeSelect.addEventListener('change', function() { refreshCharts(); }); } // 导出报告按钮 const exportBtn = document.getElementById('exportReport'); if (exportBtn) { exportBtn.addEventListener('click', exportReport); } } // 重复的chart初始化代码已被完全移除 // 现在统计分析页面的charts由setupStatisticsCharts()函数统一管理 // 初始化监控管理一张图的图表 function initializeMonitorCharts() { // 垃圾清理统计柱状图 const cleanupChartCtx = document.getElementById('cleanupChart'); if (cleanupChartCtx) { // 销毁已存在的图表实例 destroyChart('cleanupStats'); window.chartInstances.cleanupStats = new Chart(cleanupChartCtx, { type: 'bar', data: { labels: ['今日', '昨日', '本周', '上周', '本月'], datasets: [{ label: '清理量(kg)', data: [156, 142, 1200, 980, 4500], backgroundColor: [ 'rgba(52, 152, 219, 0.8)', 'rgba(46, 204, 113, 0.8)', 'rgba(155, 89, 182, 0.8)', 'rgba(241, 196, 15, 0.8)', 'rgba(231, 76, 60, 0.8)' ], borderColor: [ '#3498db', '#2ecc71', '#9b59b6', '#f1c40f', '#e74c3c' ], borderWidth: 2 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } }, scales: { x: { ticks: { color: '#b0c4de', font: { size: 10 } }, grid: { color: 'rgba(176, 196, 222, 0.1)' } }, y: { beginAtZero: true, ticks: { color: '#b0c4de', font: { size: 10 } }, grid: { color: 'rgba(176, 196, 222, 0.1)' } } } } }); } // 实时数据趋势线图 const trendChartCtx = document.getElementById('trendChart'); if (trendChartCtx) { // 销毁已存在的图表实例 destroyChart('trendChart'); window.chartInstances['trendChart'] = new Chart(trendChartCtx, { type: 'line', data: { labels: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00', '24:00'], datasets: [ { label: '垃圾检测数量', data: [5, 3, 8, 12, 15, 9, 6], borderColor: '#e74c3c', backgroundColor: 'rgba(231, 76, 60, 0.1)', tension: 0.4, fill: false }, { label: '清理完成数量', data: [3, 2, 6, 10, 13, 8, 5], borderColor: '#3498db', backgroundColor: 'rgba(52, 152, 219, 0.1)', tension: 0.4, fill: false }, { label: '设备在线率(%)', data: [95, 92, 98, 96, 94, 97, 95], borderColor: '#2ecc71', backgroundColor: 'rgba(46, 204, 113, 0.1)', tension: 0.4, fill: false, yAxisID: 'y1' } ] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } }, scales: { x: { ticks: { color: '#b0c4de', font: { size: 9 } }, grid: { color: 'rgba(176, 196, 222, 0.1)' } }, y: { type: 'linear', display: true, position: 'left', beginAtZero: true, ticks: { color: '#b0c4de', font: { size: 9 } }, grid: { color: 'rgba(176, 196, 222, 0.1)' } }, y1: { type: 'linear', display: true, position: 'right', min: 0, max: 100, ticks: { color: '#b0c4de', font: { size: 9 } }, grid: { drawOnChartArea: false } } } } }); } } function refreshCharts() { // 刷新所有图表数据 Object.values(window.chartInstances).forEach(chart => { if (chart && chart.update) { chart.update(); } }); } // 刷新监控管理一张图的图表 function refreshMonitorCharts() { // 更新垃圾清理统计数据 if (window.chartInstances.cleanupStats) { const newData = { labels: ['今日', '昨日', '本周', '上周', '本月'], datasets: [{ label: '清理量(kg)', data: [ Math.floor(Math.random() * 50) + 130, // 今日: 130-180 Math.floor(Math.random() * 40) + 120, // 昨日: 120-160 Math.floor(Math.random() * 400) + 1000, // 本周: 1000-1400 Math.floor(Math.random() * 300) + 800, // 上周: 800-1100 Math.floor(Math.random() * 1000) + 4000 // 本月: 4000-5000 ], backgroundColor: [ 'rgba(52, 152, 219, 0.8)', 'rgba(46, 204, 113, 0.8)', 'rgba(155, 89, 182, 0.8)', 'rgba(241, 196, 15, 0.8)', 'rgba(231, 76, 60, 0.8)' ], borderColor: [ '#3498db', '#2ecc71', '#9b59b6', '#f1c40f', '#e74c3c' ], borderWidth: 2 }] }; window.chartInstances.cleanupStats.data = newData; window.chartInstances.cleanupStats.update(); } // 更新实时数据趋势 if (window.chartInstances.trendStats) { const currentHour = new Date().getHours(); const timeLabels = []; const detectionData = []; const cleanupData = []; const onlineRateData = []; // 生成过去24小时的数据 for (let i = 6; i >= 0; i--) { const hour = (currentHour - i * 4 + 24) % 24; timeLabels.push(String(hour).padStart(2, '0') + ':00'); detectionData.push(Math.floor(Math.random() * 10) + 3); cleanupData.push(Math.floor(Math.random() * 8) + 2); onlineRateData.push(Math.floor(Math.random() * 8) + 92); } window.chartInstances.trendStats.data.labels = timeLabels; window.chartInstances.trendStats.data.datasets[0].data = detectionData; window.chartInstances.trendStats.data.datasets[1].data = cleanupData; window.chartInstances.trendStats.data.datasets[2].data = onlineRateData; window.chartInstances.trendStats.update(); } } function exportReport() { console.log('导出统计报告'); showNotification('报告导出成功', 'success'); } // 模态框系统 function initializeModal() { const modal = document.getElementById('modal'); const closeBtn = document.querySelector('.close'); // 点击关闭按钮 closeBtn.addEventListener('click', closeModal); // 点击模态框外部关闭 window.addEventListener('click', function(event) { if (event.target === modal) { closeModal(); } }); // ESC键关闭 document.addEventListener('keydown', function(event) { if (event.key === 'Escape') { closeModal(); } }); } function closeModal() { document.getElementById('modal').style.display = 'none'; } // 通知系统 function showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.className = `notification ${type}`; notification.innerHTML = `
${message}
`; // 添加样式 notification.style.cssText = ` position: fixed; top: 100px; right: 20px; background: white; border-radius: 8px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); padding: 1rem; z-index: 2001; display: flex; align-items: center; justify-content: space-between; min-width: 300px; border-left: 4px solid ${getNotificationColor(type)}; animation: slideInRight 0.3s ease; `; document.body.appendChild(notification); // 自动移除 setTimeout(() => { if (notification.parentElement) { notification.remove(); } }, 5000); } function getNotificationIcon(type) { const icons = { 'success': 'fa-check-circle', 'error': 'fa-exclamation-circle', 'warning': 'fa-exclamation-triangle', 'info': 'fa-info-circle' }; return icons[type] || 'fa-info-circle'; } function getNotificationColor(type) { const colors = { 'success': '#2ecc71', 'error': '#e74c3c', 'warning': '#f39c12', 'info': '#3498db' }; return colors[type] || '#3498db'; } // 数据加载 function loadMockData() { // 加载模拟工单数据 workorderData = [ { id: 'WO202401001', type: 'water', location: '橘子洲头弯道', discoveryMethod: 'AI自动识别', status: 'processing', assignee: '张三', createTime: '2024-01-10 09:30:00', description: '发现大量漂浮垃圾' }, { id: 'WO202401002', type: 'beach', location: '湘江中路段滩涂', discoveryMethod: '巡查员上报', status: 'completed', assignee: '李四', createTime: '2024-01-09 14:15:00', description: '滩涂堆积物清理' }, { id: 'WO202401003', type: 'illegal', location: '猴子石大桥下', discoveryMethod: '公众反馈', status: 'pending', assignee: '待分配', createTime: '2024-01-11 16:45:00', description: '疑似违法倾倒垃圾' } ]; // 加载模拟设备数据 deviceData = [ { id: 'CAM001', category: 'camera', name: '摄像头01', model: 'HC-AI-8000', location: '橘子洲头', status: 'online', battery: 95, lastMaintenance: '2024-01-01', installDate: '2023-06-15' }, { id: 'SHIP001', category: 'ship', name: '无人船01', model: 'AS-3500', location: '湘江中段', status: 'working', battery: 78, lastMaintenance: '2024-01-05', installDate: '2023-08-20' }, { id: 'DRONE001', category: 'drone', name: '无人机01', model: 'DJI-M300', location: '监控中心', status: 'charging', battery: 45, lastMaintenance: '2024-01-08', installDate: '2023-09-10' } ]; } // 实时数据更新 function startRealTimeUpdates() { // 每30秒更新一次实时数据 setInterval(() => { updateRealTimeData(); }, 30000); } function updateRealTimeData() { // 更新设备状态 deviceData.forEach(device => { // 随机更新电池电量 if (device.status === 'working' || device.status === 'flying') { device.battery = Math.max(0, device.battery - Math.floor(Math.random() * 3)); } else if (device.status === 'charging') { device.battery = Math.min(100, device.battery + Math.floor(Math.random() * 5)); } }); // 如果当前在设备管理页面,刷新显示 if (currentTab === 'device') { refreshDeviceGrid(); } // 更新地图标记 if (map && currentTab === 'monitor') { // 这里可以添加地图标记更新逻辑 } // 更新预警数据 if (currentTab === 'warning') { refreshWarningData(); } } // 工具函数 function formatDate(date) { return new Date(date).toLocaleDateString('zh-CN'); } function formatDateTime(date) { return new Date(date).toLocaleString('zh-CN'); } function generateId(prefix = 'ID') { return prefix + Date.now() + Math.floor(Math.random() * 1000); } function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } function throttle(func, limit) { let inThrottle; return function() { const args = arguments; const context = this; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } } } // 错误处理 window.addEventListener('error', function(event) { console.error('JavaScript错误:', event.error); showNotification('系统发生错误,请刷新页面重试', 'error'); }); // 网络状态监测 window.addEventListener('online', function() { showNotification('网络连接已恢复', 'success'); }); window.addEventListener('offline', function() { showNotification('网络连接已断开', 'warning'); }); // 页面可见性变化处理 document.addEventListener('visibilitychange', function() { if (document.hidden) { // 页面隐藏时暂停某些更新 console.log('页面隐藏,暂停实时更新'); } else { // 页面显示时恢复更新 console.log('页面显示,恢复实时更新'); updateRealTimeData(); } }); // 工单系统初始化 function initializeWorkorder() { loadWorkorderData(); setupWorkorderEvents(); } // 设备管理初始化 function initializeDevice() { loadDeviceData(); setupDeviceEvents(); } // 告警系统初始化 function initializeWarning() { loadWarningData(); setupWarningEvents(); } // 统计分析初始化 function initializeStatistics() { loadStatisticsData(); bindStatisticsEvents(); setupStatisticsCharts(); } // 加载工单数据 function loadWorkorderData() { const workorderTableBody = document.getElementById('workorderTableBody'); if (!workorderTableBody) return; const workorders = [ {id: 'WO001', type: '垃圾清理', location: '黄浦江段A区', method: '无人机发现', status: 'created', assignee: '张三', createTime: '2024-01-15 09:30', priority: '高', responseTime: '2024-01-15 11:30'}, {id: 'WO002', type: '水质异常', location: '苏州河段B区', method: '传感器监测', status: 'assigned', assignee: '李四', createTime: '2024-01-15 10:15', priority: '中', responseTime: '2024-01-15 14:15'}, {id: 'WO003', type: '设备维护', location: '黄浦江段C区', method: '定期巡检', status: 'completed', assignee: '王五', createTime: '2024-01-14 14:20', priority: '低', responseTime: '2024-01-15 02:20'}, {id: 'WO004', type: '垃圾清理', location: '苏州河段D区', method: '市民举报', status: 'dispatched', assignee: '赵六', createTime: '2024-01-15 11:45', priority: '高', responseTime: '2024-01-15 13:45'}, {id: 'WO005', type: '水质监测', location: '黄浦江段E区', method: '无人船巡检', status: 'arrived', assignee: '钱七', createTime: '2024-01-15 13:10', priority: '中', responseTime: '2024-01-15 17:10'}, {id: 'WO006', type: '设备故障', location: '苏州河段F区', method: '传感器报警', status: 'departed', assignee: '孙八', createTime: '2024-01-15 14:20', priority: '高', responseTime: '2024-01-15 16:20'}, {id: 'WO007', type: '垃圾清理', location: '黄浦江段G区', method: '巡检发现', status: 'processed', assignee: '周九', createTime: '2024-01-15 15:30', priority: '中', responseTime: '2024-01-15 19:30'}, {id: 'WO008', type: '水质异常', location: '苏州河段H区', method: '市民举报', status: 'transported', assignee: '吴十', createTime: '2024-01-15 16:45', priority: '低', responseTime: '2024-01-16 04:45'} ]; const statusMap = { 'created': {text: '新建', class: 'status-created'}, 'assigned': {text: '待分配', class: 'status-assigned'}, 'dispatched': {text: '待出发', class: 'status-dispatched'}, 'departed': {text: '已出发', class: 'status-departed'}, 'arrived': {text: '已抵达', class: 'status-arrived'}, 'processed': {text: '已处理', class: 'status-processed'}, 'transported': {text: '已转运', class: 'status-transported'}, 'completed': {text: '已完成', class: 'status-completed'} }; workorderTableBody.innerHTML = workorders.map(wo => ` ${wo.id} ${wo.method} ${wo.type} ${wo.location} ${wo.priority || '中'} ${statusMap[wo.status].text} ${wo.assignee} ${wo.createTime} ${wo.responseTime || '待设定'} `).join(''); } // 加载设备数据 function loadDeviceData() { const deviceGrid = document.getElementById('deviceGrid'); if (!deviceGrid) return; const devices = [ {id: 'CAM001', name: '监控摄像头-01', type: 'camera', status: 'online', location: '黄浦江段A区', battery: 85}, {id: 'DRONE001', name: '清理无人机-01', type: 'drone', status: 'online', location: '苏州河段B区', battery: 92}, {id: 'SHIP001', name: '巡检无人船-01', type: 'ship', status: 'offline', location: '黄浦江段C区', battery: 23}, {id: 'SENSOR001', name: '水质传感器-01', type: 'sensor', status: 'online', location: '苏州河段D区', battery: 78}, {id: 'CAM002', name: '监控摄像头-02', type: 'camera', status: 'warning', location: '黄浦江段E区', battery: 45}, {id: 'DRONE002', name: '清理无人机-02', type: 'drone', status: 'online', location: '苏州河段F区', battery: 88} ]; const statusMap = { 'online': {text: '在线', class: 'device-online'}, 'offline': {text: '离线', class: 'device-offline'}, 'warning': {text: '告警', class: 'device-warning'} }; const typeIcons = { 'camera': 'fas fa-video', 'drone': 'fas fa-helicopter', 'ship': 'fas fa-ship', 'sensor': 'fas fa-thermometer-half' }; deviceGrid.innerHTML = devices.map(device => `
${statusMap[device.status].text}

${device.name}

${device.id}

${device.location}

电量: ${device.battery}%
`).join(''); } // 加载告警数据 function loadWarningData() { loadWaterQualityWarnings(); loadDeviceWarnings(); } function loadWaterQualityWarnings() { const container = document.getElementById('waterQualityWarnings'); if (!container) return; const warnings = [ {id: 'WQ001', location: '黄浦江段A区', parameter: 'pH值', value: '8.9', threshold: '6.5-8.5', level: 'medium', time: '10分钟前'}, {id: 'WQ002', location: '苏州河段B区', parameter: '溶解氧', value: '3.2mg/L', threshold: '>5mg/L', level: 'high', time: '25分钟前'}, {id: 'WQ003', location: '黄浦江段C区', parameter: '浊度', value: '15NTU', threshold: '<10NTU', level: 'low', time: '1小时前'} ]; container.innerHTML = warnings.map(warning => `
${warning.location} ${warning.time}
${warning.parameter}: ${warning.value}
标准: ${warning.threshold}
`).join(''); } function loadDeviceWarnings() { const container = document.getElementById('deviceWarnings'); if (!container) return; const warnings = [ {id: 'DW001', device: '清理无人机-01', issue: '电量不足', level: 'high', location: '苏州河段B区', time: '5分钟前'}, {id: 'DW002', device: '水质传感器-02', issue: '通信异常', level: 'critical', location: '黄浦江段D区', time: '15分钟前'}, {id: 'DW003', device: '监控摄像头-03', issue: '图像模糊', level: 'medium', location: '苏州河段F区', time: '30分钟前'} ]; container.innerHTML = warnings.map(warning => `
${warning.device} ${warning.time}
${warning.issue}
${warning.location}
`).join(''); } // 加载统计数据 function loadStatisticsData() { // 统计数据已在HTML中静态显示,这里可以添加动态更新逻辑 } // 全局图表实例存储 window.chartInstances = window.chartInstances || {}; // 销毁图表实例的辅助函数 function destroyChart(chartId) { if (window.chartInstances[chartId]) { window.chartInstances[chartId].destroy(); delete window.chartInstances[chartId]; } } // 设置统计图表 function setupStatisticsCharts() { setupCleanupTrendChart(); setupDeviceUsageChart(); setupAreaDistributionChart(); setupEfficiencyChart(); } function setupCleanupTrendChart() { const canvas = document.getElementById('cleanupTrendChart'); if (!canvas) return; // 销毁已存在的图表实例 destroyChart('cleanupTrendChart'); const ctx = canvas.getContext('2d'); window.chartInstances['cleanupTrendChart'] = new Chart(ctx, { type: 'line', data: { labels: ['1月', '2月', '3月', '4月', '5月', '6月'], datasets: [{ label: '清理量(吨)', data: [120, 150, 180, 220, 190, 250], borderColor: '#64b5f6', backgroundColor: 'rgba(100, 181, 246, 0.1)', tension: 0.4 }] }, options: { responsive: true, plugins: { legend: { labels: { color: '#e0e0e0' } } }, scales: { x: { ticks: { color: '#b0bec5' } }, y: { ticks: { color: '#b0bec5' } } } } }); } function setupDeviceUsageChart() { const canvas = document.getElementById('deviceUsageChart'); if (!canvas) return; // 销毁已存在的图表实例 destroyChart('deviceUsageChart'); const ctx = canvas.getContext('2d'); window.chartInstances['deviceUsageChart'] = new Chart(ctx, { type: 'doughnut', data: { labels: ['摄像头', '无人机', '无人船', '传感器'], datasets: [{ data: [35, 25, 20, 20], backgroundColor: ['#64b5f6', '#42a5f5', '#2196f3', '#1976d2'] }] }, options: { responsive: true, plugins: { legend: { labels: { color: '#e0e0e0' } } } } }); } function setupAreaDistributionChart() { const canvas = document.getElementById('areaDistributionChart'); if (!canvas) return; // 销毁已存在的图表实例 destroyChart('areaDistributionChart'); const ctx = canvas.getContext('2d'); window.chartInstances['areaDistributionChart'] = new Chart(ctx, { type: 'bar', data: { labels: ['黄浦江段', '苏州河段', '长江口段', '其他水域'], datasets: [{ label: '清理次数', data: [45, 38, 22, 15], backgroundColor: '#64b5f6' }] }, options: { responsive: true, plugins: { legend: { labels: { color: '#e0e0e0' } } }, scales: { x: { ticks: { color: '#b0bec5' } }, y: { ticks: { color: '#b0bec5' } } } } }); } function setupEfficiencyChart() { const canvas = document.getElementById('efficiencyChart'); if (!canvas) return; // 销毁已存在的图表实例 destroyChart('efficiencyChart'); const ctx = canvas.getContext('2d'); window.chartInstances['efficiencyChart'] = new Chart(ctx, { type: 'radar', data: { labels: ['响应速度', '清理效率', '设备利用率', '成本控制', '环保指标'], datasets: [{ label: '当前指标', data: [85, 92, 78, 88, 95], borderColor: '#64b5f6', backgroundColor: 'rgba(100, 181, 246, 0.2)' }] }, options: { responsive: true, plugins: { legend: { labels: { color: '#e0e0e0' } } }, scales: { r: { ticks: { color: '#b0bec5' }, grid: { color: '#2a3f5f' } } } } }); } // 设置事件监听器 function setupWorkorderEvents() { // 工单相关事件处理 const createBtn = document.getElementById('createWorkorder'); if (createBtn) { createBtn.addEventListener('click', () => { console.log('创建新工单'); }); } } function setupDeviceEvents() { // 设备分类按钮事件 const categoryBtns = document.querySelectorAll('.category-btn'); categoryBtns.forEach(btn => { btn.addEventListener('click', (e) => { categoryBtns.forEach(b => b.classList.remove('active')); e.target.classList.add('active'); filterDevices(e.target.dataset.category); }); }); } function setupWarningEvents() { // 告警相关事件处理 } // 工具函数 function editWorkorder(id) { console.log('编辑工单:', id); } function controlDevice(id) { console.log('控制设备:', id); } function deviceDetail(id) { console.log('设备详情:', id); } function filterDevices(category) { console.log('筛选设备类型:', category); } // 导出全局函数供HTML调用 window.switchTab = switchTab; window.closeModal = closeModal; window.viewWorkorder = viewWorkorder; window.editWorkorder = editWorkorder; window.controlDevice = controlDevice; window.deviceDetail = deviceDetail; window.filterDevices = filterDevices; window.editWorkorder = editWorkorder; window.viewDevice = viewDevice; window.controlDevice = controlDevice; window.maintainDevice = maintainDevice; window.showNotification = showNotification; console.log('智慧河道管理平台初始化完成');