可视化大屏

This commit is contained in:
yunkexin 2026-04-29 11:11:23 +08:00
parent e3faa7549b
commit 9ed7b3b941
3 changed files with 179 additions and 369 deletions

View File

@ -76,7 +76,7 @@ class HiddenSolve extends React.Component {
if (hiddenList.length === 0) {
this.echartsInstances.hiddenBarChart.setOption({
title: {
text: '各公司隐患统计',
text: '各公司累计隐患统计数据',
x: 'center',
y: '25%',
textStyle: { fontSize: 16, color: '#999' },
@ -101,7 +101,7 @@ class HiddenSolve extends React.Component {
const option = {
title: {
text: '各公司隐患统计',
text: '各公司累计隐患统计数据',
x: 'center',
y: '5%',
textStyle: { fontSize: 16, color: '#000', fontWeight: 'bold' },
@ -227,7 +227,7 @@ class HiddenSolve extends React.Component {
if (hiddenRectifyList.length === 0) {
this.echartsInstances.hiddenRectifyChart.setOption({
title: {
text: '各公司隐患整改情况',
text: '当月各公司隐患统计数据',
x: 'center',
y: '25%',
textStyle: { fontSize: 16, color: '#999' },
@ -254,7 +254,7 @@ class HiddenSolve extends React.Component {
const option = {
title: {
text: '各公司隐患整改情况',
text: '当月各公司隐患统计数据',
x: 'center',
y: '5%',
textStyle: { fontSize: 16, color: '#000', fontWeight: 'bold' },
@ -271,7 +271,7 @@ class HiddenSolve extends React.Component {
},
},
legend: {
data: ['重大隐患总数', '重大隐患已整改', '一般隐患总数', '一般隐患已整改'],
data: ['重大隐患量', '重大隐患未整改量', '一般隐患量', '一般隐患未整改量'],
orient: 'vertical',
right: '3%',
top: '5%',
@ -318,7 +318,7 @@ class HiddenSolve extends React.Component {
],
series: [
{
name: '重大隐患总数',
name: '重大隐患',
type: 'bar',
data: majorTotal,
itemStyle: {
@ -335,7 +335,7 @@ class HiddenSolve extends React.Component {
barWidth: '20%',
},
{
name: '重大隐患已整改',
name: '重大隐患未整改量',
type: 'bar',
data: majorRectified,
itemStyle: {
@ -352,7 +352,7 @@ class HiddenSolve extends React.Component {
barWidth: '20%',
},
{
name: '一般隐患总数',
name: '一般隐患',
type: 'bar',
data: generalTotal,
itemStyle: {
@ -369,7 +369,7 @@ class HiddenSolve extends React.Component {
barWidth: '20%',
},
{
name: '一般隐患已整改',
name: '一般隐患未整改量',
type: 'bar',
data: generalRectified,
itemStyle: {
@ -403,13 +403,13 @@ class HiddenSolve extends React.Component {
hiddenRanking = hiddenRanking.filter((item) => item.companyName === selectedCompanyName);
}
if (hiddenRanking.length === 0) {
return (
<div style={{ textAlign: 'center', padding: '50px', color: '#999' }}>
{selectedCompanyName ? `${selectedCompanyName} 暂无隐患排名数据` : '暂无隐患排名数据'}
</div>
);
}
// if (hiddenRanking.length === 0) {
// return (
// <div style={{ textAlign: 'center', padding: '50px', color: '#999' }}>
// {selectedCompanyName ? `${selectedCompanyName} 暂无隐患排名数据` : '暂无隐患排名数据'}
// </div>
// );
// }
return (
<div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
@ -422,9 +422,8 @@ class HiddenSolve extends React.Component {
color: '#000',
}}
>
隐患排名
隐患次数排名列表
</div>
{/* 公司筛选器 - 与 TrainingContent 样式保持一致 */}
<div style={{ textAlign: 'right', padding: '10px 20px' }}>
<span style={{ marginRight: '8px', fontSize: '14px', color: '#000' }}>选择公司</span>
<Select
@ -437,12 +436,13 @@ class HiddenSolve extends React.Component {
{this.getCompanyOptions()}
</Select>
</div>
{/* 公司筛选器 - 与 TrainingContent 样式保持一致 */}
<div style={{ flex: 1, overflow: 'auto', padding: '0 20px 20px 20px' }}>
<table style={{ width: '100%', borderCollapse: 'collapse' }}>
<thead>
<tr style={{ backgroundColor: '#f5f5f5', borderBottom: '2px solid #e8e8e8' }}>
<th style={{ padding: '12px 8px', textAlign: 'center', fontWeight: 'bold', color: '#000' }}>排名</th>
<th style={{ padding: '12px 8px', textAlign: 'center', fontWeight: 'bold', color: '#000' }}>公司</th>
<th style={{ padding: '12px 8px', textAlign: 'center', fontWeight: 'bold', color: '#000' }}>序号</th>
<th style={{ padding: '12px 8px', textAlign: 'center', fontWeight: 'bold', color: '#000' }}>
隐患名称
</th>
@ -450,39 +450,36 @@ class HiddenSolve extends React.Component {
</tr>
</thead>
<tbody>
{hiddenRanking.map((item, index) => (
<tr
key={index}
style={{
borderBottom: '1px solid #e8e8e8',
backgroundColor: index % 2 === 0 ? '#fafafa' : '#fff',
}}
>
<td style={{ padding: '10px 8px', textAlign: 'center', color: '#000' }}>
<span
style={{
display: 'inline-block',
width: '24px',
height: '24px',
lineHeight: '24px',
borderRadius: '12px',
backgroundColor: index < 3 ? '#ffa500' : '#ccc',
color: '#fff',
fontWeight: 'bold',
}}
>
{index + 1}
</span>
</td>
<td style={{ padding: '10px 8px', textAlign: 'center', color: '#000', fontWeight: 'bold' }}>
{item.companyName}
</td>
<td style={{ padding: '10px 8px', textAlign: 'center', color: '#000' }}>{item.hiddenName}</td>
<td style={{ padding: '10px 8px', textAlign: 'center', color: '#000' }}>
<span style={{ color: '#4285F4', fontWeight: 'bold' }}>{item.qty}</span>
</td>
</tr>
))}
{hiddenRanking.length > 0 ? (
hiddenRanking.map((item, index) => (
<tr
key={index}
style={{
borderBottom: '1px solid #e8e8e8',
backgroundColor: index % 2 === 0 ? '#fafafa' : '#fff',
}}
>
<td style={{ padding: '10px 8px', textAlign: 'center', color: '#000' }}>
<span
style={{
padding: '10px 8px',
textAlign: 'center',
color: '#000',
fontWeight: 'bold',
}}
>
{index + 1}
</span>
</td>
<td style={{ padding: '10px 8px', textAlign: 'center', color: '#000' }}>{item.hiddenName}</td>
<td style={{ padding: '10px 8px', textAlign: 'center', color: '#000' }}>
<span style={{ color: '#4285F4', fontWeight: 'bold' }}>{item.qty}</span>
</td>
</tr>
))
) : (
<div style={{ textAlign: 'center', padding: '50px', color: '#999' }}>{'暂无隐患排名数据'}</div>
)}
</tbody>
</table>
</div>

View File

@ -817,7 +817,6 @@ class HomeContent extends React.Component {
muted: playSet.V_ISSILENT !== undefined ? playSet.V_ISSILENT : true,
controls: playSet.V_ISSHOWCONTROL !== undefined ? playSet.V_ISSHOWCONTROL : false,
};
console.log('视频配置:', videoConfig);
const isAutoplay = playSet.IMG_ISRE !== undefined ? playSet.IMG_ISRE : true;
const autoplaySpeed = playSet.IMG_TIMESPAN ? playSet.IMG_TIMESPAN * 1000 : 5000;

View File

@ -29,11 +29,7 @@ class FullScreen extends React.Component {
this.state = {
nowDate: '',
riskTypeRate: [],
riskTotal: [
{ name: '年度重大隐患数', value: 1 },
{ name: '年度一般隐患数量', value: 89 },
{ name: '未整改隐患数量', value: 18 },
],
riskTotal: [],
jobTodayQty: [],
hiddenSummary: [],
taskTop3: [],
@ -90,6 +86,7 @@ class FullScreen extends React.Component {
currentAnnouncement: null,
};
this.isUnmounted = false;
this.dataTimer = null; // 新增:用于数据定时请求
}
setScale = debounce(() => {
@ -104,15 +101,56 @@ class FullScreen extends React.Component {
document.exitFullscreen?.();
}
};
startDataRefreshTimer = () => {
// 清除已有定时器
if (this.dataTimer) {
clearInterval(this.dataTimer);
}
// 设置新的定时器每5分钟执行一次
this.dataTimer = setInterval(
() => {
if (!this.isUnmounted) {
if (this.state.activeTab === '首页') {
this.getHomeDataArray();
this.getYearPXData();
}
// 安全培训 - 参考原有逻辑
else if (this.state.activeTab === '安全培训') {
this.getTrainingCompanyData(); // 先获取公司列表
this.getHomeSESubYearData();
this.getHomeSESubYearMonthData();
this.getHomeSESubIDCardData();
}
// 隐患治理 - 参考安全培训的调用顺序
else if (this.state.activeTab === '隐患治理') {
this.getHiddenCompanyData(); // 先获取公司列表(与安全培训独立)
}
// 风险管控
else if (this.state.activeTab === '风险管控') {
this.getRiskSubData();
}
// 班组建设
else if (this.state.activeTab === '班组建设') {
this.getClassSubData();
}
// 危险作业
else if (this.state.activeTab === '危险作业') {
this.getDangerCompanyData();
}
}
},
1 * 60 * 1000
); // 5分钟 = 300000毫秒
};
componentDidMount() {
this.isUnmounted = false;
window.addEventListener('resize', this.setScale);
this.getHomeDataArray();
this.getYearPXData();
this.loadMediaFiles();
this.getAnnouncementData();
// 启动定时刷新
this.startDataRefreshTimer();
this.timer = setInterval(() => {
if (!this.isUnmounted) this.setState({ nowDate: this.getDate() });
}, 1000);
@ -173,27 +211,6 @@ class FullScreen extends React.Component {
});
};
getAnnouncementData = () => {
this.setState({
announcementList: [
{ ID: 1, title: '关于2024年安全生产月活动的通知', publishTime: '2024-06-01', url: '' },
{ ID: 2, title: '公司第三季度安全培训安排', publishTime: '2024-05-28', url: '' },
{ ID: 3, title: '关于开展安全隐患排查整治工作的通知', publishTime: '2024-05-20', url: '' },
{ ID: 4, title: '安全生产标准化建设阶段性总结', publishTime: '2024-05-15', url: '' },
{ ID: 5, title: '关于表彰2024年第一季度安全生产先进单位的决定', publishTime: '2024-05-10', url: '' },
],
});
};
loadMediaFiles = () => {
this.setState({
mediaList: [
{ type: 'image', url: 'http://10.2.7.18:28028//WZ_Images/static/smyzw@2x.png' },
{ type: 'video', url: 'http://10.2.7.18:28028/WZ_Images/Img_JFSC/welcom/1.mp4' },
],
});
};
handleCarouselChange = (current) => {
this.setState({ currentMediaIndex: current });
};
@ -205,9 +222,8 @@ class FullScreen extends React.Component {
handleTabClick = (name) => {
this.setState({ activeTab: name });
if (name === '首页') {
this.getHomeDataArray();
this.getYearPXData();
this.loadMediaFiles();
this.getAnnouncementData();
}
// 安全培训 - 参考原有逻辑
if (name === '安全培训') {
@ -242,6 +258,9 @@ class FullScreen extends React.Component {
this.isUnmounted = true;
window.removeEventListener('resize', this.setScale);
if (this.timer) clearInterval(this.timer);
// 清除数据刷新定时器
if (this.dataTimer) clearInterval(this.dataTimer);
document.removeEventListener('fullscreenchange', this.handleFullscreenChange);
}
@ -260,7 +279,6 @@ class FullScreen extends React.Component {
};
getHomeDataArray = () => {
console.log('获取首页数据');
const orgId = storage('lacal').getItem('webOrgId')?.val;
const json = initFilter(orgId);
this.props.dispatch({
@ -489,244 +507,75 @@ class FullScreen extends React.Component {
// 隐患治理公司筛选变化处理
handleHiddenCompanyChange = (company) => {
this.setState({ selectedHiddenCompany: company });
this.getHiddenSubData();
this.setState({ selectedHiddenCompany: company }, () => {
this.getHiddenSubData();
});
};
getHiddenSubData = () => {
let filteredData = {
hiddenList: [
{
companyName: '邦泰',
majorCount: 52,
generalCount: 128,
},
{
companyName: '宏源建设',
majorCount: 18,
generalCount: 94,
},
{
companyName: '中城建工',
majorCount: 31,
generalCount: 205,
},
],
hiddenRanking: [
// 邦泰 5 个
{
companyName: '邦泰',
hiddenName: '安全防护缺失',
qty: 42,
},
{
companyName: '邦泰',
hiddenName: '临时用电不规范',
qty: 38,
},
{
companyName: '邦泰',
hiddenName: '机械设备故障',
qty: 27,
},
{
companyName: '邦泰',
hiddenName: '特种设备未年检',
qty: 15,
},
{
companyName: '邦泰',
hiddenName: '消防器材过期',
qty: 12,
},
// 路源 6 个
{
companyName: '路源',
hiddenName: '消防通道堵塞',
qty: 29,
},
{
companyName: '路源',
hiddenName: '电气线路老化',
qty: 18,
},
{
companyName: '路源',
hiddenName: '应急照明故障',
qty: 8,
},
{
companyName: '路源',
hiddenName: '安全标识缺失',
qty: 7,
},
{
companyName: '路源',
hiddenName: '脚手架搭设不规范',
qty: 6,
},
{
companyName: '路源',
hiddenName: '劳保用品佩戴不规范',
qty: 5,
},
// 天山 7 个
{
companyName: '天山',
hiddenName: '脚手架搭设违规',
qty: 36,
},
{
companyName: '天山',
hiddenName: '高空抛物隐患',
qty: 22,
},
{
companyName: '天山',
hiddenName: '动火作业监护缺失',
qty: 14,
},
{
companyName: '天山',
hiddenName: '受限空间未审批',
qty: 11,
},
{
companyName: '天山',
hiddenName: '起重吊装违规操作',
qty: 9,
},
{
companyName: '天山',
hiddenName: '临时用电私拉乱接',
qty: 7,
},
{
companyName: '天山',
hiddenName: '高处作业安全带未挂',
qty: 5,
},
],
hiddenRectifyList: [
{
companyName: '邦泰',
majorCount: 52,
majorCountNo: 12,
generalCount: 128,
generalCountNo: 31,
},
{
companyName: '宏源建设',
majorCount: 18,
majorCountNo: 5,
generalCount: 94,
generalCountNo: 22,
},
{
companyName: '中城建工',
majorCount: 31,
majorCountNo: 9,
generalCount: 205,
generalCountNo: 47,
},
],
};
if (this.state.selectedHiddenCompany) {
const selectedCompanyObj = this.state.hiddenCompanyData?.find(
(company) => company.ID === this.state.selectedHiddenCompany
);
const selectedCompanyName = selectedCompanyObj?.NAME;
if (selectedCompanyName) {
// 筛选 hiddenRanking
filteredData.hiddenRanking = filteredData.hiddenRanking.filter(
(item) => item.companyName === selectedCompanyName
);
}
}
// 模拟数据
this.setState({
hiddenSubData: filteredData,
});
// 以下是真实的API调用代码如需使用请取消注释
// const orgId = storage('lacal').getItem('webOrgId')?.val;
// const json = initFilter(orgId);
// this.props.dispatch({
// type: 'app/getDataByPost',
// payload: json,
// url: 'BI/BIKanBanController/HiddenManage',
// onComplete: (ret) => {
// if (ret && !this.isUnmounted) {
// this.setState({
// hiddenSubData: ret.Data,
// });
// }
// },
// });
const orgId = storage('lacal').getItem('webOrgId')?.val;
const json = initFilter(orgId);
this.props.dispatch({
type: 'app/getDataByPost',
payload: json,
url: 'BI/BIKanBanController/HiddenManage',
onComplete: (ret) => {
if (ret && !this.isUnmounted) {
let filteredData = ret;
if (this.state.selectedHiddenCompany) {
const selectedCompanyObj = this.state.hiddenCompanyData?.find(
(company) => company.ID === this.state.selectedHiddenCompany
);
const selectedCompanyName = selectedCompanyObj?.NAME;
if (selectedCompanyName) {
// 筛选 hiddenRanking
filteredData.hiddenRanking = filteredData.hiddenRanking.filter(
(item) => item.companyName === selectedCompanyName
);
}
}
this.setState({
hiddenSubData: filteredData,
});
}
},
});
};
// ==================== 其他页面方法 ====================
getRiskSubData = () => {
this.setState({
riskSubData: {
riskList: [
{
companyName: '邦泰',
majorCount: 2,
largerCount: 5,
generalCount: 12,
lowCount: 33,
totalCount: 52,
},
{
companyName: '鸿源建设',
majorCount: 1,
largerCount: 3,
generalCount: 8,
lowCount: 20,
totalCount: 32,
},
{
companyName: '华安工程',
majorCount: 0,
largerCount: 2,
generalCount: 6,
lowCount: 15,
totalCount: 23,
},
{
companyName: '天达科技',
majorCount: 3,
largerCount: 4,
generalCount: 10,
lowCount: 18,
totalCount: 35,
},
],
riskTypeList: [
{ typeName: '动火作业', qty: 18 },
{ typeName: '高处作业', qty: 24 },
{ typeName: '临时用电', qty: 12 },
{ typeName: '起重吊装', qty: 9 },
{ typeName: '受限空间', qty: 7 },
],
const orgId = storage('lacal').getItem('webOrgId')?.val;
const json = initFilter(orgId);
this.props.dispatch({
type: 'app/getDataByPost',
payload: json,
url: 'BI/BIKanBanController/RiskManage',
onComplete: (ret) => {
if (ret && !this.isUnmounted) {
this.setState({
riskSubData: ret,
});
}
},
});
};
getClassSubData = () => {
this.setState({
classSubData: [
{ companyName: '邦泰', rate: '52%' },
{ companyName: '路源', rate: '52%' },
{ companyName: '安达', rate: '78%' },
{ companyName: '迅捷', rate: '63%' },
{ companyName: '恒通', rate: '45%' },
{ companyName: '华威', rate: '91%' },
{ companyName: '鼎盛', rate: '37%' },
],
const orgId = storage('lacal').getItem('webOrgId')?.val;
const json = initFilter(orgId);
this.props.dispatch({
type: 'app/getDataByPost',
payload: json,
url: 'BI/BIKanBanController/TeamManage',
onComplete: (ret) => {
if (ret && !this.isUnmounted) {
this.setState({
classSubData: ret,
});
}
},
});
};
@ -767,65 +616,30 @@ class FullScreen extends React.Component {
};
getDangerSubData = () => {
let filteredData = [
{
companyName: '邦泰',
startDate: '2025-01-01 08:30:00',
endDate: '2025-01-01 17:00:00',
jobName: '爆破作业',
areaName: '矿山采场',
place: '东采区+320平台',
users: '张三,李四,王五',
monitor: '赵正三',
approveUsers: '刘安全,陈技术',
},
{
companyName: '邦泰',
startDate: '2025-01-03 09:00:00',
endDate: '2025-01-03 18:00:00',
jobName: '高处作业',
areaName: '装置区',
place: '脱硫塔顶部',
users: '王高空,李安全带,张监护',
monitor: '周正三',
approveUsers: '吴经理,郑安全',
},
{
companyName: '天山',
startDate: '2025-01-02 08:00:00',
endDate: '2025-01-02 17:30:00',
jobName: '高处作业',
areaName: '水泥生产线',
place: '预热器塔架',
users: '检修班组',
monitor: '天山-赵正',
approveUsers: '天山-刘经理,天山-王安全',
},
{
companyName: '天山',
startDate: '2025-01-04 09:30:00',
endDate: '2025-01-04 18:00:00',
jobName: '有限空间作业',
areaName: '均化库',
place: '库内底部',
users: '清库作业组',
monitor: '天山-钱正',
approveUsers: '天山-孙厂长,天山-李安全',
},
];
const orgId = storage('lacal').getItem('webOrgId')?.val;
const json = initFilter(orgId);
this.props.dispatch({
type: 'app/getDataByPost',
payload: json,
url: 'BI/BIKanBanController/JobManage',
onComplete: (ret) => {
if (ret && !this.isUnmounted) {
let filteredData = ret;
if (this.state.selectedDangerCompany) {
const selectedCompanyObj = this.state.dangerCompanyData?.find(
(company) => company.ID === this.state.selectedDangerCompany
);
const selectedCompanyName = selectedCompanyObj?.NAME;
if (selectedCompanyName) {
filteredData = filteredData.filter((item) => item.companyName === selectedCompanyName);
}
}
if (this.state.selectedDangerCompany) {
const selectedCompanyObj = this.state.dangerCompanyData?.find(
(company) => company.ID === this.state.selectedDangerCompany
);
const selectedCompanyName = selectedCompanyObj?.NAME;
if (selectedCompanyName) {
filteredData = filteredData.filter((item) => item.companyName === selectedCompanyName);
}
}
this.setState({
dangerSubData: filteredData,
this.setState({
dangerSubData: filteredData,
});
}
},
});
};