mh_jy_safe_web/src/components/CustomPages/BI/BI064FormRunAnalysis.js

552 lines
17 KiB
JavaScript
Raw Normal View History

2026-01-27 14:19:46 +08:00
import React from 'react';
import { connect } from 'dva';
import { initFilter } from '../../../utils/common';
2026-03-09 11:30:48 +08:00
import { Table, Row, Spin, Card, Modal, Col, Button, Form } from 'antd';
import DropDownPagination from '../../common/DropDownPaginationEx';
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-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
};
}
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
};
// 获取公司数据
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-03-09 11:30:48 +08:00
let json = initFilter('00300000-0000-0000-0000-000000000000', this.state.inputText);
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) {
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-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() {
const { tableData, columns, loading } = 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>
<Col span={1} style={{ marginLeft: '20px' }}>
<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);