let table, layer, form; let utilizationChart = null, trendsChart = null; let isAnimating = false; // 防止重复动画的标志位 // 模拟数据 const mockData = { // 总体统计数据 overallStats: { totalRate: 85.2, personnelRate: 88.5, equipmentRate: 82.3, materialRate: 84.8 }, // 资源概览数据 resourceOverview: { personnel: { count: 126, rate: 88.5 }, equipment: { count: 42, rate: 82.3 }, material: { count: 89, rate: 84.8 }, energy: { count: 76, rate: 91.2 } }, // 资源详细列表 resourceDetails: [ { type: '人员', name: '土建班组A', status: 'active', rate: 92.5, assessment: '优秀' }, { type: '人员', name: '钢筋班组B', status: 'working', rate: 88.2, assessment: '良好' }, { type: '人员', name: '混凝土班组C', status: 'rest', rate: 85.7, assessment: '良好' }, { type: '设备', name: '塔吊001', status: 'running', rate: 89.3, assessment: '优秀' }, { type: '设备', name: '挖掘机002', status: 'normal', rate: 78.6, assessment: '一般' }, { type: '设备', name: '混凝土泵车', status: 'maintenance', rate: 76.4, assessment: '一般' }, { type: '设备', name: '起重机003', status: 'offline', rate: 0, assessment: '较差' }, { type: '材料', name: '钢筋', status: 'sufficient', rate: 91.2, assessment: '优秀' }, { type: '材料', name: '混凝土', status: 'normal', rate: 83.5, assessment: '良好' }, { type: '材料', name: '砂石料', status: 'low_stock', rate: 79.8, assessment: '一般' }, { type: '材料', name: '水泥', status: 'critical', rate: 65.2, assessment: '较差' }, { type: '能源', name: '电力系统', status: 'stable', rate: 93.1, assessment: '优秀' }, { type: '能源', name: '柴油储备', status: 'high_consumption', rate: 88.4, assessment: '良好' }, { type: '能源', name: '天然气', status: 'available', rate: 85.6, assessment: '良好' }, { type: '能源', name: '备用电源', status: 'standby', rate: 100, assessment: '优秀' } ], // 利用率分布数据 utilizationData: [ { name: '人员', value: 88.5, color: '#16baaa' }, { name: '设备', value: 82.3, color: '#20d3c2' }, { name: '材料', value: 84.8, color: '#25e5d0' }, { name: '能源', value: 91.2, color: '#2af0dd' } ], // 趋势数据(最近7天) trendsData: { dates: ['2024-01-15', '2024-01-16', '2024-01-17', '2024-01-18', '2024-01-19', '2024-01-20', '2024-01-21'], personnel: [85.2, 87.1, 88.5, 89.2, 88.8, 87.9, 88.5], equipment: [78.9, 80.3, 82.1, 81.7, 82.3, 83.1, 82.3], material: [82.1, 83.5, 84.2, 84.8, 85.1, 84.6, 84.8], energy: [89.5, 90.2, 91.2, 90.8, 91.5, 91.0, 91.2] }, // 优化建议 optimizationSuggestions: [ { title: '设备调度优化', description: '挖掘机002利用率偏低,建议调整作业计划,提高设备运转效率', priority: '高优先级' }, { title: '材料库存管理', description: '砂石料库存不足,建议提前采购补充,避免影响施工进度', priority: '中优先级' }, { title: '人员配置调整', description: '土建班组A效率突出,建议增加人员配置或分配更多任务', priority: '中优先级' }, { title: '能源消耗监控', description: '柴油消耗偏高,建议检查设备运行状态,优化燃油使用', priority: '低优先级' }, { title: '设备维护计划', description: '混凝土泵车正在维护中,建议制定预防性维护计划减少停机时间', priority: '高优先级' } ] }; // 页面初始化 layui.use(['layer', 'table', 'form'], function () { layer = layui.layer; table = layui.table; form = layui.form; // 初始化粒子背景 initParticles(); // 模拟加载延迟 setTimeout(() => { // 隐藏加载动画 $('#loadingOverlay').fadeOut(500); // 初始化页面数据 initPageData(); // 初始化图表 initCharts(); // 启动数据更新定时器 startDataRefresh(); }, 2000); }); // 初始化粒子背景 function initParticles() { if (typeof particlesJS !== 'undefined') { particlesJS('particles-js', { "particles": { "number": { "value": 80, "density": { "enable": true, "value_area": 800 } }, "color": { "value": "#16baaa" }, "shape": { "type": "circle", "stroke": { "width": 0, "color": "#000000" } }, "opacity": { "value": 0.5, "random": false, "anim": { "enable": false, "speed": 1, "opacity_min": 0.1, "sync": false } }, "size": { "value": 3, "random": true, "anim": { "enable": false, "speed": 40, "size_min": 0.1, "sync": false } }, "line_linked": { "enable": true, "distance": 150, "color": "#16baaa", "opacity": 0.4, "width": 1 }, "move": { "enable": true, "speed": 2, "direction": "none", "random": false, "straight": false, "out_mode": "out", "bounce": false, "attract": { "enable": false, "rotateX": 600, "rotateY": 1200 } } }, "interactivity": { "detect_on": "canvas", "events": { "onhover": { "enable": true, "mode": "repulse" }, "onclick": { "enable": true, "mode": "push" }, "resize": true }, "modes": { "grab": { "distance": 400, "line_linked": { "opacity": 1 } }, "bubble": { "distance": 400, "size": 40, "duration": 2, "opacity": 8, "speed": 3 }, "repulse": { "distance": 200, "duration": 0.4 }, "push": { "particles_nb": 4 }, "remove": { "particles_nb": 2 } } }, "retina_detect": true }); } } // 初始化页面数据 function initPageData() { // 直接设置初始值,不使用动画 const stats = mockData.overallStats; $('#totalRate').text(stats.totalRate.toFixed(1) + '%'); $('#personnelRate').text(stats.personnelRate.toFixed(1) + '%'); $('#equipmentRate').text(stats.equipmentRate.toFixed(1) + '%'); $('#materialRate').text(stats.materialRate.toFixed(1) + '%'); // 设置资源概览初始值 const overview = mockData.resourceOverview; $('#personnelCount').text(overview.personnel.count); $('#equipmentCount').text(overview.equipment.count); $('#materialCount').text(overview.material.count); $('#energyCount').text(overview.energy.count + '%'); // 更新资源详细表格 updateResourceTable(); // 更新优化建议 updateOptimizationSuggestions(); } // 更新头部统计数据 function updateHeaderStats() { const stats = mockData.overallStats; // 获取当前值,如果不存在则从0开始 const currentTotal = parseFloat($('#totalRate').text()) || 0; const currentPersonnel = parseFloat($('#personnelRate').text()) || 0; const currentEquipment = parseFloat($('#equipmentRate').text()) || 0; const currentMaterial = parseFloat($('#materialRate').text()) || 0; animateValue('totalRate', currentTotal, stats.totalRate, '%'); animateValue('personnelRate', currentPersonnel, stats.personnelRate, '%'); animateValue('equipmentRate', currentEquipment, stats.equipmentRate, '%'); animateValue('materialRate', currentMaterial, stats.materialRate, '%'); } // 数值动画函数 function animateValue(elementId, start, end, suffix = '') { const element = document.getElementById(elementId); if (!element) return; // 如果起始值无效,设为0 if (isNaN(start) || start < 0) start = 0; if (isNaN(end)) return; // 如果数值相同,直接设置,不需要动画 if (Math.abs(end - start) < 0.1) { element.textContent = end.toFixed(1) + suffix; return; } const range = end - start; const duration = 1000; // 动画持续时间(毫秒) const startTime = Date.now(); const animate = () => { const now = Date.now(); const elapsed = now - startTime; const progress = Math.min(elapsed / duration, 1); // 使用缓动函数 const easeOutQuart = 1 - Math.pow(1 - progress, 4); const current = start + (range * easeOutQuart); element.textContent = current.toFixed(1) + suffix; if (progress < 1) { requestAnimationFrame(animate); } else { element.textContent = end.toFixed(1) + suffix; } }; animate(); } // 更新资源概览 function updateResourceOverview() { const overview = mockData.resourceOverview; // 获取当前值,如果不存在则从0开始 const currentPersonnel = parseInt($('#personnelCount').text()) || 0; const currentEquipment = parseInt($('#equipmentCount').text()) || 0; const currentMaterial = parseInt($('#materialCount').text()) || 0; const currentEnergy = parseInt($('#energyCount').text()) || 0; animateValue('personnelCount', currentPersonnel, overview.personnel.count); animateValue('equipmentCount', currentEquipment, overview.equipment.count); animateValue('materialCount', currentMaterial, overview.material.count); animateValue('energyCount', currentEnergy, overview.energy.count, '%'); } // 更新资源详细表格 function updateResourceTable() { const tableBody = $('#resourceTableBody'); tableBody.empty(); mockData.resourceDetails.forEach((item, index) => { const assessmentClass = getAssessmentClass(item.assessment); const statusClass = getStatusClass(item.status); const row = ` ${item.type} ${item.name} ${translateStatus(item.status)} ${item.rate}% ${item.assessment} `; tableBody.append(row); }); } // 获取效率评估样式类 function getAssessmentClass(assessment) { switch(assessment) { case '优秀': return 'assessment-excellent'; case '良好': return 'assessment-good'; case '一般': return 'assessment-normal'; default: return ''; } } // 获取状态样式类 function getStatusClass(status) { // 处理英文状态和中英文对照状态 const lowerStatus = status.toLowerCase(); // 正常/良好状态 if (lowerStatus.includes('active') || lowerStatus.includes('normal') || lowerStatus.includes('sufficient') || lowerStatus.includes('running') || lowerStatus.includes('working') || lowerStatus.includes('available') || lowerStatus.includes('stable') || lowerStatus.includes('good') || status.includes('工作中') || status.includes('运行中') || status.includes('充足') || status.includes('正常') || status.includes('可用') || status.includes('稳定')) { return 'status-active'; } // 警告/异常状态 else if (lowerStatus.includes('rest') || lowerStatus.includes('maintenance') || lowerStatus.includes('low') || lowerStatus.includes('high_consumption') || lowerStatus.includes('low_stock') || lowerStatus.includes('warning') || lowerStatus.includes('critical') || lowerStatus.includes('offline') || lowerStatus.includes('error') || lowerStatus.includes('unavailable') || lowerStatus.includes('unstable') || lowerStatus.includes('poor') || status.includes('休息中') || status.includes('维护中') || status.includes('库存低') || status.includes('偏高') || status.includes('警告') || status.includes('紧急') || status.includes('离线') || status.includes('故障') || status.includes('不可用') || status.includes('不稳定') || status.includes('较差')) { return 'status-warning'; } // 默认状态 return 'status-normal'; } // 状态中英文对照 function translateStatus(status) { const statusMap = { 'active': '运行中', 'normal': '正常', 'sufficient': '充足', 'rest': '休息中', 'maintenance': '维护中', 'low_stock': '库存不足', 'high_consumption': '消耗偏高', 'offline': '离线', 'error': '故障', 'warning': '警告', 'good': '良好', 'poor': '较差', 'working': '工作中', 'running': '运行中', 'idle': '空闲', 'standby': '待机', 'busy': '繁忙', 'available': '可用', 'unavailable': '不可用', 'critical': '紧急', 'low': '偏低', 'high': '偏高', 'stable': '稳定', 'unstable': '不稳定' }; // 检查是否为纯英文状态(不包含中文字符) const isEnglishOnly = /^[a-zA-Z_\-\s]+$/.test(status); if (isEnglishOnly) { const lowerStatus = status.toLowerCase().trim(); // 如果是英文状态,返回中文翻译+英文原文 if (statusMap[lowerStatus]) { return `${statusMap[lowerStatus]} (${status})`; } else { // 如果没有对应翻译,但是是英文,则添加提示 return `${status} (英文状态)`; } } // 如果已经是中文或混合文本,直接返回 return status; } // 更新优化建议 function updateOptimizationSuggestions() { const container = $('#optimizationList'); container.empty(); mockData.optimizationSuggestions.forEach((suggestion, index) => { const priorityClass = getPriorityClass(suggestion.priority); const iconClass = getPriorityIcon(suggestion.priority); const item = `
${suggestion.title} ${suggestion.priority}
${suggestion.description}
`; container.append(item); }); } // 获取优先级样式类 function getPriorityClass(priority) { switch(priority) { case '高优先级': return 'priority-high'; case '中优先级': return 'priority-medium'; case '低优先级': return 'priority-low'; default: return ''; } } // 获取优先级图标 function getPriorityIcon(priority) { switch(priority) { case '高优先级': return 'fas fa-exclamation-triangle priority-icon-high'; case '中优先级': return 'fas fa-info-circle priority-icon-medium'; case '低优先级': return 'fas fa-check-circle priority-icon-low'; default: return 'fas fa-circle'; } } // 初始化图表 function initCharts() { initUtilizationChart(); initTrendsChart(); } // 初始化利用率分布图表 function initUtilizationChart() { const chartDom = document.getElementById('utilizationChart'); utilizationChart = echarts.init(chartDom); const option = { backgroundColor: 'transparent', tooltip: { trigger: 'item', backgroundColor: 'rgba(22, 186, 170, 0.9)', borderColor: '#16baaa', textStyle: { color: '#fff' } }, legend: { orient: 'vertical', left: 'left', top: 'center', textStyle: { color: '#16baaa', fontSize: 12 } }, series: [ { name: '资源利用率', type: 'pie', radius: ['40%', '70%'], center: ['65%', '50%'], avoidLabelOverlap: false, itemStyle: { borderRadius: 8, borderColor: '#0a1e2b', borderWidth: 2 }, label: { show: true, position: 'outside', color: '#8cc8c1', fontSize: 11, formatter: '{b}: {c}%' }, emphasis: { label: { show: true, fontSize: 12, fontWeight: 'bold', color: '#16baaa' }, itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(22, 186, 170, 0.5)' } }, data: mockData.utilizationData.map(item => ({ name: item.name, value: item.value, itemStyle: { color: item.color } })) } ] }; utilizationChart.setOption(option); } // 初始化趋势图表 function initTrendsChart() { const chartDom = document.getElementById('trendsChart'); trendsChart = echarts.init(chartDom); const option = { backgroundColor: 'transparent', tooltip: { trigger: 'axis', backgroundColor: 'rgba(22, 186, 170, 0.9)', borderColor: '#16baaa', textStyle: { color: '#fff' }, axisPointer: { type: 'cross', lineStyle: { color: '#16baaa' } } }, legend: { data: ['人员', '设备', '材料', '能源'], textStyle: { color: '#16baaa' }, top: 10 }, grid: { left: '3%', right: '4%', bottom: '3%', top: '15%', containLabel: true }, xAxis: { type: 'category', boundaryGap: false, data: mockData.trendsData.dates.map(date => date.substring(5)), axisLine: { lineStyle: { color: '#16baaa' } }, axisTick: { lineStyle: { color: '#16baaa' } }, axisLabel: { color: '#8cc8c1' } }, yAxis: { type: 'value', min: 70, max: 95, axisLine: { lineStyle: { color: '#16baaa' } }, axisTick: { lineStyle: { color: '#16baaa' } }, axisLabel: { color: '#8cc8c1', formatter: '{value}%' }, splitLine: { lineStyle: { color: 'rgba(22, 186, 170, 0.2)' } } }, series: [ { name: '人员', type: 'line', smooth: true, data: mockData.trendsData.personnel, lineStyle: { color: '#16baaa', width: 2 }, itemStyle: { color: '#16baaa' }, areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: 'rgba(22, 186, 170, 0.3)' }, { offset: 1, color: 'rgba(22, 186, 170, 0.1)' } ]) } }, { name: '设备', type: 'line', smooth: true, data: mockData.trendsData.equipment, lineStyle: { color: '#20d3c2', width: 2 }, itemStyle: { color: '#20d3c2' } }, { name: '材料', type: 'line', smooth: true, data: mockData.trendsData.material, lineStyle: { color: '#25e5d0', width: 2 }, itemStyle: { color: '#25e5d0' } }, { name: '能源', type: 'line', smooth: true, data: mockData.trendsData.energy, lineStyle: { color: '#2af0dd', width: 2 }, itemStyle: { color: '#2af0dd' } } ] }; trendsChart.setOption(option); } // 启动数据刷新定时器 function startDataRefresh() { setInterval(() => { // 模拟数据更新 updateMockData(); updatePageData(); updateCharts(); }, 60000); // 每60秒更新一次,减少频率 } // 更新模拟数据 function updateMockData() { // 随机更新一些数据,但变化幅度较小 const variation = 2; // 最大变化幅度 mockData.overallStats.totalRate = Math.round((mockData.overallStats.totalRate + (Math.random() - 0.5) * variation) * 10) / 10; mockData.overallStats.personnelRate = Math.round((mockData.overallStats.personnelRate + (Math.random() - 0.5) * variation) * 10) / 10; mockData.overallStats.equipmentRate = Math.round((mockData.overallStats.equipmentRate + (Math.random() - 0.5) * variation) * 10) / 10; mockData.overallStats.materialRate = Math.round((mockData.overallStats.materialRate + (Math.random() - 0.5) * variation) * 10) / 10; // 限制数值范围 mockData.overallStats.totalRate = Math.max(75, Math.min(95, mockData.overallStats.totalRate)); mockData.overallStats.personnelRate = Math.max(75, Math.min(95, mockData.overallStats.personnelRate)); mockData.overallStats.equipmentRate = Math.max(70, Math.min(90, mockData.overallStats.equipmentRate)); mockData.overallStats.materialRate = Math.max(75, Math.min(95, mockData.overallStats.materialRate)); // 同步更新资源概览数据 mockData.resourceOverview.personnel.rate = mockData.overallStats.personnelRate; mockData.resourceOverview.equipment.rate = mockData.overallStats.equipmentRate; mockData.resourceOverview.material.rate = mockData.overallStats.materialRate; } // 更新页面数据 function updatePageData() { if (isAnimating) return; // 如果正在动画中,跳过更新 isAnimating = true; updateHeaderStats(); updateResourceOverview(); // 1.5秒后重置动画标志 setTimeout(() => { isAnimating = false; }, 1500); } // 更新图表数据 function updateCharts() { if (utilizationChart) { // 更新利用率分布图 mockData.utilizationData[0].value = mockData.overallStats.personnelRate; mockData.utilizationData[1].value = mockData.overallStats.equipmentRate; mockData.utilizationData[2].value = mockData.overallStats.materialRate; utilizationChart.setOption({ series: [{ data: mockData.utilizationData.map(item => ({ name: item.name, value: parseFloat(item.value.toFixed(1)), itemStyle: { color: item.color } })) }] }); } } // 窗口大小改变时重新调整图表 window.addEventListener('resize', function() { if (utilizationChart) { utilizationChart.resize(); } if (trendsChart) { trendsChart.resize(); } }); // 添加状态和评估样式 $(document).ready(function() { $('