2026-01-27 14:19:46 +08:00
|
|
|
|
import React from 'react';
|
|
|
|
|
|
import { connect } from 'dva';
|
2026-05-19 16:29:12 +08:00
|
|
|
|
import moment from 'moment'
|
2026-01-27 14:19:46 +08:00
|
|
|
|
import { initFilter } from '../../../utils/common';
|
2026-05-19 16:29:12 +08:00
|
|
|
|
import { Table, Row, Spin, Card, Modal, DatePicker,Col, Button, Form ,Select} from 'antd';
|
2026-03-09 11:30:48 +08:00
|
|
|
|
import DropDownPagination from '../../common/DropDownPaginationEx';
|
2026-05-19 17:19:09 +08:00
|
|
|
|
const { Option } = Select;
|
2026-01-27 14:19:46 +08:00
|
|
|
|
class BI064FormRunAnalysis extends React.Component {
|
|
|
|
|
|
constructor(props) {
|
|
|
|
|
|
super(props);
|
|
|
|
|
|
this.state = {
|
2026-03-09 09:49:08 +08:00
|
|
|
|
depart: {},
|
2026-03-09 11:30:48 +08:00
|
|
|
|
inputText: '',
|
2026-05-19 16:29:12 +08:00
|
|
|
|
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'),
|
2026-05-19 17:19:09 +08:00
|
|
|
|
selectForms:['安全风险辨识与评估计划','安全风险辨识表', '安全风险辨识结果表', '安全风险辨识结果汇总表', '安全风险评估表',
|
|
|
|
|
|
'安全风险评估汇总表', '风险检查关联表','安全检查通知','安全检查记录','安全检查记录汇总','隐患上报','手动隐患上报完善',
|
|
|
|
|
|
'隐患确认单','隐患整改通知单', '隐患整改记录', '延期整改申请'],
|
2026-01-27 14:19:46 +08:00
|
|
|
|
retData: [], // 表单运行数据
|
|
|
|
|
|
companyData: [], // 公司数据
|
|
|
|
|
|
loading: true,
|
|
|
|
|
|
tableData: [], // 处理后的表格数据
|
|
|
|
|
|
columns: [], // 动态生成的列
|
2026-01-27 17:04:24 +08:00
|
|
|
|
scoreVisible: false,
|
|
|
|
|
|
scoreTitle: '',
|
|
|
|
|
|
standardScoreTemp: [],
|
|
|
|
|
|
scoreColumns: [
|
|
|
|
|
|
// {
|
|
|
|
|
|
// title: '序号',
|
|
|
|
|
|
// render: (text, record, index) => `${index + 1}`
|
|
|
|
|
|
// },
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '待办名称',
|
|
|
|
|
|
dataIndex: 'NOTICE_TITLE',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '姓名',
|
|
|
|
|
|
dataIndex: 'USER_NAME',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '开始时间',
|
|
|
|
|
|
dataIndex: 'TASK_STARTDT',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '结束时间',
|
|
|
|
|
|
dataIndex: 'TASK_ENDDT',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '实际处理时间',
|
|
|
|
|
|
dataIndex: 'TASK_DT',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '处理状态',
|
|
|
|
|
|
dataIndex: 'NOTICE_STATUS',
|
|
|
|
|
|
render: (text, record) => {
|
|
|
|
|
|
const currentTime = new Date();
|
|
|
|
|
|
const endTime = new Date(record.TASK_ENDDT);
|
|
|
|
|
|
|
|
|
|
|
|
if (text == 1) {
|
|
|
|
|
|
return '正常完成';
|
|
|
|
|
|
} else if (text == 2) {
|
|
|
|
|
|
return '超时完成';
|
|
|
|
|
|
} else if (text == 0 && endTime >= currentTime) {
|
|
|
|
|
|
return '进行中';
|
|
|
|
|
|
} else if (text == 0 && endTime < currentTime) {
|
|
|
|
|
|
return '超期未完成';
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return '未知状态';
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
2026-01-27 14:19:46 +08:00
|
|
|
|
};
|
|
|
|
|
|
}
|
2026-05-19 16:29:12 +08:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
2026-01-27 14:19:46 +08:00
|
|
|
|
componentDidMount() {
|
|
|
|
|
|
this.loadData();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 加载数据
|
|
|
|
|
|
loadData = () => {
|
|
|
|
|
|
this.getBaseData();
|
2026-03-09 09:49:08 +08:00
|
|
|
|
};
|
2026-03-09 11:30:48 +08:00
|
|
|
|
handleSearch = ({ data, record }) => {
|
2026-03-09 09:49:08 +08:00
|
|
|
|
this.setState({
|
|
|
|
|
|
depart: {
|
|
|
|
|
|
...this.state.depart,
|
|
|
|
|
|
ID: data[0],
|
2026-03-09 11:30:48 +08:00
|
|
|
|
NAME: record?.NAME,
|
2026-03-09 09:49:08 +08:00
|
|
|
|
},
|
2026-03-09 11:30:48 +08:00
|
|
|
|
inputText: record ? record?.NAME : this.state.inputText,
|
|
|
|
|
|
});
|
2026-01-27 14:19:46 +08:00
|
|
|
|
};
|
2026-05-19 16:29:12 +08:00
|
|
|
|
handleSearch2 = (value) => {
|
2026-05-19 17:19:09 +08:00
|
|
|
|
let temps = ['安全风险辨识与评估计划','安全风险辨识表', '安全风险辨识结果表', '安全风险辨识结果汇总表', '安全风险评估表',
|
|
|
|
|
|
'安全风险评估汇总表', '风险检查关联表','安全检查通知','安全检查记录','安全检查记录汇总','隐患上报','手动隐患上报完善',
|
|
|
|
|
|
'隐患确认单','隐患整改通知单', '隐患整改记录', '延期整改申请'];
|
2026-05-19 16:29:12 +08:00
|
|
|
|
|
|
|
|
|
|
if(value === "双重预防机制" )
|
|
|
|
|
|
{
|
2026-05-19 17:19:09 +08:00
|
|
|
|
temps = ['安全风险辨识与评估计划','安全风险辨识表', '安全风险辨识结果表', '安全风险辨识结果汇总表', '安全风险评估表',
|
|
|
|
|
|
'安全风险评估汇总表', '风险检查关联表','安全检查通知','安全检查记录','安全检查记录汇总','隐患上报','手动隐患上报完善',
|
|
|
|
|
|
'隐患确认单','隐患整改通知单', '隐患整改记录', '延期整改申请'];
|
2026-05-19 16:29:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
if(value === "作业现场安全管理" )
|
|
|
|
|
|
{
|
|
|
|
|
|
|
2026-05-19 17:19:09 +08:00
|
|
|
|
temps = [ '班前会议', '岗位当班记录', '交接班记录', '班组活动记录','一般作业活动记录', '作业方案讨论记录','关键许可工作票',
|
|
|
|
|
|
'安全技术交底表','关键许可作业活动记录','矿山动火作业工作票','技术交底表','安全交底表','领导带班下井记录'];
|
2026-05-19 16:29:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
if(value === "安全教育与培训" )
|
|
|
|
|
|
{
|
|
|
|
|
|
|
2026-05-19 17:19:09 +08:00
|
|
|
|
temps = ['安全意识调查', '培训需求调查','培训通知', '培训通知(转训)','培训记录', '培训效果评估调查表', '三级安全教育培训记录',
|
|
|
|
|
|
'新三级安全教育记录', '新三级安全教育卡' ];
|
2026-05-19 16:29:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
this.setState({
|
|
|
|
|
|
inputText2: value,
|
|
|
|
|
|
selectForms:temps
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
handleSearch3 = (value) => {
|
|
|
|
|
|
this.setState({
|
|
|
|
|
|
inputText3: value
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
startChange=(value)=>{
|
|
|
|
|
|
this.setState({
|
|
|
|
|
|
startTime:value
|
|
|
|
|
|
})
|
|
|
|
|
|
};
|
|
|
|
|
|
endChange=(value)=>{
|
|
|
|
|
|
this.setState({
|
|
|
|
|
|
endTime:value
|
|
|
|
|
|
})
|
|
|
|
|
|
};
|
2026-01-27 14:19:46 +08:00
|
|
|
|
// 获取公司数据
|
|
|
|
|
|
getBaseData = () => {
|
|
|
|
|
|
const json = initFilter(this.props.login.OrgId);
|
2026-03-09 09:49:08 +08:00
|
|
|
|
// let json = initFilter("00300000-0000-0000-0000-000000000000");
|
2026-01-27 14:19:46 +08:00
|
|
|
|
this.props.dispatch({
|
|
|
|
|
|
type: 'app/getDataByPost',
|
2026-03-09 09:49:08 +08:00
|
|
|
|
url: 'FM/Organization/OrderEntities',
|
2026-01-27 14:19:46 +08:00
|
|
|
|
payload: json,
|
|
|
|
|
|
onlyData: false,
|
|
|
|
|
|
onComplete: (ret) => {
|
|
|
|
|
|
if (ret && ret.Data) {
|
2026-03-09 11:30:48 +08:00
|
|
|
|
let keyword = ret.Data[0]?.NAME;
|
|
|
|
|
|
if (this.props.login.OrgId === '00300000-0000-0000-0000-000000000000') {
|
|
|
|
|
|
keyword = ret.Data.filter((t) => t.ID == this.props.login.OrgId)[0]?.NAME;
|
2026-03-09 09:49:08 +08:00
|
|
|
|
}
|
2026-03-09 11:30:48 +08:00
|
|
|
|
this.setState({ companyData: ret.Data, inputText: keyword }, () => {
|
2026-03-09 09:49:08 +08:00
|
|
|
|
this.getrealData();
|
|
|
|
|
|
// this.processData();
|
2026-01-27 14:19:46 +08:00
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 获取表单运行数据
|
|
|
|
|
|
getrealData = () => {
|
2026-03-09 09:49:08 +08:00
|
|
|
|
// const json = initFilter(this.props.login.OrgId);
|
2026-05-19 16:29:12 +08:00
|
|
|
|
let json = initFilter('00300000-0000-0000-0000-000000000000', this.state.inputText,"","","",this.state.startTime,this.state.endTime);
|
2026-01-27 14:19:46 +08:00
|
|
|
|
this.props.dispatch({
|
|
|
|
|
|
type: 'app/getDataByPost',
|
|
|
|
|
|
url: 'BI/BIStatiscialAnalysisController/GetTaskViewInfo',
|
|
|
|
|
|
payload: json,
|
|
|
|
|
|
onlyData: false,
|
|
|
|
|
|
onComplete: (ret) => {
|
|
|
|
|
|
if (ret && ret.Data) {
|
2026-05-19 16:29:12 +08:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
2026-01-27 14:19:46 +08:00
|
|
|
|
this.setState({ retData: ret.Data, loading: false }, () => {
|
|
|
|
|
|
this.processData();
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.setState({ loading: false });
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理数据,生成表格所需格式
|
|
|
|
|
|
processData = () => {
|
2026-03-09 11:30:48 +08:00
|
|
|
|
const { retData, companyData, inputText } = this.state;
|
2026-01-27 14:19:46 +08:00
|
|
|
|
if (!retData.length || !companyData.length) return;
|
2026-03-09 11:30:48 +08:00
|
|
|
|
let companyDataTemp = companyData.filter((t) => t.NAME === inputText);
|
2026-05-19 16:29:12 +08:00
|
|
|
|
|
2026-01-27 14:19:46 +08:00
|
|
|
|
// 获取所有模块和表单的列表
|
|
|
|
|
|
const modules = [...new Set(retData.map((item) => item.MOULD_NAME))];
|
|
|
|
|
|
const forms = [];
|
|
|
|
|
|
|
|
|
|
|
|
// 按模块组织表单
|
|
|
|
|
|
modules.forEach((module) => {
|
|
|
|
|
|
const moduleForms = [
|
|
|
|
|
|
...new Set(retData.filter((item) => item.MOULD_NAME === module).map((item) => item.FORM_NAME)),
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
moduleForms.forEach((form) => {
|
|
|
|
|
|
forms.push({
|
|
|
|
|
|
module,
|
|
|
|
|
|
form,
|
|
|
|
|
|
key: `${module}_${form}`,
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 处理每个公司的数据
|
|
|
|
|
|
const tableData = forms.map((formItem) => {
|
|
|
|
|
|
const { module, form, key } = formItem;
|
|
|
|
|
|
const rowData = {
|
|
|
|
|
|
key,
|
|
|
|
|
|
module,
|
|
|
|
|
|
form,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 为每个公司添加数据
|
2026-03-09 09:49:08 +08:00
|
|
|
|
companyDataTemp.forEach((company) => {
|
2026-01-27 14:19:46 +08:00
|
|
|
|
const companyName = company.NAME;
|
|
|
|
|
|
const companyDataKey = companyName.replace(/\s+/g, '');
|
|
|
|
|
|
|
|
|
|
|
|
// 查找该公司该表单的数据
|
|
|
|
|
|
const formData = retData.find(
|
|
|
|
|
|
(item) => item.MOULD_NAME === module && item.FORM_NAME === form && item.COMPANY_NAME === companyName
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (formData) {
|
|
|
|
|
|
// 计算完成率和及时率
|
|
|
|
|
|
// const finishRate =
|
|
|
|
|
|
// formData.TOTAL_QTY > 0
|
|
|
|
|
|
// ? (((formData.NORMAL_FINISH + formData.OVER_FINISH + formData.DOING) / formData.TOTAL_QTY) * 100).toFixed(
|
|
|
|
|
|
// 0
|
|
|
|
|
|
// )
|
|
|
|
|
|
// : '0';
|
|
|
|
|
|
|
|
|
|
|
|
// const normalRate =
|
|
|
|
|
|
// formData.NORMAL_FINISH + formData.OVER_FINISH + formData.DOING > 0
|
|
|
|
|
|
// ? (
|
|
|
|
|
|
// (formData.NORMAL_FINISH / (formData.NORMAL_FINISH + formData.OVER_FINISH + formData.DOING)) *
|
|
|
|
|
|
// 100
|
|
|
|
|
|
// ).toFixed(0)
|
|
|
|
|
|
// : '0';
|
2026-01-27 17:04:24 +08:00
|
|
|
|
rowData[`${companyDataKey}_details`] = formData.details || []; // 假设返回数据中有details字段
|
2026-01-27 14:19:46 +08:00
|
|
|
|
rowData[`${companyDataKey}_total`] = formData.TOTAL_QTY;
|
|
|
|
|
|
rowData[`${companyDataKey}_normal`] = formData.NORMAL_FINISH;
|
|
|
|
|
|
rowData[`${companyDataKey}_overtime`] = formData.OVER_FINISH;
|
|
|
|
|
|
rowData[`${companyDataKey}_doing`] = formData.DOING;
|
|
|
|
|
|
rowData[`${companyDataKey}_unfinish`] = formData.UNFINISH;
|
|
|
|
|
|
rowData[`${companyDataKey}_overUnfinish`] = formData.OVER_UNFINISH;
|
|
|
|
|
|
rowData[`${companyDataKey}_finishRate`] = formData.FINISH_RATE;
|
|
|
|
|
|
rowData[`${companyDataKey}_normalRate`] = formData.NORMAL_RATE;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 如果没有数据,设置默认值
|
2026-01-27 17:04:24 +08:00
|
|
|
|
// 如果没有数据,设置默认值
|
|
|
|
|
|
rowData[`${companyDataKey}_details`] = [];
|
2026-01-27 14:19:46 +08:00
|
|
|
|
rowData[`${companyDataKey}_total`] = 0;
|
|
|
|
|
|
rowData[`${companyDataKey}_normal`] = 0;
|
|
|
|
|
|
rowData[`${companyDataKey}_overtime`] = 0;
|
|
|
|
|
|
rowData[`${companyDataKey}_doing`] = 0;
|
|
|
|
|
|
rowData[`${companyDataKey}_unfinish`] = 0;
|
|
|
|
|
|
rowData[`${companyDataKey}_overUnfinish`] = 0;
|
|
|
|
|
|
rowData[`${companyDataKey}_finishRate`] = '0';
|
|
|
|
|
|
rowData[`${companyDataKey}_normalRate`] = '0';
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
return rowData;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 计算每个模块的行数,用于合并单元格
|
|
|
|
|
|
const moduleRowCounts = {};
|
|
|
|
|
|
let currentModule = null;
|
|
|
|
|
|
let count = 0;
|
|
|
|
|
|
|
|
|
|
|
|
tableData.forEach((row, index) => {
|
|
|
|
|
|
if (row.module !== currentModule) {
|
|
|
|
|
|
if (currentModule !== null) {
|
|
|
|
|
|
moduleRowCounts[currentModule] = count;
|
|
|
|
|
|
}
|
|
|
|
|
|
currentModule = row.module;
|
|
|
|
|
|
count = 1;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
count++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 最后一个模块
|
|
|
|
|
|
if (index === tableData.length - 1) {
|
|
|
|
|
|
moduleRowCounts[currentModule] = count;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 将行数信息添加到tableData中,供render使用
|
|
|
|
|
|
const tableDataWithRowSpan = tableData.map((row, index) => {
|
|
|
|
|
|
// 找到该模块的起始索引
|
|
|
|
|
|
const moduleStartIndex = tableData.findIndex((item) => item.module === row.module);
|
|
|
|
|
|
|
|
|
|
|
|
// 如果是该模块的第一行,设置rowSpan为该模块的行数
|
|
|
|
|
|
if (index === moduleStartIndex) {
|
|
|
|
|
|
return {
|
|
|
|
|
|
...row,
|
|
|
|
|
|
moduleRowSpan: moduleRowCounts[row.module] || 1,
|
|
|
|
|
|
};
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 不是第一行,设置rowSpan为0,表示不显示
|
|
|
|
|
|
return {
|
|
|
|
|
|
...row,
|
|
|
|
|
|
moduleRowSpan: 0,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 生成表格列
|
2026-03-09 09:49:08 +08:00
|
|
|
|
const columns = this.generateColumns(companyDataTemp, tableDataWithRowSpan);
|
2026-01-27 14:19:46 +08:00
|
|
|
|
|
|
|
|
|
|
this.setState({ tableData: tableDataWithRowSpan, columns });
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 动态生成表格列
|
2026-03-09 11:30:48 +08:00
|
|
|
|
generateColumns = (companyData) => {
|
2026-01-27 14:19:46 +08:00
|
|
|
|
const baseColumns = [
|
|
|
|
|
|
{
|
2026-03-09 11:30:48 +08:00
|
|
|
|
// width: '150px',
|
2026-01-27 14:19:46 +08:00
|
|
|
|
title: '模块',
|
|
|
|
|
|
dataIndex: 'module',
|
|
|
|
|
|
key: 'module',
|
2026-03-09 11:30:48 +08:00
|
|
|
|
// fixed: 'left',
|
2026-01-27 14:19:46 +08:00
|
|
|
|
align: 'center',
|
2026-03-09 11:30:48 +08:00
|
|
|
|
onCell: (record) => ({
|
|
|
|
|
|
style: {
|
|
|
|
|
|
minWidth: '150px', // 设置最小宽度
|
|
|
|
|
|
whiteSpace: 'nowrap', // 防止换行
|
|
|
|
|
|
},
|
|
|
|
|
|
}),
|
2026-01-27 14:19:46 +08:00
|
|
|
|
render: (value, row, index) => {
|
|
|
|
|
|
const obj = {
|
|
|
|
|
|
children: value,
|
|
|
|
|
|
props: {},
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 设置rowSpan属性
|
|
|
|
|
|
if (row.moduleRowSpan !== undefined) {
|
|
|
|
|
|
obj.props.rowSpan = row.moduleRowSpan;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
2026-03-09 11:30:48 +08:00
|
|
|
|
// width: '200px',
|
2026-01-27 14:19:46 +08:00
|
|
|
|
title: '表单',
|
|
|
|
|
|
dataIndex: 'form',
|
|
|
|
|
|
key: 'form',
|
2026-03-09 11:30:48 +08:00
|
|
|
|
// fixed: 'left',
|
2026-01-27 14:19:46 +08:00
|
|
|
|
align: 'center',
|
2026-03-09 11:30:48 +08:00
|
|
|
|
onCell: () => ({
|
|
|
|
|
|
style: {
|
|
|
|
|
|
minWidth: '200px',
|
|
|
|
|
|
whiteSpace: 'nowrap',
|
|
|
|
|
|
},
|
|
|
|
|
|
}),
|
2026-01-27 14:19:46 +08:00
|
|
|
|
},
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
// 为每个公司生成列组
|
|
|
|
|
|
companyData.forEach((company) => {
|
|
|
|
|
|
const companyName = company.NAME;
|
|
|
|
|
|
const companyDataKey = companyName.replace(/\s+/g, '');
|
|
|
|
|
|
|
|
|
|
|
|
const companyColumns = {
|
|
|
|
|
|
title: `${companyName}运行数据`,
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '总任务数',
|
|
|
|
|
|
dataIndex: `${companyDataKey}_total`,
|
|
|
|
|
|
key: `${companyDataKey}_total`,
|
2026-03-09 11:30:48 +08:00
|
|
|
|
width: '150px',
|
2026-01-27 14:19:46 +08:00
|
|
|
|
align: 'center',
|
2026-01-27 17:04:24 +08:00
|
|
|
|
render: (text, record) => (
|
|
|
|
|
|
<span>
|
|
|
|
|
|
<a onClick={() => this.showDetail(record, 1, companyName)}>{record[`${companyDataKey}_total`]}</a>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
),
|
2026-01-27 14:19:46 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '正常完成',
|
|
|
|
|
|
dataIndex: `${companyDataKey}_normal`,
|
|
|
|
|
|
key: `${companyDataKey}_normal`,
|
2026-03-09 11:30:48 +08:00
|
|
|
|
width: '150px',
|
2026-01-27 14:19:46 +08:00
|
|
|
|
align: 'center',
|
2026-01-27 17:04:24 +08:00
|
|
|
|
render: (text, record) => (
|
|
|
|
|
|
<span>
|
|
|
|
|
|
<a onClick={() => this.showDetail(record, 2, companyName)}>{record[`${companyDataKey}_normal`]}</a>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
),
|
2026-01-27 14:19:46 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '超时完成',
|
|
|
|
|
|
dataIndex: `${companyDataKey}_overtime`,
|
|
|
|
|
|
key: `${companyDataKey}_overtime`,
|
2026-03-09 11:30:48 +08:00
|
|
|
|
width: '150px',
|
2026-01-27 14:19:46 +08:00
|
|
|
|
align: 'center',
|
2026-01-27 17:04:24 +08:00
|
|
|
|
render: (text, record) => (
|
|
|
|
|
|
<span>
|
|
|
|
|
|
<a onClick={() => this.showDetail(record, 3, companyName)}>{record[`${companyDataKey}_overtime`]}</a>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
),
|
2026-01-27 14:19:46 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '进行中',
|
|
|
|
|
|
dataIndex: `${companyDataKey}_doing`,
|
|
|
|
|
|
key: `${companyDataKey}_doing`,
|
2026-03-09 11:30:48 +08:00
|
|
|
|
width: '150px',
|
2026-01-27 14:19:46 +08:00
|
|
|
|
align: 'center',
|
2026-01-27 17:04:24 +08:00
|
|
|
|
render: (text, record) => (
|
|
|
|
|
|
<span>
|
|
|
|
|
|
<a onClick={() => this.showDetail(record, 4, companyName)}>{record[`${companyDataKey}_doing`]}</a>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
),
|
2026-01-27 14:19:46 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '超期未完成',
|
|
|
|
|
|
dataIndex: `${companyDataKey}_overUnfinish`,
|
|
|
|
|
|
key: `${companyDataKey}_overUnfinish`,
|
2026-03-09 11:30:48 +08:00
|
|
|
|
width: '150px',
|
2026-01-27 14:19:46 +08:00
|
|
|
|
align: 'center',
|
2026-01-27 17:04:24 +08:00
|
|
|
|
render: (text, record) => (
|
|
|
|
|
|
<span>
|
|
|
|
|
|
<a onClick={() => this.showDetail(record, 5, companyName)}>
|
|
|
|
|
|
{record[`${companyDataKey}_overUnfinish`]}
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
),
|
2026-01-27 14:19:46 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '完成率',
|
|
|
|
|
|
dataIndex: `${companyDataKey}_finishRate`,
|
|
|
|
|
|
key: `${companyDataKey}_finishRate`,
|
2026-03-09 11:30:48 +08:00
|
|
|
|
width: '150px',
|
2026-01-27 14:19:46 +08:00
|
|
|
|
align: 'center',
|
|
|
|
|
|
render: (text) => <span>{text}%</span>,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '及时率',
|
|
|
|
|
|
dataIndex: `${companyDataKey}_normalRate`,
|
|
|
|
|
|
key: `${companyDataKey}_normalRate`,
|
|
|
|
|
|
align: 'center',
|
2026-03-09 11:30:48 +08:00
|
|
|
|
width: '150px',
|
2026-01-27 14:19:46 +08:00
|
|
|
|
render: (text) => <span>{text}%</span>,
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
baseColumns.push(companyColumns);
|
|
|
|
|
|
});
|
2026-03-09 11:30:48 +08:00
|
|
|
|
console.log('生成的列:', baseColumns);
|
2026-01-27 14:19:46 +08:00
|
|
|
|
|
|
|
|
|
|
return baseColumns;
|
|
|
|
|
|
};
|
2026-01-27 17:04:24 +08:00
|
|
|
|
showDetail = (record, type, companyName) => {
|
|
|
|
|
|
const currentTime = new Date();
|
|
|
|
|
|
const companyDataKey = companyName.replace(/\s+/g, '');
|
|
|
|
|
|
|
|
|
|
|
|
// 从record中获取该公司的明细数据
|
|
|
|
|
|
const details = record[`${companyDataKey}_details`] || [];
|
|
|
|
|
|
|
|
|
|
|
|
let filteredDetails = [];
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
|
case 1: // 总任务数
|
|
|
|
|
|
filteredDetails = details;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 2: // 正常完成
|
|
|
|
|
|
filteredDetails = details.filter((item) => item.NOTICE_STATUS == 1);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 3: // 超时完成
|
|
|
|
|
|
filteredDetails = details.filter((item) => item.NOTICE_STATUS == 2);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 4: // 进行中
|
|
|
|
|
|
filteredDetails = details.filter((item) => item.NOTICE_STATUS == 0 && new Date(item.TASK_ENDDT) >= currentTime);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 5: // 超期未完成
|
|
|
|
|
|
filteredDetails = details.filter((item) => item.NOTICE_STATUS == 0 && new Date(item.TASK_ENDDT) < currentTime);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
filteredDetails = details;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const typeTitles = {
|
|
|
|
|
|
1: '总任务数',
|
|
|
|
|
|
2: '正常完成',
|
|
|
|
|
|
3: '超时完成',
|
|
|
|
|
|
4: '进行中',
|
|
|
|
|
|
5: '超期未完成',
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
|
|
standardScoreTemp: filteredDetails,
|
|
|
|
|
|
scoreVisible: true,
|
|
|
|
|
|
scoreTitle: `${companyName} - ${record.module} - ${record.form} 的${typeTitles[type]}明细`,
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
clearScoreData = () => {
|
|
|
|
|
|
this.setState({
|
|
|
|
|
|
scoreVisible: false,
|
|
|
|
|
|
// standardScore: [],//newtmpData
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
2026-01-27 14:19:46 +08:00
|
|
|
|
|
|
|
|
|
|
render() {
|
2026-05-19 16:29:12 +08:00
|
|
|
|
const { tableData, columns, loading,selectForms } = this.state;
|
2026-03-09 09:49:08 +08:00
|
|
|
|
const formItemLayout = {
|
|
|
|
|
|
labelCol: { span: 8 },
|
|
|
|
|
|
wrapperCol: { span: 16 },
|
2026-03-09 11:30:48 +08:00
|
|
|
|
};
|
2026-01-27 14:19:46 +08:00
|
|
|
|
return (
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<div
|
|
|
|
|
|
style={{
|
|
|
|
|
|
backgroundColor: 'white',
|
|
|
|
|
|
width: '100%',
|
|
|
|
|
|
minHeight: '100vh',
|
|
|
|
|
|
margin: 'auto',
|
|
|
|
|
|
borderStyle: 'solid',
|
|
|
|
|
|
borderColor: '#ccc',
|
|
|
|
|
|
borderWidth: '1px',
|
|
|
|
|
|
padding: '20px',
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
2026-01-27 17:04:24 +08:00
|
|
|
|
<Modal
|
|
|
|
|
|
visible={this.state.scoreVisible}
|
|
|
|
|
|
title={this.state.scoreTitle}
|
|
|
|
|
|
maskClosable={false}
|
|
|
|
|
|
onCancel={this.clearScoreData}
|
|
|
|
|
|
footer={null}
|
|
|
|
|
|
className="antd-modal-fullscreen"
|
|
|
|
|
|
closeModal={this.clearScoreData}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Table
|
|
|
|
|
|
dataSource={this.state.standardScoreTemp}
|
|
|
|
|
|
columns={this.state.scoreColumns}
|
|
|
|
|
|
pagination={false}
|
|
|
|
|
|
bordered
|
|
|
|
|
|
size="small"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Modal>
|
2026-01-27 14:19:46 +08:00
|
|
|
|
<h1
|
|
|
|
|
|
style={{
|
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
|
marginTop: '20px',
|
|
|
|
|
|
marginBottom: '30px',
|
|
|
|
|
|
fontWeight: 'bold',
|
|
|
|
|
|
fontSize: '24px',
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
系统运行情况统计分析
|
|
|
|
|
|
</h1>
|
2026-03-09 11:30:48 +08:00
|
|
|
|
<Row style={{ width: '100%', margin: 'auto' }}>
|
|
|
|
|
|
<Col span={5}>
|
|
|
|
|
|
<Form.Item label={'公司名称'} {...formItemLayout}>
|
|
|
|
|
|
<DropDownPagination
|
|
|
|
|
|
inputDataApi={'FM/Organization/OrderPaged'}
|
|
|
|
|
|
fieldName={'NAME'}
|
|
|
|
|
|
data={this.state.depart}
|
|
|
|
|
|
onSelect={this.handleSearch}
|
|
|
|
|
|
onFilter={({ params }) => {
|
|
|
|
|
|
params.OrderType = 1;
|
|
|
|
|
|
params.OrgId = this.props.login.OrgId;
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
</Col>
|
2026-05-19 16:29:12 +08:00
|
|
|
|
<Col span={5}>
|
|
|
|
|
|
<Form.Item
|
|
|
|
|
|
label={'模块'}
|
|
|
|
|
|
{...formItemLayout}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Select
|
|
|
|
|
|
style={{ width: '180px' }}
|
|
|
|
|
|
allowClear
|
|
|
|
|
|
onChange={this.handleSearch2}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Option value="双重预防机制">双重预防机制</Option>
|
|
|
|
|
|
<Option value="作业现场安全管理">作业现场安全管理</Option>
|
|
|
|
|
|
<Option value="安全教育与培训">安全教育与培训</Option>
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
<Col span={5}>
|
|
|
|
|
|
<Form.Item
|
|
|
|
|
|
label={'表单'}
|
|
|
|
|
|
{...formItemLayout}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Select
|
|
|
|
|
|
style={{ width: '180px' }}
|
|
|
|
|
|
allowClear
|
|
|
|
|
|
onChange={this.handleSearch3}
|
2026-05-19 17:19:09 +08:00
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
{
|
|
|
|
|
|
selectForms && selectForms.map(item => (
|
|
|
|
|
|
<Option key={item}>{item}</Option>
|
|
|
|
|
|
))
|
|
|
|
|
|
}
|
|
|
|
|
|
</Select>
|
2026-05-19 16:29:12 +08:00
|
|
|
|
</Form.Item>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
<Col span={5} style={{ marginLeft: "10px" }}>
|
|
|
|
|
|
<Form.Item
|
|
|
|
|
|
label={'开始时间:'}
|
|
|
|
|
|
{...formItemLayout}
|
|
|
|
|
|
>
|
|
|
|
|
|
<DatePicker showTime
|
|
|
|
|
|
// defaultValue={moment(this.state.startTime, 'YYYY-MM-DD 00:00:00')}
|
|
|
|
|
|
value={this.state.startTime}
|
|
|
|
|
|
format="YYYY-MM-DD HH:mm:ss" onChange={this.startChange}/>
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
|
|
|
|
<Col span={5} style={{ marginLeft: "10px" }}>
|
|
|
|
|
|
<Form.Item
|
|
|
|
|
|
label={'结束时间:'}
|
|
|
|
|
|
{...formItemLayout}
|
|
|
|
|
|
>
|
|
|
|
|
|
<DatePicker showTime
|
|
|
|
|
|
// defaultValue={moment(this.state.endTime, 'YYYY-MM-DD 23:59:59')}
|
|
|
|
|
|
value={this.state.endTime}
|
|
|
|
|
|
format="YYYY-MM-DD HH:mm:ss" onChange={this.endChange}/>
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
<Col span={2} style={{ marginLeft: '20px' }}>
|
2026-03-09 11:30:48 +08:00
|
|
|
|
<Button type="primary" onClick={() => this.getrealData()}>
|
|
|
|
|
|
查询
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</Col>
|
2026-03-09 09:49:08 +08:00
|
|
|
|
</Row>
|
2026-01-27 14:19:46 +08:00
|
|
|
|
<Row>
|
|
|
|
|
|
<Spin spinning={loading}>
|
|
|
|
|
|
{/* <Card> */}
|
|
|
|
|
|
<Table
|
|
|
|
|
|
style={{
|
|
|
|
|
|
width: '100%',
|
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
|
}}
|
2026-03-09 11:30:48 +08:00
|
|
|
|
scroll={{ x: 1500, y: 600 }}
|
2026-01-27 14:19:46 +08:00
|
|
|
|
dataSource={tableData}
|
|
|
|
|
|
columns={columns}
|
|
|
|
|
|
pagination={false}
|
|
|
|
|
|
loading={loading}
|
|
|
|
|
|
size="middle"
|
|
|
|
|
|
bordered
|
|
|
|
|
|
rowKey="key"
|
|
|
|
|
|
/>
|
|
|
|
|
|
{/* </Card> */}
|
|
|
|
|
|
</Spin>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default connect(({ login, app }) => ({ login, app }))(BI064FormRunAnalysis);
|