From b5c71a7cdec64c47c7f709b09b22f2aa5c747d2e Mon Sep 17 00:00:00 2001 From: yunkexin <760754045@qq.com> Date: Thu, 23 Apr 2026 11:29:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=85=E4=BE=9B=E6=B5=8B=E8=AF=95=EF=BC=8C?= =?UTF-8?q?=E8=AF=B7=E5=8B=BF=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layout/FullOther/HomeContent.js | 4 +- src/layout/FullOther/TrainingContent.js | 179 ++++++++++++++++++------ src/layout/FullScreenInter.js | 43 +++++- 3 files changed, 182 insertions(+), 44 deletions(-) diff --git a/src/layout/FullOther/HomeContent.js b/src/layout/FullOther/HomeContent.js index 15bff2e..10bdee3 100644 --- a/src/layout/FullOther/HomeContent.js +++ b/src/layout/FullOther/HomeContent.js @@ -335,7 +335,7 @@ class HomeContent extends React.Component { title: { text: '当月工作培训统计数量', x: 'center', - y: 'center', + y: '25%', textStyle: { fontSize: 16, color: '#999' }, }, graphic: { @@ -343,7 +343,7 @@ class HomeContent extends React.Component { left: 'center', top: 'middle', style: { - text: '暂无培训数据', + text: '暂无数据', fill: '#999', fontSize: 14, }, diff --git a/src/layout/FullOther/TrainingContent.js b/src/layout/FullOther/TrainingContent.js index ee7dfb1..8327142 100644 --- a/src/layout/FullOther/TrainingContent.js +++ b/src/layout/FullOther/TrainingContent.js @@ -60,7 +60,7 @@ class TrainingContent extends React.Component { title: { text: '本年度各公司培训分析', x: 'center', - y: 'center', + y: '25%', textStyle: { fontSize: 16, color: '#999' }, }, graphic: { @@ -68,7 +68,7 @@ class TrainingContent extends React.Component { left: 'center', top: 'middle', style: { - text: '暂无培训数据', + text: '暂无数据', fill: '#999', fontSize: 14, }, @@ -190,6 +190,14 @@ class TrainingContent extends React.Component { )); }; + getCompanyOptions = () => { + const { companyData } = this.props; + return companyData.map((company, index) => ( + + )); + }; // 图表2: 各部门培训完成率(横向柱状图) renderChart2 = async () => { @@ -219,7 +227,7 @@ class TrainingContent extends React.Component { title: { text: '本年度各公司培训分析', x: 'center', - y: 'center', + y: '25%', textStyle: { fontSize: 16, color: '#999' }, }, graphic: { @@ -227,7 +235,7 @@ class TrainingContent extends React.Component { left: 'center', top: 'middle', style: { - text: '暂无培训数据', + text: '暂无数据', fill: '#999', fontSize: 14, }, @@ -357,60 +365,131 @@ class TrainingContent extends React.Component { this.echartsInstances.chart3 = echarts.init(chartDom); - // 培训类型分布数据 - const trainingTypes = [ - { name: '安全法规培训', value: 35 }, - { name: '操作规程培训', value: 28 }, - { name: '应急演练培训', value: 20 }, - { name: '职业健康培训', value: 12 }, - { name: '其他培训', value: 5 }, - ]; + // 使用 props 传入的 trainingSubData 数据(来自 getHomeSESubYear 接口) + const { trainingSubBSType } = this.props; + const listNAME = trainingSubBSType?.listNAME || []; + const monthRecordCount = trainingSubBSType?.MonthRecordCount || []; // 培训场次 + const monthPersonCount = trainingSubBSType?.MonthPersonCount || []; // 培训人次 + + // 如果没有数据,显示暂无数据提示 + if (listNAME.length === 0) { + this.echartsInstances.chart3.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 option = { title: { - text: '培训类型分布', + text: '当月公司的培训类型情况', x: 'center', y: '5%', textStyle: { fontSize: 16, color: '#000', fontWeight: 'bold' }, }, tooltip: { - trigger: 'item', + trigger: 'axis', + axisPointer: { type: 'shadow' }, formatter: function (params) { - return `${params.name}: ${params.value}场 (${params.percent}%)`; + let result = `${params[0].axisValue}
`; + params.forEach((param) => { + result += `${param.marker}${param.seriesName}: ${param.value}
`; + }); + return result; }, }, legend: { - orient: 'vertical', - right: '5%', - top: 'middle', - itemGap: 12, - itemWidth: 14, - itemHeight: 10, - textStyle: { color: '#333', fontSize: 11 }, - formatter: function (name) { - const item = trainingTypes.find((t) => t.name === name); - return `${name} ${item?.value || 0}场`; - }, + data: ['培训人次', '培训场次'], + right: '3%', // 靠右 + top: '5%', // 垂直居中 + itemGap: 16, + itemWidth: 18, + itemHeight: 12, + textStyle: { color: '#000', fontSize: 14 }, }, - color: ['#4285F4', '#66bb6a', '#ffa94d', '#ab47bc', '#ef5350'], + grid: { + left: '5%', + right: '5%', // 为右侧垂直图例留出空间 + top: '18%', + bottom: '8%', + containLabel: true, + }, + xAxis: [ + { + type: 'category', + data: listNAME, + axisLine: { show: false }, + axisTick: { show: false }, + axisLabel: { + textStyle: { color: '#000' }, + rotate: listNAME.length > 4 ? 15 : 0, + interval: 0, + }, + }, + ], + yAxis: [ + { + type: 'value', + show: true, + axisLine: { show: false }, + axisTick: { show: false }, + axisLabel: { + show: true, + textStyle: { color: '#000' }, + }, + splitLine: { show: false }, + name: '', + nameTextStyle: { show: false }, + }, + ], series: [ { - name: '培训场次', - type: 'pie', - radius: ['45%', '70%'], - center: ['40%', '55%'], - avoidLabelOverlap: false, + name: '培训人次', + type: 'bar', + data: monthPersonCount, + itemStyle: { + normal: { + color: '#4285F4', // 蓝色 + }, + }, label: { show: true, - position: 'outside', - formatter: '{b}: {d}%', - textStyle: { fontSize: 11, color: '#333' }, + position: 'top', + textStyle: { color: '#4285F4', fontSize: 12 }, + formatter: (params) => `${params.value}`, }, - emphasis: { - label: { show: true, fontSize: 14, fontWeight: 'bold' }, + barWidth: '35%', + }, + { + name: '培训场次', + type: 'bar', + data: monthRecordCount, + itemStyle: { + normal: { + color: '#ffe066', // 黄色 + }, }, - labelLine: { length: 8, length2: 8, smooth: true }, - data: trainingTypes, + label: { + show: true, + position: 'top', + textStyle: { color: '#d4a000', fontSize: 12 }, + formatter: (params) => `${params.value}`, + }, + barWidth: '35%', }, ], }; @@ -565,13 +644,19 @@ class TrainingContent extends React.Component { componentDidUpdate(prevProps) { // 当 trainingSubData 或 trainingSubDataMonth 变化时重新渲染图表 if ( - prevProps.trainingSubData !== this.props.trainingSubData || prevProps.trainingSubDataMonth !== this.props.trainingSubDataMonth || prevProps.selectedMonth !== this.props.selectedMonth ) { // this.renderChart1(); this.renderChart2(); } + if ( + prevProps.trainingSubBSType !== this.props.trainingSubBSType || + prevProps.selectedCompany !== this.props.selectedCompany + ) { + // this.renderChart1(); + this.renderChart3(); + } } componentWillUnmount() { @@ -580,7 +665,7 @@ class TrainingContent extends React.Component { } render() { - const { selectedMonth = 1, onMonthChange } = this.props; + const { selectedMonth = 1, onMonthChange, onCompanyChange, selectedCompany } = this.props; return (
@@ -608,6 +693,18 @@ class TrainingContent extends React.Component { {/* 第二行 - 图表3和图表4 */}
+ {/* 添加月份选择器 */} +
+ 选择公司: + +
diff --git a/src/layout/FullScreenInter.js b/src/layout/FullScreenInter.js index 0dd7ba4..77cfa0b 100644 --- a/src/layout/FullScreenInter.js +++ b/src/layout/FullScreenInter.js @@ -61,8 +61,10 @@ class FullScreen extends React.Component { }, trainingSubIDCard: {}, trainingSubBSType: {}, + companyData: [], // 新增:当前选择的月份 selectedMonth: new Date().getMonth() + 1, // 默认当前月份,1-12 + selectedCompany: '', }; this.isUnmounted = false; } @@ -132,6 +134,7 @@ class FullScreen extends React.Component { this.getHomeSESubYearMonthData(); this.getHomeSESubIDCardData(); this.getBSTypeMonthData(); + this.getCompanyData(); } }; @@ -238,6 +241,13 @@ class FullScreen extends React.Component { this.getHomeSESubYearMonthData(); }); }; + handleCompanyChange = (company) => { + console.log(company, '11111'); + this.setState({ selectedCompany: company }, () => { + // 重新获取月份数据 + this.getBSTypeMonthData(); + }); + }; // 获取安全培训页面数据 getHomeSESubYearMonthData = () => { const orgId = storage('lacal').getItem('webOrgId')?.val; @@ -280,6 +290,7 @@ class FullScreen extends React.Component { const currentDateStr = `${year}-${month}-${day}`; // 例如:2024-06-15 json.Parameter1 = currentDateStr; // 设置为当前日期 + json.Parameter2 = this.state.selectedCompany.toString(); // 月份 this.props.dispatch({ type: 'app/getDataByPost', payload: json, @@ -303,6 +314,7 @@ class FullScreen extends React.Component { const currentDateStr = `${year}-${month}-${day}`; // 例如:2024-06-15 json.Parameter1 = currentDateStr; // 设置为当前日期 + json.Parameter2 = this.state.selectedCompany; this.props.dispatch({ type: 'app/getDataByPost', payload: json, @@ -316,18 +328,47 @@ class FullScreen extends React.Component { }, }); }; + getCompanyData = () => { + const orgId = storage('lacal').getItem('webOrgId')?.val; + const json = initFilter(orgId); + this.props.dispatch({ + type: 'app/getDataByPost', + payload: json, + url: 'FM/Organization/OrderPaged', + onComplete: (ret) => { + if (ret && !this.isUnmounted) { + this.setState({ + companyData: ret, + }); + } + }, + }); + }; renderOtherTabContent = () => { - const { activeTab, trainingData, trainingSubData, trainingSubDataMonth, selectedMonth } = this.state; + const { + activeTab, + trainingData, + trainingSubData, + trainingSubDataMonth, + selectedMonth, + selectedCompany, + trainingSubBSType, + companyData, + } = this.state; // 如果是安全培训,显示专门的培训页面 if (activeTab === '安全培训') { return ( ); }