Merge branch 'master' of http://121.41.2.71:3000/wyw/mh_jy_safe_web
This commit is contained in:
commit
05692eba30
BIN
src/assets/layout/dt.png
Normal file
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
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
BIN
src/assets/layout/kqmj.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
BIN
src/assets/layout/kqmj@2x.png
Normal file
BIN
src/assets/layout/kqmj@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
BIN
src/assets/layout/scgm.png
Normal file
BIN
src/assets/layout/scgm.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
BIN
src/assets/layout/scgm@2x.png
Normal file
BIN
src/assets/layout/scgm@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.5 KiB |
@ -64,6 +64,7 @@ class SE018EditPage extends React.Component {
|
|||||||
extendInclude(json, 'Nav_Users.Nav_Files.Nav_ImgFile');
|
extendInclude(json, 'Nav_Users.Nav_Files.Nav_ImgFile');
|
||||||
extendInclude(json, 'Nav_Files.Nav_ImgFile');
|
extendInclude(json, 'Nav_Files.Nav_ImgFile');
|
||||||
extendInclude(json, 'Nav_Papers');
|
extendInclude(json, 'Nav_Papers');
|
||||||
|
extendInclude(json, 'Nav_UserApro');
|
||||||
json.IgnoreDataRule = true;
|
json.IgnoreDataRule = true;
|
||||||
this.props.dispatch({
|
this.props.dispatch({
|
||||||
type: 'app/getDataByPost',
|
type: 'app/getDataByPost',
|
||||||
@ -79,7 +80,8 @@ class SE018EditPage extends React.Component {
|
|||||||
updateData(data) {
|
updateData(data) {
|
||||||
let isApprove = false;
|
let isApprove = false;
|
||||||
// if (data.Nav_Notify.Nav_TrainCheckType.NAME == "笔试") {
|
// if (data.Nav_Notify.Nav_TrainCheckType.NAME == "笔试") {
|
||||||
if (data.Nav_Notify.CHECKTYPE == 51 || data.Nav_Notify.CHECKTYPE == 56 || data.Nav_Notify.CHECKTYPE == 81) {
|
if ((data.Nav_Notify.CHECKTYPE == 51 || data.Nav_Notify.CHECKTYPE == 56 || data.Nav_Notify.CHECKTYPE == 81) && data.STATUS > 1) {
|
||||||
|
//data.STATUS > 1 签到的时候 看到分数为0 怪怪的
|
||||||
this.state.isExam = true;
|
this.state.isExam = true;
|
||||||
this.state.isShow = "table-cell";
|
this.state.isShow = "table-cell";
|
||||||
}
|
}
|
||||||
@ -88,8 +90,11 @@ class SE018EditPage extends React.Component {
|
|||||||
data.Nav_Users = data.Nav_Users.filter(item => item.STATUS == 0);
|
data.Nav_Users = data.Nav_Users.filter(item => item.STATUS == 0);
|
||||||
|
|
||||||
var passRateThis = 0
|
var passRateThis = 0
|
||||||
var userAll = data.Nav_Users.filter(e => e.STATUS == 0 && e.ENABLE_STATUS == 0 && e.EXAMINATION_RESULTS != null)
|
// var userAll = data.Nav_Users.filter(e => e.STATUS == 0 && e.ENABLE_STATUS == 0 && e.EXAMINATION_RESULTS != null)
|
||||||
var userPass = data.Nav_Users.filter(e => e.STATUS == 0 && e.ENABLE_STATUS == 0 && e.EXAMINATION_RESULTS != null && e.EXAMINATION_RESULTS == 1)
|
// var userPass = data.Nav_Users.filter(e => e.STATUS == 0 && e.ENABLE_STATUS == 0 && e.EXAMINATION_RESULTS != null && e.EXAMINATION_RESULTS == 1)
|
||||||
|
var userAll = data.Nav_Users.filter(e => e.OK)
|
||||||
|
var userPass = data.Nav_Users.filter(e => e.OK && e.EXAMINATION_RESULTS == 1)
|
||||||
|
|
||||||
if (userAll && userAll.length > 0 && userPass && userPass.length > 0) {
|
if (userAll && userAll.length > 0 && userPass && userPass.length > 0) {
|
||||||
passRateThis = (userPass.length / userAll.length).toFixed(4) * 100;
|
passRateThis = (userPass.length / userAll.length).toFixed(4) * 100;
|
||||||
}
|
}
|
||||||
@ -226,7 +231,7 @@ class SE018EditPage extends React.Component {
|
|||||||
{
|
{
|
||||||
this.state.isView && <>
|
this.state.isView && <>
|
||||||
<ReactToPrint
|
<ReactToPrint
|
||||||
trigger={() => <Button type={'primary'} icon={'printer'} >打印</Button>}
|
trigger={() => <Button type={'primary'} style={{ marginLeft: '8px' }} icon={'printer'} >打印</Button>}
|
||||||
content={() => this.componentRef}
|
content={() => this.componentRef}
|
||||||
/>
|
/>
|
||||||
<Button style={{ marginLeft: '8px' }} onClick={() => this.onTableBtnExport()} icon="export" >导出</Button>
|
<Button style={{ marginLeft: '8px' }} onClick={() => this.onTableBtnExport()} icon="export" >导出</Button>
|
||||||
@ -337,12 +342,13 @@ class SE018EditPage extends React.Component {
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan={4} rowSpan={1} className={styles.fontBold}>审阅意见</td>
|
<td colSpan={4} className={styles.fontBold}>审阅意见</td>
|
||||||
<td colSpan={20} rowSpan={1} >
|
|
||||||
{
|
{
|
||||||
data && data.STATUS > 2 && '已阅'
|
data && data.STATUS > 2 && data.DT_APPROVE ? <td colSpan={20}>
|
||||||
|
<p>审阅人:{showUserSign(data.Nav_UserApro, config.picServerHost)}</p>
|
||||||
|
<p>审阅时间:{data.DT_APPROVE}</p>
|
||||||
|
</td> : <td colSpan={20} ></td>
|
||||||
}
|
}
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan={4} rowSpan={1} className={styles.fontBold}>合格率</td>
|
<td colSpan={4} rowSpan={1} className={styles.fontBold}>合格率</td>
|
||||||
@ -381,12 +387,12 @@ class SE018EditPage extends React.Component {
|
|||||||
{this.state.isExam && <td colSpan={4} rowSpan={1}>{it?.SCORE}</td>}
|
{this.state.isExam && <td colSpan={4} rowSpan={1}>{it?.SCORE}</td>}
|
||||||
|
|
||||||
{/* if (data.Nav_Notify.CHECKTYPE == 51 || data.Nav_Notify.CHECKTYPE == 56 || data.Nav_Notify.CHECKTYPE == 81) { */}
|
{/* if (data.Nav_Notify.CHECKTYPE == 51 || data.Nav_Notify.CHECKTYPE == 56 || data.Nav_Notify.CHECKTYPE == 81) { */}
|
||||||
{/* 线上考核 51 看试卷 56 81 看附件 */}
|
{/* 线上考核 51 看试卷 56 81 看附件 showUserSign(user, imgHost, width, height, extShowTimeText) */}
|
||||||
{
|
{
|
||||||
!signable && (
|
!signable && (
|
||||||
this.state.isShow && data.Nav_Notify.CHECKTYPE ? (
|
this.state.isShow && data.Nav_Notify.CHECKTYPE ? (
|
||||||
data.Nav_Notify.CHECKTYPE == 51 ? <td colSpan={4} rowSpan={1} ><div onClick={() => this.showDetailModal(it.RECORD_ID, it.USER_ID)}><Icon type="eye" style={{ color: "#005b9b", cursor: "pointer" }} /></div></td>
|
data.Nav_Notify.CHECKTYPE == 51 ? <td colSpan={4} rowSpan={1} style={{ display: this.state.isShow }} ><div onClick={() => this.showDetailModal(it.RECORD_ID, it.USER_ID)}><Icon type="eye" style={{ color: "#005b9b", cursor: "pointer" }} /></div></td>
|
||||||
: <td colSpan={4} rowSpan={1} > {showFiles(it?.Nav_Files, config.picServerHost, this, false)}</td>
|
: <td colSpan={4} rowSpan={1} style={{ display: this.state.isShow }} > {showFiles(it?.Nav_Files, config.picServerHost, this, false)}</td>
|
||||||
)
|
)
|
||||||
: <td colSpan={4} rowSpan={1} style={{ display: this.state.isShow }}><div onClick={() => this.showDetailModal(it.RECORD_ID, it.USER_ID)}><Icon type="eye" style={{ color: "#005b9b", cursor: "pointer" }} /></div></td>
|
: <td colSpan={4} rowSpan={1} style={{ display: this.state.isShow }}><div onClick={() => this.showDetailModal(it.RECORD_ID, it.USER_ID)}><Icon type="eye" style={{ color: "#005b9b", cursor: "pointer" }} /></div></td>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -218,7 +218,11 @@ class SE018PaperPage extends React.Component {
|
|||||||
hasAnswered = false
|
hasAnswered = false
|
||||||
else
|
else
|
||||||
hasAnswered = true
|
hasAnswered = true
|
||||||
|
if (!hasAnswered) {
|
||||||
|
if (this.props.data.tableKey == null || this.props.data.tableKey == '2') {
|
||||||
|
hasAnswered = true
|
||||||
|
}
|
||||||
|
}
|
||||||
var perPaper = []
|
var perPaper = []
|
||||||
if (isCourEdit == false)
|
if (isCourEdit == false)
|
||||||
perPaper = papers //提供显示
|
perPaper = papers //提供显示
|
||||||
@ -641,16 +645,10 @@ class SE018PaperPage extends React.Component {
|
|||||||
}, () => {
|
}, () => {
|
||||||
this.getPapers();
|
this.getPapers();
|
||||||
})
|
})
|
||||||
|
|
||||||
}}
|
}}
|
||||||
filterOption={(input, option) =>
|
filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} >
|
||||||
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{
|
{
|
||||||
this.state.UserList.map(usr =>
|
this.state.UserList.map(usr => <Option key={usr.ID} value={usr.ID}>{usr.NAME}</Option>)
|
||||||
<Option key={usr.ID} value={usr.ID}>{usr.NAME}</Option>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
</Select>
|
</Select>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,11 +17,12 @@ export default {
|
|||||||
let minutes = (Date.parse(stateData.TRAIN_END_TIME) - Date.parse(stateData.TRAIN_START_TIME)) / 1000 / 60 / 45;
|
let minutes = (Date.parse(stateData.TRAIN_END_TIME) - Date.parse(stateData.TRAIN_START_TIME)) / 1000 / 60 / 45;
|
||||||
temps.push({ field: 'HOURS', value: minutes.toFixed(1) }) // setFieldValue("HOURS", minutes.toFixed(1));
|
temps.push({ field: 'HOURS', value: minutes.toFixed(1) }) // setFieldValue("HOURS", minutes.toFixed(1));
|
||||||
}
|
}
|
||||||
// if (colInfo.FIELD_NAME == 'TRAIN_START_TIME' && stateData.TRAIN_START_TIME) {
|
if (colInfo.FIELD_NAME == 'TRAIN_START_TIME' && stateData.TRAIN_START_TIME) {
|
||||||
// //默认自动处理 开始培训前5分钟开始签到
|
//默认自动处理 开始培训前5分钟开始签到
|
||||||
// var TRAIN_END_TIME = new Date(stateData.TRAIN_START_TIME);
|
var TRAIN_END_TIME = new Date(stateData.TRAIN_START_TIME);
|
||||||
// temps.push({ field: 'DT_START_SIGN', value: new Date(TRAIN_END_TIME.setMinutes(TRAIN_END_TIME.getMinutes() - 5)) })
|
stateData.DT_START_SIGN = new Date(TRAIN_END_TIME.setMinutes(TRAIN_END_TIME.getMinutes() - 5))
|
||||||
// }
|
temps.push({ field: 'DT_START_SIGN', value: stateData.DT_START_SIGN.Format('yyyy-MM-dd HH:mm:ss') })
|
||||||
|
}
|
||||||
if (temps && temps.length > 0)
|
if (temps && temps.length > 0)
|
||||||
setFieldValueByBatch(temps);
|
setFieldValueByBatch(temps);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { message } from "antd/lib/index";
|
import { message } from "antd/lib/index";
|
||||||
import { getPropertyData, extendInclude, extendRule, getDataFieldValue, setDataFieldValue, initFilter, empty } from "../../utils/common";
|
import { getPropertyData, extendInclude, extendRule, getDataFieldValue, setDataFieldValue, initFilter, initFilterGroup, extendGroupRule, extendFilterGroup, empty } from "../../utils/common";
|
||||||
import { connect } from 'dva';
|
import { connect } from 'dva';
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
@ -23,9 +23,36 @@ export default {
|
|||||||
|
|
||||||
if (stateData.Nav_Users && stateData.Nav_Users.length > 0) {
|
if (stateData.Nav_Users && stateData.Nav_Users.length > 0) {
|
||||||
stateData.Nav_Users.forEach(e => {
|
stateData.Nav_Users.forEach(e => {
|
||||||
if (e.STATUS == 0 && e.EXAMINATION_RESULTS == undefined)
|
if (e.STATUS == 0 && e.EXAMINATION_RESULTS == undefined && e.DT_SIGN != null && stateData.Nav_Notify && stateData.Nav_Notify.CHECKTYPE == 56) {
|
||||||
e.EXAMINATION_RESULTS = 1
|
e.EXAMINATION_RESULTS = 1 //默认合格 不考试 Nav_Notify.CHECKTYPE 56
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
btnRefresh: (params) => {//params
|
||||||
|
let json = initFilter(params.login.OrgId);
|
||||||
|
extendRule(json, 'RECORD_ID', 1, params.stateData.ID);
|
||||||
|
params.dispatch({
|
||||||
|
type: 'app/getDataByPost',
|
||||||
|
url: 'SE/TrainRecordUser/Entities',
|
||||||
|
payload: json,
|
||||||
|
onComplete: (ret) => {
|
||||||
|
if (ret && ret.length > 0) {
|
||||||
|
params.stateData.Nav_Users.forEach(e => {
|
||||||
|
let r = ret.find(x => x.ID == e.ID)
|
||||||
|
if (e.DT_SIGN != r.DT_SIGN) {
|
||||||
|
e.DT_SIGN = r.DT_SIGN
|
||||||
|
e.STATUS = r.STATUS
|
||||||
|
e.OK = r.OK
|
||||||
|
e.EXAMINATION_RESULTS = r.EXAMINATION_RESULTS
|
||||||
|
if (e.DT_SIGN != null && e.EXAMINATION_RESULTS == null && params.stateData.Nav_Notify && params.stateData.Nav_Notify.CHECKTYPE == 56) {
|
||||||
|
e.EXAMINATION_RESULTS = 1 //有签到 默认 考核通过 不考试 Nav_Notify.CHECKTYPE 56
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
params.setState({ data: params.stateData });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
// DangerJob.js - 危险作业页面组件
|
// DangerJob.js - 危险作业页面组件
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Table, Select, Pagination } from 'antd';
|
import { Table, Select, Pagination, DatePicker } from 'antd';
|
||||||
|
import echarts from 'echarts';
|
||||||
import styles from './../fullinter.less';
|
import styles from './../fullinter.less';
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
@ -10,9 +11,15 @@ class DangerJob extends React.Component {
|
|||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
pageSize: 20,
|
pageSize: 10,
|
||||||
};
|
};
|
||||||
|
this.echartsInstances = {
|
||||||
|
dangerOperationChart: null, // 当日工作票统计柱状图
|
||||||
|
};
|
||||||
|
this.chartResizeHandlers = {};
|
||||||
this.isUnmounted = false;
|
this.isUnmounted = false;
|
||||||
|
// 添加缓存,用于比较数据是否真正变化
|
||||||
|
this.lastJobTodayQty = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成公司选项(与 TrainingContent 保持一致)
|
// 生成公司选项(与 TrainingContent 保持一致)
|
||||||
@ -23,8 +30,6 @@ class DangerJob extends React.Component {
|
|||||||
}
|
}
|
||||||
return companyData.map((company, index) => (
|
return companyData.map((company, index) => (
|
||||||
<Option key={company.ID || index} value={company.ID}>
|
<Option key={company.ID || index} value={company.ID}>
|
||||||
{' '}
|
|
||||||
{/* 使用 ID 作为 value,与 TrainingContent 一致 */}
|
|
||||||
{company.NAME}
|
{company.NAME}
|
||||||
</Option>
|
</Option>
|
||||||
));
|
));
|
||||||
@ -40,14 +45,222 @@ class DangerJob extends React.Component {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 处理开始日期变化
|
||||||
|
startChange = (value) => {
|
||||||
|
const { onStartChange } = this.props;
|
||||||
|
this.setState({ currentPage: 1 }, () => {
|
||||||
|
if (onStartChange) {
|
||||||
|
onStartChange(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理结束日期变化
|
||||||
|
endChange = (value) => {
|
||||||
|
const { onEndChange } = this.props;
|
||||||
|
this.setState({ currentPage: 1 }, () => {
|
||||||
|
if (onEndChange) {
|
||||||
|
onEndChange(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 处理页码变化
|
// 处理页码变化
|
||||||
handlePageChange = (page, pageSize) => {
|
handlePageChange = (page, pageSize) => {
|
||||||
this.setState({ currentPage: page, pageSize });
|
this.setState({ currentPage: page, pageSize });
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理每页条数变化
|
// 等待DOM元素加载完成
|
||||||
handleShowSizeChange = (current, size) => {
|
waitForElement = (elementId, maxRetries = 10) => {
|
||||||
this.setState({ currentPage: 1, pageSize: size });
|
return new Promise((resolve) => {
|
||||||
|
let retries = 0;
|
||||||
|
const checkInterval = setInterval(() => {
|
||||||
|
const element = document.getElementById(elementId);
|
||||||
|
if (element || retries >= maxRetries) {
|
||||||
|
clearInterval(checkInterval);
|
||||||
|
resolve(!!element);
|
||||||
|
}
|
||||||
|
retries++;
|
||||||
|
}, 50);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 设置resize监听
|
||||||
|
setupResizeHandler = (chartName, renderMethod) => {
|
||||||
|
const resizeHandler = () => {
|
||||||
|
if (this.echartsInstances[chartName] && !this.isUnmounted) {
|
||||||
|
this.echartsInstances[chartName].resize();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.chartResizeHandlers[chartName] = resizeHandler;
|
||||||
|
window.addEventListener('resize', resizeHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 图表: 当日工作票统计柱状图
|
||||||
|
renderDangerOperationChart = async () => {
|
||||||
|
if (this.isUnmounted) return;
|
||||||
|
const elementExists = await this.waitForElement('dangerOperationChart');
|
||||||
|
if (!elementExists || this.isUnmounted) return;
|
||||||
|
|
||||||
|
if (this.echartsInstances.dangerOperationChart) {
|
||||||
|
this.echartsInstances.dangerOperationChart.dispose();
|
||||||
|
this.echartsInstances.dangerOperationChart = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const chartDom = document.getElementById('dangerOperationChart');
|
||||||
|
if (!chartDom) return;
|
||||||
|
|
||||||
|
this.echartsInstances.dangerOperationChart = echarts.init(chartDom);
|
||||||
|
|
||||||
|
const { jobTodayQty } = this.props;
|
||||||
|
let linkData = jobTodayQty || [];
|
||||||
|
|
||||||
|
// 如果没有数据,显示“暂无数据”提示
|
||||||
|
if (linkData.length === 0) {
|
||||||
|
this.echartsInstances.dangerOperationChart.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 xAxisData = linkData.map((item) => item.name);
|
||||||
|
const seriesData = linkData.map((item) => item.qty);
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
title: {
|
||||||
|
text: '当日工作票的统计数量',
|
||||||
|
x: 'center',
|
||||||
|
y: '5%',
|
||||||
|
textStyle: { fontSize: 16, color: '#000', fontWeight: 'bold' },
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: { type: 'shadow' },
|
||||||
|
formatter: function (params) {
|
||||||
|
const color = params[0].color;
|
||||||
|
return `<div style="display: flex; align-items: center;">
|
||||||
|
<span style="display: inline-block; width: 12px; height: 12px; background-color: ${color}; margin-right: 8px;"></span>
|
||||||
|
<span>${params[0].name}:</span>
|
||||||
|
<span style="font-weight: bold; margin-left: 8px; font-size: 16px;">${params[0].value}</span>
|
||||||
|
</div>`;
|
||||||
|
},
|
||||||
|
backgroundColor: 'rgba(255, 255, 255, 0.9)',
|
||||||
|
borderColor: '#4285F4',
|
||||||
|
borderWidth: 1,
|
||||||
|
textStyle: { color: '#000', fontSize: 14 },
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '8%',
|
||||||
|
right: '5%',
|
||||||
|
top: '18%',
|
||||||
|
bottom: '8%',
|
||||||
|
containLabel: true,
|
||||||
|
},
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
data: xAxisData,
|
||||||
|
axisLine: { show: false },
|
||||||
|
axisTick: { show: false },
|
||||||
|
axisLabel: {
|
||||||
|
textStyle: { color: '#000' },
|
||||||
|
rotate: xAxisData.length > 4 ? 15 : 0,
|
||||||
|
interval: 0,
|
||||||
|
fontSize: 12,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
show: true,
|
||||||
|
axisLine: { show: false },
|
||||||
|
axisTick: { show: false },
|
||||||
|
axisLabel: {
|
||||||
|
show: true,
|
||||||
|
textStyle: { color: '#000' },
|
||||||
|
},
|
||||||
|
splitLine: { show: false },
|
||||||
|
name: '工作票数量',
|
||||||
|
nameTextStyle: { fontSize: 12 },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '危险作业数量',
|
||||||
|
type: 'bar',
|
||||||
|
data: seriesData,
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: '#4285F4',
|
||||||
|
borderRadius: [12, 12, 0, 0],
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
shadowBlur: 10,
|
||||||
|
shadowOffsetX: 0,
|
||||||
|
shadowColor: 'rgba(0, 0, 0, 0.3)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'top',
|
||||||
|
textStyle: { color: '#4285F4', fontSize: 12, fontWeight: 'bold' },
|
||||||
|
formatter: (params) => `${params.value}`,
|
||||||
|
},
|
||||||
|
barWidth: '50%',
|
||||||
|
barMaxWidth: 60,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
this.echartsInstances.dangerOperationChart.setOption(option);
|
||||||
|
this.setupResizeHandler('dangerOperationChart', this.renderDangerOperationChart);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 初始化所有图表
|
||||||
|
initAllCharts = () => {
|
||||||
|
if (this.isUnmounted) return;
|
||||||
|
setTimeout(() => {
|
||||||
|
if (this.isUnmounted) return;
|
||||||
|
this.renderDangerOperationChart();
|
||||||
|
}, 100);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 销毁所有图表
|
||||||
|
disposeAllCharts = () => {
|
||||||
|
Object.keys(this.echartsInstances).forEach((key) => {
|
||||||
|
if (this.echartsInstances[key]) {
|
||||||
|
try {
|
||||||
|
this.echartsInstances[key].dispose();
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(`Dispose chart ${key} error:`, e);
|
||||||
|
}
|
||||||
|
this.echartsInstances[key] = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(this.chartResizeHandlers).forEach((key) => {
|
||||||
|
if (this.chartResizeHandlers[key]) {
|
||||||
|
window.removeEventListener('resize', this.chartResizeHandlers[key]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.chartResizeHandlers = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
// 获取过滤后的数据(添加类型检查和默认值)
|
// 获取过滤后的数据(添加类型检查和默认值)
|
||||||
@ -88,33 +301,48 @@ class DangerJob extends React.Component {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 添加 shouldComponentUpdate 优化性能
|
||||||
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
|
// 检查状态变化
|
||||||
|
if (this.state.currentPage !== nextState.currentPage || this.state.pageSize !== nextState.pageSize) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 检查 props 变化
|
||||||
|
if (
|
||||||
|
this.props.jobTodayQty !== nextProps.jobTodayQty ||
|
||||||
|
this.props.dangerSubData !== nextProps.dangerSubData ||
|
||||||
|
this.props.selectedCompany !== nextProps.selectedCompany ||
|
||||||
|
this.props.selectedStartDate !== nextProps.selectedStartDate ||
|
||||||
|
this.props.selectedEndDate !== nextProps.selectedEndDate ||
|
||||||
|
this.props.companyData !== nextProps.companyData
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// 渲染危险作业表格
|
// 渲染危险作业表格
|
||||||
renderDangerTable = () => {
|
renderDangerTable = () => {
|
||||||
const { selectedCompany, companyData } = this.props;
|
const { selectedCompany, companyData } = this.props;
|
||||||
const { currentPage, pageSize } = this.state;
|
const { currentPage, pageSize } = this.state;
|
||||||
const { data: tableData, total } = this.getCurrentPageData();
|
const { data: tableData, total } = this.getCurrentPageData();
|
||||||
|
|
||||||
|
// 如果没有数据,返回空
|
||||||
if (!tableData || tableData.length === 0) {
|
if (!tableData || tableData.length === 0) {
|
||||||
// 获取选中的公司名称用于显示
|
|
||||||
let companyName = '';
|
|
||||||
if (selectedCompany && companyData) {
|
|
||||||
const selectedCompanyObj = companyData.find((company) => company.ID === selectedCompany);
|
|
||||||
companyName = selectedCompanyObj?.NAME || '';
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
padding: '50px',
|
padding: '50px',
|
||||||
color: '#999',
|
color: '#999',
|
||||||
fontSize: '26px',
|
fontSize: '20px',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
flex: 1,
|
flex: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{selectedCompany ? `${companyName}暂无危险作业数据` : '暂无危险作业数据'}
|
暂无危险作业数据
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -196,10 +424,8 @@ class DangerJob extends React.Component {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// 计算横向滚动宽度(如果列数过多)
|
// 不设置 y 滚动,让表格自然高度,由外层容器控制滚动
|
||||||
const scrollX = columns.reduce((sum, col) => sum + (col.width || 120), 0);
|
const scrollConfig = { x: columns.length * 100, y: 320 };
|
||||||
const scrollConfig = scrollX > 1200 ? { x: scrollX } : {};
|
|
||||||
|
|
||||||
// 表格数据转换(添加唯一key)
|
// 表格数据转换(添加唯一key)
|
||||||
const dataSource = tableData.map((item, index) => ({
|
const dataSource = tableData.map((item, index) => ({
|
||||||
key: `${item.companyName}_${item.startDate}_${index}`,
|
key: `${item.companyName}_${item.startDate}_${index}`,
|
||||||
@ -215,6 +441,7 @@ class DangerJob extends React.Component {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
|
<div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@ -227,13 +454,13 @@ class DangerJob extends React.Component {
|
|||||||
>
|
>
|
||||||
当日各公司危险作业清单
|
当日各公司危险作业清单
|
||||||
</div>
|
</div>
|
||||||
<div style={{ flex: 1, padding: '10px' }}>
|
<div style={{ flex: 1, minHeight: 0, padding: '10px' }}>
|
||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={dataSource}
|
dataSource={dataSource}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
scroll={scrollConfig}
|
scroll={scrollConfig}
|
||||||
size="small"
|
size="middle"
|
||||||
bordered
|
bordered
|
||||||
className={styles.certificateTable}
|
className={styles.certificateTable}
|
||||||
/>
|
/>
|
||||||
@ -247,9 +474,9 @@ class DangerJob extends React.Component {
|
|||||||
padding: '12px 16px',
|
padding: '12px 16px',
|
||||||
borderTop: '1px solid #f0f0f0',
|
borderTop: '1px solid #f0f0f0',
|
||||||
backgroundColor: '#fff',
|
backgroundColor: '#fff',
|
||||||
|
flexShrink: 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* 自定义每页条数选择器 */}
|
|
||||||
<div>
|
<div>
|
||||||
<span style={{ marginRight: '8px' }}>每页显示:</span>
|
<span style={{ marginRight: '8px' }}>每页显示:</span>
|
||||||
<Select
|
<Select
|
||||||
@ -267,20 +494,19 @@ class DangerJob extends React.Component {
|
|||||||
current={currentPage}
|
current={currentPage}
|
||||||
pageSize={pageSize}
|
pageSize={pageSize}
|
||||||
total={total}
|
total={total}
|
||||||
// showSizeChanger
|
|
||||||
showQuickJumper
|
showQuickJumper
|
||||||
showTotal={(total) => `共 ${total} 条记录`}
|
showTotal={(total) => `共 ${total} 条记录`}
|
||||||
onChange={this.handlePageChange}
|
onChange={this.handlePageChange}
|
||||||
onShowSizeChange={false}
|
|
||||||
// pageSizeOptions={['10', '20']}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.isUnmounted = false;
|
this.isUnmounted = false;
|
||||||
|
this.initAllCharts();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
@ -288,6 +514,13 @@ class DangerJob extends React.Component {
|
|||||||
if (prevProps.selectedCompany !== this.props.selectedCompany) {
|
if (prevProps.selectedCompany !== this.props.selectedCompany) {
|
||||||
this.setState({ currentPage: 1 });
|
this.setState({ currentPage: 1 });
|
||||||
}
|
}
|
||||||
|
if (prevProps.selectedStartDate !== this.props.selectedStartDate) {
|
||||||
|
this.setState({ currentPage: 1 });
|
||||||
|
}
|
||||||
|
if (prevProps.selectedEndDate !== this.props.selectedEndDate) {
|
||||||
|
this.setState({ currentPage: 1 });
|
||||||
|
}
|
||||||
|
|
||||||
// 当数据变化时,如果当前页没有数据且不是第一页,重置到第一页
|
// 当数据变化时,如果当前页没有数据且不是第一页,重置到第一页
|
||||||
if (prevProps.dangerSubData !== this.props.dangerSubData) {
|
if (prevProps.dangerSubData !== this.props.dangerSubData) {
|
||||||
const { currentPage } = this.state;
|
const { currentPage } = this.state;
|
||||||
@ -298,21 +531,38 @@ class DangerJob extends React.Component {
|
|||||||
this.setState({ currentPage: 1 });
|
this.setState({ currentPage: 1 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查 jobTodayQty 是否变化,只在数据真正变化时重新渲染图表
|
||||||
|
const prevJobTodayQty = prevProps.jobTodayQty;
|
||||||
|
const currentJobTodayQty = this.props.jobTodayQty;
|
||||||
|
const jobTodayQtyChanged = JSON.stringify(prevJobTodayQty) !== JSON.stringify(currentJobTodayQty);
|
||||||
|
|
||||||
|
if (jobTodayQtyChanged) {
|
||||||
|
this.renderDangerOperationChart();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.isUnmounted = true;
|
this.isUnmounted = true;
|
||||||
|
this.disposeAllCharts();
|
||||||
}
|
}
|
||||||
|
disabledCurrentYearDate = (current) => {
|
||||||
|
if (!current) return false;
|
||||||
|
const currentYear = new Date().getFullYear();
|
||||||
|
const selectedYear = current.year();
|
||||||
|
// 只能选择当前年份
|
||||||
|
return selectedYear !== currentYear;
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { companyData, selectedCompany } = this.props;
|
const { companyData, selectedCompany, selectedStartDate, selectedEndDate } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.trainingContentWrapper}>
|
<div className={styles.trainingContentWrapper}>
|
||||||
<div className={styles.trainingGrid}>
|
<div className={styles.trainingGrid}>
|
||||||
<div className={styles.trainingRow}>
|
<div className={styles.trainingRow}>
|
||||||
<div className={styles.trainingCard}>
|
<div className={styles.trainingCard}>
|
||||||
{/* 公司筛选器 */}
|
{/* 筛选器 */}
|
||||||
<div className={styles.monthSelectorWrapper}>
|
<div className={styles.monthSelectorWrapper}>
|
||||||
<span className={styles.monthSelectorLabel}>选择公司:</span>
|
<span className={styles.monthSelectorLabel}>选择公司:</span>
|
||||||
<Select
|
<Select
|
||||||
@ -325,10 +575,34 @@ class DangerJob extends React.Component {
|
|||||||
>
|
>
|
||||||
{this.getCompanyOptions()}
|
{this.getCompanyOptions()}
|
||||||
</Select>
|
</Select>
|
||||||
|
<span className={styles.monthSelectorLabel} style={{ margin: '0 20px' }}>
|
||||||
|
开始日期:
|
||||||
|
</span>
|
||||||
|
<DatePicker
|
||||||
|
value={selectedStartDate}
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
onChange={this.startChange}
|
||||||
|
disabledDate={this.disabledCurrentYearDate}
|
||||||
|
/>
|
||||||
|
<span className={styles.monthSelectorLabel} style={{ margin: '0 20px' }}>
|
||||||
|
结束日期:
|
||||||
|
</span>
|
||||||
|
<DatePicker
|
||||||
|
value={selectedEndDate}
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
onChange={this.endChange}
|
||||||
|
disabledDate={this.disabledCurrentYearDate}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
{this.renderDangerTable()}
|
{this.renderDangerTable()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/* 第二行 - 当日工作票统计柱状图 */}
|
||||||
|
<div className={styles.trainingRow}>
|
||||||
|
<div className={styles.trainingCard}>
|
||||||
|
<div id="dangerOperationChart" className={styles.trainingChartContainer}></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -575,7 +575,7 @@ class HomeContent extends React.Component {
|
|||||||
if (this.isUnmounted) return;
|
if (this.isUnmounted) return;
|
||||||
this.riskLevel();
|
this.riskLevel();
|
||||||
this.safeCheckChart();
|
this.safeCheckChart();
|
||||||
this.dangerOperation();
|
// this.dangerOperation();
|
||||||
this.backLog();
|
this.backLog();
|
||||||
}, 100);
|
}, 100);
|
||||||
};
|
};
|
||||||
@ -939,6 +939,79 @@ class HomeContent extends React.Component {
|
|||||||
|
|
||||||
{/* 右侧区域 */}
|
{/* 右侧区域 */}
|
||||||
<Col span={7} className={styles.rightCol}>
|
<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>--家</span>
|
||||||
|
</div>
|
||||||
|
<div className={styles.infoSpan}>
|
||||||
|
<span>地下矿</span>
|
||||||
|
<span>--家</span>
|
||||||
|
</div>
|
||||||
|
<div className={styles.infoSpan}>
|
||||||
|
<span>尾矿库</span>
|
||||||
|
<span>--家</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}>
|
<div className={styles.riskCard}>
|
||||||
<Row className={styles.riskRow}>
|
<Row className={styles.riskRow}>
|
||||||
<Col span={8} className={styles.trainingStatsCol}>
|
<Col span={8} className={styles.trainingStatsCol}>
|
||||||
@ -958,12 +1031,6 @@ class HomeContent extends React.Component {
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.spacer}></div>
|
|
||||||
|
|
||||||
<div className={styles.dangerCard}>
|
|
||||||
<div id="dangerOperationChart" className={styles.fullChartContainer}></div>
|
|
||||||
</div>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
{/* 公告详情弹窗 */}
|
{/* 公告详情弹窗 */}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import RiskControl from './FullOther/RiskControl';
|
|||||||
import ClassBuild from './FullOther/ClassBuild';
|
import ClassBuild from './FullOther/ClassBuild';
|
||||||
import DangerJob from './FullOther/DangerJob';
|
import DangerJob from './FullOther/DangerJob';
|
||||||
import HiddenSolve from './FullOther/HiddenSolve';
|
import HiddenSolve from './FullOther/HiddenSolve';
|
||||||
|
import moment from 'moment'; // 添加这一行
|
||||||
|
|
||||||
const getScale = () => {
|
const getScale = () => {
|
||||||
const width = 1920,
|
const width = 1920,
|
||||||
@ -30,7 +31,7 @@ class FullScreen extends React.Component {
|
|||||||
nowDate: '',
|
nowDate: '',
|
||||||
riskTypeRate: [],
|
riskTypeRate: [],
|
||||||
riskTotal: [],
|
riskTotal: [],
|
||||||
jobTodayQty: [],
|
// jobTodayQty: [],
|
||||||
hiddenSummary: [],
|
hiddenSummary: [],
|
||||||
taskTop3: [],
|
taskTop3: [],
|
||||||
scale: getScale(),
|
scale: getScale(),
|
||||||
@ -77,8 +78,11 @@ class FullScreen extends React.Component {
|
|||||||
riskSubData: {},
|
riskSubData: {},
|
||||||
classSubData: [],
|
classSubData: [],
|
||||||
dangerSubData: {},
|
dangerSubData: {},
|
||||||
|
jobTodayQty: [],
|
||||||
dangerCompanyData: [],
|
dangerCompanyData: [],
|
||||||
selectedDangerCompany: '',
|
selectedDangerCompany: '',
|
||||||
|
selectedStartDate: moment(),
|
||||||
|
selectedEndDate: moment(),
|
||||||
|
|
||||||
announcementDetail: null,
|
announcementDetail: null,
|
||||||
announcementDetailLoading: false,
|
announcementDetailLoading: false,
|
||||||
@ -289,7 +293,7 @@ class FullScreen extends React.Component {
|
|||||||
if (ret && !this.isUnmounted) {
|
if (ret && !this.isUnmounted) {
|
||||||
this.setState({
|
this.setState({
|
||||||
riskTypeRate: ret.riskTypeRate || [],
|
riskTypeRate: ret.riskTypeRate || [],
|
||||||
jobTodayQty: ret.jobTodayQty || [],
|
// jobTodayQty: ret.jobTodayQty || [],
|
||||||
hiddenSummary: ret.hiddenSummary || [],
|
hiddenSummary: ret.hiddenSummary || [],
|
||||||
taskTop3: ret.taskTop3 || [],
|
taskTop3: ret.taskTop3 || [],
|
||||||
});
|
});
|
||||||
@ -308,16 +312,7 @@ class FullScreen extends React.Component {
|
|||||||
onComplete: (ret) => {
|
onComplete: (ret) => {
|
||||||
if (ret && !this.isUnmounted) {
|
if (ret && !this.isUnmounted) {
|
||||||
this.setState({
|
this.setState({
|
||||||
trainingData: {
|
trainingData: ret,
|
||||||
listNAME: ret.listNAME || [],
|
|
||||||
YearCount: ret.YearCount || [],
|
|
||||||
MonthRecordCount: ret.MonthRecordCount || [],
|
|
||||||
MonthPersonCount: ret.MonthPersonCount || [],
|
|
||||||
listAnnourcement: ret.listAnnourcement || [],
|
|
||||||
TITLE: ret.TITLE || '',
|
|
||||||
listVideoImg: ret.listVideoImg || [],
|
|
||||||
playSet: ret.playSet || [],
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -598,17 +593,29 @@ class FullScreen extends React.Component {
|
|||||||
this.getDangerSubData();
|
this.getDangerSubData();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
handleStartDateChange = (startDate) => {
|
||||||
|
this.setState({ selectedStartDate: startDate }, () => {
|
||||||
|
this.getDangerSubData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
handleEndDateChange = (endDate) => {
|
||||||
|
this.setState({ selectedEndDate: endDate }, () => {
|
||||||
|
this.getDangerSubData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
getDangerSubData = () => {
|
getDangerSubData = () => {
|
||||||
const orgId = storage('lacal').getItem('webOrgId')?.val;
|
const orgId = storage('lacal').getItem('webOrgId')?.val;
|
||||||
const json = initFilter(orgId);
|
const json = initFilter(orgId);
|
||||||
|
json.Parameter1 = this.state.selectedStartDate.format('YYYY-MM-DD');
|
||||||
|
json.Parameter2 = this.state.selectedEndDate.format('YYYY-MM-DD');
|
||||||
this.props.dispatch({
|
this.props.dispatch({
|
||||||
type: 'app/getDataByPost',
|
type: 'app/getDataByPost',
|
||||||
payload: json,
|
payload: json,
|
||||||
url: 'BI/BIKanBanController/JobManage',
|
url: 'BI/BIKanBanController/JobManage',
|
||||||
onComplete: (ret) => {
|
onComplete: (ret) => {
|
||||||
if (ret && !this.isUnmounted) {
|
if (ret && !this.isUnmounted) {
|
||||||
let filteredData = ret;
|
let filteredData = ret.jobList;
|
||||||
if (this.state.selectedDangerCompany) {
|
if (this.state.selectedDangerCompany) {
|
||||||
const selectedCompanyObj = this.state.dangerCompanyData?.find(
|
const selectedCompanyObj = this.state.dangerCompanyData?.find(
|
||||||
(company) => company.ID === this.state.selectedDangerCompany
|
(company) => company.ID === this.state.selectedDangerCompany
|
||||||
@ -621,6 +628,7 @@ class FullScreen extends React.Component {
|
|||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
dangerSubData: filteredData,
|
dangerSubData: filteredData,
|
||||||
|
jobTodayQty: ret.jobTodayQty,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -679,9 +687,14 @@ class FullScreen extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<DangerJob
|
<DangerJob
|
||||||
dangerSubData={this.state.dangerSubData}
|
dangerSubData={this.state.dangerSubData}
|
||||||
|
jobTodayQty={this.state.jobTodayQty}
|
||||||
companyData={this.state.dangerCompanyData}
|
companyData={this.state.dangerCompanyData}
|
||||||
selectedCompany={this.state.selectedDangerCompany}
|
selectedCompany={this.state.selectedDangerCompany}
|
||||||
onCompanyChange={this.handleDangerCompanyChange}
|
onCompanyChange={this.handleDangerCompanyChange}
|
||||||
|
selectedStartDate={this.state.selectedStartDate}
|
||||||
|
onStartChange={this.handleStartDateChange}
|
||||||
|
selectedEndDate={this.state.selectedEndDate}
|
||||||
|
onEndChange={this.handleEndDateChange}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -770,7 +783,7 @@ class FullScreen extends React.Component {
|
|||||||
riskTypeRate={riskTypeRate}
|
riskTypeRate={riskTypeRate}
|
||||||
riskTotal={riskTotal}
|
riskTotal={riskTotal}
|
||||||
hiddenSummary={hiddenSummary}
|
hiddenSummary={hiddenSummary}
|
||||||
jobTodayQty={jobTodayQty}
|
// jobTodayQty={jobTodayQty}
|
||||||
taskTop3={taskTop3}
|
taskTop3={taskTop3}
|
||||||
mediaList={mediaList}
|
mediaList={mediaList}
|
||||||
announcementList={announcementList}
|
announcementList={announcementList}
|
||||||
|
|||||||
@ -162,6 +162,277 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
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: 10px;
|
||||||
|
}
|
||||||
|
.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 {
|
.riskCard {
|
||||||
|
|||||||
@ -2,7 +2,17 @@ import React, { useState, useEffect, useRef, Component } from 'react';
|
|||||||
import { connect } from 'dva';
|
import { connect } from 'dva';
|
||||||
import storage from '../utils/storage';
|
import storage from '../utils/storage';
|
||||||
import IconFont from '../utils/iconFont';
|
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 './home.less';
|
||||||
// 组件库
|
// 组件库
|
||||||
import {
|
import {
|
||||||
@ -28,6 +38,7 @@ import FormPage from '../components/FormPage';
|
|||||||
import backlog from '../assets/home/backlog.png';
|
import backlog from '../assets/home/backlog.png';
|
||||||
import backlog_i from '../assets/home/backlog_icon.png';
|
import backlog_i from '../assets/home/backlog_icon.png';
|
||||||
import styles from './dashboard.css';
|
import styles from './dashboard.css';
|
||||||
|
import styleshome from './annourcement.less';
|
||||||
import 'slick-carousel/slick/slick.css';
|
import 'slick-carousel/slick/slick.css';
|
||||||
import 'slick-carousel/slick/slick-theme.css';
|
import 'slick-carousel/slick/slick-theme.css';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
@ -182,6 +193,13 @@ class Home extends React.Component {
|
|||||||
},
|
},
|
||||||
taskSelects: [],
|
taskSelects: [],
|
||||||
mineType: localStorage.getItem('currentMineType') === '20' ? '10' : localStorage.getItem('currentMineType'),
|
mineType: localStorage.getItem('currentMineType') === '20' ? '10' : localStorage.getItem('currentMineType'),
|
||||||
|
annourcement: [],
|
||||||
|
announcementDetail: null, // 公告详情
|
||||||
|
announcementModalVisible: false, // 公告弹窗可见性
|
||||||
|
announcementDetailLoading: false, // 公告详情加载状态
|
||||||
|
fileForm: {
|
||||||
|
visible: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
// this.enums = [];
|
// this.enums = [];
|
||||||
this.reportType = '';
|
this.reportType = '';
|
||||||
@ -618,20 +636,20 @@ class Home extends React.Component {
|
|||||||
};
|
};
|
||||||
//风险等级占比
|
//风险等级占比
|
||||||
riskLevel = () => {
|
riskLevel = () => {
|
||||||
const userInfo = storage('lacal').getItem('webUserInfo').val;
|
|
||||||
let json = initFilter(this.props.login.OrgId);
|
let json = initFilter(this.props.login.OrgId);
|
||||||
extendOrder(json, 'NUM', 0);
|
extendOrder(json, 'NUM', 0);
|
||||||
extendRule(json, 'COLOR', 1, this.state.mineType);
|
extendOrder(json, 'CREATE_TIME', 1);
|
||||||
this.props.dispatch({
|
this.props.dispatch({
|
||||||
type: 'app/getDataByPost',
|
type: 'app/getDataByPost',
|
||||||
url: 'FM/RiskLevelProportion/OrderPaged',
|
url: 'PF/PFAnnourcement/OrderPaged',
|
||||||
payload: json,
|
payload: json,
|
||||||
onlyData: false,
|
onlyData: false,
|
||||||
onComplete: (data) => {
|
onComplete: (data) => {
|
||||||
if (data && data.IsSuccessful) {
|
if (data && data.IsSuccessful) {
|
||||||
if (data.Data && data.Data.length > 0) {
|
if (data.Data && data.Data.length > 0) {
|
||||||
|
console.log('风险等级占比', data.Data);
|
||||||
this.setState({
|
this.setState({
|
||||||
riskLevelPage: data.Data,
|
annourcement: data.Data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1369,9 +1387,141 @@ class Home extends React.Component {
|
|||||||
detailForm: detailForm,
|
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() {
|
render() {
|
||||||
const { tableData } = this.state;
|
const { tableData, annourcement } = this.state;
|
||||||
const thingsData = this.state.delayData;
|
const thingsData = this.state.delayData;
|
||||||
const settings = {
|
const settings = {
|
||||||
dots: false,
|
dots: false,
|
||||||
@ -1431,6 +1581,20 @@ class Home extends React.Component {
|
|||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</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
|
<Modal
|
||||||
visible={this.state.scoreVisible}
|
visible={this.state.scoreVisible}
|
||||||
title="标准化得分明细"
|
title="标准化得分明细"
|
||||||
@ -1643,34 +1807,38 @@ class Home extends React.Component {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="dashboard-div-style">
|
<div className="dashboard-div-style">
|
||||||
<div className="statistical-title-style">
|
<div className={styleshome.announcementCard}>
|
||||||
<div className="badge-style">
|
<div className={styleshome.announcementHeader}>
|
||||||
<Icon type="pie-chart" style={{ color: '#5f6ac2', marginRight: '4px' }}></Icon>
|
<div className={styleshome.announcementTitle}>
|
||||||
风险等级占比
|
<Icon type="sound" className={styleshome.announcementIcon} />
|
||||||
|
<span>公司公告</span>
|
||||||
</div>
|
</div>
|
||||||
{this.state.riskLevelPage.length > 0 ? (
|
<span className={styleshome.announcementCount}>共 {annourcement?.length || 0} 条公告</span>
|
||||||
<span
|
</div>
|
||||||
style={{
|
<div className={styleshome.announcementList}>
|
||||||
fontSize: '14px',
|
{annourcement?.length > 0 ? (
|
||||||
float: 'right',
|
<ul className={styleshome.announcementUl}>
|
||||||
marginRight: '16px',
|
{annourcement.map((item, index) => (
|
||||||
// marginTop: "4px",
|
<li
|
||||||
}}
|
key={item.id || index}
|
||||||
|
className={styleshome.announcementItem}
|
||||||
|
onClick={() => this.handleAnnouncementClick(item)}
|
||||||
>
|
>
|
||||||
<div onClick={() => this.showDetailModal('BI013_RISKANALYSISMODEL')}>
|
<span className={styleshome.announcementItemTitle} title={item.TITLE}>
|
||||||
<IconFont
|
{item.TITLE}
|
||||||
type="icon-24gl-expand2"
|
|
||||||
style={{
|
|
||||||
fontSize: '18px',
|
|
||||||
color: '#333333',
|
|
||||||
cursor: 'pointer',
|
|
||||||
}}
|
|
||||||
></IconFont>
|
|
||||||
</div>
|
|
||||||
</span>
|
</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>
|
</div>
|
||||||
{this.state.riskLevelPage.length > 0 ? <RisiLevel riskLevelPage={this.state.riskLevelPage} /> : null}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
|
|||||||
98
src/routes/annourcement.less
Normal file
98
src/routes/annourcement.less
Normal 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;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user