diff --git a/src/layout/FullOther/DangerJob.js b/src/layout/FullOther/DangerJob.js
index 27468a8..1f36159 100644
--- a/src/layout/FullOther/DangerJob.js
+++ b/src/layout/FullOther/DangerJob.js
@@ -1,6 +1,7 @@
// DangerJob.js - 危险作业页面组件
import React from 'react';
-import { Table, Select, Pagination } from 'antd';
+import { Table, Select, Pagination, DatePicker } from 'antd';
+import echarts from 'echarts';
import styles from './../fullinter.less';
const { Option } = Select;
@@ -10,9 +11,15 @@ class DangerJob extends React.Component {
super(props);
this.state = {
currentPage: 1,
- pageSize: 20,
+ pageSize: 10,
};
+ this.echartsInstances = {
+ dangerOperationChart: null, // 当日工作票统计柱状图
+ };
+ this.chartResizeHandlers = {};
this.isUnmounted = false;
+ // 添加缓存,用于比较数据是否真正变化
+ this.lastJobTodayQty = null;
}
// 生成公司选项(与 TrainingContent 保持一致)
@@ -23,8 +30,6 @@ class DangerJob extends React.Component {
}
return companyData.map((company, index) => (
));
@@ -40,14 +45,222 @@ class DangerJob extends React.Component {
});
};
+ // 处理开始日期变化
+ startChange = (value) => {
+ const { onStartChange } = this.props;
+ this.setState({ currentPage: 1 }, () => {
+ if (onStartChange) {
+ onStartChange(value);
+ }
+ });
+ };
+
+ // 处理结束日期变化
+ endChange = (value) => {
+ const { onEndChange } = this.props;
+ this.setState({ currentPage: 1 }, () => {
+ if (onEndChange) {
+ onEndChange(value);
+ }
+ });
+ };
+
// 处理页码变化
handlePageChange = (page, pageSize) => {
this.setState({ currentPage: page, pageSize });
};
- // 处理每页条数变化
- handleShowSizeChange = (current, size) => {
- this.setState({ currentPage: 1, pageSize: size });
+ // 等待DOM元素加载完成
+ 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);
+ });
+ };
+
+ // 设置resize监听
+ setupResizeHandler = (chartName, renderMethod) => {
+ const resizeHandler = () => {
+ if (this.echartsInstances[chartName] && !this.isUnmounted) {
+ this.echartsInstances[chartName].resize();
+ }
+ };
+ this.chartResizeHandlers[chartName] = resizeHandler;
+ window.addEventListener('resize', resizeHandler);
+ };
+
+ // 图表: 当日工作票统计柱状图
+ renderDangerOperationChart = async () => {
+ if (this.isUnmounted) return;
+ const elementExists = await this.waitForElement('dangerOperationChart');
+ if (!elementExists || this.isUnmounted) return;
+
+ if (this.echartsInstances.dangerOperationChart) {
+ this.echartsInstances.dangerOperationChart.dispose();
+ this.echartsInstances.dangerOperationChart = null;
+ }
+
+ const chartDom = document.getElementById('dangerOperationChart');
+ if (!chartDom) return;
+
+ this.echartsInstances.dangerOperationChart = echarts.init(chartDom);
+
+ const { jobTodayQty } = this.props;
+ let linkData = jobTodayQty || [];
+
+ // 如果没有数据,显示“暂无数据”提示
+ if (linkData.length === 0) {
+ this.echartsInstances.dangerOperationChart.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 xAxisData = linkData.map((item) => item.name);
+ const seriesData = linkData.map((item) => item.qty);
+
+ const option = {
+ title: {
+ text: '当日工作票的统计数量',
+ x: 'center',
+ y: '5%',
+ textStyle: { fontSize: 16, color: '#000', fontWeight: 'bold' },
+ },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: { type: 'shadow' },
+ formatter: function (params) {
+ const color = params[0].color;
+ return `
+
+ ${params[0].name}:
+ ${params[0].value}
+
`;
+ },
+ backgroundColor: 'rgba(255, 255, 255, 0.9)',
+ borderColor: '#4285F4',
+ borderWidth: 1,
+ textStyle: { color: '#000', fontSize: 14 },
+ },
+ grid: {
+ left: '8%',
+ right: '5%',
+ top: '18%',
+ bottom: '8%',
+ containLabel: true,
+ },
+ xAxis: [
+ {
+ type: 'category',
+ data: xAxisData,
+ axisLine: { show: false },
+ axisTick: { show: false },
+ axisLabel: {
+ textStyle: { color: '#000' },
+ rotate: xAxisData.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: seriesData,
+ itemStyle: {
+ normal: {
+ color: '#4285F4',
+ borderRadius: [12, 12, 0, 0],
+ },
+ emphasis: {
+ shadowBlur: 10,
+ shadowOffsetX: 0,
+ shadowColor: 'rgba(0, 0, 0, 0.3)',
+ },
+ },
+ label: {
+ show: true,
+ position: 'top',
+ textStyle: { color: '#4285F4', fontSize: 12, fontWeight: 'bold' },
+ formatter: (params) => `${params.value}`,
+ },
+ barWidth: '50%',
+ barMaxWidth: 60,
+ },
+ ],
+ };
+
+ this.echartsInstances.dangerOperationChart.setOption(option);
+ this.setupResizeHandler('dangerOperationChart', this.renderDangerOperationChart);
+ };
+
+ // 初始化所有图表
+ initAllCharts = () => {
+ if (this.isUnmounted) return;
+ setTimeout(() => {
+ if (this.isUnmounted) return;
+ this.renderDangerOperationChart();
+ }, 100);
+ };
+
+ // 销毁所有图表
+ disposeAllCharts = () => {
+ Object.keys(this.echartsInstances).forEach((key) => {
+ if (this.echartsInstances[key]) {
+ try {
+ this.echartsInstances[key].dispose();
+ } catch (e) {
+ console.warn(`Dispose chart ${key} error:`, e);
+ }
+ this.echartsInstances[key] = null;
+ }
+ });
+
+ Object.keys(this.chartResizeHandlers).forEach((key) => {
+ if (this.chartResizeHandlers[key]) {
+ window.removeEventListener('resize', this.chartResizeHandlers[key]);
+ }
+ });
+ this.chartResizeHandlers = {};
};
// 获取过滤后的数据(添加类型检查和默认值)
@@ -88,33 +301,48 @@ class DangerJob extends React.Component {
};
};
+ // 添加 shouldComponentUpdate 优化性能
+ shouldComponentUpdate(nextProps, nextState) {
+ // 检查状态变化
+ if (this.state.currentPage !== nextState.currentPage || this.state.pageSize !== nextState.pageSize) {
+ return true;
+ }
+ // 检查 props 变化
+ if (
+ this.props.jobTodayQty !== nextProps.jobTodayQty ||
+ this.props.dangerSubData !== nextProps.dangerSubData ||
+ this.props.selectedCompany !== nextProps.selectedCompany ||
+ this.props.selectedStartDate !== nextProps.selectedStartDate ||
+ this.props.selectedEndDate !== nextProps.selectedEndDate ||
+ this.props.companyData !== nextProps.companyData
+ ) {
+ return true;
+ }
+ return false;
+ }
+
// 渲染危险作业表格
renderDangerTable = () => {
const { selectedCompany, companyData } = this.props;
const { currentPage, pageSize } = this.state;
const { data: tableData, total } = this.getCurrentPageData();
+ // 如果没有数据,返回空
if (!tableData || tableData.length === 0) {
- // 获取选中的公司名称用于显示
- let companyName = '';
- if (selectedCompany && companyData) {
- const selectedCompanyObj = companyData.find((company) => company.ID === selectedCompany);
- companyName = selectedCompanyObj?.NAME || '';
- }
return (
- {selectedCompany ? `${companyName}暂无危险作业数据` : '暂无危险作业数据'}
+ 暂无危险作业数据
);
}
@@ -196,10 +424,8 @@ class DangerJob extends React.Component {
},
];
- // 计算横向滚动宽度(如果列数过多)
- const scrollX = columns.reduce((sum, col) => sum + (col.width || 120), 0);
- const scrollConfig = scrollX > 1200 ? { x: scrollX } : {};
-
+ // 不设置 y 滚动,让表格自然高度,由外层容器控制滚动
+ const scrollConfig = { x: columns.length * 100, y: 320 };
// 表格数据转换(添加唯一key)
const dataSource = tableData.map((item, index) => ({
key: `${item.companyName}_${item.startDate}_${index}`,
@@ -215,72 +441,72 @@ class DangerJob extends React.Component {
}));
return (
-
-
- 当日各公司危险作业清单
-
-
- {/* 分页组件 */}
-
- {/* 自定义每页条数选择器 */}
-
-
每页显示:
-
+ <>
+
+
+ 当日各公司危险作业清单
+
+
+ {/* 分页组件 */}
+
+
+ 每页显示:
+
+
+
`共 ${total} 条记录`}
+ onChange={this.handlePageChange}
+ />
-
`共 ${total} 条记录`}
- onChange={this.handlePageChange}
- onShowSizeChange={false}
- // pageSizeOptions={['10', '20']}
- />
-
+ >
);
};
componentDidMount() {
this.isUnmounted = false;
+ this.initAllCharts();
}
componentDidUpdate(prevProps) {
@@ -288,6 +514,13 @@ class DangerJob extends React.Component {
if (prevProps.selectedCompany !== this.props.selectedCompany) {
this.setState({ currentPage: 1 });
}
+ if (prevProps.selectedStartDate !== this.props.selectedStartDate) {
+ this.setState({ currentPage: 1 });
+ }
+ if (prevProps.selectedEndDate !== this.props.selectedEndDate) {
+ this.setState({ currentPage: 1 });
+ }
+
// 当数据变化时,如果当前页没有数据且不是第一页,重置到第一页
if (prevProps.dangerSubData !== this.props.dangerSubData) {
const { currentPage } = this.state;
@@ -298,21 +531,38 @@ class DangerJob extends React.Component {
this.setState({ currentPage: 1 });
}
}
+
+ // 检查 jobTodayQty 是否变化,只在数据真正变化时重新渲染图表
+ const prevJobTodayQty = prevProps.jobTodayQty;
+ const currentJobTodayQty = this.props.jobTodayQty;
+ const jobTodayQtyChanged = JSON.stringify(prevJobTodayQty) !== JSON.stringify(currentJobTodayQty);
+
+ if (jobTodayQtyChanged) {
+ this.renderDangerOperationChart();
+ }
}
componentWillUnmount() {
this.isUnmounted = true;
+ this.disposeAllCharts();
}
+ disabledCurrentYearDate = (current) => {
+ if (!current) return false;
+ const currentYear = new Date().getFullYear();
+ const selectedYear = current.year();
+ // 只能选择当前年份
+ return selectedYear !== currentYear;
+ };
render() {
- const { companyData, selectedCompany } = this.props;
+ const { companyData, selectedCompany, selectedStartDate, selectedEndDate } = this.props;
return (
- {/* 公司筛选器 */}
+ {/* 筛选器 */}
选择公司:
+
+ 开始日期:
+
+
+
+ 结束日期:
+
+
{this.renderDangerTable()}
+ {/* 第二行 - 当日工作票统计柱状图 */}
+
);
diff --git a/src/layout/FullOther/HomeContent.js b/src/layout/FullOther/HomeContent.js
index 45851c5..4c5d5d9 100644
--- a/src/layout/FullOther/HomeContent.js
+++ b/src/layout/FullOther/HomeContent.js
@@ -575,7 +575,7 @@ class HomeContent extends React.Component {
if (this.isUnmounted) return;
this.riskLevel();
this.safeCheckChart();
- this.dangerOperation();
+ // this.dangerOperation();
this.backLog();
}, 100);
};
@@ -970,15 +970,15 @@ class HomeContent extends React.Component {
>
露天矿
- 1家
+ --家
地下矿
- 12家
+ --家
尾矿库
- 13家
+ --家
)}
diff --git a/src/layout/FullScreenInter.js b/src/layout/FullScreenInter.js
index 487e7bf..3be5407 100644
--- a/src/layout/FullScreenInter.js
+++ b/src/layout/FullScreenInter.js
@@ -14,6 +14,7 @@ import RiskControl from './FullOther/RiskControl';
import ClassBuild from './FullOther/ClassBuild';
import DangerJob from './FullOther/DangerJob';
import HiddenSolve from './FullOther/HiddenSolve';
+import moment from 'moment'; // 添加这一行
const getScale = () => {
const width = 1920,
@@ -30,7 +31,7 @@ class FullScreen extends React.Component {
nowDate: '',
riskTypeRate: [],
riskTotal: [],
- jobTodayQty: [],
+ // jobTodayQty: [],
hiddenSummary: [],
taskTop3: [],
scale: getScale(),
@@ -77,8 +78,11 @@ class FullScreen extends React.Component {
riskSubData: {},
classSubData: [],
dangerSubData: {},
+ jobTodayQty: [],
dangerCompanyData: [],
selectedDangerCompany: '',
+ selectedStartDate: moment(),
+ selectedEndDate: moment(),
announcementDetail: null,
announcementDetailLoading: false,
@@ -289,7 +293,7 @@ class FullScreen extends React.Component {
if (ret && !this.isUnmounted) {
this.setState({
riskTypeRate: ret.riskTypeRate || [],
- jobTodayQty: ret.jobTodayQty || [],
+ // jobTodayQty: ret.jobTodayQty || [],
hiddenSummary: ret.hiddenSummary || [],
taskTop3: ret.taskTop3 || [],
});
@@ -589,17 +593,29 @@ class FullScreen extends React.Component {
this.getDangerSubData();
});
};
+ handleStartDateChange = (startDate) => {
+ this.setState({ selectedStartDate: startDate }, () => {
+ this.getDangerSubData();
+ });
+ };
+ handleEndDateChange = (endDate) => {
+ this.setState({ selectedEndDate: endDate }, () => {
+ this.getDangerSubData();
+ });
+ };
getDangerSubData = () => {
const orgId = storage('lacal').getItem('webOrgId')?.val;
const json = initFilter(orgId);
+ json.Parameter1 = this.state.selectedStartDate.format('YYYY-MM-DD');
+ json.Parameter2 = this.state.selectedEndDate.format('YYYY-MM-DD');
this.props.dispatch({
type: 'app/getDataByPost',
payload: json,
url: 'BI/BIKanBanController/JobManage',
onComplete: (ret) => {
if (ret && !this.isUnmounted) {
- let filteredData = ret;
+ let filteredData = ret.jobList;
if (this.state.selectedDangerCompany) {
const selectedCompanyObj = this.state.dangerCompanyData?.find(
(company) => company.ID === this.state.selectedDangerCompany
@@ -612,6 +628,7 @@ class FullScreen extends React.Component {
this.setState({
dangerSubData: filteredData,
+ jobTodayQty: ret.jobTodayQty,
});
}
},
@@ -670,9 +687,14 @@ class FullScreen extends React.Component {
return (
);
}
@@ -761,7 +783,7 @@ class FullScreen extends React.Component {
riskTypeRate={riskTypeRate}
riskTotal={riskTotal}
hiddenSummary={hiddenSummary}
- jobTodayQty={jobTodayQty}
+ // jobTodayQty={jobTodayQty}
taskTop3={taskTop3}
mediaList={mediaList}
announcementList={announcementList}
diff --git a/src/layout/fullinter.less b/src/layout/fullinter.less
index ac31893..72bd5ae 100644
--- a/src/layout/fullinter.less
+++ b/src/layout/fullinter.less
@@ -174,7 +174,7 @@
font-weight: bold;
text-align: left;
color: #000;
- margin-bottom: 24px;
+ margin-bottom: 10px;
}
.infoCard {
display: flex;