|
@@ -1,4 +1,4 @@
|
|
-import React, {useEffect, useState, useRef, useMemo, memo} from 'react';
|
|
|
|
|
|
+import React, { useEffect, useState, useRef, useMemo, memo } from 'react';
|
|
import {
|
|
import {
|
|
Modal,
|
|
Modal,
|
|
Input,
|
|
Input,
|
|
@@ -18,21 +18,25 @@ import {
|
|
Tooltip,
|
|
Tooltip,
|
|
} from 'antd';
|
|
} from 'antd';
|
|
import Flow from '@/components/Flow/index';
|
|
import Flow from '@/components/Flow/index';
|
|
-import {connect} from 'dva';
|
|
|
|
-import {GetTokenFromUrl, getToken} from '@/utils/utils';
|
|
|
|
-import {MODELS, useXFlowApp, useModelAsync} from '@antv/xflow';
|
|
|
|
-import {CheckOutlined} from '@ant-design/icons';
|
|
|
|
|
|
+import { connect } from 'dva';
|
|
|
|
+import { GetTokenFromUrl, getToken } from '@/utils/utils';
|
|
|
|
+import { MODELS, useXFlowApp, useModelAsync } from '@antv/xflow';
|
|
|
|
+import { CheckOutlined } from '@ant-design/icons';
|
|
import {
|
|
import {
|
|
- queryDelPurchaseExcel, queryDingInstanceDetail, queryRecordSheet, queryTrySeal, queryVserionByNode,
|
|
|
|
|
|
+ queryDelPurchaseExcel,
|
|
|
|
+ queryDingInstanceDetail,
|
|
|
|
+ queryRecordSheet,
|
|
|
|
+ queryTrySeal,
|
|
|
|
+ queryVserionByNode,
|
|
} from '@/services/boom';
|
|
} from '@/services/boom';
|
|
-import {async} from '@antv/x6/lib/registry/marker/async';
|
|
|
|
|
|
+import { async } from '@antv/x6/lib/registry/marker/async';
|
|
import VersionModal from './VersionModal';
|
|
import VersionModal from './VersionModal';
|
|
-import styles from './Index.less'
|
|
|
|
|
|
+import styles from './Index.less';
|
|
|
|
|
|
-const {Option} = Select;
|
|
|
|
-const {Step} = Steps;
|
|
|
|
|
|
+const { Option } = Select;
|
|
|
|
+const { Step } = Steps;
|
|
|
|
|
|
-const {TextArea} = Input;
|
|
|
|
|
|
+const { TextArea } = Input;
|
|
const localData = JSON.parse(localStorage.ggDetaiData || '{}');
|
|
const localData = JSON.parse(localStorage.ggDetaiData || '{}');
|
|
const PAGE_SIZE = 8;
|
|
const PAGE_SIZE = 8;
|
|
let controller = new AbortController();
|
|
let controller = new AbortController();
|
|
@@ -41,7 +45,10 @@ let controller = new AbortController();
|
|
function FlowModal(props) {
|
|
function FlowModal(props) {
|
|
let token = getToken();
|
|
let token = getToken();
|
|
const SELECT_TYPE = {
|
|
const SELECT_TYPE = {
|
|
- NAME: '0', TYPE: '1', CREATOR: '2', STATE: '3',
|
|
|
|
|
|
+ NAME: '0',
|
|
|
|
+ TYPE: '1',
|
|
|
|
+ CREATOR: '2',
|
|
|
|
+ STATE: '3',
|
|
};
|
|
};
|
|
const {
|
|
const {
|
|
visible,
|
|
visible,
|
|
@@ -69,7 +76,7 @@ function FlowModal(props) {
|
|
const [versionVisible, setVersionVisible] = useState(false);
|
|
const [versionVisible, setVersionVisible] = useState(false);
|
|
const [selectType, setSelectType] = useState(SELECT_TYPE.NAME);
|
|
const [selectType, setSelectType] = useState(SELECT_TYPE.NAME);
|
|
const [inputValue, setInputValue] = useState();
|
|
const [inputValue, setInputValue] = useState();
|
|
- const [expandedRowKey, setExpandedRowKey] = useState([])
|
|
|
|
|
|
+ const [expandedRowKey, setExpandedRowKey] = useState([]);
|
|
|
|
|
|
const [sealLoading, setSealLoading] = useState(false);
|
|
const [sealLoading, setSealLoading] = useState(false);
|
|
// const [currentTempNodeId, setCurrentTempNodeId] = useState();
|
|
// const [currentTempNodeId, setCurrentTempNodeId] = useState();
|
|
@@ -78,10 +85,12 @@ function FlowModal(props) {
|
|
const graphData = useMemo(() => {
|
|
const graphData = useMemo(() => {
|
|
if (!flowDetail) return;
|
|
if (!flowDetail) return;
|
|
let nodes = flowDetail.nodes?.map(item => ({
|
|
let nodes = flowDetail.nodes?.map(item => ({
|
|
- ...item, isCheck: item.Id == version.template_node_id,
|
|
|
|
|
|
+ ...item,
|
|
|
|
+ isCheck: item.Id == version.template_node_id,
|
|
}));
|
|
}));
|
|
return {
|
|
return {
|
|
- nodes, edges: flowDetail.edges,
|
|
|
|
|
|
+ nodes,
|
|
|
|
+ edges: flowDetail.edges,
|
|
};
|
|
};
|
|
}, [flowDetail, version.template_node_id]);
|
|
}, [flowDetail, version.template_node_id]);
|
|
|
|
|
|
@@ -108,12 +117,17 @@ function FlowModal(props) {
|
|
|
|
|
|
const onDelVersion = data => {
|
|
const onDelVersion = data => {
|
|
Modal.confirm({
|
|
Modal.confirm({
|
|
- title: '提示', content: `是否确认删除清单?`, okText: '确定', cancelText: '取消', onOk: async () => {
|
|
|
|
|
|
+ title: '提示',
|
|
|
|
+ content: `是否确认删除清单?`,
|
|
|
|
+ okText: '确定',
|
|
|
|
+ cancelText: '取消',
|
|
|
|
+ onOk: async () => {
|
|
const res = await queryDelPurchaseExcel(data);
|
|
const res = await queryDelPurchaseExcel(data);
|
|
if (res.code == 200) {
|
|
if (res.code == 200) {
|
|
message.success('删除成功');
|
|
message.success('删除成功');
|
|
dispatch({
|
|
dispatch({
|
|
- type: 'xflow/queryBoomFlowDetail', payload: {
|
|
|
|
|
|
+ type: 'xflow/queryBoomFlowDetail',
|
|
|
|
+ payload: {
|
|
id: templateId,
|
|
id: templateId,
|
|
},
|
|
},
|
|
});
|
|
});
|
|
@@ -130,15 +144,18 @@ function FlowModal(props) {
|
|
}
|
|
}
|
|
setNodeLoading(true);
|
|
setNodeLoading(true);
|
|
controller = new AbortController();
|
|
controller = new AbortController();
|
|
- const res = await queryVserionByNode({
|
|
|
|
- template_node_id: template_node_id,
|
|
|
|
- }, controller.signal);
|
|
|
|
|
|
+ const res = await queryVserionByNode(
|
|
|
|
+ {
|
|
|
|
+ template_node_id: template_node_id,
|
|
|
|
+ },
|
|
|
|
+ controller.signal
|
|
|
|
+ );
|
|
controller = null;
|
|
controller = null;
|
|
let data = [];
|
|
let data = [];
|
|
if (!res.data.excel_version_tree) setData([]);
|
|
if (!res.data.excel_version_tree) setData([]);
|
|
res.data.excel_version_tree?.map(arr => {
|
|
res.data.excel_version_tree?.map(arr => {
|
|
if (res.data.flow_id) {
|
|
if (res.data.flow_id) {
|
|
- data = [...data, {...arr, flow_id: res.data.flow_id}];
|
|
|
|
|
|
+ data = [...data, { ...arr, flow_id: res.data.flow_id }];
|
|
} else {
|
|
} else {
|
|
data = [...data, arr];
|
|
data = [...data, arr];
|
|
}
|
|
}
|
|
@@ -177,9 +194,14 @@ function FlowModal(props) {
|
|
if (item.audit_status == 2) status = 'error';
|
|
if (item.audit_status == 2) status = 'error';
|
|
});
|
|
});
|
|
let curNode = flowDetail.nodes.find(item => item.Id == itemDataList[0].template_node_id);
|
|
let curNode = flowDetail.nodes.find(item => item.Id == itemDataList[0].template_node_id);
|
|
- const seqList = itemDataList[0].FlowInfo.FlowNodes.filter(item => item.template_node_id == template_node_id).sort((a, b) => a.seq - b.seq);
|
|
|
|
|
|
+ const seqList = itemDataList[0].FlowInfo.FlowNodes.filter(
|
|
|
|
+ item => item.template_node_id == template_node_id
|
|
|
|
+ ).sort((a, b) => a.seq - b.seq);
|
|
let obj = {
|
|
let obj = {
|
|
- status, current: curid, list: seqList, name: curNode?.label || itemDataList[0].FlowInfo.name,
|
|
|
|
|
|
+ status,
|
|
|
|
+ current: curid,
|
|
|
|
+ list: seqList,
|
|
|
|
+ name: curNode?.label || itemDataList[0].FlowInfo.name,
|
|
};
|
|
};
|
|
return obj;
|
|
return obj;
|
|
});
|
|
});
|
|
@@ -191,116 +213,163 @@ function FlowModal(props) {
|
|
let type = item.flow_id ? '/queryAuditRecord' : '/queryAuditExcel';
|
|
let type = item.flow_id ? '/queryAuditRecord' : '/queryAuditExcel';
|
|
// console.log(`${file}${type}`, item);
|
|
// console.log(`${file}${type}`, item);
|
|
dispatch({
|
|
dispatch({
|
|
- type: `${file}${type}`, payload: {
|
|
|
|
- excel_id: item.id, pageSize: 100,
|
|
|
|
- }, callback: res => {
|
|
|
|
|
|
+ type: `${file}${type}`,
|
|
|
|
+ payload: {
|
|
|
|
+ excel_id: item.id,
|
|
|
|
+ pageSize: 100,
|
|
|
|
+ },
|
|
|
|
+ callback: res => {
|
|
updateSteps(res, item.template_node_id);
|
|
updateSteps(res, item.template_node_id);
|
|
},
|
|
},
|
|
});
|
|
});
|
|
};
|
|
};
|
|
|
|
|
|
const columns = useMemo(() => {
|
|
const columns = useMemo(() => {
|
|
- return [{
|
|
|
|
- title: '名称', width: '20%', render: item => {
|
|
|
|
- return (<>
|
|
|
|
- <span style={{color: item.audit_status != 0 ? '#9b9b9b' : ''}}>
|
|
|
|
- {(item.id == version.id && !item.isParent) && (<CheckOutlined style={{marginRight: 10}}/>)}
|
|
|
|
- {item.version_no && !item.children?.length ? `${item.version_name}.${item.version_no}` : `${item.version_name}`}
|
|
|
|
|
|
+ return [
|
|
|
|
+ {
|
|
|
|
+ title: '名称',
|
|
|
|
+ width: '20%',
|
|
|
|
+ render: item => {
|
|
|
|
+ return (
|
|
|
|
+ <>
|
|
|
|
+ <span style={{ color: item.audit_status != 0 ? '#9b9b9b' : '' }}>
|
|
|
|
+ {item.id == version.id && !item.isParent && (
|
|
|
|
+ <CheckOutlined style={{ marginRight: 10 }} />
|
|
|
|
+ )}
|
|
|
|
+ {item.version_no && !item.children?.length
|
|
|
|
+ ? `${item.version_name}.${item.version_no}`
|
|
|
|
+ : `${item.version_name}`}
|
|
</span>
|
|
</span>
|
|
- </>)
|
|
|
|
|
|
+ </>
|
|
|
|
+ );
|
|
|
|
+ },
|
|
},
|
|
},
|
|
- }, {
|
|
|
|
- title: '创建人', width: '15%', render: item => {
|
|
|
|
- return (item.isParent && (<span>{userList.find(cur => cur.ID == item.author)?.CName || '-'}</span>));
|
|
|
|
|
|
+ {
|
|
|
|
+ title: '创建人',
|
|
|
|
+ width: '15%',
|
|
|
|
+ render: item => {
|
|
|
|
+ return (
|
|
|
|
+ item.isParent && (
|
|
|
|
+ <span>{userList.find(cur => cur.ID == item.author)?.CName || '-'}</span>
|
|
|
|
+ )
|
|
|
|
+ );
|
|
|
|
+ },
|
|
},
|
|
},
|
|
- }, {
|
|
|
|
- title: '分类', width: '15%', render: item => {
|
|
|
|
- return (item.isParent && (<span>{typeOptions.find(cur => cur.id == item.classify_id)?.name}</span>));
|
|
|
|
|
|
+ {
|
|
|
|
+ title: '分类',
|
|
|
|
+ width: '15%',
|
|
|
|
+ render: item => {
|
|
|
|
+ return (
|
|
|
|
+ item.isParent && (
|
|
|
|
+ <span>{typeOptions.find(cur => cur.id == item.classify_id)?.name}</span>
|
|
|
|
+ )
|
|
|
|
+ );
|
|
|
|
+ },
|
|
},
|
|
},
|
|
- }, {
|
|
|
|
- title: '状态', width: '15%', render: item => {
|
|
|
|
- if (!item.flow_id && item.isParent) return;
|
|
|
|
- let style = {color: getColor(item)};
|
|
|
|
- let txt = '';
|
|
|
|
- let dom = '';
|
|
|
|
- switch (item.audit_status) {
|
|
|
|
- case 0:
|
|
|
|
- txt = '未提交';
|
|
|
|
- break;
|
|
|
|
- case 1:
|
|
|
|
- txt = '待审批';
|
|
|
|
- break;
|
|
|
|
- case 2:
|
|
|
|
- txt = '已拒绝';
|
|
|
|
- break;
|
|
|
|
- case 3:
|
|
|
|
- txt = '已通过';
|
|
|
|
- break;
|
|
|
|
- case 4:
|
|
|
|
- txt = '已提交';
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- if (item.status == 1) txt = '已失效';
|
|
|
|
|
|
+ {
|
|
|
|
+ title: '状态',
|
|
|
|
+ width: '15%',
|
|
|
|
+ render: item => {
|
|
|
|
+ if (!item.flow_id && item.isParent) return;
|
|
|
|
+ let style = { color: getColor(item) };
|
|
|
|
+ let txt = '';
|
|
|
|
+ let dom = '';
|
|
|
|
+ switch (item.audit_status) {
|
|
|
|
+ case 0:
|
|
|
|
+ txt = '未提交';
|
|
|
|
+ break;
|
|
|
|
+ case 1:
|
|
|
|
+ txt = '待审批';
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ txt = '已拒绝';
|
|
|
|
+ break;
|
|
|
|
+ case 3:
|
|
|
|
+ txt = '已通过';
|
|
|
|
+ break;
|
|
|
|
+ case 4:
|
|
|
|
+ txt = '已提交';
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if (item.status == 1) txt = '已失效';
|
|
|
|
|
|
- // 显示拒绝原因
|
|
|
|
- // if (item.audit_comment) {
|
|
|
|
- // dom = (
|
|
|
|
- // <Popover content={item.audit_comment} title="原因">
|
|
|
|
- // {txt}
|
|
|
|
- // </Popover>
|
|
|
|
- // );
|
|
|
|
- // } else {
|
|
|
|
- dom = txt;
|
|
|
|
- // }
|
|
|
|
- return item.audit_status != 0 ? (<Button onClick={() => handleChangeClick(item)}>{dom}</Button>) : (
|
|
|
|
- <span style={style}>{dom}</span>);
|
|
|
|
|
|
+ // 显示拒绝原因
|
|
|
|
+ // if (item.audit_comment) {
|
|
|
|
+ // dom = (
|
|
|
|
+ // <Popover content={item.audit_comment} title="原因">
|
|
|
|
+ // {txt}
|
|
|
|
+ // </Popover>
|
|
|
|
+ // );
|
|
|
|
+ // } else {
|
|
|
|
+ dom = txt;
|
|
|
|
+ // }
|
|
|
|
+ return item.audit_status != 0 ? (
|
|
|
|
+ <Button onClick={() => handleChangeClick(item)}>{dom}</Button>
|
|
|
|
+ ) : (
|
|
|
|
+ <span style={style}>{dom}</span>
|
|
|
|
+ );
|
|
|
|
+ },
|
|
},
|
|
},
|
|
- }, {
|
|
|
|
- title: '印章申请', width: '15%', render: item => {
|
|
|
|
- if (!item.flow_id && item.isParent) return;
|
|
|
|
- let txt = '';
|
|
|
|
- //申请印章成功 1 默认0 失败2
|
|
|
|
- switch (item.is_seal_succeed) {
|
|
|
|
- case 0:
|
|
|
|
- txt = '-';
|
|
|
|
- break;
|
|
|
|
- case 1:
|
|
|
|
- txt = '成功';
|
|
|
|
- break;
|
|
|
|
- case 2:
|
|
|
|
- txt = '失败';
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- return (<Space>
|
|
|
|
- <span>{txt}</span>
|
|
|
|
- {item.is_seal_succeed == 2 && <a onClick={() => handleRetryClick(item.id)}>重试</a>}
|
|
|
|
- </Space>);
|
|
|
|
|
|
+ {
|
|
|
|
+ title: '印章申请',
|
|
|
|
+ width: '15%',
|
|
|
|
+ render: item => {
|
|
|
|
+ if (!item.flow_id && item.isParent) return;
|
|
|
|
+ let txt = '';
|
|
|
|
+ //申请印章成功 1 默认0 失败2
|
|
|
|
+ switch (item.is_seal_succeed) {
|
|
|
|
+ case 0:
|
|
|
|
+ txt = '-';
|
|
|
|
+ break;
|
|
|
|
+ case 1:
|
|
|
|
+ txt = '成功';
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ txt = '失败';
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ return (
|
|
|
|
+ <Space>
|
|
|
|
+ <span>{txt}</span>
|
|
|
|
+ {item.is_seal_succeed == 2 && <a onClick={() => handleRetryClick(item.id)}>重试</a>}
|
|
|
|
+ </Space>
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ title: '操作',
|
|
|
|
+ width: '20%',
|
|
|
|
+ render: item =>
|
|
|
|
+ (item.flow_id || !item.isParent) &&
|
|
|
|
+ item.id != version.id && (
|
|
|
|
+ <Space>
|
|
|
|
+ <a
|
|
|
|
+ onClick={() => {
|
|
|
|
+ onChangeVersion(item);
|
|
|
|
+ onClose();
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ 加载
|
|
|
|
+ </a>
|
|
|
|
+ {item.audit_status == 0 &&
|
|
|
|
+ item.author == currentUser.ID && ( //自己创建的&&未提交的清单自己可以删除
|
|
|
|
+ <a
|
|
|
|
+ onClick={() => {
|
|
|
|
+ onDelVersion({ excel_id: item.id });
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ 删除
|
|
|
|
+ </a>
|
|
|
|
+ )}
|
|
|
|
+ </Space>
|
|
|
|
+ ),
|
|
},
|
|
},
|
|
- }, {
|
|
|
|
- title: '操作', width: '20%', render: item => (item.flow_id || !item.isParent) && item.id != version.id && (<Space>
|
|
|
|
- <a
|
|
|
|
- onClick={() => {
|
|
|
|
- onChangeVersion(item);
|
|
|
|
- onClose();
|
|
|
|
- }}
|
|
|
|
- >
|
|
|
|
- 加载
|
|
|
|
- </a>
|
|
|
|
- {item.audit_status == 0 && item.author == currentUser.ID && ( //自己创建的&&未提交的清单自己可以删除
|
|
|
|
- <a
|
|
|
|
- onClick={() => {
|
|
|
|
- onDelVersion({excel_id: item.id});
|
|
|
|
- }}
|
|
|
|
- >
|
|
|
|
- 删除
|
|
|
|
- </a>)}
|
|
|
|
- </Space>),
|
|
|
|
- },];
|
|
|
|
|
|
+ ];
|
|
}, [version]);
|
|
}, [version]);
|
|
|
|
|
|
const handleRetryClick = async id => {
|
|
const handleRetryClick = async id => {
|
|
setNodeLoading(true);
|
|
setNodeLoading(true);
|
|
- const res = await queryTrySeal({excel_id: id});
|
|
|
|
|
|
+ const res = await queryTrySeal({ excel_id: id });
|
|
setNodeLoading(false);
|
|
setNodeLoading(false);
|
|
if (res.data?.errcode != 0) {
|
|
if (res.data?.errcode != 0) {
|
|
message.error(res.data?.errmsg);
|
|
message.error(res.data?.errmsg);
|
|
@@ -319,16 +388,43 @@ function FlowModal(props) {
|
|
setInputValue(null);
|
|
setInputValue(null);
|
|
};
|
|
};
|
|
|
|
|
|
- const getDescription = node => {
|
|
|
|
|
|
+ function calculateHoursDifference(date1, date2) {
|
|
|
|
+ const timestamp1 = date1.getTime(); // 获取第一个Date对象的时间戳(以毫秒为单位)
|
|
|
|
+ const timestamp2 = date2.getTime(); // 获取第二个Date对象的时间戳(以毫秒为单位)
|
|
|
|
+
|
|
|
|
+ const timeDifferenceInMillis = Math.abs(timestamp2 - timestamp1); // 计算时间戳之间的差值(毫秒数)
|
|
|
|
+ const hoursDifference = timeDifferenceInMillis / (1000 * 60 * 60); // 将差值转换为小时数
|
|
|
|
+
|
|
|
|
+ return hoursDifference.toFixed(2);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const getDescription = (node, prevNode) => {
|
|
let str = `审批人:${node.AuditorUser?.CName || '-'}`;
|
|
let str = `审批人:${node.AuditorUser?.CName || '-'}`;
|
|
- return (<div>
|
|
|
|
- 审批人:{node.AuditorUser?.CName || '-'}
|
|
|
|
|
|
+ const date = new Date(node.audit_time);
|
|
|
|
+ const auditTime =
|
|
|
|
+ node.audit_time === '0001-01-01T00:00:00Z'
|
|
|
|
+ ? '-'
|
|
|
|
+ : date.toLocaleDateString('zh-CN', {
|
|
|
|
+ format: 'YYYY-MM-DD hh:mm:ss',
|
|
|
|
+ });
|
|
|
|
+ const residenceTime =
|
|
|
|
+ auditTime === '-' ? '-' : calculateHoursDifference(date, new Date(prevNode.audit_time));
|
|
|
|
+ return (
|
|
<div>
|
|
<div>
|
|
- <span style={{color: '#1A73E8', textDecoration: 'undeline'}}>
|
|
|
|
|
|
+ 审批人:{node.AuditorUser?.CName || '-'}
|
|
|
|
+ <div>
|
|
|
|
+ <span style={{ color: '#1A73E8', textDecoration: 'unerline' }}>
|
|
审批意见:{node.desc || '-'}
|
|
审批意见:{node.desc || '-'}
|
|
</span>
|
|
</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div>
|
|
|
|
+ <span>审批时间:{auditTime || '-'}</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div>
|
|
|
|
+ <span>滞留时间:{`${residenceTime}小时`}</span>
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
- </div>);
|
|
|
|
|
|
+ );
|
|
};
|
|
};
|
|
|
|
|
|
const filterState = () => {
|
|
const filterState = () => {
|
|
@@ -365,18 +461,18 @@ function FlowModal(props) {
|
|
setShowData(resultData);
|
|
setShowData(resultData);
|
|
}, [inputValue, data]);
|
|
}, [inputValue, data]);
|
|
|
|
|
|
- const setRowClassName = (row) => {
|
|
|
|
- const rowId = localStorage.excelId
|
|
|
|
|
|
+ const setRowClassName = row => {
|
|
|
|
+ const rowId = localStorage.excelId;
|
|
|
|
|
|
if (row.id.toString() === rowId) {
|
|
if (row.id.toString() === rowId) {
|
|
return styles.selectedROW;
|
|
return styles.selectedROW;
|
|
}
|
|
}
|
|
- return ''
|
|
|
|
- }
|
|
|
|
|
|
+ return '';
|
|
|
|
+ };
|
|
|
|
|
|
- const handleExpandedRowChange = (expandedRows) => {
|
|
|
|
- setExpandedRowKey(expandedRows)
|
|
|
|
- }
|
|
|
|
|
|
+ const handleExpandedRowChange = expandedRows => {
|
|
|
|
+ setExpandedRowKey(expandedRows);
|
|
|
|
+ };
|
|
|
|
|
|
//列表筛选状态
|
|
//列表筛选状态
|
|
const STATE = {
|
|
const STATE = {
|
|
@@ -387,146 +483,165 @@ function FlowModal(props) {
|
|
SUBMIT: 4, //已提交
|
|
SUBMIT: 4, //已提交
|
|
FAILURE: 5, //已失效
|
|
FAILURE: 5, //已失效
|
|
};
|
|
};
|
|
- return (<>
|
|
|
|
- <Modal
|
|
|
|
- // confirmLoading={loading}
|
|
|
|
- destroyOnClose
|
|
|
|
- title="流程图"
|
|
|
|
- visible={visible}
|
|
|
|
- onCancel={() => {
|
|
|
|
- setSelectType(SELECT_TYPE.NAME);
|
|
|
|
- setInputValue('');
|
|
|
|
- onClose();
|
|
|
|
- }}
|
|
|
|
- footer={false}
|
|
|
|
- width="98%"
|
|
|
|
- // bodyStyle={{ maxHeight: '660px', overflow: 'auto' }}
|
|
|
|
- >
|
|
|
|
- <Row gutter={8}>
|
|
|
|
- <Col span={14}>
|
|
|
|
- <Flow meta={{type: 'view'}} flowDetail={graphData} onSelectNode={handleSelectNode}/>
|
|
|
|
- </Col>
|
|
|
|
- <Col span={10}>
|
|
|
|
- <div style={{fontSize: '16px', marginBottom: '10px'}}>清单列表</div>
|
|
|
|
- <div style={{display: 'flex', justifyContent: 'space-between'}}>
|
|
|
|
- <div style={{width: '60%'}}>
|
|
|
|
- <Select
|
|
|
|
- value={selectType}
|
|
|
|
- style={{width: '30%'}}
|
|
|
|
- onChange={value => {
|
|
|
|
- setSelectType(value);
|
|
|
|
- setInputValue('');
|
|
|
|
- }}
|
|
|
|
- >
|
|
|
|
- <Option value={SELECT_TYPE.NAME}>名称:</Option>
|
|
|
|
- <Option value={SELECT_TYPE.TYPE}>分类:</Option>
|
|
|
|
- <Option value={SELECT_TYPE.CREATOR}>创建人:</Option>
|
|
|
|
- <Option value={SELECT_TYPE.STATE}>状态:</Option>
|
|
|
|
- </Select>
|
|
|
|
- {(selectType == SELECT_TYPE.NAME || selectType == SELECT_TYPE.CREATOR) && (<Input
|
|
|
|
- style={{width: '70%'}}
|
|
|
|
- placeholder="请输入"
|
|
|
|
- value={inputValue}
|
|
|
|
- onChange={e => setInputValue(e.target.value)}
|
|
|
|
- />)}
|
|
|
|
- {selectType == SELECT_TYPE.TYPE && (<Select
|
|
|
|
- showSearch
|
|
|
|
- allowClear
|
|
|
|
- style={{width: '70%'}}
|
|
|
|
- placeholder="请选择分类"
|
|
|
|
- options={typeOptions}
|
|
|
|
- onChange={id => setInputValue(id)}
|
|
|
|
- filterOption={(input, option) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase())}
|
|
|
|
- />)}
|
|
|
|
- {selectType == SELECT_TYPE.STATE && (<Select
|
|
|
|
- showSearch
|
|
|
|
- allowClear
|
|
|
|
- style={{width: '70%'}}
|
|
|
|
- placeholder="请选择状态"
|
|
|
|
- // options={typeOptions}
|
|
|
|
- onChange={id => setInputValue(id)}
|
|
|
|
- >
|
|
|
|
- <Option value={STATE.NOSUBMIT}>未提交</Option>
|
|
|
|
- <Option value={STATE.NOAPPROVE}>待审批</Option>
|
|
|
|
- <Option value={STATE.REJECT}>已拒绝</Option>
|
|
|
|
- <Option value={STATE.PASS}>已通过</Option>
|
|
|
|
- <Option value={STATE.SUBMIT}>已提交</Option>
|
|
|
|
- <Option value={STATE.FAILURE}>已失效</Option>
|
|
|
|
- </Select>)}
|
|
|
|
|
|
+ return (
|
|
|
|
+ <>
|
|
|
|
+ <Modal
|
|
|
|
+ // confirmLoading={loading}
|
|
|
|
+ destroyOnClose
|
|
|
|
+ title="流程图"
|
|
|
|
+ visible={visible}
|
|
|
|
+ onCancel={() => {
|
|
|
|
+ setSelectType(SELECT_TYPE.NAME);
|
|
|
|
+ setInputValue('');
|
|
|
|
+ onClose();
|
|
|
|
+ }}
|
|
|
|
+ footer={false}
|
|
|
|
+ width="98%"
|
|
|
|
+ // bodyStyle={{ maxHeight: '660px', overflow: 'auto' }}
|
|
|
|
+ >
|
|
|
|
+ <Row gutter={8}>
|
|
|
|
+ <Col span={14}>
|
|
|
|
+ <Flow meta={{ type: 'view' }} flowDetail={graphData} onSelectNode={handleSelectNode} />
|
|
|
|
+ </Col>
|
|
|
|
+ <Col span={10}>
|
|
|
|
+ <div style={{ fontSize: '16px', marginBottom: '10px' }}>清单列表</div>
|
|
|
|
+ <div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
|
|
|
+ <div style={{ width: '60%' }}>
|
|
|
|
+ <Select
|
|
|
|
+ value={selectType}
|
|
|
|
+ style={{ width: '30%' }}
|
|
|
|
+ onChange={value => {
|
|
|
|
+ setSelectType(value);
|
|
|
|
+ setInputValue('');
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ <Option value={SELECT_TYPE.NAME}>名称:</Option>
|
|
|
|
+ <Option value={SELECT_TYPE.TYPE}>分类:</Option>
|
|
|
|
+ <Option value={SELECT_TYPE.CREATOR}>创建人:</Option>
|
|
|
|
+ <Option value={SELECT_TYPE.STATE}>状态:</Option>
|
|
|
|
+ </Select>
|
|
|
|
+ {(selectType == SELECT_TYPE.NAME || selectType == SELECT_TYPE.CREATOR) && (
|
|
|
|
+ <Input
|
|
|
|
+ style={{ width: '70%' }}
|
|
|
|
+ placeholder="请输入"
|
|
|
|
+ value={inputValue}
|
|
|
|
+ onChange={e => setInputValue(e.target.value)}
|
|
|
|
+ />
|
|
|
|
+ )}
|
|
|
|
+ {selectType == SELECT_TYPE.TYPE && (
|
|
|
|
+ <Select
|
|
|
|
+ showSearch
|
|
|
|
+ allowClear
|
|
|
|
+ style={{ width: '70%' }}
|
|
|
|
+ placeholder="请选择分类"
|
|
|
|
+ options={typeOptions}
|
|
|
|
+ onChange={id => setInputValue(id)}
|
|
|
|
+ filterOption={(input, option) =>
|
|
|
|
+ (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
|
|
|
|
+ }
|
|
|
|
+ />
|
|
|
|
+ )}
|
|
|
|
+ {selectType == SELECT_TYPE.STATE && (
|
|
|
|
+ <Select
|
|
|
|
+ showSearch
|
|
|
|
+ allowClear
|
|
|
|
+ style={{ width: '70%' }}
|
|
|
|
+ placeholder="请选择状态"
|
|
|
|
+ // options={typeOptions}
|
|
|
|
+ onChange={id => setInputValue(id)}
|
|
|
|
+ >
|
|
|
|
+ <Option value={STATE.NOSUBMIT}>未提交</Option>
|
|
|
|
+ <Option value={STATE.NOAPPROVE}>待审批</Option>
|
|
|
|
+ <Option value={STATE.REJECT}>已拒绝</Option>
|
|
|
|
+ <Option value={STATE.PASS}>已通过</Option>
|
|
|
|
+ <Option value={STATE.SUBMIT}>已提交</Option>
|
|
|
|
+ <Option value={STATE.FAILURE}>已失效</Option>
|
|
|
|
+ </Select>
|
|
|
|
+ )}
|
|
|
|
+ </div>
|
|
|
|
+ {isOut && (
|
|
|
|
+ <Button type="primary" onClick={() => setVersionVisible(true)}>
|
|
|
|
+ 新建清单
|
|
|
|
+ </Button>
|
|
|
|
+ )}
|
|
</div>
|
|
</div>
|
|
- {isOut && (<Button type="primary" onClick={() => setVersionVisible(true)}>
|
|
|
|
- 新建清单
|
|
|
|
- </Button>)}
|
|
|
|
- </div>
|
|
|
|
|
|
|
|
- <div style={{width: '100%', marginTop: '10px'}}>
|
|
|
|
- <Table
|
|
|
|
- columns={columns}
|
|
|
|
- dataSource={showData}
|
|
|
|
- loading={nodeLoading}
|
|
|
|
- bordered={false}
|
|
|
|
- rowKey='id'
|
|
|
|
- pagination={{position: ['none', 'none'], pageSize: 999, onChange}}
|
|
|
|
- scroll={{y: '460px'}}
|
|
|
|
- rowClassName={setRowClassName}
|
|
|
|
- onExpandedRowsChange={handleExpandedRowChange}
|
|
|
|
- expandedRowKeys={expandedRowKey}
|
|
|
|
- defaultExpandedRowKeys={expandedRowKey}
|
|
|
|
- // childrenColumnName="none"
|
|
|
|
- // expandable={{
|
|
|
|
- // expandedRowRender: record => (
|
|
|
|
- // <Table
|
|
|
|
- // columns={columns}
|
|
|
|
- // dataSource={record.children}
|
|
|
|
- // pagination={{ position: ['none', 'none'] }}
|
|
|
|
- // />
|
|
|
|
- // ),
|
|
|
|
- // rowExpandable: record => record.children?.length > 0,
|
|
|
|
- // }}
|
|
|
|
- />
|
|
|
|
- </div>
|
|
|
|
- {/* <Spin spinning={loading.global}> */}
|
|
|
|
- <div
|
|
|
|
- style={{
|
|
|
|
- display: 'flex', justifyContent: 'space-around', maxHeight: '300px', overflow: 'auto',
|
|
|
|
- }}
|
|
|
|
- >
|
|
|
|
- {stepsData.map((item, idx) => (
|
|
|
|
- <div key={`${item.name}_${idx}`} style={{marginTop: '20px', display: 'inline'}}>
|
|
|
|
- <div style={{marginBottom: '4px'}}>{item.name}</div>
|
|
|
|
- <Steps
|
|
|
|
- direction="vertical"
|
|
|
|
- size="small"
|
|
|
|
- current={item.current}
|
|
|
|
- status={item.status}
|
|
|
|
- >
|
|
|
|
- {item.list.map(node => (<Step
|
|
|
|
- key={`${node.id}_${node.node}`}
|
|
|
|
- title={node.node}
|
|
|
|
- description={getDescription(node)}
|
|
|
|
- />))}
|
|
|
|
- </Steps>
|
|
|
|
- </div>))}
|
|
|
|
- </div>
|
|
|
|
- {/* </Spin> */}
|
|
|
|
- </Col>
|
|
|
|
- </Row>
|
|
|
|
- </Modal>
|
|
|
|
- <VersionModal
|
|
|
|
- typeOptions={typeOptions}
|
|
|
|
- visible={versionVisible}
|
|
|
|
- version={version}
|
|
|
|
- versionList={versionList}
|
|
|
|
- flowDetail={flowDetail}
|
|
|
|
- onClose={() => setVersionVisible(false)}
|
|
|
|
- onOk={values => {
|
|
|
|
- onCommit?.(values, () => {
|
|
|
|
- setVersionVisible(false);
|
|
|
|
- });
|
|
|
|
- }}
|
|
|
|
- loading={commitLoading}
|
|
|
|
- />
|
|
|
|
- </>);
|
|
|
|
|
|
+ <div style={{ width: '100%', marginTop: '10px' }}>
|
|
|
|
+ <Table
|
|
|
|
+ columns={columns}
|
|
|
|
+ dataSource={showData}
|
|
|
|
+ loading={nodeLoading}
|
|
|
|
+ bordered={false}
|
|
|
|
+ rowKey="id"
|
|
|
|
+ pagination={{ position: ['none', 'none'], pageSize: 999, onChange }}
|
|
|
|
+ scroll={{ y: '460px' }}
|
|
|
|
+ rowClassName={setRowClassName}
|
|
|
|
+ onExpandedRowsChange={handleExpandedRowChange}
|
|
|
|
+ expandedRowKeys={expandedRowKey}
|
|
|
|
+ defaultExpandedRowKeys={expandedRowKey}
|
|
|
|
+ // childrenColumnName="none"
|
|
|
|
+ // expandable={{
|
|
|
|
+ // expandedRowRender: record => (
|
|
|
|
+ // <Table
|
|
|
|
+ // columns={columns}
|
|
|
|
+ // dataSource={record.children}
|
|
|
|
+ // pagination={{ position: ['none', 'none'] }}
|
|
|
|
+ // />
|
|
|
|
+ // ),
|
|
|
|
+ // rowExpandable: record => record.children?.length > 0,
|
|
|
|
+ // }}
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ {/* <Spin spinning={loading.global}> */}
|
|
|
|
+ <div
|
|
|
|
+ style={{
|
|
|
|
+ display: 'flex',
|
|
|
|
+ justifyContent: 'space-around',
|
|
|
|
+ maxHeight: '300px',
|
|
|
|
+ overflow: 'auto',
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ {stepsData.length > 0 &&
|
|
|
|
+ stepsData.map((item, idx) => (
|
|
|
|
+ <div key={`${item.name}_${idx}`} style={{ marginTop: '20px', display: 'inline' }}>
|
|
|
|
+ <div style={{ marginBottom: '4px' }}>{item.name}</div>
|
|
|
|
+ <Steps
|
|
|
|
+ direction="vertical"
|
|
|
|
+ size="small"
|
|
|
|
+ current={item.current}
|
|
|
|
+ status={item.status}
|
|
|
|
+ >
|
|
|
|
+ {item.list.reduce((prev, node) => (
|
|
|
|
+ <Step
|
|
|
|
+ key={`${node.id}_${node.node}`}
|
|
|
|
+ title={node.node}
|
|
|
|
+ description={getDescription(node, prev)}
|
|
|
|
+ />
|
|
|
|
+ ))}
|
|
|
|
+ </Steps>
|
|
|
|
+ </div>
|
|
|
|
+ ))}
|
|
|
|
+ </div>
|
|
|
|
+ {/* </Spin> */}
|
|
|
|
+ </Col>
|
|
|
|
+ </Row>
|
|
|
|
+ </Modal>
|
|
|
|
+ <VersionModal
|
|
|
|
+ typeOptions={typeOptions}
|
|
|
|
+ visible={versionVisible}
|
|
|
|
+ version={version}
|
|
|
|
+ versionList={versionList}
|
|
|
|
+ flowDetail={flowDetail}
|
|
|
|
+ onClose={() => setVersionVisible(false)}
|
|
|
|
+ onOk={values => {
|
|
|
|
+ onCommit?.(values, () => {
|
|
|
|
+ setVersionVisible(false);
|
|
|
|
+ });
|
|
|
|
+ }}
|
|
|
|
+ loading={commitLoading}
|
|
|
|
+ />
|
|
|
|
+ </>
|
|
|
|
+ );
|
|
}
|
|
}
|
|
|
|
|
|
const getColor = item => {
|
|
const getColor = item => {
|
|
@@ -551,7 +666,9 @@ const getColor = item => {
|
|
return color;
|
|
return color;
|
|
};
|
|
};
|
|
|
|
|
|
-export default connect(({loading, user}) => ({
|
|
|
|
- loading, currentUser: user.currentUser, userList: user.list,
|
|
|
|
|
|
+export default connect(({ loading, user }) => ({
|
|
|
|
+ loading,
|
|
|
|
+ currentUser: user.currentUser,
|
|
|
|
+ userList: user.list,
|
|
}))(FlowModal);
|
|
}))(FlowModal);
|
|
// export default FlowModal;
|
|
// export default FlowModal;
|