// HiddenSolve.js - 隐患解决页面组件
import React from 'react';
import { Select, Table } from 'antd';
import styles from './../fullinter.less';
import echarts from 'echarts';
const { Option } = Select;
class HiddenSolve extends React.Component {
constructor(props) {
super(props);
this.echartsInstances = {
hiddenBarChart: null, // 各公司隐患统计柱状图(使用 hiddenList)
hiddenRectifyChart: null, // 隐患整改情况柱状图(使用 hiddenRectifyList)
};
this.chartResizeHandlers = {};
this.isUnmounted = false;
// 添加缓存,用于比较数据是否真正变化
this.lastHiddenList = null;
this.lastHiddenRectifyList = null;
}
// 获取公司选项(使用 props 传入的 companyData,与 TrainingContent 一致)
getCompanyOptions = () => {
const { companyData } = this.props;
if (!companyData || companyData.length === 0) {
return [];
}
return companyData.map((company, index) => (
));
};
// 根据选中的公司ID获取公司名称(用于筛选模拟数据)
getSelectedCompanyName = () => {
const { companyData, selectedCompany } = this.props;
if (!selectedCompany || !companyData || companyData.length === 0) {
return null;
}
const selectedCompanyObj = companyData.find((company) => company.ID === selectedCompany);
return selectedCompanyObj ? selectedCompanyObj.NAME : null;
};
waitForElement = (elementId, maxRetries = 10) => {
return new Promise((resolve) => {
let retries = 0;
const checkInterval = setInterval(() => {
const element = document.getElementById(elementId);
if (element || retries >= maxRetries) {
clearInterval(checkInterval);
resolve(!!element);
}
retries++;
}, 50);
});
};
// 图表1: 各公司隐患统计柱状图(使用 hiddenList 数据)
renderHiddenBarChart = async () => {
if (this.isUnmounted) return;
const elementExists = await this.waitForElement('hiddenBarChart');
if (!elementExists || this.isUnmounted) return;
if (this.echartsInstances.hiddenBarChart) {
this.echartsInstances.hiddenBarChart.dispose();
this.echartsInstances.hiddenBarChart = null;
}
const chartDom = document.getElementById('hiddenBarChart');
if (!chartDom) return;
this.echartsInstances.hiddenBarChart = echarts.init(chartDom);
const { hiddenSubData } = this.props;
let hiddenList = hiddenSubData?.hiddenList || [];
if (hiddenList.length === 0) {
this.echartsInstances.hiddenBarChart.setOption({
title: {
text: '各公司累计隐患统计数据',
x: 'center',
y: '25%',
textStyle: { fontSize: 16, color: '#999' },
},
graphic: {
type: 'text',
left: 'center',
top: 'middle',
style: {
text: '暂无数据',
fill: '#999',
fontSize: 14,
},
},
});
return;
}
const companyNames = hiddenList.map((item) => item.companyName);
const majorCounts = hiddenList.map((item) => item.majorCount);
const generalCounts = hiddenList.map((item) => item.generalCount);
const option = {
title: {
text: '各公司累计隐患统计数据',
x: 'center',
y: '5%',
textStyle: { fontSize: 16, color: '#000', fontWeight: 'bold' },
},
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' },
formatter: function (params) {
let result = `${params[0].axisValue}
`;
params.forEach((param) => {
result += `${param.marker}${param.seriesName}: ${param.value}
`;
});
return result;
},
},
legend: {
data: ['重大隐患', '一般隐患'],
right: '3%',
top: '10%',
itemGap: 12,
itemWidth: 16,
itemHeight: 10,
textStyle: { color: '#000', fontSize: 12 },
},
grid: {
left: '8%',
right: '5%',
top: '28%',
bottom: '8%',
containLabel: true,
},
xAxis: [
{
type: 'category',
data: companyNames,
axisLine: { show: false },
axisTick: { show: false },
axisLabel: {
textStyle: { color: '#000' },
rotate: companyNames.length > 4 ? 15 : 0,
interval: 0,
fontSize: 12,
},
},
],
yAxis: [
{
type: 'value',
show: true,
axisLine: { show: false },
axisTick: { show: false },
axisLabel: {
show: true,
textStyle: { color: '#000' },
},
splitLine: { show: false },
name: '隐患数量',
nameTextStyle: { fontSize: 12 },
},
],
series: [
{
name: '重大隐患',
type: 'bar',
data: majorCounts,
itemStyle: {
normal: {
color: '#c92a2a', // 红色
},
},
label: {
show: true,
position: 'top',
textStyle: { color: '#c92a2a', fontSize: 12 },
formatter: (params) => `${params.value}`,
},
barWidth: '35%',
},
{
name: '一般隐患',
type: 'bar',
data: generalCounts,
itemStyle: {
normal: {
color: '#4285F4', // 蓝色
},
},
label: {
show: true,
position: 'top',
textStyle: { color: '#4285F4', fontSize: 12 },
formatter: (params) => `${params.value}`,
},
barWidth: '35%',
},
],
};
this.echartsInstances.hiddenBarChart.setOption(option);
this.setupResizeHandler('hiddenBarChart', this.renderHiddenBarChart);
};
// 图表2: 隐患整改情况柱状图(使用 hiddenRectifyList 数据)
renderHiddenRectifyChart = async () => {
if (this.isUnmounted) return;
const elementExists = await this.waitForElement('hiddenRectifyChart');
if (!elementExists || this.isUnmounted) return;
if (this.echartsInstances.hiddenRectifyChart) {
this.echartsInstances.hiddenRectifyChart.dispose();
this.echartsInstances.hiddenRectifyChart = null;
}
const chartDom = document.getElementById('hiddenRectifyChart');
if (!chartDom) return;
this.echartsInstances.hiddenRectifyChart = echarts.init(chartDom);
const { hiddenSubData } = this.props;
let hiddenRectifyList = hiddenSubData?.hiddenRectifyList || [];
if (hiddenRectifyList.length === 0) {
this.echartsInstances.hiddenRectifyChart.setOption({
title: {
text: '当月各公司隐患统计数据',
x: 'center',
y: '25%',
textStyle: { fontSize: 16, color: '#999' },
},
graphic: {
type: 'text',
left: 'center',
top: 'middle',
style: {
text: '暂无数据',
fill: '#999',
fontSize: 14,
},
},
});
return;
}
const companyNames = hiddenRectifyList.map((item) => item.companyName);
const majorTotal = hiddenRectifyList.map((item) => item.majorCount);
const majorRectified = hiddenRectifyList.map((item) => (item.majorCount || 0) - (item.majorCountNo || 0));
const generalTotal = hiddenRectifyList.map((item) => item.generalCount);
const generalRectified = hiddenRectifyList.map((item) => (item.generalCount || 0) - (item.generalCountNo || 0));
const option = {
title: {
text: '当月各公司隐患统计数据',
x: 'center',
y: '5%',
textStyle: { fontSize: 16, color: '#000', fontWeight: 'bold' },
},
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' },
formatter: function (params) {
let result = `${params[0].axisValue}
`;
params.forEach((param) => {
result += `${param.marker}${param.seriesName}: ${param.value}
`;
});
return result;
},
},
legend: {
data: ['重大隐患量', '重大隐患未整改量', '一般隐患量', '一般隐患未整改量'],
right: '3%',
top: '10%',
itemGap: 12,
itemWidth: 16,
itemHeight: 10,
textStyle: { color: '#000', fontSize: 12 },
},
grid: {
left: '8%',
right: '5%',
top: '28%',
bottom: '8%',
containLabel: true,
},
xAxis: [
{
type: 'category',
data: companyNames,
axisLine: { show: false },
axisTick: { show: false },
axisLabel: {
textStyle: { color: '#000' },
rotate: companyNames.length > 4 ? 15 : 0,
interval: 0,
fontSize: 12,
},
},
],
yAxis: [
{
type: 'value',
show: true,
axisLine: { show: false },
axisTick: { show: false },
axisLabel: {
show: true,
textStyle: { color: '#000' },
},
splitLine: { show: false },
name: '隐患数量',
nameTextStyle: { fontSize: 12 },
},
],
series: [
{
name: '重大隐患量',
type: 'bar',
data: majorTotal,
itemStyle: {
normal: {
color: '#c92a2a', // 红色
},
},
label: {
show: true,
position: 'top',
textStyle: { color: '#c92a2a', fontSize: 11 },
formatter: (params) => `${params.value}`,
},
barWidth: '20%',
},
{
name: '重大隐患未整改量',
type: 'bar',
data: majorRectified,
itemStyle: {
normal: {
color: '#ffa94d', // 橙色
},
},
label: {
show: true,
position: 'top',
textStyle: { color: '#ffa94d', fontSize: 11 },
formatter: (params) => `${params.value}`,
},
barWidth: '20%',
},
{
name: '一般隐患量',
type: 'bar',
data: generalTotal,
itemStyle: {
normal: {
color: '#4285F4', // 蓝色
},
},
label: {
show: true,
position: 'top',
textStyle: { color: '#4285F4', fontSize: 11 },
formatter: (params) => `${params.value}`,
},
barWidth: '20%',
},
{
name: '一般隐患未整改量',
type: 'bar',
data: generalRectified,
itemStyle: {
normal: {
color: '#ffe066', // 黄色
},
},
label: {
show: true,
position: 'top',
textStyle: { color: '#d4a000', fontSize: 11 },
formatter: (params) => `${params.value}`,
},
barWidth: '20%',
},
],
};
this.echartsInstances.hiddenRectifyChart.setOption(option);
this.setupResizeHandler('hiddenRectifyChart', this.renderHiddenRectifyChart);
};
// 排名列表组件(支持公司筛选)
renderRankingList = () => {
const { hiddenSubData, selectedCompany, onCompanyChange, companyData } = this.props;
let hiddenRanking = hiddenSubData?.hiddenRanking || [];
// 根据选中的公司筛选数据(前端筛选)
const selectedCompanyName = this.getSelectedCompanyName();
let filteredRanking = hiddenRanking;
if (selectedCompanyName) {
filteredRanking = hiddenRanking.filter((item) => item.companyName === selectedCompanyName);
}
// 如果没选中公司或筛选后没有数据,显示全部或空状态
if (!selectedCompanyName || filteredRanking.length === 0) {
filteredRanking = selectedCompanyName ? [] : hiddenRanking;
}
// 表格列配置(与 RiskControl 样式保持一致)
const columns = [
{
title: '序号',
dataIndex: 'index',
key: 'index',
align: 'center',
width: 80,
render: (text, record, index) => {index + 1},
},
{
title: '隐患名称',
dataIndex: 'hiddenName',
key: 'hiddenName',
align: 'center',
// 中间列自适应,不设置固定宽度
render: (text) => {text},
},
{
title: '数量',
dataIndex: 'qty',
key: 'qty',
align: 'center',
width: 80,
render: (text) => {text},
},
];
const tableData = filteredRanking.map((item, index) => ({
key: index,
index: index + 1,
hiddenName: item.hiddenName,
qty: item.qty,
}));
const scrollConfig = filteredRanking.length > 5 ? { y: 300 } : {};
return (