From 5260b510b6e3c0c543fe6822e2050d98f6c549a6 Mon Sep 17 00:00:00 2001
From: yunkexin <760754045@qq.com>
Date: Wed, 21 Jan 2026 14:05:35 +0800
Subject: [PATCH] =?UTF-8?q?=E5=8F=AF=E8=A7=86=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/layout/FullScreenInter.js | 1790 +++++++++++++++++++--------------
src/layout/fullinter.less | 4 +-
2 files changed, 1012 insertions(+), 782 deletions(-)
diff --git a/src/layout/FullScreenInter.js b/src/layout/FullScreenInter.js
index 8423e86..cbf1429 100644
--- a/src/layout/FullScreenInter.js
+++ b/src/layout/FullScreenInter.js
@@ -44,259 +44,15 @@ class FullScreen extends React.Component {
sliderSize: '24px',
nowDate: '',
riskTypeRate: [], //风险等级占比
+ linkSum: [],
jobTodayTop3: [], //当日工作票排名前三
- hiddenRectifyRate: {}, //隐患整改率
+ hiddenRectify: {}, //隐患整改率
taskTop3: [], //各事项排名前三
jobFinishRate: [], //作业现场完成情况统计
safeCheckSum: [], //各公司安全检查统计
- riskChangeData: [
- { name: '隐患数量', value: 103 },
- { name: '延期整改数', value: 18 },
- { name: '按期整改数', value: 85 },
- ],
- configBanner: [
- { name: '首页', value: 103 },
- { name: '风险管控', value: 103 },
- { name: '隐患治理', value: 103 },
- { name: '班组建设', value: 103 },
- { name: '危险作业', value: 103 },
- { name: '安全培训', value: 103 },
- ],
- checkData: [
- { name: '公司检查', value: 103 },
- { name: '部门检查', value: 79 },
- { name: '车间检查', value: 86 },
- { name: '班组检查', value: 94 },
- ],
- widthp: '70%',
- scrollConfig: {
- header: ['检查类型', '检查次数', '完成率'],
- data: [
- ['巡回检查', '322', '99%'],
- ['例行检查', '255', '99%'],
- ['日常检查', '253', '99%'],
- ['专业检查', '123', '99%'],
- ['巡回检查', '322', '99%'],
- ['例行检查', '255', '99%'],
- ['日常检查', '253', '99%'],
- ['专业检查', '123', '99%'],
- ],
- waitTime: 200000,
- },
- safescrollConfig: {
- header: ['部门', '车间', '活动', '进度'],
- data: [
- ['矿山部', '穿爆车间', '班前会议', '98%'],
- ['矿山部', '金宇宁化分公司', '班前会议', '98%'],
- ['选矿部', '破碎车间', '班前会议', '95%'],
- ['矿山部', '磨重车间', '班前会议', '92%'],
- ['矿山部', '机电设备管理科', '班前会议', '83%'],
- ['矿山部', '钨细泥回收车间', '班前会议', '93%'],
- ['矿山部', '穿爆车间', '班前会议', '90%'],
- ['矿山部', '穿爆车间', '班前会议', '90%'],
- ['矿山部', '穿爆车间', '班前会议', '90%'],
- ],
- index: true,
- columnWidth: [80, 200, 300, 200, 200],
- align: ['center'],
- waitTime: 2000,
- },
- chartConfig: {
- data: [
- {
- name: '电工日常班',
- value: 97,
- },
- {
- name: '电工三班',
- value: 95,
- },
- {
- name: '破碎一班',
- value: 91,
- },
- {
- name: '磨重二班',
- value: 86,
- },
- {
- name: '磨重三班',
- value: 83,
- },
- {
- name: '电工日常班',
- value: 97,
- },
- {
- name: '电工三班',
- value: 95,
- },
- {
- name: '破碎一班',
- value: 91,
- },
- {
- name: '磨重二班',
- value: 86,
- },
- {
- name: '磨重三班',
- value: 83,
- },
- {
- name: '电工日常班',
- value: 97,
- },
- {
- name: '电工三班',
- value: 95,
- },
- {
- name: '破碎一班',
- value: 91,
- },
- {
- name: '磨重二班',
- value: 86,
- },
- {
- name: '磨重三班',
- value: 83,
- },
- ],
- showValue: true,
- },
- riskData: [
- { color: '#c92a2a', value: 2, name: '重大风险' },
- { color: '#FF6710', value: 5, name: '较大风险' },
- { color: '#FFDD1E', value: 15, name: '一般风险' },
- { color: '#0091FF', value: 30, name: '低风险' },
- ],
- WaterLevelPondconfig1: {
- data: [75],
- shape: 'round',
- },
- WaterLevelPondconfig2: {
- data: [85],
- shape: 'round',
- },
- WaterLevelPondconfig3: {
- data: [95],
- shape: 'round',
- },
- completeData: [
- {
- name: '班组会议完成率',
- value: 75,
- },
- {
- name: '岗位交接班完成率',
- value: 85,
- },
- {
- name: '岗位当班记录完成率',
- value: 95,
- },
- ],
- // completeDatatwo: {
- // name: "岗位交接班完成率",
- // value: 85,
- // id: "completetwo",
- // },
- // completeDatathree: {
- // name: "岗位当班记录完成率",
- // value: 95,
- // id: "completethree",
- // },
- meetingData: [
- {
- name: '班前会议',
- value: 32,
- },
- {
- name: '班组活动',
- value: 132,
- },
- {
- name: '岗位交接班',
- value: 32,
- },
- {
- name: '岗位当班',
- value: 132,
- },
- {
- name: '班前会议',
- value: 32,
- },
- {
- name: '班组活动',
- value: 132,
- },
- {
- name: '岗位交接班',
- value: 32,
- },
- {
- name: '岗位当班',
- value: 132,
- },
- ],
- roaData: [
- {
- name: '总任务数',
- value: 1456,
- },
- {
- name: '超时待办数',
- value: 132,
- },
- {
- name: '安全检查数',
- value: 1456,
- },
- {
- name: '检查完成率',
- value: 32,
- },
- {
- name: '职业危害',
- value: 132,
- },
- {
- name: '管控措施',
- value: 1456,
- },
- {
- name: '安全检查库',
- value: 132,
- },
- {
- name: '危险源库',
- value: 32,
- },
- {
- name: '培训计划完成率',
- value: 132,
- },
- {
- name: '用户活跃度',
- value: 1456,
- },
- {
- name: '系统用户数',
- value: 132,
- },
- {
- name: '正常已办数',
- value: 32,
- },
- {
- name: '未完成数',
- value: 132,
- },
- ],
+ listSETrainSum: [], //各公司安全培训统计
scale: getScale(),
+ configBanner: ['首页', '风险管理', '安全检查', '隐患管理', '作业现场', '安全培训'],
};
this.echartsInstances = {
riskLevel: null,
@@ -317,100 +73,33 @@ class FullScreen extends React.Component {
// this.getHomeTitle();
this.getHomeDataArray();
this.setState({ activeTab: '首页' });
- this.riskLevel();
- this.safedanger();
- this.completeChart(this.state.completeData);
+
this.timer = setInterval(() => {
this.setState({
nowDate: this.getDate(),
});
}, 1000);
}
+ executionChart = () => {
+ this.riskLevel();
+ this.safeCheckChart();
+ this.dangerOperation();
+ this.completeChart();
+ this.backLog();
+ this.safedanger();
+ };
componentDidUpdate(prevProps, prevState) {
// 当从其他tab切换回首页时
if (prevState.activeTab !== this.state.activeTab && this.state.activeTab === '首页') {
- console.log('切换到首页,初始化图表');
-
// 延迟确保DOM已渲染
setTimeout(() => {
- this.riskLevel();
- this.safedanger();
- this.completeChart(this.state.completeData);
+ this.executionChart();
}, 300); // 稍微增加延迟时间
}
-
- // 当离开首页时,清理图表
- if (prevState.activeTab === '首页' && this.state.activeTab !== '首页') {
- console.log('离开首页,清理图表');
- this.cleanupCharts();
- }
}
- getHomeDataArray = () => {
- var orgId = storage('lacal').getItem('webOrgId')?.val; //登录后有存储登录信息
- let json = initFilter(orgId);
- this.props.dispatch({
- type: 'app/getDataByPost',
- payload: json,
- url: 'BI/BIKanBanController/ReturnAllData',
- onComplete: (ret) => {
- console.log(ret, '877777');
- if (ret) {
- console.log('首页标题数据', ret);
- this.setState({
- riskTypeRate: ret.riskTypeRate,
- jobTodayTop3: ret.jobTodayTop3,
- hiddenRectifyRate: ret.hiddenRectifyRate,
- taskTop3: ret.taskTop3,
- jobFinishRate: ret.jobFinishRate,
- safeCheckSum: ret.safeCheckSum,
- });
- }
- },
- });
- };
-
- // 添加清理方法
- cleanupCharts = () => {
- // 清理风险分级图表
- if (this.echartsInstances.riskLevel) {
- this.echartsInstances.riskLevel.dispose();
- this.echartsInstances.riskLevel = null;
- }
-
- // 清理运行走势图
- if (this.echartsInstances.opretionTrend) {
- this.echartsInstances.opretionTrend.dispose();
- this.echartsInstances.opretionTrend = null;
- }
-
- // 清理完成率图表
- if (this.echartsInstances.completeone) {
- this.echartsInstances.completeone.dispose();
- this.echartsInstances.completeone = null;
- }
-
- // 移除resize监听器
- if (this.riskResizeHandler) {
- window.removeEventListener('resize', this.riskResizeHandler);
- this.riskResizeHandler = null;
- }
-
- if (this.trendResizeHandler) {
- window.removeEventListener('resize', this.trendResizeHandler);
- this.trendResizeHandler = null;
- }
-
- if (this.completeResizeHandler) {
- window.removeEventListener('resize', this.completeResizeHandler);
- this.completeResizeHandler = null;
- }
- };
handleTabClick = (name) => {
// 如果从首页切换到其他tab,先清理图表
- if (this.state.activeTab === '首页' && name !== '首页') {
- this.cleanupCharts();
- }
this.setState({ activeTab: name });
@@ -435,35 +124,7 @@ class FullScreen extends React.Component {
componentWillUnmount() {
window.removeEventListener('resize', this.setScale);
clearInterval(this.timer);
- this.cleanupCharts();
}
- getHomeTitle = () => {
- console.log('获取首页标题数据');
- var orgId = storage('lacal').getItem('webOrgId')?.val; //登录后有存储登录信息
- let json = initFilter(orgId);
- console.log(json, '首页标题数据');
- this.props.dispatch({
- type: 'app/getDataByPost',
- payload: json,
- url: 'PF/HomeTitle/OrderPaged',
- onComplete: (ret) => {
- console.log(ret, '877777');
- if (ret) {
- console.log('首页标题数据', ret);
- this.setState({
- safetySloganOne: ret[0].TITLE,
- // safetySloganOne: "1.安全方针:以人为本、关注健康、依法治企、安全发展。 2.安全理念:一切风险皆可控,一切事故皆可防!3.安全方针:以人为本、关注健康、依法治企、安全发展。4.安全方针:以人为本、关注健康、依法治企、安全发展。5.安全方针:以人为本、关注健康、依法治企、安全发展。 6.安全理念:一切风险皆可控,一切事故皆可防!7.安全方针:以人为本、关注健康、依法治企、安全发展。8.安全方针:以人为本、关注健康、依法治企、安全发展。",
- animationDuration: ret[0].SECOND,
- sliderColor: ret[0].COCOR,
- sliderSize: ret[0].FONTSIZE,
- });
- }
- },
- });
- };
- callback = (key) => {
- console.log(key);
- };
getDate = () => {
var myDate = new Date();
var year = myDate.getFullYear(); //获取当前年
@@ -491,357 +152,33 @@ class FullScreen extends React.Component {
var now = year + ' 年 ' + mon + ' 月 ' + date + ' 日 ' + '\t\t\t' + hours + ' : ' + minutes + ' : ' + seconds;
return now;
};
- completeChart = (evt) => {
- if (this.echartsInstances.completeone) {
- this.echartsInstances.completeone.dispose();
- this.echartsInstances.completeone = null;
- }
-
- let completeCharts = document.getElementById('completeone');
- if (!completeCharts) {
- requestAnimationFrame(() => {
- this.completeChart(evt);
- });
- return;
- }
-
- console.log('初始化完成率图表');
-
- this.echartsInstances.completeone = echarts.init(completeCharts);
- let seriesArr = [];
- let centerArr = [
- ['20%', '50%'],
- ['50%', '50%'],
- ['80%', '50%'],
- ];
- evt.forEach((item, index) => {
- seriesArr.push({
- center: centerArr[index],
- axisLine: {
- show: true,
- lineStyle: {
- color: [
- [0.25, '#c23531'],
- [0.5, '#EFC631'],
- [0.75, '#63869e'],
- [1, '#91c7ae'],
- ],
- width: 8,
- },
- radius: '90%', // 控制轴线本身的半径
- },
- axisTick: {
- show: false,
- },
- splitLine: {
- length: 8, // 刻度线长度
- distance: 25, // 向内移动距离,负值越大越向内
- lineStyle: {
- color: '#fff', // 刻度线颜色
- width: 2, // 刻度线宽度
- },
- },
- axisLabel: {
- distance: 15, // 标签与刻度线的距离
- textStyle: {
- color: '#fff',
- fontSize: 10,
- },
- // 调整标签偏移
- offset: [0, 0], // [水平偏移, 垂直偏移]
- },
- itemStyle: {
- normal: {
- color: 'auto',
- },
- },
- radius: '80%',
- pointer: {
- show: true,
- width: '8%',
- length: '20%',
- },
- title: {
- textStyle: {
- // fontWeight: 'bolder',
- fontSize: 14,
- color: '#fff',
- },
- offsetCenter: [0, '100%'],
- },
- detail: {
- textStyle: {
- fontWeight: 'bolder',
- fontSize: 20,
- color: '#fff',
- },
- offsetCenter: [0, '68%'],
- // formatter: '{value}万\n(5048人)',
- },
- min: 0,
- max: 100,
- // name: '米类仪表盘',
- type: 'gauge',
- show: false,
- splitNumber: 10,
- data: [
- {
- name: item.name,
- value: item.value,
- },
- ],
- });
+ getHomeDataArray = () => {
+ var orgId = storage('lacal').getItem('webOrgId')?.val; //登录后有存储登录信息
+ let json = initFilter(orgId);
+ this.props.dispatch({
+ type: 'app/getDataByPost',
+ payload: json,
+ url: 'BI/BIKanBanController/ReturnAllData',
+ onComplete: (ret) => {
+ if (ret) {
+ this.setState(
+ {
+ riskTypeRate: ret.riskTypeRate,
+ linkSum: ret.linkSum,
+ jobTodayTop3: ret.jobTodayTop3,
+ hiddenRectify: ret.hiddenRectify,
+ taskTop3: ret.taskTop3,
+ jobFinishRate: ret.jobFinishRate,
+ safeCheckSum: ret.safeCheckSum,
+ listSETrainSum: ret.listSETrainSum,
+ },
+ () => {
+ this.executionChart();
+ }
+ );
+ }
+ },
});
- this.echartsInstances.completeone.setOption({
- series: seriesArr,
- });
-
- // 监听resize
- const resizeHandler = () => {
- if (this.echartsInstances.completeone) {
- this.echartsInstances.completeone.resize();
- }
- };
-
- if (this.completeResizeHandler) {
- window.removeEventListener('resize', this.completeResizeHandler);
- }
-
- this.completeResizeHandler = resizeHandler;
- window.addEventListener('resize', resizeHandler);
- };
- safedanger = () => {
- if (this.echartsInstances.opretionTrend) {
- this.echartsInstances.opretionTrend.dispose();
- this.echartsInstances.opretionTrend = null;
- }
-
- const opretionTrends = document.getElementById('opretionTrend');
- if (!opretionTrends) {
- requestAnimationFrame(() => {
- this.safedanger();
- });
- return;
- }
-
- console.log('初始化运行走势图');
- this.echartsInstances.opretionTrend = echarts.init(opretionTrends);
-
- // ... 原有配置代码
- let bgColor = '#000';
- let color = [
- '#0090FF',
- '#36CE9E',
- '#e690d1',
- '#FF515A',
- '#8B5CFF',
- '#00CA69',
- '#FFC107',
- '#E91E63',
- '#9C27B0',
- '#3F51B5',
- '#2196F3',
- '#4CAF50',
- '#FF9800',
- '#795548',
- '#607D8B',
- ];
- const seriesNames = [
- '选矿部门',
- '矿山部门',
- '尾矿部门',
- '机电部门',
- '安全部门',
- '生产部门',
- '技术部门',
- '维修部门',
- '运输部门',
- '仓储部门',
- '质检部门',
- '环保部门',
- '研发部门',
- '行政部门',
- '财务部门',
- ];
- // 生成x轴数据(12个月)
- let xAxisData = [];
- for (let i = 1; i <= 12; i++) {
- xAxisData.push(i.toString());
- }
-
- // 生成15个系列的数据
- let seriesArr = [];
- for (let i = 0; i < 15; i++) {
- let yAxisData = [];
- for (let j = 0; j < 12; j++) {
- // 生成60-100的随机数据
- yAxisData.push(Math.floor(Math.random() * 40) + 60);
- }
-
- seriesArr.push({
- name: seriesNames[i],
- type: 'line',
- smooth: true,
- symbolSize: 6,
- data: yAxisData,
- });
- }
-
- const hexToRgba = (hex, opacity) => {
- let rgbaColor = '';
- let reg = /^#[\da-f]{6}$/i;
- if (reg.test(hex)) {
- rgbaColor = `rgba(${parseInt('0x' + hex.slice(1, 3))},${parseInt('0x' + hex.slice(3, 5))},${parseInt(
- '0x' + hex.slice(5, 7)
- )},${opacity})`;
- }
- return rgbaColor;
- };
- const option = {
- title: [
- {
- text: '各家公司的安全教育培训学时统计',
- x: 'center',
- y: '5%',
- textStyle: {
- fontSize: 16,
- color: '#fff',
- },
- },
- ],
- backgroundColor: '',
- color: color,
- legend: {
- type: 'scroll', // 如果项目多可以使用滚动
- orient: 'vertical', // 设置为垂直排列
- right: 10, // 距离右侧的距离
- top: 'center', // 垂直居中
- align: 'left', // 文本左对齐
- textStyle: {
- color: '#fff', // 文字颜色
- fontSize: 12,
- },
- itemStyle: {
- color: 'inherit',
- borderWidth: 0,
- opacity: 1,
- },
- symbol: 'rect', // 实心矩形
- symbolSize: [12, 8], // 大小
- itemWidth: 10, // 图例标记的宽度
- itemHeight: 10, // 图例标记的高度
- itemGap: 15, // 图例每项之间的间隔
- pageButtonItemGap: 3,
- pageButtonGap: 5,
- pageButtonPosition: 'end',
- pageIconColor: '#00caf7',
- width: 100, // 限制宽度
- height: 250, // 限制高度,超出就会显示滚动
- },
- tooltip: {
- trigger: 'axis',
- formatter: function (params) {
- let html = '';
- params.forEach((v) => {
- html += `
-
- ${v.seriesName}
-
${v.value}
- %`;
- });
-
- return html;
- },
- extraCssText: 'background: #fff; border-radius: 0;box-shadow: 0 0 3px rgba(0, 0, 0, 0.2);color: #333;',
- axisPointer: {
- type: 'shadow',
- shadowStyle: {
- // color: "#ffffff",
- shadowColor: 'rgba(225,225,225,1)',
- shadowBlur: 5,
- },
- },
- },
- grid: {
- top: '15%',
- left: '5%',
- right: '15%', // 为图例留出空间
- bottom: '15%',
- containLabel: true,
- },
- xAxis: [
- {
- type: 'category',
- boundaryGap: false,
- axisLabel: {
- formatter: '{value}月',
- textStyle: {
- color: '#fff',
- },
- },
- axisTick: {
- show: false,
- },
- axisLine: {
- lineStyle: {
- color: '#fff',
- },
- },
- data: xAxisData,
- },
- ],
- yAxis: [
- {
- type: 'value',
- axisLabel: {
- textStyle: {
- color: '#fff',
- },
- },
- nameTextStyle: {
- color: '#fff',
- fontSize: 12,
- lineHeight: 40,
- },
- splitLine: {
- show: false,
- lineStyle: {
- type: 'dashed',
- color: '#fff',
- },
- },
- axisLine: {
- show: false,
- lineStyle: {
- color: '#00c7ff',
- width: 1,
- type: 'solid',
- },
- },
- axisTick: {
- show: false,
- },
- },
- ],
- series: seriesArr,
- };
-
- this.echartsInstances.opretionTrend.setOption(option);
- // 监听resize
- const resizeHandler = () => {
- if (this.echartsInstances.opretionTrend) {
- this.echartsInstances.opretionTrend.resize();
- }
- };
-
- if (this.trendResizeHandler) {
- window.removeEventListener('resize', this.trendResizeHandler);
- }
-
- this.trendResizeHandler = resizeHandler;
- window.addEventListener('resize', resizeHandler);
};
riskLevel = () => {
// 如果已有实例,先销毁
@@ -852,16 +189,12 @@ class FullScreen extends React.Component {
const riskLevels = document.getElementById('riskLevelFull');
if (!riskLevels) {
- console.warn('风险分级图表容器未找到');
// 使用requestAnimationFrame而不是setTimeout
requestAnimationFrame(() => {
- this.riskLevel();
+ this.executionChart();
});
return;
}
-
- console.log('初始化风险分级图表');
-
// 初始化echarts实例并保存引用
this.echartsInstances.riskLevel = echarts.init(riskLevels);
const option = {
@@ -945,7 +278,10 @@ class FullScreen extends React.Component {
show: false,
},
},
- data: this.state.riskTypeRate,
+ data: this.state.riskTypeRate.map((item) => ({
+ name: item.riskType,
+ value: item.count,
+ })),
},
],
};
@@ -967,6 +303,849 @@ class FullScreen extends React.Component {
this.riskResizeHandler = resizeHandler;
window.addEventListener('resize', resizeHandler);
};
+ transformDat = (originalData, barTopColor, num) => {
+ // 添加空值检查
+ if (!originalData || !Array.isArray(originalData) || originalData.length === 0) {
+ return {
+ companyNames: [],
+ series: [],
+ legendData: [],
+ };
+ }
+ // 获取所有的类型名称(去重)
+ let allTypes = [];
+ if (num == 1) {
+ allTypes = [...new Set(originalData.flatMap((item) => item.details?.map((detail) => detail.jobName)))];
+ } else {
+ allTypes = [...new Set(originalData.flatMap((item) => item.details?.map((detail) => detail.name)))];
+ }
+
+ // 获取所有的公司名称(作为 x 轴标签)
+ const companyNames = originalData?.map((item) => item.company);
+
+ // 为每个类型创建数据系列
+ const series = allTypes?.map((typeName, index) => {
+ return {
+ name: typeName,
+ type: 'bar',
+ itemStyle: {
+ normal: {
+ color: function (params) {
+ if (num == 1) {
+ return barTopColor[index];
+ } else {
+ return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+ {
+ offset: 0,
+ color: barTopColor[index][0],
+ },
+ {
+ offset: 1,
+ color: barTopColor[index][1],
+ },
+ ]);
+ }
+ },
+ },
+ },
+ data: originalData?.map((company) => {
+ // 找到该公司对应类型的数据,如果没有则返回 0
+ const detail = company.details?.find((d) => (num == 1 ? d.jobName : d.name) === typeName);
+ return detail ? detail.qty : 0;
+ }),
+ };
+ });
+
+ return {
+ companyNames, // x 轴数据
+ series, // 系列数据
+ legendData: allTypes, // legend 的 data
+ };
+ };
+
+ safeCheckChart = () => {
+ if (this.echartsInstances.safeCheckChart) {
+ this.echartsInstances.safeCheckChart.dispose();
+ this.echartsInstances.safeCheckChart = null;
+ }
+
+ let safeCheckCharts = document.getElementById('safeCheckChart');
+ if (!safeCheckCharts) {
+ requestAnimationFrame(() => {
+ this.safeCheckChart();
+ });
+ return;
+ }
+ const barTopColor = ['#02c3f1', '#53e568', '#a154e9'];
+
+ this.echartsInstances.safeCheckChart = echarts.init(safeCheckCharts);
+ let xdata = [];
+ xdata = this.transformDat(this.state.jobTodayTop3, barTopColor, 1);
+ this.echartsInstances.safeCheckChart.setOption({
+ title: {
+ text: '当日工作票排名前三家的数据',
+ textStyle: {
+ fontSize: 16,
+ color: '#fff',
+ },
+ },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ // 坐标轴指示器,坐标轴触发有效
+ type: 'shadow', // 默认为直线,可选为:'line' | 'shadow'
+ },
+ },
+ legend: {
+ data: xdata.legendData,
+ align: 'right',
+ right: 10,
+ itemGap: 16,
+ itemWidth: 18,
+ itemHeight: 10,
+ textStyle: {
+ color: '#fff',
+ fontStyle: 'normal',
+ fontFamily: '微软雅黑',
+ fontSize: 14,
+ },
+ },
+ color: barTopColor,
+ grid: {
+ left: '3%',
+ right: '4%',
+ bottom: '3%',
+ containLabel: true,
+ },
+ xAxis: [
+ {
+ type: 'category',
+ data: xdata.companyNames,
+ textStyle: {
+ fontSize: 18,
+ color: '#ffffff',
+ },
+ //坐标轴
+ axisLine: {
+ lineStyle: {
+ color: '#3eb2e8',
+ },
+ },
+ //坐标值标注
+ axisLabel: {
+ show: true,
+ textStyle: {
+ color: '#fff',
+ },
+ },
+ },
+ ],
+ yAxis: [
+ {
+ type: 'value',
+ textStyle: {
+ fontSize: 14,
+ color: '#ffffff',
+ },
+ //坐标轴
+ axisLine: {
+ show: false,
+ },
+ //坐标值标注
+ axisLabel: {
+ show: true,
+ textStyle: {
+ color: '#fff',
+ },
+ },
+ //分格线
+ splitLine: {
+ lineStyle: {
+ color: '#4784e8',
+ },
+ },
+ },
+ ],
+ series: xdata.series,
+ });
+
+ // 监听resize
+ const resizeHandler = () => {
+ if (this.echartsInstances.safeCheckChart) {
+ this.echartsInstances.safeCheckChart.resize();
+ }
+ };
+
+ if (this.safeCheckResizeHandler) {
+ window.removeEventListener('resize', this.safeCheckResizeHandler);
+ }
+
+ this.safeCheckResizeHandler = resizeHandler;
+ window.addEventListener('resize', resizeHandler);
+ };
+ dangerOperation = () => {
+ // 如果已有实例,先销毁
+ if (this.echartsInstances.dangerOperation) {
+ this.echartsInstances.dangerOperation.dispose();
+ this.echartsInstances.dangerOperation = null;
+ }
+
+ const dangerOperationCharts = document.getElementById('dangerOperationChart');
+ if (!dangerOperationCharts) {
+ // 使用requestAnimationFrame而不是setTimeout
+ requestAnimationFrame(() => {
+ this.executionChart();
+ });
+ return;
+ }
+
+ let legendData = [];
+ (this.state.linkSum.map((item) => {
+ legendData.push(item.name);
+ }),
+ // 初始化echarts实例并保存引用
+ (this.echartsInstances.dangerOperation = echarts.init(dangerOperationCharts)));
+
+ const option = {
+ color: [
+ '#0090FF',
+ '#36CE9E',
+ '#e690d1',
+ '#FF515A',
+ '#8B5CFF',
+ '#00CA69',
+ '#FFC107',
+ '#E91E63',
+ '#9C27B0',
+ '#3F51B5',
+ '#2196F3',
+ '#4CAF50',
+ '#FF9800',
+ '#795548',
+ '#607D8B',
+ ],
+ title: [
+ {
+ text: '各公司危险作业分类统计',
+ x: 'center',
+ y: '5%',
+ textStyle: {
+ fontSize: 16,
+ color: '#fff',
+ },
+ },
+ ],
+ legend: {
+ type: 'scroll',
+ orient: 'vertical',
+ left: '5%',
+ align: 'left',
+ top: '5%',
+ textStyle: {
+ color: '#fff',
+ },
+ height: 250,
+ },
+ tooltip: {
+ trigger: 'item',
+ formatter: function (params) {
+ const color = params.color;
+ return `
+
+ ${params.name}:
+ ${params.value}
+
`;
+ },
+ backgroundColor: 'rgba(255, 255, 255, 0.5)',
+ borderColor: '#FFFFFF',
+ borderWidth: 2,
+ textStyle: {
+ color: '#000',
+ fontSize: 14,
+ fontWeight: 'normal',
+ },
+ },
+ series: [
+ {
+ name: '访问来源',
+ type: 'pie',
+ minAngle: 20,
+ center: ['55%', '50%'],
+ radius: ['40%', '65%'],
+ clockwise: true,
+ avoidLabelOverlap: true,
+ hoverOffset: 15,
+ label: {
+ show: true,
+ position: 'outside',
+ formatter: '{a|{b}:{c}}{e|({d}%)}\n',
+ // color: '#FFFFFF',
+ textBorderWidth: 0,
+ rich: {
+ a: {
+ padding: [-15, 0, 0, 0],
+ fontSize: 15,
+ // color: '#FFFFFF',
+ textBorderWidth: 0,
+ textShadow: 'none',
+ },
+ e: {
+ fontSize: 14,
+ // color: '#FFFFFF',
+ padding: [-15, 0, 0, 5],
+ textBorderWidth: 0,
+ textShadow: 'none',
+ },
+ },
+ },
+ labelLine: {
+ normal: {
+ length: 5,
+ length2: 3,
+ smooth: true,
+ },
+ },
+ data: this.state.linkSum.map((item) => ({
+ name: item.name,
+ value: item.qty,
+ })),
+ },
+ ],
+ };
+
+ this.echartsInstances.dangerOperation.setOption(option);
+
+ // 监听窗口大小变化
+ const resizeHandler = () => {
+ if (this.echartsInstances.dangerOperation) {
+ this.echartsInstances.dangerOperation.resize();
+ }
+ };
+
+ // 移除旧的监听器
+ if (this.dangerOperationResizeHandler) {
+ window.removeEventListener('resize', this.dangerOperationResizeHandler);
+ }
+
+ this.dangerOperationResizeHandler = resizeHandler;
+ window.addEventListener('resize', resizeHandler);
+ };
+ backLog = () => {
+ if (this.echartsInstances.backLogChart) {
+ this.echartsInstances.backLogChart.dispose();
+ this.echartsInstances.backLogChart = null;
+ }
+
+ let backLogCharts = document.getElementById('backLogChart');
+ if (!backLogCharts) {
+ requestAnimationFrame(() => {
+ this.backLogChart();
+ });
+ return;
+ }
+ const barTopColor = [
+ ['#75baf3', '#2177d5'],
+ ['#ffa94d', '#f76707'],
+ ['#99ca6e', '#48a447'],
+ ];
+
+ this.echartsInstances.backLogChart = echarts.init(backLogCharts);
+ let xdata = [];
+ xdata = this.transformDat(this.state.taskTop3, barTopColor, 2);
+ // 创建图例的渐变色块
+ const legendColors = barTopColor.map((gradient) => gradient[0]);
+ this.echartsInstances.backLogChart.setOption({
+ title: {
+ text: '各事项排名前三名统计',
+ textStyle: {
+ fontSize: 16,
+ color: '#fff',
+ },
+ },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ // 坐标轴指示器,坐标轴触发有效
+ type: 'shadow', // 默认为直线,可选为:'line' | 'shadow'
+ },
+ },
+ legend: {
+ data: xdata.legendData.map((name, index) => ({
+ name: name,
+ // 使用渐变的起始颜色作为图例颜色
+ // icon: 'rect',
+ itemStyle: {
+ color: legendColors[index],
+ borderWidth: 0,
+ },
+ textStyle: {
+ color: '#fff',
+ fontSize: 14,
+ },
+ })),
+ align: 'right',
+ right: 10,
+ itemGap: 16,
+ itemWidth: 18,
+ itemHeight: 12,
+ textStyle: {
+ color: '#fff',
+ fontStyle: 'normal',
+ fontFamily: '微软雅黑',
+ fontSize: 14,
+ },
+ },
+ color: legendColors, // 设置全局颜色
+
+ grid: {
+ left: '3%',
+ right: '4%',
+ bottom: '3%',
+ containLabel: true,
+ },
+ xAxis: [
+ {
+ type: 'category',
+ data: xdata.companyNames,
+ textStyle: {
+ fontSize: 18,
+ color: '#ffffff',
+ },
+ //坐标轴
+ axisLine: {
+ lineStyle: {
+ color: '#3eb2e8',
+ },
+ },
+ //坐标值标注
+ axisLabel: {
+ show: true,
+ textStyle: {
+ color: '#fff',
+ },
+ },
+ },
+ ],
+ yAxis: [
+ {
+ type: 'value',
+ textStyle: {
+ fontSize: 14,
+ color: '#ffffff',
+ },
+ //坐标轴
+ axisLine: {
+ show: false,
+ },
+ //坐标值标注
+ axisLabel: {
+ show: true,
+ textStyle: {
+ color: '#fff',
+ },
+ },
+ //分格线
+ splitLine: {
+ lineStyle: {
+ color: '#4784e8',
+ },
+ },
+ },
+ ],
+ series: xdata.series,
+ });
+
+ // 监听resize
+ const resizeHandler = () => {
+ if (this.echartsInstances.backLogChart) {
+ this.echartsInstances.backLogChart.resize();
+ }
+ };
+
+ if (this.backLogResizeHandler) {
+ window.removeEventListener('resize', this.backLogResizeHandler);
+ }
+
+ this.backLogResizeHandler = resizeHandler;
+ window.addEventListener('resize', resizeHandler);
+ };
+ completeChart = () => {
+ if (this.echartsInstances.completeone) {
+ this.echartsInstances.completeone.dispose();
+ this.echartsInstances.completeone = null;
+ }
+
+ let completeCharts = document.getElementById('completeone');
+ if (!completeCharts) {
+ requestAnimationFrame(() => {
+ this.completeChart();
+ });
+ return;
+ }
+
+ this.echartsInstances.completeone = echarts.init(completeCharts);
+ let seriesArr = [];
+ let centerArr = [
+ ['20%', '50%'],
+ ['50%', '50%'],
+ ['80%', '50%'],
+ ];
+ const completeData = this.state.jobFinishRate
+ .filter((item) => item.name === '班前会议' || item.name === '岗位当班' || item.name === '岗位交接班')
+ .map((item) => {
+ return {
+ name: item.name,
+ value: item.rate,
+ };
+ });
+ const colorArr = [
+ [
+ [0.2, '#2ec7c9'],
+ [0.8, '#b6a2de'],
+ [1, '#5ab1ef'],
+ ],
+ [
+ [0.2, '#5470c6'],
+ [0.8, '#91cc75'],
+ [1, '#fac858'],
+ ],
+ [
+ [0.2, '#4ea397'],
+ [0.8, '#22c3aa'],
+ [1, '#7bd9a5'],
+ ],
+ ];
+ completeData.forEach((item, index) => {
+ seriesArr.push({
+ center: centerArr[index],
+ axisLine: {
+ show: true,
+ lineStyle: {
+ color: colorArr[index],
+ width: 8,
+ },
+ radius: '90%', // 控制轴线本身的半径
+ },
+ axisTick: {
+ show: false,
+ },
+ splitLine: {
+ length: 8, // 刻度线长度
+ distance: 25, // 向内移动距离,负值越大越向内
+ lineStyle: {
+ color: '#fff', // 刻度线颜色
+ width: 1, // 刻度线宽度
+ },
+ },
+ axisLabel: {
+ distance: 15, // 标签与刻度线的距离
+ textStyle: {
+ color: '#fff',
+ fontSize: 10,
+ },
+ // 调整标签偏移
+ offset: [0, 0], // [水平偏移, 垂直偏移]
+ },
+ itemStyle: {
+ normal: {
+ color: 'auto',
+ },
+ },
+ radius: '80%',
+ pointer: {
+ show: true,
+ width: '8%',
+ length: '30%',
+ },
+ title: {
+ textStyle: {
+ // fontWeight: 'bolder',
+ fontSize: 14,
+ color: '#fff',
+ },
+ offsetCenter: [0, '100%'],
+ },
+ detail: {
+ textStyle: {
+ fontWeight: 'bolder',
+ fontSize: 16,
+ color: '#fff',
+ },
+ offsetCenter: [0, '68%'],
+ formatter: '{value}%',
+ // formatter: '{value}万\n(5048人)',
+ },
+ min: 0,
+ max: 100,
+ // name: '米类仪表盘',
+ type: 'gauge',
+ show: false,
+ splitNumber: 10,
+ data: [
+ {
+ name: item.name,
+ value: item.value,
+ },
+ ],
+ });
+ });
+ this.echartsInstances.completeone.setOption({
+ series: seriesArr,
+ });
+
+ // 监听resize
+ const resizeHandler = () => {
+ if (this.echartsInstances.completeone) {
+ this.echartsInstances.completeone.resize();
+ }
+ };
+
+ if (this.completeResizeHandler) {
+ window.removeEventListener('resize', this.completeResizeHandler);
+ }
+
+ this.completeResizeHandler = resizeHandler;
+ window.addEventListener('resize', resizeHandler);
+ };
+ safedanger = () => {
+ if (this.echartsInstances.opretionTrend) {
+ this.echartsInstances.opretionTrend.dispose();
+ this.echartsInstances.opretionTrend = null;
+ }
+
+ const opretionTrends = document.getElementById('opretionTrend');
+ if (!opretionTrends) {
+ requestAnimationFrame(() => {
+ this.safedanger();
+ });
+ return;
+ }
+
+ this.echartsInstances.opretionTrend = echarts.init(opretionTrends);
+
+ // ... 原有配置代码
+ let bgColor = '#000';
+ let color = [
+ '#0090FF',
+ '#36CE9E',
+ '#e690d1',
+ '#FF515A',
+ '#8B5CFF',
+ '#00CA69',
+ '#FFC107',
+ '#E91E63',
+ '#9C27B0',
+ '#3F51B5',
+ '#2196F3',
+ '#4CAF50',
+ '#FF9800',
+ '#795548',
+ '#607D8B',
+ ];
+ const seriesNames = [];
+ this.state.listSETrainSum.map((item) => {
+ seriesNames.push(item.CN);
+ });
+
+ // 生成x轴数据(12个月)
+ let xAxisData = [];
+ xAxisData = Object.keys(
+ this.state.listSETrainSum[0] === undefined || this.state.listSETrainSum[0] === null
+ ? {}
+ : this.state.listSETrainSum[0]
+ )
+ .filter((key) => key.startsWith('dtNowYM'))
+ .map((key) => this.state.listSETrainSum[0][key].substring(0, 7))
+ .sort((a, b) => new Date(a) - new Date(b)); // 按日期升序
+
+ let yAxisData = [];
+ yAxisData = this.state.listSETrainSum.map((item) => {
+ const values = [];
+ for (let i = 0; i <= 5; i++) {
+ const key = i === 0 ? 'SUM_TRAIN_HOUR' : `SUM_TRAIN_HOUR_${i}`;
+ values.push(item[key]);
+ }
+ return values;
+ });
+
+ // 生成15个系列的数据
+ let seriesArr = [];
+ for (let i = 0; i < this.state.listSETrainSum.length; i++) {
+ seriesArr.push({
+ name: seriesNames[i],
+ type: 'line',
+ smooth: true,
+ symbolSize: 6,
+ data: yAxisData[i],
+ });
+ }
+
+ const hexToRgba = (hex, opacity) => {
+ let rgbaColor = '';
+ let reg = /^#[\da-f]{6}$/i;
+ if (reg.test(hex)) {
+ rgbaColor = `rgba(${parseInt('0x' + hex.slice(1, 3))},${parseInt('0x' + hex.slice(3, 5))},${parseInt(
+ '0x' + hex.slice(5, 7)
+ )},${opacity})`;
+ }
+ return rgbaColor;
+ };
+ const option = {
+ title: [
+ {
+ text: '各家公司的安全教育培训学时统计',
+ x: 'center',
+ y: '5%',
+ textStyle: {
+ fontSize: 16,
+ color: '#fff',
+ },
+ },
+ ],
+ backgroundColor: '',
+ color: color,
+ legend: {
+ type: 'scroll', // 如果项目多可以使用滚动
+ orient: 'vertical', // 设置为垂直排列
+ right: 10, // 距离右侧的距离
+ top: 'center', // 垂直居中
+ align: 'left', // 文本左对齐
+ textStyle: {
+ color: '#fff', // 文字颜色
+ fontSize: 12,
+ },
+ itemStyle: {
+ color: 'inherit',
+ borderWidth: 0,
+ opacity: 1,
+ },
+ symbol: 'rect', // 实心矩形
+ symbolSize: [12, 8], // 大小
+ itemWidth: 10, // 图例标记的宽度
+ itemHeight: 10, // 图例标记的高度
+ itemGap: 15, // 图例每项之间的间隔
+ pageButtonItemGap: 3,
+ pageButtonGap: 5,
+ pageButtonPosition: 'end',
+ pageIconColor: '#00caf7',
+ width: 100, // 限制宽度
+ height: 250, // 限制高度,超出就会显示滚动
+ },
+ tooltip: {
+ trigger: 'axis',
+ formatter: function (params) {
+ let html = '';
+ params.forEach((v) => {
+ html += `
+
+ ${v.seriesName}
+
${v.value}
+ `;
+ });
+
+ return html;
+ },
+ extraCssText: 'background: #fff; border-radius: 0;box-shadow: 0 0 3px rgba(0, 0, 0, 0.2);color: #333;',
+ axisPointer: {
+ type: 'shadow',
+ shadowStyle: {
+ // color: "#ffffff",
+ shadowColor: 'rgba(225,225,225,1)',
+ shadowBlur: 5,
+ },
+ },
+ },
+ grid: {
+ top: '15%',
+ left: '5%',
+ right: '15%', // 为图例留出空间
+ bottom: '15%',
+ containLabel: true,
+ },
+ xAxis: [
+ {
+ type: 'category',
+ boundaryGap: false,
+ axisLabel: {
+ textStyle: {
+ color: '#fff',
+ },
+ },
+ axisTick: {
+ show: false,
+ },
+ axisLine: {
+ lineStyle: {
+ color: '#fff',
+ },
+ },
+ data: xAxisData,
+ },
+ ],
+ yAxis: [
+ {
+ type: 'value',
+ axisLabel: {
+ textStyle: {
+ color: '#fff',
+ },
+ },
+ nameTextStyle: {
+ color: '#fff',
+ fontSize: 12,
+ lineHeight: 40,
+ },
+ splitLine: {
+ show: false,
+ lineStyle: {
+ type: 'dashed',
+ color: '#fff',
+ },
+ },
+ axisLine: {
+ show: false,
+ lineStyle: {
+ color: '#00c7ff',
+ width: 1,
+ type: 'solid',
+ },
+ },
+ axisTick: {
+ show: false,
+ },
+ },
+ ],
+ series: seriesArr,
+ };
+
+ this.echartsInstances.opretionTrend.setOption(option);
+ // 监听resize
+ const resizeHandler = () => {
+ if (this.echartsInstances.opretionTrend) {
+ this.echartsInstances.opretionTrend.resize();
+ }
+ };
+
+ if (this.trendResizeHandler) {
+ window.removeEventListener('resize', this.trendResizeHandler);
+ }
+
+ this.trendResizeHandler = resizeHandler;
+ window.addEventListener('resize', resizeHandler);
+ };
render() {
const width = 1920,
@@ -974,6 +1153,31 @@ class FullScreen extends React.Component {
// 固定好16:9的宽高比,计算出最合适的缩放比,宽高比可根据需要自行更改
const { scale, safetySloganOne, animationDuration, sliderColor, sliderSize, activeTab } = this.state;
const renderContent = () => {
+ const riskChangeData = [
+ {
+ name: '隐患数',
+ value: this.state.hiddenRectify.qty,
+ },
+ {
+ name: '按期整改数',
+ value: this.state.hiddenRectify.ontimeQty,
+ },
+ {
+ name: '延期整改数',
+ value: this.state.hiddenRectify.delayQty,
+ },
+ ];
+ const chartConfig = {
+ data: this.state.safeCheckSum.map((item) => ({
+ name: item.company,
+ value: item.qty,
+ })),
+ showValue: true,
+ };
+ const meetingData = this.state.jobFinishRate.map((item) => ({
+ name: item.name,
+ value: item.qty,
+ }));
if (activeTab === '首页') {
return (
<>
@@ -1018,10 +1222,10 @@ class FullScreen extends React.Component {
item.riskType === '重大风险'
? '#c92a2a'
: item.riskType === '较大风险'
- ? '#FF6710'
- : item.riskType === '一般风险'
- ? '#FFDD1E'
- : '#0091FF',
+ ? '#FF6710'
+ : item.riskType === '一般风险'
+ ? '#FFDD1E'
+ : '#0091FF',
margin: '10px 20px',
padding: '5px 10px',
fontSize: '16px',
@@ -1069,6 +1273,7 @@ class FullScreen extends React.Component {
justifyContent: 'center',
width: '100%',
height: '100%',
+ padding: '10px',
}}
>
@@ -1194,11 +1412,21 @@ class FullScreen extends React.Component {
justifyContent: 'center',
width: '100%',
height: '100%',
+ padding: '10px',
}}
>
-
-
-
+
@@ -1246,30 +1474,31 @@ class FullScreen extends React.Component {
}}
>
- {this.state.meetingData.map((item, index) => (
-
-
-
-
-
{item.name}
-
- {item.value}
-
- 次
-
+ {meetingData &&
+ meetingData.map((item, index) => (
+
+
+
+
+
{item.name}
+
+ {item.value}
+
+ 次
+
+
-
-
- ))}
+
+ ))}
@@ -1303,23 +1532,24 @@ class FullScreen extends React.Component {
}}
>
- {this.state.riskChangeData.map((item, index) => (
-
-
-
-
{item.name}
-
{item.value}
+ {riskChangeData &&
+ riskChangeData.map((item, index) => (
+
+
+
+
{item.name}
+
{item.value}
+
-
- ))}
+ ))}
整改率
-
83.98%
+
{this.state.hiddenRectify.rate}%
@@ -1369,7 +1599,7 @@ class FullScreen extends React.Component {
各家公司安全检查统计
-
+
@@ -1453,22 +1683,23 @@ class FullScreen extends React.Component {
marginLeft: 'auto',
}}
>
- {this.state.configBanner.slice(0, 3).map((item, index) => (
-
this.handleTabClick(item.name)}
- onKeyPress={(e) => e.key === 'Enter' && this.handleTabClick(item.name)}
- tabIndex={0}
- title={`点击进入${item.name}`}
- role="button"
- style={{ cursor: 'pointer' }}
- >
- {item.name}
-
- ))}
+ {this.state.configBanner &&
+ this.state.configBanner.slice(0, 3).map((item, index) => (
+
this.handleTabClick(item)}
+ onKeyPress={(e) => e.key === 'Enter' && this.handleTabClick(item)}
+ tabIndex={0}
+ title={`点击进入${item}`}
+ role="button"
+ style={{ cursor: 'pointer' }}
+ >
+ {item}
+
+ ))}
@@ -1493,22 +1724,21 @@ class FullScreen extends React.Component {
style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', height: '100%' }}
>
- {this.state.configBanner.slice(3, 6).map((item, index) => (
-
this.handleTabClick(item.name)}
- onKeyPress={(e) => e.key === 'Enter' && this.handleTabClick(item.name)}
- tabIndex={0}
- title={`点击进入${item.name}`}
- role="button"
- style={{ cursor: 'pointer' }}
- >
- {item.name}
-
- ))}
+ {this.state.configBanner &&
+ this.state.configBanner.slice(3, 6).map((item, index) => (
+
this.handleTabClick(item)}
+ onKeyPress={(e) => e.key === 'Enter' && this.handleTabClick(item)}
+ tabIndex={0}
+ title={`点击进入${item}`}
+ role="button"
+ style={{ cursor: 'pointer' }}
+ >
+ {item}
+
+ ))}
{/* {this.state.nowWeek} */}
diff --git a/src/layout/fullinter.less b/src/layout/fullinter.less
index 409a83a..78156c9 100644
--- a/src/layout/fullinter.less
+++ b/src/layout/fullinter.less
@@ -137,14 +137,14 @@
}
.otherTabContent {
flex: 1; // 占据剩余空间
- width: 100%;
+ // width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: rgba(2, 20, 40, 0.7);
border-radius: 10px;
- margin: 10px;
+ margin: 0px 10px 10px 10px;
border: 1px solid rgba(0, 202, 247, 0.3);
}
.row {