集团企业信息汇总

This commit is contained in:
yunkexin 2026-05-19 17:36:06 +08:00
parent d41c91fc8e
commit a1dcf8b53d
11 changed files with 642 additions and 47 deletions

BIN
src/assets/layout/dt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
src/assets/layout/dt@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

BIN
src/assets/layout/kqmj.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
src/assets/layout/scgm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@ -939,6 +939,79 @@ class HomeContent extends React.Component {
{/* 右侧区域 */}
<Col span={7} className={styles.rightCol}>
<div className={styles.dangerCard}>
{/* <div id="dangerOperationChart" className={styles.fullChartContainer}></div> */}
<div className={styles.infoContainer}>
<div className={styles.infoTitle}>集团企业信息汇总</div>
<div className={styles.infoCard}>
<div className={styles.infoCardMark}>集团公司</div>
<div className={styles.infoCardTitle}>吐鲁番金源矿冶有限责任公司</div>
<div className={styles.infoCardDetail}>子公司数量{trainingData?.SumSubCount || '-'}</div>
</div>
<div className={styles.infoBanner}>
{trainingData.listSubTypeCount && Object.keys(trainingData.listSubTypeCount).length > 0 ? (
<>
<div className={styles.bannerScrollContainer} ref={this.bannerScrollRef}>
<div className={styles.bannerScrollContent}>
{Object.entries(trainingData.listSubTypeCount).map(([key, value], index) => (
<div key={index} className={styles.infoSpan}>
<span>{key}</span>
<span>{value}</span>
</div>
))}
</div>
</div>
</>
) : (
// 默认显示当没有数据时保持原有3个的样子
<div
className={styles.bannerScrollContent}
style={{ width: '100%', justifyContent: 'space-around' }}
>
<div className={styles.infoSpan}>
<span>露天矿</span>
<span>1</span>
</div>
<div className={styles.infoSpan}>
<span>地下矿</span>
<span>12</span>
</div>
<div className={styles.infoSpan}>
<span>尾矿库</span>
<span>13</span>
</div>
</div>
)}
</div>
<div className={styles.infoBottom}>
<div className={styles.infoBottomContent}>
<div className={styles.infoBottomImg}>
<img src={require('../../assets/layout/scgm.png')}></img>
</div>
<div className={styles.infoBottomContentRight}>
<div className={styles.infoBottomTitle}>生产规模</div>
<div className={styles.infoBottomNum}>
<span>{trainingData?.SumSubMode || '-'}</span>/
</div>
</div>
</div>
<div className={styles.infoBottomContent}>
<div className={styles.infoBottomImg}>
<img src={require('../../assets/layout/kqmj.png')}></img>
</div>
<div className={styles.infoBottomContentRight}>
<div className={styles.infoBottomTitle}>矿区面积</div>
<div className={styles.infoBottomNum}>
<span>{trainingData?.SumSubArea || '-'}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div className={styles.spacer}></div>
<div className={styles.riskCard}>
<Row className={styles.riskRow}>
<Col span={8} className={styles.trainingStatsCol}>
@ -958,12 +1031,6 @@ class HomeContent extends React.Component {
</Col>
</Row>
</div>
<div className={styles.spacer}></div>
<div className={styles.dangerCard}>
<div id="dangerOperationChart" className={styles.fullChartContainer}></div>
</div>
</Col>
</Row>
{/* 公告详情弹窗 */}

View File

@ -308,16 +308,7 @@ class FullScreen extends React.Component {
onComplete: (ret) => {
if (ret && !this.isUnmounted) {
this.setState({
trainingData: {
listNAME: ret.listNAME || [],
YearCount: ret.YearCount || [],
MonthRecordCount: ret.MonthRecordCount || [],
MonthPersonCount: ret.MonthPersonCount || [],
listAnnourcement: ret.listAnnourcement || [],
TITLE: ret.TITLE || '',
listVideoImg: ret.listVideoImg || [],
playSet: ret.playSet || [],
},
trainingData: ret,
});
}
},

View File

@ -162,6 +162,277 @@
flex-direction: column;
overflow: hidden;
}
.infoContainer {
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 20px;
height: 100%;
}
.infoTitle {
font-size: 20px;
font-weight: bold;
text-align: left;
color: #000;
margin-bottom: 24px;
}
.infoCard {
display: flex;
flex-direction: column;
justify-content: space-between;
position: relative;
background: url('../assets/layout/dt.png') no-repeat center center;
background-size: cover;
border-radius: 10px;
padding: 28px 28px 36px 28px;
align-items: flex-start;
}
.infoCardMark {
position: absolute;
top: 0px;
right: 0px;
background-color: #1668fe;
padding: 6px 17px;
border-radius: 0 10px;
font-size: 14px;
color: #fff;
}
.infoCardTitle {
font-size: 20px;
color: #082a61;
font-weight: bold;
text-align: left;
margin-bottom: 14px;
}
.infoCardDetail {
font-size: 13px;
color: #1f69ff;
text-align: left;
background: rgba(255, 255, 255, 0.5);
border-radius: 13px;
padding: 4px 16px;
}
// 替换原有的 .infoBanner 样式
.infoBanner {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
margin: 20px 0;
position: relative;
width: 100%;
overflow: hidden;
}
// 滚动容器
.bannerScrollContainer {
flex: 1;
overflow-x: auto;
overflow-y: hidden;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
// 隐藏滚动条(可选,如果想要保持美观)
&::-webkit-scrollbar {
height: 4px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 2px;
}
&::-webkit-scrollbar-thumb {
background: #ccc;
border-radius: 2px;
&:hover {
background: #999;
}
}
}
.bannerScrollContent {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around; // 保持平均分布
gap: 30px;
padding: 0 10px;
}
// 当项目数量 <= 3 时,每个项目平均分布
.infoBanner:not(.hasScroll) .infoSpan {
flex: 1;
}
// 修改 infoSpan 内部样式 - 保持固定宽度
.infoSpan {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
flex-shrink: 0; // 防止被压缩
width: 100px; // 固定宽度保持和3个时一样大
min-width: 100px;
> span:first-child {
color: #5f7291;
font-size: 18px;
font-weight: 500;
white-space: nowrap;
}
> span:last-child {
color: #000;
font-size: 27px;
font-weight: bold;
white-space: nowrap;
}
// 添加分割线效果
position: relative;
&:not(:last-child)::after {
content: '';
position: absolute;
right: -15px;
top: 50%;
transform: translateY(-50%);
width: 1px;
height: 40px;
background: linear-gradient(to bottom, transparent, #ccc, transparent);
}
}
// 左右箭头样式
.bannerArrowLeft,
.bannerArrowRight {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 32px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 10;
background-color: rgba(0, 0, 0, 0.4);
border-radius: 4px;
transition: all 0.3s ease;
i,
.anticon {
font-size: 18px;
color: #fff;
}
&:hover {
background-color: rgba(0, 0, 0, 0.7);
transform: translateY(-50%) scale(1.05);
}
}
.bannerArrowLeft {
left: 0;
}
.bannerArrowRight {
right: 0;
}
// 修改 infoSpan 内部样式
.infoSpan {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px; // 标题和数值间距 10px
> span:first-child {
color: #5f7291;
font-size: 18px;
font-weight: 500;
}
> span:last-child {
color: #000;
font-size: 27px;
font-weight: bold;
}
}
.infoBottom {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
background-color: #f5f7fc;
border-radius: 10px;
// padding: 26px;
margin-top: 10px;
position: relative;
.infoBottomContent {
flex: 1;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 12px;
position: relative;
padding: 26px;
&:not(:last-child)::after {
content: '';
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
width: 2px;
height: 60px;
background: linear-gradient(to bottom, transparent, #e6e9f3, transparent);
}
}
}
.infoBottomImg {
width: 40px;
height: 40px;
flex-shrink: 0;
margin-right: 10px;
img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
.infoBottomContentRight {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
}
.infoBottomTitle {
font-size: 18px;
color: #5f7291;
margin-bottom: 4px;
font-weight: 500;
white-space: nowrap;
}
.infoBottomNum {
font-size: 16px;
color: #1d6fe9;
white-space: nowrap;
span {
font-size: 20px;
font-weight: bold;
}
}
// 左侧和右侧卡片样式
.riskCard {

View File

@ -2,7 +2,17 @@ import React, { useState, useEffect, useRef, Component } from 'react';
import { connect } from 'dva';
import storage from '../utils/storage';
import IconFont from '../utils/iconFont';
import { initFilter, addRuleAndGroups, guid, extendInclude, extendRule, extend, extendOrder } from '../utils/common';
import {
initFilter,
addRuleAndGroups,
guid,
extendInclude,
extendRule,
extend,
extendOrder,
showFiles,
GetFileModel,
} from '../utils/common';
import './home.less';
// 组件库
import {
@ -28,6 +38,7 @@ import FormPage from '../components/FormPage';
import backlog from '../assets/home/backlog.png';
import backlog_i from '../assets/home/backlog_icon.png';
import styles from './dashboard.css';
import styleshome from './annourcement.less';
import 'slick-carousel/slick/slick.css';
import 'slick-carousel/slick/slick-theme.css';
import moment from 'moment';
@ -182,6 +193,13 @@ class Home extends React.Component {
},
taskSelects: [],
mineType: localStorage.getItem('currentMineType') === '20' ? '10' : localStorage.getItem('currentMineType'),
annourcement: [],
announcementDetail: null, // 公告详情
announcementModalVisible: false, // 公告弹窗可见性
announcementDetailLoading: false, // 公告详情加载状态
fileForm: {
visible: false,
},
};
// this.enums = [];
this.reportType = '';
@ -618,20 +636,20 @@ class Home extends React.Component {
};
//风险等级占比
riskLevel = () => {
const userInfo = storage('lacal').getItem('webUserInfo').val;
let json = initFilter(this.props.login.OrgId);
extendOrder(json, 'NUM', 0);
extendRule(json, 'COLOR', 1, this.state.mineType);
extendOrder(json, 'CREATE_TIME', 1);
this.props.dispatch({
type: 'app/getDataByPost',
url: 'FM/RiskLevelProportion/OrderPaged',
url: 'PF/PFAnnourcement/OrderPaged',
payload: json,
onlyData: false,
onComplete: (data) => {
if (data && data.IsSuccessful) {
if (data.Data && data.Data.length > 0) {
console.log('风险等级占比', data.Data);
this.setState({
riskLevelPage: data.Data,
annourcement: data.Data,
});
}
}
@ -1369,9 +1387,141 @@ class Home extends React.Component {
detailForm: detailForm,
});
};
// 添加获取公告详情的方法
getAnnouncementDetail = (announcement) => {
return new Promise((resolve, reject) => {
const orgId = storage('lacal').getItem('webOrgId')?.val;
const json = initFilter(orgId);
extendRule(json, 'ID', 1, announcement.ID);
json.Include = ['Nav_Orgs', 'Nav_Orgs.Nav_OrgSub', 'Nav_Files.Nav_ImgFile'];
this.setState({ announcementDetailLoading: true, announcementDetail: null });
this.props.dispatch({
type: 'app/getDataByPost',
payload: json,
url: 'PF/PFAnnourcement/Get',
onComplete: (ret) => {
if (ret) {
this.setState({
announcementDetail: ret,
announcementDetailLoading: false,
});
resolve(ret);
} else {
message.error('暂无公告详情');
this.setState({ announcementDetailLoading: false });
reject(new Error('获取公告详情失败'));
}
},
onError: (error) => {
this.setState({ announcementDetailLoading: false });
reject(error);
},
});
});
};
// 添加点击公告的处理方法
handleAnnouncementClick = async (announcement) => {
try {
const detail = await this.getAnnouncementDetail(announcement);
this.setState({
announcementModalVisible: true,
});
} catch (error) {
console.error('获取公告详情失败:', error);
message.error('获取公告详情失败');
}
};
// 添加关闭公告弹窗的方法
handleAnnouncementModalClose = () => {
this.setState({
announcementModalVisible: false,
announcementDetail: null,
});
};
// 添加渲染公告弹窗内容的方法
renderAnnouncementModal = () => {
const { announcementDetail, announcementDetailLoading } = this.state;
if (announcementDetailLoading) {
return (
<div style={{ textAlign: 'center', padding: '50px' }}>
<Icon type="loading" style={{ fontSize: '32px' }} />
</div>
);
}
if (!announcementDetail) return null;
const { TITLE, ABSTRACT, START, END, CONTENT, CREATE_USER_NAME, Nav_Files = [] } = announcementDetail;
return (
<div>
{/* 标题 */}
<div style={{ textAlign: 'center', fontSize: '18px', color: '#333', marginBottom: '16px', fontWeight: 'bold' }}>
{TITLE}
</div>
{/* 摘要 */}
{ABSTRACT && (
<div
style={{
fontSize: '14px',
color: '#676767',
wordBreak: 'break-all',
wordWrap: 'break-word',
marginBottom: '12px',
lineHeight: '1.5',
padding: '0 16px',
}}
>
{ABSTRACT}
</div>
)}
{/* 日期和发布人 */}
<div style={{ fontSize: '12px', color: '#999', marginBottom: '16px', textAlign: 'center' }}>
{START ? START.split(' ')[0] : '--'} {END ? END.split(' ')[0] : '--'}
{CREATE_USER_NAME && <span style={{ marginLeft: '20px' }}>发布人{CREATE_USER_NAME}</span>}
</div>
{/* 分割线 */}
<div style={{ borderTop: '1px solid #e8e8e8', marginBottom: '16px' }}></div>
{/* 正文内容 */}
<div
style={{
fontSize: '14px',
lineHeight: '1.8',
color: '#333',
marginBottom: '16px',
maxHeight: '60vh',
overflowY: 'auto',
padding: '0 8px',
}}
dangerouslySetInnerHTML={{ __html: CONTENT || '<div style="color:#999;text-align:center;">暂无内容</div>' }}
/>
{/* 附件列表 */}
{Nav_Files && Nav_Files.length > 0 && (
<div style={{ marginTop: '16px', borderTop: '1px solid #f0f0f0', paddingTop: '12px' }}>
<div style={{ fontWeight: 'bold', marginBottom: '12px', fontSize: '14px', color: '#333' }}>
附件 ({Nav_Files.length})
</div>
{showFiles(Nav_Files, config.picServerHost, this)}
{GetFileModel(Modal, FormPage, this, this.state.fileForm.visible)}
</div>
)}
</div>
);
};
render() {
const { tableData } = this.state;
const { tableData, annourcement } = this.state;
const thingsData = this.state.delayData;
const settings = {
dots: false,
@ -1431,6 +1581,20 @@ class Home extends React.Component {
size="small"
/>
</Modal>
<Modal
title="公告详情"
visible={this.state.announcementModalVisible}
onCancel={this.handleAnnouncementModalClose}
footer={[
<Button key="close" onClick={this.handleAnnouncementModalClose}>
关闭
</Button>,
]}
width="600px"
bodyStyle={{ padding: '20px', maxHeight: '70vh', overflowY: 'auto' }}
>
{this.renderAnnouncementModal()}
</Modal>
<Modal
visible={this.state.scoreVisible}
title="标准化得分明细"
@ -1643,34 +1807,38 @@ class Home extends React.Component {
}}
>
<div className="dashboard-div-style">
<div className="statistical-title-style">
<div className="badge-style">
<Icon type="pie-chart" style={{ color: '#5f6ac2', marginRight: '4px' }}></Icon>
风险等级占比
<div className={styleshome.announcementCard}>
<div className={styleshome.announcementHeader}>
<div className={styleshome.announcementTitle}>
<Icon type="sound" className={styleshome.announcementIcon} />
<span>公司公告</span>
</div>
{this.state.riskLevelPage.length > 0 ? (
<span
style={{
fontSize: '14px',
float: 'right',
marginRight: '16px',
// marginTop: "4px",
}}
<span className={styleshome.announcementCount}> {annourcement?.length || 0} 条公告</span>
</div>
<div className={styleshome.announcementList}>
{annourcement?.length > 0 ? (
<ul className={styleshome.announcementUl}>
{annourcement.map((item, index) => (
<li
key={item.id || index}
className={styleshome.announcementItem}
onClick={() => this.handleAnnouncementClick(item)}
>
<div onClick={() => this.showDetailModal('BI013_RISKANALYSISMODEL')}>
<IconFont
type="icon-24gl-expand2"
style={{
fontSize: '18px',
color: '#333333',
cursor: 'pointer',
}}
></IconFont>
</div>
<span className={styleshome.announcementItemTitle} title={item.TITLE}>
{item.TITLE}
</span>
) : null}
<span className={styleshome.announcementItemTime}>{item.START}</span>
</li>
))}
</ul>
) : (
<div className={styleshome.emptyAnnouncement}>
<Icon type="inbox" className={styleshome.emptyIcon} />
<span>暂无公告</span>
</div>
)}
</div>
</div>
{this.state.riskLevelPage.length > 0 ? <RisiLevel riskLevelPage={this.state.riskLevelPage} /> : null}
</div>
</div>
</Col>

View File

@ -0,0 +1,98 @@
.announcementCard {
flex: 3;
background-color: #fff;
border-radius: 4px;
display: flex;
flex-direction: column;
overflow: hidden;
min-height: 0;
height: 100%;
}
.announcementHeader {
width: 100%;
padding: 8px 20px;
border-bottom: 2px solid #1890ff;
display: flex;
align-items: center;
justify-content: space-between;
flex-shrink: 0;
}
.announcementTitle {
display: flex;
align-items: center;
}
.announcementIcon {
font-size: 16px;
color: #1890ff;
margin-right: 8px;
}
.announcementTitle span {
font-size: 18px;
color: #333333;
}
.announcementCount {
font-size: 14px;
color: #999;
}
.announcementList {
flex: 1;
overflow-y: auto;
padding: 8px 0;
}
.announcementUl {
list-style: none;
margin: 0;
padding: 0;
}
.announcementItem {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 16px;
border-bottom: 1px solid #f0f0f0;
cursor: pointer;
transition: background-color 0.3s;
&:hover {
background-color: #f5f5f5;
}
}
.announcementItemTitle {
font-size: 14px;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
text-align: left;
}
.announcementItemTime {
font-size: 14px;
color: #999;
margin-left: 16px;
white-space: nowrap;
}
.emptyAnnouncement {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
color: #999;
}
.emptyIcon {
font-size: 48px;
margin-bottom: 16px;
}