let table, layer, form, laydate;
let delayDistributionChart = null;
let bidCode = parent.parent.$('#bidPro').val();
let modalKeyword = '';
let modalTaskStatus = '';
let modalQueryParams = {
projectId: bidCode,
startTestDay: '',
endTestDay: '',
taskStatus: ''
};
// 获取当天日期
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,
}
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 getElectricTrend() {
const url = commonUrl + "screen/worker/analysis/summary?projectId=" + bidCode + "&startTestDay=" + '' + "&endTestDay=" + '';
ajaxRequestGet(url, "GET", true, function () {
}, function (result) {
console.log(result, '近七天用电趋势');
if (result) {
updateElectricTrendData(result.data);
}
}, aqEnnable);
}
// 更新近七天用电趋势数据
function updateElectricTrendData(data) {
const totalCount = data.totalCount || 0;
const finishedCount = data.finishedCount || 0;
const processingCount = data.processingCount || 0;
const notStartedCount = data.notStartedCount || 0;
const delayCount = data.delayCount || 0;
// 更新中心的任务总数
$('#totalTasks').text(totalCount);
// 计算百分比(保留2位小数)
const calculatePercent = function (count, total) {
if (total === 0) return '0.00';
return ((count / total) * 100).toFixed(2);
};
// 更新四个方向的显示:数量 + 百分比
const finishedPercent = calculatePercent(finishedCount, totalCount);
$('#completedPercent').text(finishedCount + ' ' + finishedPercent + '%');
const processingPercent = calculatePercent(processingCount, totalCount);
$('#inProgressPercent').text(processingCount + ' ' + processingPercent + '%');
const notStartedPercent = calculatePercent(notStartedCount, totalCount);
$('#notStartedPercent').text(notStartedCount + ' ' + notStartedPercent + '%');
const delayPercent = calculatePercent(delayCount, totalCount);
$('#delayedPercent').text(delayCount + ' ' + delayPercent + '%');
}
// 获取右上角月工种任务分布
function getTaskDistribution() {
const url = commonUrl + "screen/worker/analysis/gzsummary?projectId=" + bidCode + "&startTestDay=" + '' + "&endTestDay=" + '';
ajaxRequestGet(url, "GET", true, function () {
}, function (result) {
console.log(result, '月工种任务分布');
let data = result;
if (result && result.data) {
data = result.data;
}
if (data) {
// 更新顶部两个指标
const totalPerson = data.totalPerson || 0;
const totalTask = data.totalTask || 0;
$('#taskPersonnel').text(totalPerson);
$('#avgTasks').text(totalTask);
// 处理 taskCountByWorkType 对象
const taskCountByWorkType = data.taskCountByWorkType || {};
const jobTypeList = Object.keys(taskCountByWorkType).map(key => ({
name: key,
value: '人均' + (taskCountByWorkType[key] || 0) + '任务'
}));
updateJobTypeDistribution(jobTypeList);
}
}, aqEnnable);
}
// 获取左下角月任务延期排名top5
function getTaskDelayRanking() {
const url = commonUrl + "screen/worker/analysis/delay/person?projectId=" + bidCode + "&startTestDay=" + '' + "&endTestDay=" + '';
ajaxRequestGet(url, "GET", true, function () {
}, function (result) {
console.log(result, '月任务延期排名top5');
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;
}
// 转换数据格式:{ userName, delayCount } -> { name, count }
const formattedData = data.map(item => ({
name: item.userName || '',
count: parseInt(item.delayCount) || 0
}));
updateDelayRanking(formattedData);
}, aqEnnable);
}
// 获取下方中间的月任务延期分布
function getTaskDelayDistribution() {
const url = commonUrl + "screen/worker/analysis/delay/workType?projectId=" + bidCode + "&startTestDay=" + '' + "&endTestDay=" + '';
ajaxRequestGet(url, "GET", true, function () {
}, function (result) {
console.log(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;
}
// 转换数据格式并计算百分比
const totalDelayCount = data.reduce((sum, item) => sum + (parseInt(item.delayCount) || 0), 0);
const formattedData = data.map(item => {
const delayCount = parseInt(item.delayCount) || 0;
const percentage = totalDelayCount > 0 ? ((delayCount / totalDelayCount) * 100).toFixed(2) : 0;
return {
name: item.workType || '',
value: parseFloat(percentage)
};
});
updateDelayDistributionChart(formattedData);
}, aqEnnable);
}
// 获取右下方分析预警
function getAnalysisWarning() {
const url = commonUrl + "screen/worker/analysis/yujingdetail?projectId=" + bidCode + "&startTestDay=" + '' + "&endTestDay=" + '';
ajaxRequestGet(url, "GET", true, function () {
}, function (result) {
console.log(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;
}
updateWarningList(data);
}, aqEnnable);
}
// 获取数据(在页面初始化时调用)
// getElectricTrend();
// getTaskDistribution();
// getTaskDelayRanking();
// getTaskDelayDistribution();
// getAnalysisWarning();
// 初始化页面
function initPage() {
initDelayDistributionChart();
initMockData();
// 调用接口获取真实数据
getElectricTrend();
getTaskDistribution();
getTaskDelayRanking();
getTaskDelayDistribution();
getAnalysisWarning();
}
// 防抖函数
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;
$('#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-15 ~ 2026-01-15)
$('#dateRange').val(startDate + ' ~ ' + endDateStr);
// 更新查询参数
queryParams.startTestDay = startDate;
queryParams.endTestDay = endDateStr;
// 日期变化后,重新调用所有模块接口
refreshAllModules();
} else {
// 如果格式不正确,重置为当天日期
resetToToday();
}
} else {
// 清空时,重置为当天日期
resetToToday();
}
}
});
}
// 刷新所有模块数据
function refreshAllModules() {
// 重新调用所有接口
getElectricTrend();
getTaskDistribution();
getTaskDelayRanking();
getTaskDelayDistribution();
getAnalysisWarning();
// 注意:不再重新初始化图表,而是通过各自的更新函数来更新
}
// 初始化月任务延期分布饼图
function initDelayDistributionChart() {
const chartDom = document.getElementById('delayDistributionChart');
if (!chartDom) return;
if (delayDistributionChart) {
delayDistributionChart.dispose();
}
delayDistributionChart = echarts.init(chartDom);
// 模拟数据 - 后续替换为真实接口数据
const data = [
{ value: 15.87, name: '架子工' },
{ value: 26.50, name: '高空作业工' },
{ value: 23.14, name: 'XX工' },
{ value: 20.50, name: 'XX工' },
{ value: 10.28, name: 'XX工' }
];
const option = {
backgroundColor: 'transparent',
tooltip: {
trigger: 'item',
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) {
return `${params.name}
${params.value}%`;
}
},
legend: {
show: false
},
series: [
{
name: '月任务延期分布',
type: 'pie',
radius: ['40%', '70%'],
center: ['50%', '50%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 4,
borderColor: 'transparent',
borderWidth: 0
},
label: {
show: true,
position: 'outside',
formatter: function (params) {
return params.name + ': ' + params.value + '%';
},
color: '#FFFFFF',
fontSize: 12
},
labelLine: {
show: true,
lineStyle: {
color: 'rgba(255, 255, 255, 0.5)'
}
},
data: data.map(function (item, index) {
const colors = [
new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#00FFD4' },
{ offset: 1, color: '#00A8FF' }
]),
new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#FF9C65' },
{ offset: 1, color: '#FFD700' }
]),
new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#50E3C2' },
{ offset: 1, color: '#00D4FF' }
]),
new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#87CEEB' },
{ offset: 1, color: '#4A90E2' }
]),
new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#FF6B6B' },
{ offset: 1, color: '#FF8E53' }
])
];
return {
...item,
itemStyle: {
color: colors[index % colors.length]
}
};
})
}
]
};
delayDistributionChart.setOption(option);
// 更新图例
updateDelayLegend(data);
// 响应式调整
window.addEventListener('resize', debounce(function () {
if (delayDistributionChart) {
delayDistributionChart.resize();
}
}, 300));
}
// 更新延期分布图例
function updateDelayLegend(data) {
const legendContainer = document.getElementById('delayLegend');
if (!legendContainer) return;
const colors = ['#00FFD4', '#FF9C65', '#50E3C2', '#87CEEB', '#FF6B6B'];
const legendHtml = data.map(function (item, index) {
return `