hb_zhgd_screen/js/pages/dataAnalysisOctober/overallEfficiency.js

843 lines
26 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

let table, layer, form, laydate;
let avgTasksChart = null;
let equipmentUsageChart = null;
let bidCode = parent.parent.$('#bidPro').val();
// 获取当天日期
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');
return year + '-' + month + '-' + day;
}
// 获取当月第一天和最后一天(保留用于其他功能)
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 = {
projectId: bidCode,
startTestDay: today,
endTestDay: today,
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);
};
},
});
// 初始化页面
initPage();
// 初始化日期范围选择器
initDateRangePicker();
});
// 初始化页面
function initPage() {
initPersonnelTables();
getTop5Personnel();
getBottom5Personnel();
getTradeProportionAndAvgTasks();
getEquipmentUsageAndFailureRank();
getEquipmentFailureRank();
initTradeProportion();
initAvgTasksChart();
initEquipmentUsageChart();
initEquipmentFailureList();
initWarningTable();
initMockData();
}
// 获取人员数据中的班组利用率排名前五名的
function getTop5Personnel() {
const url = commonUrl + 'screen/largeScreen/sjNewOverall/selectTopList'
+ '?bidCode=' + (bidCode || '')
+ '&startTime=' + (queryParams.startTime || '')
+ '&endTime=' + (queryParams.endTime || '');
ajaxRequestGet(url, 'GET', true, function () { }, function (result) {
let data = [];
if (result && result.data && Array.isArray(result.data)) {
data = result.data;
} else if (result && Array.isArray(result)) {
data = result;
} else if (result && result.rows && Array.isArray(result.rows)) {
data = result.rows;
}
updateTop5PersonnelTable(data);
}, aqEnnable);
}
// 获取后5名人员数据
function getBottom5Personnel() {
const url = commonUrl + 'screen/largeScreen/sjNewOverall/selectDownList'
+ '?bidCode=' + (bidCode || '')
+ '&startTime=' + (queryParams.startTime || '')
+ '&endTime=' + (queryParams.endTime || '');
ajaxRequestGet(url, 'GET', true, function () { }, function (result) {
let data = [];
if (result && result.data && Array.isArray(result.data)) {
data = result.data;
} else if (result && Array.isArray(result)) {
data = result;
} else if (result && result.rows && Array.isArray(result.rows)) {
data = result.rows;
}
updateBottom5PersonnelTable(data);
}, aqEnnable);
}
// 获取各工种任务占比和人均任务数
function getTradeProportionAndAvgTasks() {
const url = commonUrl + 'screen/largeScreen/sjNewOverall/getWorkTypeRate'
+ '?bidCode=' + (bidCode || '')
+ '&startTime=' + (queryParams.startTime || '')
+ '&endTime=' + (queryParams.endTime || '');
ajaxRequestGet(url, 'GET', true, function () { }, function (result) {
let data = [];
if (result && result.data && Array.isArray(result.data)) {
data = result.data;
} else if (result && Array.isArray(result)) {
data = result;
} else if (result && result.rows && Array.isArray(result.rows)) {
data = result.rows;
}
updateTradeProportion(data);
updateAvgTasksChart(data);
}, aqEnnable);
}
// 获取设备使用率
function getEquipmentUsageAndFailureRank() {
const url = commonUrl + 'screen/largeScreen/sjNewOverall/getWeeksDevData'
+ '?bidCode=' + (bidCode || '')
+ '&startTime=' + (queryParams.startTime || '')
+ '&endTime=' + (queryParams.endTime || '');
ajaxRequestGet(url, 'GET', true, function () { }, function (result) {
let data = [];
if (result && result.data && Array.isArray(result.data)) {
data = result.data;
} else if (result && Array.isArray(result)) {
data = result;
} else if (result && result.rows && Array.isArray(result.rows)) {
data = result.rows;
}
updateEquipmentUsageChart(data);
}, aqEnnable);
}
// 获取设备故障排名
function getEquipmentFailureRank() {
const url = commonUrl + 'screen/largeScreen/sjNewOverall/getDevErrTop'
+ '?bidCode=' + (bidCode || '')
+ '&startTime=' + (queryParams.startTime || '')
+ '&endTime=' + (queryParams.endTime || '');
ajaxRequestGet(url, 'GET', true, function () { }, function (result) {
let data = [];
if (result && result.data && Array.isArray(result.data)) {
data = result.data;
} else if (result && Array.isArray(result)) {
data = result;
} else if (result && result.rows && Array.isArray(result.rows)) {
data = result.rows;
}
updateEquipmentFailureList(data);
}, aqEnnable);
}
// 获取工程进度
function getEngineeringProgress() {
const url = commonUrl + 'screen/largeScreen/sjNewOverall/getProProgress'
+ '?bidCode=' + (bidCode || '')
+ '&startTime=' + (queryParams.startTime || '')
+ '&endTime=' + (queryParams.endTime || '');
ajaxRequestGet(url, 'GET', true, function () { }, function (result) {
let data = [];
if (result && result.data && Array.isArray(result.data)) {
data = result.data;
} else if (result && Array.isArray(result)) {
data = result;
} else if (result && result.rows && Array.isArray(result.rows)) {
data = result.rows;
}
updateEngineeringProgress(data);
}, aqEnnable);
}
getEngineeringProgress()
// 更新工程进度展示(取 data[0] 的 planProgress、progress
function updateEngineeringProgress(data) {
if (!data || !Array.isArray(data) || data.length === 0) {
return;
}
const item = data[0];
const planProgress = parseFloat(item.planProgress || 0);
const progress = parseFloat(item.progress || 0);
$('#plannedProgressText').text(planProgress.toFixed(1) + '%');
$('#actualProgressText').text(progress.toFixed(1) + '%');
// 进度条宽度归一化,两者之和为 100%
const total = planProgress + progress;
const planPercent = total > 0 ? (planProgress / total * 100) : 50;
const actualPercent = total > 0 ? (progress / total * 100) : 50;
$('#actualProgressFill').css('width', actualPercent + '%');
$('#plannedProgressFill').css('width', planPercent + '%');
}
// 获取分析预警
function getAnalysisWarning() {
const url = commonUrl + 'screen/largeScreen/sjNewOverall/getWarnList'
+ '?bidCode=' + (bidCode || '')
+ '&startTime=' + (queryParams.startTime || '')
+ '&endTime=' + (queryParams.endTime || '');
ajaxRequestGet(url, 'GET', true, function () { }, function (result) {
let data = [];
if (result && result.data && Array.isArray(result.data)) {
data = result.data;
} else if (result && Array.isArray(result)) {
data = result;
} else if (result && result.rows && Array.isArray(result.rows)) {
data = result.rows;
}
updateAnalysisWarningTable(data);
}, aqEnnable);
}
getAnalysisWarning()
// 更新分析预警表格data 直接渲染)
function updateAnalysisWarningTable(data) {
if (!table) return;
table.reload('warningTable', {
data: data || []
});
}
// 防抖函数
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// 初始化日期范围选择器
function initDateRangePicker() {
// 设置初始显示值为当天范围
const initialValue = queryParams.startTestDay + ' ~ ' + queryParams.endTestDay;
$('#dateRange').val(initialValue);
// 使用范围选择器,单个输入框显示日期范围
laydate.render({
elem: '#dateRange',
type: 'date',
range: true,
format: 'yyyy-MM-dd',
theme: 'dark',
value: queryParams.startTestDay + ' - ' + queryParams.endTestDay,
done: function (value, date, endDate) {
// 重置为当天日期的函数
const resetToToday = function () {
const today = getTodayDate();
queryParams.startTestDay = today;
queryParams.endTestDay = today;
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();
$('#dateRange').val(startDate + ' ~ ' + endDateStr);
queryParams.startTestDay = startDate;
queryParams.endTestDay = endDateStr;
queryParams.startTime = startDate;
queryParams.endTime = endDateStr;
refreshAllModules();
} else {
resetToToday();
}
} else {
resetToToday();
}
}
});
}
// 刷新所有模块数据
function refreshAllModules() {
getTop5Personnel();
getBottom5Personnel();
getTradeProportionAndAvgTasks();
getEquipmentUsageAndFailureRank();
getEquipmentFailureRank();
if (avgTasksChart) {
initAvgTasksChart();
}
if (equipmentUsageChart) {
initEquipmentUsageChart();
}
if (table) {
table.reload('warningTable');
}
}
// 初始化人员数据表格前5名和后5名
function initPersonnelTables() {
// 前5名表格
table.render({
elem: '#top5PersonnelTable',
id: 'top5PersonnelTable',
data: [],
skin: 'line',
page: false,
height: 'full',
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: '18%', align: 'center' },
{ field: 'teamPeople', title: '班组人数', width: '12%', align: 'center' },
{ field: 'dutyPeople', title: '当日到岗', width: '12%', align: 'center' },
{
field: 'userRate',
title: '利用率',
width: '13%',
align: 'center',
templet: function (d) {
const rate = d.userRate || '0.00%';
return rate;
}
}
]]
});
// 后5名表格
table.render({
elem: '#bottom5PersonnelTable',
id: 'bottom5PersonnelTable',
data: [],
skin: 'line',
page: false,
height: 'full',
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: '18%', align: 'center' },
{ field: 'teamPeople', title: '班组人数', width: '12%', align: 'center' },
{ field: 'dutyPeople', title: '当日到岗', width: '12%', align: 'center' },
{
field: 'userRate',
title: '利用率',
width: '13%',
align: 'center',
templet: function (d) {
const rate = d.userRate || '0.00%';
return rate;
}
}
]]
});
}
// 更新前5名人员表格数据
function updateTop5PersonnelTable(data) {
if (!table || !data || !Array.isArray(data)) return;
table.reload('top5PersonnelTable', {
data: data
});
}
// 更新后5名人员表格数据
function updateBottom5PersonnelTable(data) {
if (!table || !data || !Array.isArray(data)) return;
table.reload('bottom5PersonnelTable', {
data: data
});
}
// 初始化各工种任务占比(六边形卡片)
function initTradeProportion() {
// 初始化为空,等待接口数据
const container = document.getElementById('tradeProportionContainer');
if (!container) return;
container.innerHTML = '';
}
// 更新各工种任务占比(六边形卡片)
function updateTradeProportion(data) {
if (!data || !Array.isArray(data) || data.length === 0) {
const container = document.getElementById('tradeProportionContainer');
if (container) {
container.innerHTML = '';
}
return;
}
// 计算总任务数
const totalTasks = data.reduce((sum, item) => {
const taskNum = parseFloat(item.taskNum || 0);
return sum + taskNum;
}, 0);
// 计算每个工种的占比
const proportionData = data.map(function (item) {
const taskNum = parseFloat(item.taskNum || 0);
const percentage = totalTasks > 0 ? (taskNum / totalTasks * 100).toFixed(2) : 0;
return {
value: parseFloat(percentage),
label: item.workType || ''
};
});
const container = document.getElementById('tradeProportionContainer');
if (!container) return;
const html = proportionData.map(function (item) {
return `
<div class="trade-proportion-box">
<div class="trade-proportion-value">${item.value}%</div>
<div class="trade-proportion-label">${item.label}</div>
</div>
`;
}).join('');
container.innerHTML = html;
}
// 初始化各工种人均任务数柱状图
function initAvgTasksChart() {
const chartDom = document.getElementById('avgTasksChart');
if (!chartDom) return;
if (avgTasksChart) {
avgTasksChart.dispose();
}
avgTasksChart = echarts.init(chartDom);
// 初始化为空数据
const option = {
backgroundColor: 'transparent',
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' },
backgroundColor: 'rgba(13, 34, 37, 0.95)',
borderColor: 'rgba(6, 189, 221, 0.8)',
borderWidth: 1,
borderRadius: 4,
padding: [12, 16],
textStyle: {
color: '#FFFFFF',
fontSize: 12
},
formatter: function (params) {
if (!params || !params.length) return '';
const name = params[0].name || '';
const value = params[0].value || 0;
return `${name}<br/>人均任务数: ${value}`;
}
},
grid: {
left: '10%',
right: '10%',
bottom: '15%',
top: '10%',
containLabel: true
},
xAxis: {
type: 'category',
data: [],
axisLabel: {
color: '#FFFFFF',
fontSize: 12
},
axisLine: {
lineStyle: {
color: 'rgba(255, 255, 255, 0.3)',
type: 'dashed'
}
},
axisTick: { show: false }
},
yAxis: {
type: 'value',
min: 0,
axisLabel: {
color: '#FFFFFF',
fontSize: 12
},
axisLine: {
show: false
},
splitLine: {
lineStyle: {
color: 'rgba(255, 255, 255, 0.15)',
type: 'dashed'
}
},
axisTick: { show: false }
},
series: [
{
name: '人均任务数',
type: 'bar',
data: [],
barWidth: '40%',
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: '#00FFB8'
}, {
offset: 0.5,
color: '#00D4FF'
}, {
offset: 1,
color: '#00A8FF'
}]),
borderRadius: [2, 2, 0, 0]
},
label: {
show: true,
position: 'top',
color: '#FFFFFF',
fontSize: 12
}
}
]
};
avgTasksChart.setOption(option);
// 响应式调整
window.addEventListener('resize', debounce(function () {
if (avgTasksChart) {
avgTasksChart.resize();
}
}, 300));
}
// 更新各工种人均任务数柱状图
function updateAvgTasksChart(data) {
if (!avgTasksChart || !data || !Array.isArray(data) || data.length === 0) {
return;
}
// 提取工种类型和任务数
const categories = data.map(item => item.workType || '');
const taskNums = data.map(item => parseFloat(item.taskNum || 0));
// 计算y轴最大值向上取整到最近的10的倍数
const maxValue = Math.max(...taskNums, 0);
const yAxisMax = maxValue > 0 ? Math.ceil(maxValue / 10) * 10 : 10;
const interval = Math.ceil(yAxisMax / 5);
avgTasksChart.setOption({
xAxis: {
data: categories
},
yAxis: {
max: yAxisMax,
interval: interval
},
series: [
{
data: taskNums
}
]
});
}
// 初始化各设备使用率折线图
function initEquipmentUsageChart() {
const chartDom = document.getElementById('equipmentUsageChart');
if (!chartDom) return;
if (equipmentUsageChart) {
equipmentUsageChart.dispose();
}
equipmentUsageChart = echarts.init(chartDom);
// 初始化为空数据
const option = {
backgroundColor: 'transparent',
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(13, 34, 37, 0.95)',
borderColor: 'rgba(6, 189, 221, 0.8)',
borderWidth: 1,
borderRadius: 4,
padding: [12, 16],
textStyle: {
color: '#FFFFFF',
fontSize: 12
}
},
legend: {
data: ['入场天数', '使用天数'],
top: '5%',
right: '5%',
textStyle: {
color: '#FFFFFF',
fontSize: 12
},
itemWidth: 12,
itemHeight: 12
},
grid: {
left: '10%',
right: '10%',
bottom: '15%',
top: '20%',
containLabel: true
},
xAxis: {
type: 'category',
data: [],
axisLabel: {
color: '#FFFFFF',
fontSize: 12
},
axisLine: {
lineStyle: {
color: 'rgba(255, 255, 255, 0.3)',
type: 'dashed'
}
},
axisTick: { show: false }
},
yAxis: {
type: 'value',
min: 0,
axisLabel: {
color: '#FFFFFF',
fontSize: 12
},
axisLine: {
show: false
},
splitLine: {
lineStyle: {
color: 'rgba(255, 255, 255, 0.15)',
type: 'dashed'
}
},
axisTick: { show: false }
},
series: [
{
name: '入场天数',
type: 'line',
data: [],
itemStyle: {
color: '#00FFB8'
},
lineStyle: {
width: 2,
color: '#00FFB8'
},
symbol: 'circle',
symbolSize: 6,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(0, 255, 184, 0.3)'
}, {
offset: 1,
color: 'rgba(0, 255, 184, 0.05)'
}])
}
},
{
name: '使用天数',
type: 'line',
data: [],
itemStyle: {
color: '#50E3C2'
},
lineStyle: {
width: 2,
color: '#50E3C2'
},
symbol: 'circle',
symbolSize: 6,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(80, 227, 194, 0.3)'
}, {
offset: 1,
color: 'rgba(80, 227, 194, 0.05)'
}])
}
}
]
};
equipmentUsageChart.setOption(option);
// 响应式调整
window.addEventListener('resize', debounce(function () {
if (equipmentUsageChart) {
equipmentUsageChart.resize();
}
}, 300));
}
// 更新各设备使用率折线图
function updateEquipmentUsageChart(data) {
if (!equipmentUsageChart || !data || !Array.isArray(data) || data.length === 0) {
return;
}
// 提取设备名称、入场天数和使用天数
const categories = data.map(item => item.devName || '');
const usedDayData = data.map(item => parseFloat(item.usedDay || 0));
const usedNumData = data.map(item => parseFloat(item.usedNum || 0));
// 计算y轴最大值向上取整到最近的10的倍数
const maxValue = Math.max(...usedDayData, ...usedNumData, 0);
const yAxisMax = maxValue > 0 ? Math.ceil(maxValue / 10) * 10 : 10;
const interval = Math.ceil(yAxisMax / 5);
equipmentUsageChart.setOption({
xAxis: {
data: categories
},
yAxis: {
max: yAxisMax,
interval: interval
},
series: [
{
name: '入场天数',
data: usedDayData
},
{
name: '使用天数',
data: usedNumData
}
]
});
}
// 初始化设备故障排名列表
function initEquipmentFailureList() {
// 初始化为空,等待接口数据
const container = document.getElementById('equipmentFailureList');
if (!container) return;
container.innerHTML = '';
}
// 更新设备故障排名列表
function updateEquipmentFailureList(data) {
if (!data || !Array.isArray(data) || data.length === 0) {
const container = document.getElementById('equipmentFailureList');
if (container) {
container.innerHTML = '';
}
return;
}
const container = document.getElementById('equipmentFailureList');
if (!container) return;
const html = data.map(function (item) {
const devName = item.devName || '';
const remark = item.remark || '0';
return `
<div class="failure-item">
<span class="failure-equipment">${devName}</span>
<span class="failure-count">累计故障${remark}次</span>
</div>
`;
}).join('');
container.innerHTML = html;
}
// 初始化分析预警表格(无分页)
function initWarningTable() {
table.render({
elem: '#warningTable',
id: 'warningTable',
data: [],
skin: 'line',
page: false,
height: 'full',
cols: [[
{ type: 'numbers', title: '序号', width: '10%', align: 'center' },
{ field: 'txTime', title: '预警时间', width: '20%', align: 'center' },
{ field: 'content', title: '预警内容', width: '50%', align: 'left' },
{
title: '操作',
width: '20%',
align: 'center',
templet: function (d) {
return '<a href="javascript:void(0)" style="color: #00FFB8;" onclick="formulateStrategy(\'' + (d.id || '') + '\')">制定策略</a>';
}
}
]]
});
}
// 制定策略(占位函数)
function formulateStrategy(id) {
console.log('制定策略ID:', id);
// 后续实现
}
// 初始化模拟数据(后续替换为真实接口数据)
function initMockData() {
// 人员数据表格使用layui table的url自动加载
// 其他模块数据已在各自的init函数中初始化
}