// 资源利用率页面(前端模拟数据,方便对照设计稿) let table, layer, form, laydate; let trendChart = null; let equipmentChart = null; let bidCode = parent.parent.$('#bidPro').val(); let modalPersonnelQueryParams = { workType: '', teamName: '', teamLeader: '' }; let modalDeviceQueryParams = { devName: '' }; let pageSize = 10; // 获取当天日期 function getTodayDate() { const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); const day = String(now.getDate()).padStart(2, '0'); const today = year + '-' + month + '-' + day; return today; } // 获取当月第一天和最后一天(保留用于其他功能) function getCurrentMonthRange() { const now = new Date(); const year = now.getFullYear(); const month = now.getMonth(); // 当月第一天 const firstDay = new Date(year, month, 1); const startDate = year + '-' + String(month + 1).padStart(2, '0') + '-' + String(firstDay.getDate()).padStart(2, '0'); // 当月最后一天 const lastDay = new Date(year, month + 1, 0); const endDate = year + '-' + String(month + 1).padStart(2, '0') + '-' + String(lastDay.getDate()).padStart(2, '0'); return { startDate, endDate }; } const today = getTodayDate(); let queryParams = { bidCode: bidCode, startTime: today, endTime: today, } layui.use(['layer', 'table', 'form', 'laydate'], function () { layer = layui.layer; table = layui.table; form = layui.form; laydate = layui.laydate; // 响应成功后的拦截器 $.ajaxSetup({ beforeSend: function (xhr, options) { var originalSuccess = options.success; options.success = function (data, textStatus, jqXhr) { data = modifyResponseData(data); originalSuccess.apply(this, arguments); }; }, }); initCards(); initTeamTable(); initTrendChart(); initEquipmentChart(); initAnalysisTabs(); initPersonnelModalEvents(); initDeviceModalEvents(); // 初始化日期范围选择器 initDateRangePicker(); // 调用接口获取数据 getTeamUtilizationList(); getOverallSituation(); getWeekOnDutyEcharts(); getPersonnelOnDuty(); getDeviceSituation(); getAnalysisWarning(); // 默认加载全部 window.addEventListener('resize', debounce(() => { if (trendChart) trendChart.resize(); if (equipmentChart) equipmentChart.resize(); }, 300)); }); function debounce(fn, delay) { let t = null; return function () { clearTimeout(t); t = setTimeout(() => fn.apply(this, arguments), delay); }; } // 获取班组人员利用率排名列表 function getTeamUtilizationList() { const url = commonUrl + 'screen/resourceUtilization/selectTopList' + '?bidCode=' + (queryParams.bidCode || '') + '&startTime=' + (queryParams.startTime || '') + '&endTime=' + (queryParams.endTime || ''); ajaxRequestGet(url, 'GET', true, function () { }, function (result) { console.log(result, '班组人员利用率排名列表'); if (result && Array.isArray(result)) { // 如果返回的是数组,直接使用 updateTeamTable(result.data); } else if (result && result.data && Array.isArray(result.data)) { // 如果返回的是对象,取data字段 updateTeamTable(result.data); } else if (result && result.rows && Array.isArray(result.rows)) { // 如果返回的是对象,取rows字段 updateTeamTable(result.rows); } else { // 如果没有数据,清空表格 updateTeamTable([]); } }, aqEnnable); } // 获取整体情况 function getOverallSituation() { const url = commonUrl + 'screen/resourceUtilization/selectOverallData' + '?bidCode=' + (queryParams.bidCode || '') + '&startTime=' + (queryParams.startTime || '') + '&endTime=' + (queryParams.endTime || ''); ajaxRequestGet(url, 'GET', true, function () { }, function (result) { console.log(result, '整体情况'); if (result) { updateOverallSituation(result.data); } }, aqEnnable); } // 获取一周到岗人数趋势 function getWeekOnDutyEcharts() { const url = commonUrl + 'screen/resourceUtilization/getWeeksUserData' + '?bidCode=' + (queryParams.bidCode || '') + '&startTime=' + (queryParams.startTime || '') + '&endTime=' + (queryParams.endTime || ''); ajaxRequestGet(url, 'GET', true, function () { }, function (result) { console.log(result, '一周到岗人数趋势'); if (result && result.timeList && result.valueList) { updateTrendChart(result.timeList, result.valueList); } else if (result && result.data && result.data.timeList && result.data.valueList) { updateTrendChart(result.data.timeList, result.data.valueList); } else { // 如果没有数据,使用空数组 updateTrendChart([], []); } }, aqEnnable); } // 获取人员到岗情况 function getPersonnelOnDuty() { const url = commonUrl + 'screen/resourceUtilization/getOnDutyData' + '?bidCode=' + (queryParams.bidCode || '') + '&startTime=' + (queryParams.startTime || '') + '&endTime=' + (queryParams.endTime || ''); ajaxRequestGet(url, 'GET', true, function () { }, function (result) { console.log(result, '人员到岗情况'); if (result) { updatePersonnelOnDuty(result.data); } else if (result && result.data) { updatePersonnelOnDuty(result.data); } else { // 如果没有数据,使用默认值 updatePersonnelOnDuty({ todayNum: '0', yDayNum: '0' }); } }, aqEnnable); } // 获取设备情况 function getDeviceSituation() { const url = commonUrl + 'screen/resourceUtilization/getWeeksDevData' + '?bidCode=' + (queryParams.bidCode || '') + '&startTime=' + (queryParams.startTime || '') + '&endTime=' + (queryParams.endTime || ''); ajaxRequestGet(url, 'GET', true, function () { }, function (result) { console.log(result, '设备情况'); if (result && Array.isArray(result)) { // 如果返回的是数组,直接使用 updateEquipmentChart(result); } else if (result && result.data && Array.isArray(result.data)) { // 如果返回的是对象,取data字段 updateEquipmentChart(result.data); } else if (result && result.rows && Array.isArray(result.rows)) { // 如果返回的是对象,取rows字段 updateEquipmentChart(result.rows); } else { // 如果没有数据,使用空数组 updateEquipmentChart([]); } }, aqEnnable); } // 当前选中的分析提醒类型 let currentAnalysisType = ''; // ''表示全部,'人员'表示人员,'设备'表示设备 // 获取分析提醒 function getAnalysisWarning(txType = '') { currentAnalysisType = txType; const url = commonUrl + 'screen/resourceUtilization/getWarnList' + '?bidCode=' + (queryParams.bidCode || '') + '&startTime=' + (queryParams.startTime || '') + '&endTime=' + (queryParams.endTime || '') + (txType ? '&txType=' + encodeURIComponent(txType) : ''); ajaxRequestGet(url, 'GET', true, function () { }, function (result) { console.log(result, '分析提醒'); if (result && Array.isArray(result)) { // 如果返回的是数组,直接使用 updateAnalysisList(result); } else if (result && result.data && Array.isArray(result.data)) { // 如果返回的是对象,取data字段 updateAnalysisList(result.data); } else if (result && result.rows && Array.isArray(result.rows)) { // 如果返回的是对象,取rows字段 updateAnalysisList(result.rows); } else { // 如果没有数据,显示空列表 updateAnalysisList([]); } }, aqEnnable); } // 更新分析提醒列表 function updateAnalysisList(data) { if (!data || data.length === 0) { $('#analysisList').html('
暂无数据
'); return; } // 提取content字段并渲染 const html = data.map(item => { const content = item.content || ''; return `
${content}
`; }).join(''); $('#analysisList').html(html); } // 初始化分析提醒tab切换 function initAnalysisTabs() { // 绑定tab点击事件 $('.analysis-tab').on('click', function () { // 移除所有active类 $('.analysis-tab').removeClass('active'); // 给当前点击的tab添加active类 $(this).addClass('active'); // 根据tab文本确定txType参数 const tabText = $(this).text().trim(); let txType = ''; if (tabText === '人员') { txType = '人员'; } else if (tabText === '设备') { txType = '设备'; } // '全部' 或其他情况,txType 为空字符串 // 调用接口获取对应类型的数据 getAnalysisWarning(txType); }); } // 更新设备情况柱状图数据 function updateEquipmentChart(data) { if (!equipmentChart) return; if (!data || data.length === 0) { // 如果没有数据,显示空图表 equipmentChart.setOption({ xAxis: { data: [] }, series: [ { data: [] }, { data: [] } ] }); // 重新绑定点击事件 equipmentChart.off('click'); equipmentChart.on('click', function (params) { console.log('设备情况图表点击事件触发'); openDeviceListModal(); }); return; } // 提取数据 const devNames = data.map(item => item.devName || ''); const einDays = data.map(item => parseFloat(item.usedDay) || 0); const usedDays = data.map(item => parseFloat(item.usedNum) || 0); // 更新图表 equipmentChart.setOption({ xAxis: { data: devNames }, series: [ { name: '入场天数', data: einDays }, { name: '使用天数', data: usedDays } ] }); // 重新绑定点击事件(确保事件不会丢失) equipmentChart.off('click'); equipmentChart.on('click', function (params) { openDeviceListModal(); }); } // 更新人员到岗情况数据 function updatePersonnelOnDuty(data) { // 更新今日到岗人数 const todayNum = data.todayNum || '0'; $('#todayDutyRate').text(todayNum); // 更新昨日到岗人数 const yDayNum = data.yDayNum || '0'; $('#yesterdayDutyRate').text(yDayNum); } // 更新整体情况数据 function updateOverallSituation(data) { // 更新人员利用率 const userRate = data.userRate || '0.00%'; $('#workerUtilization').text(userRate); // 更新大型设备利用率 const devRate = data.devRate || '0.00%'; $('#deviceUtilization').text(devRate); } // 更新班组人员利用率表格 function updateTeamTable(data) { if (!data || data.length === 0) { // 如果没有数据,显示空表格 table.reload('teamTable', { data: [], page: false }); return; } // 调试:打印第一条数据查看字段名 if (data.length > 0) { console.log('第一条数据字段:', data[0]); } // 映射数据字段(尝试多个可能的字段名) const tableData = data.map(item => ( { workType: item.workType || '', teamName: item.teamName || '', teamLeader: item.teamLeader || '', // 尝试多个可能的字段名:peopleNum, totalPeople, teamPeople teamPeople: item.teamPeople || item.peopleNum || item.totalPeople || 0, // dutyNum 应该是正确的字段名 dutyPeople: item.dutyPeople || 0, utilizationRate: item.userRate || '0.00%' })); console.log(tableData, 'tableData'); // 重新加载表格数据 table.reload('teamTable', { data: tableData, page: false }); } // 初始化日期范围选择器(与工程质量分析保持一致) function initDateRangePicker() { // 设置初始显示值 const initialValue = queryParams.startTime + ' ~ ' + queryParams.endTime; $('#dateRange').val(initialValue); // 使用范围选择器,单个输入框显示日期范围 laydate.render({ elem: '#dateRange', type: 'date', range: true, // 启用范围选择 format: 'yyyy-MM-dd', theme: 'dark', // 默认值使用当月范围 value: queryParams.startTime + ' - ' + queryParams.endTime, done: function (value, date, endDate) { // 重置为当天日期的函数 const resetToToday = function () { const today = getTodayDate(); queryParams.startTime = today; queryParams.endTime = today; $('#dateRange').val(today + ' ~ ' + today); refreshAllModules(); }; if (value && value.trim() !== '') { const dates = value.split(' - '); if (dates.length === 2) { const startDate = dates[0].trim(); const endDateStr = dates[1].trim(); // 在单个输入框中显示日期范围(格式:2026-01-01 ~ 2026-01-01) $('#dateRange').val(startDate + ' ~ ' + endDateStr); // 更新查询参数 queryParams.startTime = startDate; queryParams.endTime = endDateStr; // 日期变化后,重新调用所有模块接口 refreshAllModules(); } else { // 如果格式不正确,重置为当天日期 resetToToday(); } } else { // 清空时,重置为当天日期 resetToToday(); } } }); } // 刷新所有模块数据 function refreshAllModules() { // 重新调用接口 getTeamUtilizationList(); getOverallSituation(); getWeekOnDutyEcharts(); getPersonnelOnDuty(); getDeviceSituation(); // 可以在这里添加其他接口调用 } // 顶部/中部数字卡片模拟数据(初始化默认值) function initCards() { // 初始化时使用默认值,实际数据会通过接口更新 $('#workerUtilization').text('0.00%'); $('#deviceUtilization').text('0.00%'); $('#todayDutyRate').text('0'); $('#yesterdayDutyRate').text('0'); } // 班组人员利用率表格(初始化表格结构) function initTeamTable() { table.render({ elem: '#teamTable', id: 'teamTable', data: [], page: false, skin: 'line', cols: [[ { type: 'numbers', title: '序号', width: '8%', align: 'center' }, { field: 'workType', title: '专业', width: '16%', align: 'center' }, { field: 'teamName', title: '班组', width: '18%', align: 'center' }, { field: 'teamLeader', title: '班组负责人', width: '16%', align: 'center' }, { field: 'teamPeople', title: '班组人数', width: '14%', align: 'center', templet: function (d) { return '' + (d.teamPeople || 0) + ''; } }, { field: 'dutyPeople', title: '当日到岗', width: '14%', align: 'center', templet: function (d) { return '' + (d.dutyPeople || 0) + ''; } }, { field: 'utilizationRate', title: '利用率', align: 'center', templet: function (d) { // userRate字段可能已经是百分比格式,直接显示 return d.utilizationRate || '0.00%'; } } ]] }); } // 一周到岗趋势(折线面积图) function initTrendChart() { trendChart = echarts.init(document.getElementById('trendChart')); // 初始化空图表 const option = { tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' }, backgroundColor: 'rgba(19,51,55,.8)', borderColor: 'rgba(255,255,255,.2)', textStyle: { color: '#fff' }, formatter: params => { if (!params || !params.length) return ''; const name = params[0].name; let html = `
${name}
`; params.forEach(p => { html += `
${p.seriesName} ${p.value}
`; }); return html; } }, legend: { data: ['实到'], top: 8, right: 20, textStyle: { color: '#fff' } }, grid: { top: '22%', left: '6%', right: '4%', bottom: '15%' }, xAxis: { type: 'category', data: [], axisLabel: { color: '#fff' }, axisLine: { lineStyle: { color: '#5A6E71' } } }, yAxis: { type: 'value', axisLabel: { color: 'rgba(255,255,255,0.8)' }, splitLine: { lineStyle: { color: 'rgba(255,255,255,0.2)', type: 'dashed' } } }, series: [ { name: '实到', type: 'line', smooth: true, data: [], lineStyle: { width: 2, color: '#00FEFC' }, itemStyle: { color: '#00FEFC' }, areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: 'rgba(18,86,100,0.6)' }, { offset: 1, color: 'rgba(16,72,81,0.7)' } ]) } } ], dataZoom: [ { show: true, height: 12, bottom: '8%', start: 0, end: 100 }, { type: 'inside', start: 0, end: 100 } ] }; trendChart.setOption(option); } // 更新一周到岗趋势图表数据 function updateTrendChart(timeList, valueList) { if (!trendChart) return; // 处理日期格式:从 "2026-01-01" 转换为 "01-01" const formattedDates = (timeList || []).map(dateStr => { if (!dateStr) return ''; // 提取月-日部分 const parts = dateStr.split('-'); if (parts.length >= 3) { return parts[1] + '-' + parts[2]; } return dateStr; }); // 处理数值:转换为数字 const values = (valueList || []).map(val => parseFloat(val) || 0); // 更新图表 trendChart.setOption({ xAxis: { data: formattedDates }, series: [ { name: '实到', data: values } ] }); } // 设备情况柱状图 function initEquipmentChart() { equipmentChart = echarts.init(document.getElementById('equipmentStatus')); const color1 = { type: 'linear', x: 0, x2: 1, y: 0, y2: 0, colorStops: [{ offset: 0, color: '#1CFFA3' }, { offset: 1, color: '#1CFFA3' }] }; const color2 = { type: 'linear', x: 0, x2: 1, y: 0, y2: 0, colorStops: [{ offset: 0, color: '#00FEFC' }, { offset: 1, color: '#00FEFC' }] }; const option = { legend: { top: '10%', right: '3%', textStyle: { fontSize: 12, color: '#FFF' }, selectedMode: false, icon: 'circle', itemWidth: 12, itemHeight: 10, itemGap: 15 }, grid: { x: '6%', x2: '4%', y: '25%', y2: '18%' }, tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' }, backgroundColor: 'rgba(19,51,55,.8)', borderColor: 'rgba(255,255,255,.2)', textStyle: { color: '#fff' }, formatter: params => { if (!params || !params.length) return ''; const name = params[0].name; let html = `
${name}
`; params.forEach(p => { html += `
${p.seriesName} ${p.value}
`; }); return html; } }, xAxis: { data: [], axisLine: { lineStyle: { color: '#214776' } }, axisLabel: { color: '#C5DFFB', fontSize: 12 }, axisTick: { show: false } }, yAxis: { type: 'value', splitLine: { lineStyle: { type: 'dashed', opacity: 0.2 } }, axisTick: { show: false }, axisLine: { show: false }, axisLabel: { color: '#C5DFFB' } }, dataZoom: [ { show: true, height: 12, bottom: '8%', start: 0, end: 100 }, { type: 'inside', start: 0, end: 100 } ], series: [ { name: '入场天数', type: 'bar', barWidth: 18, data: [], itemStyle: { color: color1 } }, { name: '使用天数', type: 'bar', barWidth: 18, data: [], itemStyle: { color: color2 } } ] }; equipmentChart.setOption(option, true); // 绑定图表点击事件 equipmentChart.off('click'); equipmentChart.on('click', function (params) { openDeviceListModal(); }); } // 初始化人员列表弹框点击事件 function initPersonnelModalEvents() { // 点击人员利用率模块打开弹框(第一个metric-card,包含#workerUtilization) $('#workerUtilization').closest('.metric-card').on('click', function () { openPersonnelListModal(); }); // 点击折线图打开弹框 $('#trendChart').on('click', function () { openPersonnelListModal(); }); } // 初始化设备列表弹框点击事件 function initDeviceModalEvents() { // 点击大型设备利用率模块打开弹框 // 使用事件委托,确保元素存在后再绑定 setTimeout(function () { $('#deviceUtilization').closest('.metric-card').on('click', function (e) { e.stopPropagation(); openDeviceListModal(); }); }, 100); } // 打开人员列表弹框 function openPersonnelListModal() { const modal = $('#personnelListModal'); if (modal.length === 0) { console.error('人员列表弹框元素不存在'); return; } // 先关闭设备列表弹框(如果打开的话) $('#deviceListModal').removeClass('show').css('display', 'none'); // 显示人员列表弹框 modal.addClass('show'); modal.css({ 'display': 'flex', 'align-items': 'center', 'justify-content': 'center', 'z-index': '99999' }); // 重置查询参数 modalPersonnelQueryParams = { workType: '', teamName: '', teamLeader: '' }; $('#modalWorkTypeInput').val(''); $('#modalTeamNameInput').val(''); $('#modalTeamLeaderInput').val(''); // 延迟初始化表格,确保弹框完全显示后再渲染表格 setTimeout(function () { initModalPersonnelListTable(); }, 100); } // 关闭人员列表弹框 function closePersonnelListModal() { const modal = $('#personnelListModal'); modal.removeClass('show'); modal.css({ 'display': 'none' }); } // 初始化弹框内人员列表表格 function initModalPersonnelListTable() { table.render({ elem: '#modalPersonnelListTable', id: 'modalPersonnelListTable', url: commonUrl + 'screen/resourceUtilization/getTeamList', headers: { decrypt: 'decrypt', Authorization: token }, method: 'GET', where: { bidCode: bidCode, workType: modalPersonnelQueryParams.workType || '', teamName: modalPersonnelQueryParams.teamName || '', teamLeader: modalPersonnelQueryParams.teamLeader || '' }, skin: 'line', page: { layout: ['prev', 'page', 'next', 'count', 'skip'], groups: 5, limit: pageSize, limits: [10, 20, 30, 50] }, height: 'full', request: { pageName: 'pageNum', limitName: 'pageSize' }, response: { statusName: 'code', statusCode: 0, msgName: 'msg', countName: 'count', dataName: 'data' }, cols: [[ { type: 'numbers', title: '序号', width: '10%', align: 'center' }, { field: 'workType', title: '专业', width: '15%', align: 'center' }, { field: 'teamName', title: '班组名称', width: '20%', align: 'center' }, { field: 'teamLeader', title: '班组长', width: '25%', align: 'center', templet: function (d) { // 如果teamLeader包含电话号码,显示格式:姓名 / 电话 const leader = d.teamLeader || ''; // 假设电话号码格式,可以根据实际情况调整 return leader; } }, { field: 'peopleNum', title: '班组人数', width: '15%', align: 'center', templet: function (d) { // 只显示数字,不可点击 return '' + (d.peopleNum || 0) + ''; } }, { field: 'dutyNum', title: '当日到岗人数', width: '15%', align: 'center', templet: function (d) { // 只显示数字,不可点击,优先使用peopleNum,如果没有则使用dutyNum const count = d.dutyNum || 0; return '' + count + ''; } } ]] }); } // 弹框内查询人员列表 function queryPersonnelList() { // 获取搜索条件 modalPersonnelQueryParams.workType = $('#modalWorkTypeInput').val() || ''; modalPersonnelQueryParams.teamName = $('#modalTeamNameInput').val() || ''; modalPersonnelQueryParams.teamLeader = $('#modalTeamLeaderInput').val() || ''; // 重新加载表格 table.reload('modalPersonnelListTable', { where: { bidCode: bidCode, workType: modalPersonnelQueryParams.workType, teamName: modalPersonnelQueryParams.teamName, teamLeader: modalPersonnelQueryParams.teamLeader }, page: { curr: 1 // 重新从第1页开始 } }); } // 打开设备列表弹框 function openDeviceListModal() { const modal = $('#deviceListModal'); if (modal.length === 0) { console.error('设备列表弹框元素不存在'); return; } // 先关闭人员列表弹框(如果打开的话) $('#personnelListModal').removeClass('show').css('display', 'none'); // 显示设备列表弹框 modal.addClass('show'); modal.css({ 'display': 'flex', 'align-items': 'center', 'justify-content': 'center', 'z-index': '99999' }); // 重置查询参数 modalDeviceQueryParams = { devName: '' }; $('#modalDevNameInput').val(''); // 延迟初始化表格,确保弹框完全显示后再渲染表格 setTimeout(function () { initModalDeviceListTable(); }, 100); } // 关闭设备列表弹框 function closeDeviceListModal() { const modal = $('#deviceListModal'); modal.removeClass('show'); modal.css({ 'display': 'none' }); } // 初始化弹框内设备列表表格 function initModalDeviceListTable() { table.render({ elem: '#modalDeviceListTable', id: 'modalDeviceListTable', url: commonUrl + 'screen/resourceUtilization/getDevList', headers: { decrypt: 'decrypt', Authorization: token }, method: 'GET', where: { bidCode: bidCode, devName: modalDeviceQueryParams.devName || '' }, skin: 'line', page: { layout: ['prev', 'page', 'next', 'count', 'skip'], groups: 5, limit: pageSize, limits: [10, 20, 30, 50] }, height: 'full', request: { pageName: 'pageNum', limitName: 'pageSize' }, response: { statusName: 'code', statusCode: 0, msgName: 'msg', countName: 'count', dataName: 'data' }, cols: [[ { type: 'numbers', title: '序号', width: '10%', align: 'center' }, { field: 'devName', title: '设备名称', width: '25%', align: 'center' }, { field: 'inTime', title: '设备入场时间', width: '22%', align: 'center', templet: function (d) { return d.inTime || '-'; } }, { field: 'outTime', title: '设备出场时间', width: '22%', align: 'center', templet: function (d) { return d.outTime || '-'; } }, { field: 'usedDay', title: '设备在场使用天数', width: '21%', align: 'center', templet: function (d) { return d.usedDay || d.usedNum || 0; } } ]] }); } // 弹框内查询设备列表 function queryDeviceList() { // 获取搜索条件 modalDeviceQueryParams.devName = $('#modalDevNameInput').val() || ''; // 重新加载表格 table.reload('modalDeviceListTable', { where: { bidCode: bidCode, devName: modalDeviceQueryParams.devName }, page: { curr: 1 // 重新从第1页开始 } }); }