diff --git a/src/assets/layout/dt.png b/src/assets/layout/dt.png new file mode 100644 index 0000000..6f42e6a Binary files /dev/null and b/src/assets/layout/dt.png differ diff --git a/src/assets/layout/dt@2x.png b/src/assets/layout/dt@2x.png new file mode 100644 index 0000000..a62ba30 Binary files /dev/null and b/src/assets/layout/dt@2x.png differ diff --git a/src/assets/layout/kqmj.png b/src/assets/layout/kqmj.png new file mode 100644 index 0000000..cbe2963 Binary files /dev/null and b/src/assets/layout/kqmj.png differ diff --git a/src/assets/layout/kqmj@2x.png b/src/assets/layout/kqmj@2x.png new file mode 100644 index 0000000..524c018 Binary files /dev/null and b/src/assets/layout/kqmj@2x.png differ diff --git a/src/assets/layout/scgm.png b/src/assets/layout/scgm.png new file mode 100644 index 0000000..7dc54ca Binary files /dev/null and b/src/assets/layout/scgm.png differ diff --git a/src/assets/layout/scgm@2x.png b/src/assets/layout/scgm@2x.png new file mode 100644 index 0000000..6e8d25b Binary files /dev/null and b/src/assets/layout/scgm@2x.png differ diff --git a/src/components/CustomPages/BI/BI064FormRunAnalysis.js b/src/components/CustomPages/BI/BI064FormRunAnalysis.js index 4be82a9..8902ed2 100644 --- a/src/components/CustomPages/BI/BI064FormRunAnalysis.js +++ b/src/components/CustomPages/BI/BI064FormRunAnalysis.js @@ -1,14 +1,23 @@ import React from 'react'; import { connect } from 'dva'; +import moment from 'moment' import { initFilter } from '../../../utils/common'; -import { Table, Row, Spin, Card, Modal, Col, Button, Form } from 'antd'; +import { Table, Row, Spin, Card, Modal, DatePicker,Col, Button, Form ,Select} from 'antd'; import DropDownPagination from '../../common/DropDownPaginationEx'; +const { Option } = Select; class BI064FormRunAnalysis extends React.Component { constructor(props) { super(props); this.state = { depart: {}, inputText: '', + inputText2: '', + inputText3: '', + startTime:moment(this.getDate(), 'YYYY-MM-DD 00:00:00'),//moment(new Date()).add(-1, "month").format('YYYY-MM-DD 00:00:00'), + endTime:moment(this.getEndDate(), 'YYYY-MM-DD 23:59:59'), + selectForms:['安全风险辨识与评估计划','安全风险辨识表', '安全风险辨识结果表', '安全风险辨识结果汇总表', '安全风险评估表', + '安全风险评估汇总表', '风险检查关联表','安全检查通知','安全检查记录','安全检查记录汇总','隐患上报','手动隐患上报完善', + '隐患确认单','隐患整改通知单', '隐患整改记录', '延期整改申请'], retData: [], // 表单运行数据 companyData: [], // 公司数据 loading: true, @@ -65,7 +74,50 @@ class BI064FormRunAnalysis extends React.Component { ], }; } + getDate=()=>{ + let date = new Date() + let y = date.getFullYear() + let m = date.getMonth() + 1 + let d = date.getDate(); + // 当前日期 + let nowDate = y + "-" + (m < 10 ? "0" + m : m) + "-" + (d < 10 ? "0" + d : d); + // 一月的时候年份要减一 + // if(m == 1) { + // y-- + // m = 12 + // }else if(m == 3 && d > 28) { + + // //三月要考虑是否为闰年 + // m-- + // if(y%4 == 0 && y%100!=0 || y%400 == 0) { + // d = 29 + // }else { + // d-28 + // } + // }else if((m != 12 || m != 8 )&& d == 31) { + + // //31号的月份要考虑上个月是否有31号 + // m-- + // d = 30 + // }else { + // m-- + // } + // 一个月前的日期(默认月份) + //let pastDate = y + (m < 10 ? "0" + m : m) + (d < 10 ? "0" + d : d) + let pastDate = moment(nowDate).add(-1, "day").format('YYYY-MM-DD 00:00:00') + return pastDate; +} +getEndDate=()=>{ + let date = new Date() + let y = date.getFullYear() + let m = date.getMonth() + 1 + let d = date.getDate(); + // 当前日期 + let nowDate = y + "-" + (m < 10 ? "0" + m : m) + "-" + (d < 10 ? "0" + d : d); + let pastDate = moment(nowDate).add(-1, "day").add(23,'hour').add(59,'m').add(59,'s')//format('YYYY-MM-DD 23:59:59') + return pastDate; +} componentDidMount() { this.loadData(); } @@ -84,6 +136,49 @@ class BI064FormRunAnalysis extends React.Component { inputText: record ? record?.NAME : this.state.inputText, }); }; + handleSearch2 = (value) => { + let temps = ['安全风险辨识与评估计划','安全风险辨识表', '安全风险辨识结果表', '安全风险辨识结果汇总表', '安全风险评估表', + '安全风险评估汇总表', '风险检查关联表','安全检查通知','安全检查记录','安全检查记录汇总','隐患上报','手动隐患上报完善', + '隐患确认单','隐患整改通知单', '隐患整改记录', '延期整改申请']; + + if(value === "双重预防机制" ) + { + temps = ['安全风险辨识与评估计划','安全风险辨识表', '安全风险辨识结果表', '安全风险辨识结果汇总表', '安全风险评估表', + '安全风险评估汇总表', '风险检查关联表','安全检查通知','安全检查记录','安全检查记录汇总','隐患上报','手动隐患上报完善', + '隐患确认单','隐患整改通知单', '隐患整改记录', '延期整改申请']; + } + if(value === "作业现场安全管理" ) + { + + temps = [ '班前会议', '岗位当班记录', '交接班记录', '班组活动记录','一般作业活动记录', '作业方案讨论记录','关键许可工作票', + '安全技术交底表','关键许可作业活动记录','矿山动火作业工作票','技术交底表','安全交底表','领导带班下井记录']; + } + if(value === "安全教育与培训" ) + { + + temps = ['安全意识调查', '培训需求调查','培训通知', '培训通知(转训)','培训记录', '培训效果评估调查表', '三级安全教育培训记录', + '新三级安全教育记录', '新三级安全教育卡' ]; + } + this.setState({ + inputText2: value, + selectForms:temps + }) + } + handleSearch3 = (value) => { + this.setState({ + inputText3: value + }) + } + startChange=(value)=>{ + this.setState({ + startTime:value + }) + }; + endChange=(value)=>{ + this.setState({ + endTime:value + }) + }; // 获取公司数据 getBaseData = () => { const json = initFilter(this.props.login.OrgId); @@ -111,7 +206,7 @@ class BI064FormRunAnalysis extends React.Component { // 获取表单运行数据 getrealData = () => { // const json = initFilter(this.props.login.OrgId); - let json = initFilter('00300000-0000-0000-0000-000000000000', this.state.inputText); + let json = initFilter('00300000-0000-0000-0000-000000000000', this.state.inputText,"","","",this.state.startTime,this.state.endTime); this.props.dispatch({ type: 'app/getDataByPost', url: 'BI/BIStatiscialAnalysisController/GetTaskViewInfo', @@ -119,6 +214,14 @@ class BI064FormRunAnalysis extends React.Component { onlyData: false, onComplete: (ret) => { if (ret && ret.Data) { + if(this.state.inputText2) + { + ret.Data= ret.Data.filter((t) => t.MOULD_NAME === this.state.inputText2); + } + if(this.state.inputText3) + { + ret.Data= ret.Data.filter((t) => t.FORM_NAME === this.state.inputText3); + } this.setState({ retData: ret.Data, loading: false }, () => { this.processData(); }); @@ -134,6 +237,7 @@ class BI064FormRunAnalysis extends React.Component { const { retData, companyData, inputText } = this.state; if (!retData.length || !companyData.length) return; let companyDataTemp = companyData.filter((t) => t.NAME === inputText); + // 获取所有模块和表单的列表 const modules = [...new Set(retData.map((item) => item.MOULD_NAME))]; const forms = []; @@ -454,7 +558,7 @@ class BI064FormRunAnalysis extends React.Component { }; render() { - const { tableData, columns, loading } = this.state; + const { tableData, columns, loading,selectForms } = this.state; const formItemLayout = { labelCol: { span: 8 }, wrapperCol: { span: 16 }, @@ -516,7 +620,66 @@ class BI064FormRunAnalysis extends React.Component { /> - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/layout/FullOther/HomeContent.js b/src/layout/FullOther/HomeContent.js index e5fa090..45851c5 100644 --- a/src/layout/FullOther/HomeContent.js +++ b/src/layout/FullOther/HomeContent.js @@ -939,6 +939,79 @@ class HomeContent extends React.Component { {/* 右侧区域 */} +
+ {/*
*/} +
+
集团企业信息汇总
+
+
集团公司
+
吐鲁番金源矿冶有限责任公司
+
子公司数量:{trainingData?.SumSubCount || '-'}家
+
+
+ {trainingData.listSubTypeCount && Object.keys(trainingData.listSubTypeCount).length > 0 ? ( + <> +
+
+ {Object.entries(trainingData.listSubTypeCount).map(([key, value], index) => ( +
+ {key} + {value}家 +
+ ))} +
+
+ + ) : ( + // 默认显示(当没有数据时,保持原有3个的样子) +
+
+ 露天矿 + 1家 +
+
+ 地下矿 + 12家 +
+
+ 尾矿库 + 13家 +
+
+ )} +
+
+
+
+ +
+
+
生产规模
+
+ {trainingData?.SumSubMode || '-'}吨/年 +
+
+
+
+
+ +
+
+
矿区面积
+
+ {trainingData?.SumSubArea || '-'}平方公里 +
+
+
+
+
+
+ +
+
@@ -958,12 +1031,6 @@ class HomeContent extends React.Component {
- -
- -
-
-
{/* 公告详情弹窗 */} diff --git a/src/layout/FullScreenInter.js b/src/layout/FullScreenInter.js index 3a184d9..487e7bf 100644 --- a/src/layout/FullScreenInter.js +++ b/src/layout/FullScreenInter.js @@ -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, }); } }, diff --git a/src/layout/fullinter.less b/src/layout/fullinter.less index acb7f3f..ac31893 100644 --- a/src/layout/fullinter.less +++ b/src/layout/fullinter.less @@ -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 { diff --git a/src/routes/Home.js b/src/routes/Home.js index ea8c55a..189eaf7 100644 --- a/src/routes/Home.js +++ b/src/routes/Home.js @@ -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 ( +
+ +
+ ); + } + + if (!announcementDetail) return null; + + const { TITLE, ABSTRACT, START, END, CONTENT, CREATE_USER_NAME, Nav_Files = [] } = announcementDetail; + + return ( +
+ {/* 标题 */} +
+ {TITLE} +
+ + {/* 摘要 */} + {ABSTRACT && ( +
+ {ABSTRACT} +
+ )} + + {/* 日期和发布人 */} +
+ {START ? START.split(' ')[0] : '--'} 至 {END ? END.split(' ')[0] : '--'} + {CREATE_USER_NAME && 发布人:{CREATE_USER_NAME}} +
+ + {/* 分割线 */} +
+ + {/* 正文内容 */} +
暂无内容
' }} + /> + + {/* 附件列表 */} + {Nav_Files && Nav_Files.length > 0 && ( +
+
+ 附件 ({Nav_Files.length}个) +
+ {showFiles(Nav_Files, config.picServerHost, this)} + {GetFileModel(Modal, FormPage, this, this.state.fileForm.visible)} +
+ )} +
+ ); + }; 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" /> + + 关闭 + , + ]} + width="600px" + bodyStyle={{ padding: '20px', maxHeight: '70vh', overflowY: 'auto' }} + > + {this.renderAnnouncementModal()} +
-
-
- - 风险等级占比 +
+
+
+ + 公司公告 +
+ 共 {annourcement?.length || 0} 条公告
- {this.state.riskLevelPage.length > 0 ? ( - -
this.showDetailModal('BI013_RISKANALYSISMODEL')}> - +
+ {annourcement?.length > 0 ? ( +
    + {annourcement.map((item, index) => ( +
  • this.handleAnnouncementClick(item)} + > + + {item.TITLE} + + {item.START} +
  • + ))} +
+ ) : ( +
+ + 暂无公告
- - ) : null} + )} +
- {this.state.riskLevelPage.length > 0 ? : null}
diff --git a/src/routes/annourcement.less b/src/routes/annourcement.less new file mode 100644 index 0000000..07e34a0 --- /dev/null +++ b/src/routes/annourcement.less @@ -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; +}