/* eslint-disable prettier/prettier */ import React, { useEffect, useState } from 'react'; import { WFGetAllFlow, GetFlowNode, DeleteFlow } from '@/services/workflow/workflow'; import { Card, Spin, Tooltip, notification, Empty, Modal } from 'antd'; import { DoubleLeftOutlined, DoubleRightOutlined, PlusSquareFilled, FileAddTwoTone, FormOutlined, DeleteTwoTone, ExclamationCircleOutlined, ControlOutlined, } from '@ant-design/icons'; import classnames from 'classnames'; import Tree from '@/components/ExpendableTree'; import PageContainer from '@/components/BasePageContainer'; import FlowChart from './workFlowComponents/FlowChart'; import FlowModal from './workFlowComponents/FlowModal'; import FlowGroupModal from './workFlowComponents/FlowGroupModal'; import Timelimit from '../workFlow/flowComponents/Timelimit'; import styles from './workflow.less'; const { confirm } = Modal; const Workflow = () => { const [treeLoading, setTreeLoading] = useState(false); const [treeData, setTreeData] = useState([]); // 流程数据 const [currentSelectId, setCurrentSelectId] = useState(''); // 选中得节点 const [flowData, setFlowData] = useState({ Nodes: [], Lines: [] }); // 流程图数据 const [treeId, setTreeId] = useState(''); // 树形节点ID const [modalType, setModalType] = useState(''); // 弹窗类型是编辑还是新增 const [editMsg, setEditMsg] = useState({}); // 弹窗编辑回显 const [editIndex, setEditIndex] = useState(); // 编辑流程组得索引 const [treeVisible, setTreeVisible] = useState(true); const [chartLoading, setChartLoading] = useState(false); // 流程图的loading const [canSelect, setCanSelect] = useState(true); // 是否可以切换树 const [expandedKey, setExpandedKey] = useState(''); // 默认展开项 const [flag, setFlag] = useState(1); const [keep, setKeep] = useState([]); const [visible, setVisible] = useState({ FlowModal: false, FlowGroupModal: false, auxiliaryView: false, }); // 弹窗显示 useEffect(() => { getFlowList(); }, []); useEffect(() => { if (flag === 2) { if (treeData.length === 0) { return; } setExpandedKey(treeData[0].name + 0); if (!treeData[0].children) { return; } setCurrentSelectId(treeData[0].children[0].FlowID); setTreeId(treeData[0].children[0].FlowID); GetFlowNode({ flowID: treeData[0].children[0].FlowID }).then(res => { setChartLoading(false); if (res.code === 0) { res.data.Nodes.forEach(item => { item.nodeDetail = JSON.stringify(item); }); setFlowData({ ...res.data, flowName: treeData[0].children[0].FlowName }); } else { setFlowData({ Nodes: [], Lines: [], flowName: '' }); notification.error({ title: '提示', duration: 3, description: res.msg, }); } }); } }, [treeData]); // 弹窗显示控制 const showModal = (key, value) => { setVisible({ ...visible, [key]: value }); }; // 获取流程列表 const getFlowList = () => { setTreeLoading(true); WFGetAllFlow().then(res => { setTreeLoading(false); if (res.code === 0) { setFlag(flag + 1); let listdata = []; res.data.forEach(i => { if (i.children.length > 0) { i.children.forEach(j => { listdata.push(j.FlowName); }); } }); setKeep(listdata); let data = res.data.map(item => { item.isOld = true; return item; }); setTreeData(data); } }); }; // 新增流程 const addFlow = (val, e) => { e.stopPropagation(); showModal('FlowModal', true); setEditMsg(val); setModalType('add'); }; // 编辑流程 const editFlow = (val, e) => { e.stopPropagation(); showModal('FlowModal', true); setModalType('edit'); setEditMsg(val); }; const timeConfig = (val, e) => { console.log(val, 'val1'); e.stopPropagation(); showModal('auxiliaryView', true); setModalType('edit'); setEditMsg({ ...val, name: val.FlowName, ID: val.FlowID }); }; // 删除流程 const delFlow = (val, e) => { e.stopPropagation(); confirm({ title: '确定要删除吗?', icon: <ExclamationCircleOutlined />, content: '', okText: '是', okType: 'danger', cancelText: '否', onOk() { DeleteFlow({ FlowId: val.FlowID }) .then(res => { if (res.code === 0) { getFlowList(); notification.success({ message: '提示', duration: 3, description: '删除成功', }); } else { notification.error({ message: '提示', duration: 3, description: res.msg, }); } }) .catch(() => { notification.error({ message: '提示', duration: 3, description: '网络异常请稍后再试', }); }); }, onCancel() {}, }); }; // 编辑流程组 const eiditFlowGroup = (val, e, index) => { e.stopPropagation(); setEditIndex(index); showModal('FlowGroupModal', true); setModalType('edit'); setEditMsg(val); }; // 添加流程组 const addFlowGroup = e => { e.stopPropagation(); showModal('FlowGroupModal', true); setModalType('add'); }; // 选择节点 const chooseNode = (prop, treeNode) => { if (!treeNode || treeNode.node.children) { setCurrentSelectId(treeId); return; } // 组节点不触发选中 if (prop[0]) { // 选中节点处理 setTreeVisible(false); setCurrentSelectId(prop[0]); setTreeId(prop[0]); setChartLoading(true); GetFlowNode({ flowID: prop[0] }).then(res => { setChartLoading(false); if (res.code === 0) { res.data.Nodes.forEach(item => { item.nodeDetail = JSON.stringify(item); }); setFlowData({ ...res.data, flowName: treeNode.node.flowName }); } else { setFlowData({ Nodes: [], Lines: [], flowName: '' }); notification.error({ title: '提示', duration: 3, description: res.msg, }); } }); } else { setCurrentSelectId(treeId); } }; // 点击节点树触发 const onSelect = (prop, treeNode) => { // 如果没有保存弹是否保存弹窗 if (!canSelect && !treeNode.node.children) { confirm({ title: '已编辑流程未发布,确定要离开吗?', icon: <ExclamationCircleOutlined />, content: '', okText: '是', okType: 'primary', cancelText: '否', onOk() { setCanSelect(true); chooseNode(prop, treeNode); }, onCancel() {}, }); } else { chooseNode(prop, treeNode); } }; // 处理树数据 const mapTree = (val, index) => { const obj = { ...val }; return { title: ( <div className={styles.nodeTitle}> <span>{obj.name}</span> <div className={styles.nodeTip}> <Tooltip title="新增流程" className={styles.fs}> <FileAddTwoTone onClick={e => addFlow(obj, e)} /> </Tooltip> <Tooltip title="编辑流程组" className={styles.fs}> <FormOutlined onClick={e => eiditFlowGroup(obj, e, index)} /> </Tooltip> </div> </div> ), key: obj.name + index, children: obj.children ? obj.children.map(i => mapTreeNode(i)) : [], }; }; // 渲染树子节点 const mapTreeNode = val => { const obj = { ...val }; return { title: ( <div className={styles.nodeTitle}> <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', }} > {obj.FlowName} </span> <div className={styles.nodeTip}> {/* <Tooltip title="时限配置"> <ControlOutlined onClick={e => { timeConfig(obj, e); }} style={{ fontSize: '16px', color: '#1890FF' }} /> </Tooltip> */} <Tooltip title="编辑流程" className={styles.fs}> <FormOutlined onClick={e => editFlow(obj, e)} /> </Tooltip> <Tooltip title="删除流程" className={styles.fs}> <DeleteTwoTone onClick={e => delFlow(obj, e)} /> </Tooltip> </div> </div> ), flowName: obj.FlowName, key: obj.FlowID, }; }; // 保存分组后的回调函数 const groupCallBack = val => { showModal('FlowGroupModal', false); // 编辑老数据需要掉接口更新新数据手动修改数据,新增插入一条数据 if (modalType === 'edit' && editMsg.isOld) { getFlowList(); } else if (modalType === 'edit') { let newTree = [...treeData]; newTree[editIndex].name = val; setTreeData(newTree); } else { setTreeData([...treeData, { name: val }]); } // 选中当前选中的节点 onSelect(); }; // 数据改变后的回调函数 const leaveCallBack = val => { setCanSelect(!val); }; return ( <PageContainer> <div className={styles.flowContainer}> {/* 流程树 */} <Spin spinning={treeLoading}> <Card className={classnames({ [styles.treeContainer]: true, [styles.treeContainerHide]: !treeVisible, })} > <div style={{ display: `${treeVisible ? 'block' : 'none'}`, height: '100%' }}> <span className={styles.processTitle}>流程树</span> <Tooltip title="添加流程"> <PlusSquareFilled onClick={e => addFlow({}, e)} className={styles.treeHeadIcon} /> </Tooltip> <hr className={styles.splitLine} /> <div className={styles.treeContent}> <Tree blockNode autoExpandParent onSelect={onSelect} selectedKeys={[currentSelectId]} treeData={treeData.map((item, index) => mapTree(item, index))} expandedKeys={expandedKey} /> </div> </div> <div className={styles.switcher}> {treeVisible && ( <Tooltip title="隐藏流程列表"> <DoubleLeftOutlined onClick={() => setTreeVisible(false)} /> </Tooltip> )} {!treeVisible && ( <Tooltip title="显示流程列表"> <DoubleRightOutlined onClick={() => setTreeVisible(true)} /> </Tooltip> )} </div> </Card> </Spin> {/* 流程图 */} <div className={styles.flowChartContainer}> {currentSelectId ? ( <FlowChart treeVisible={treeVisible} flowData={flowData} flowID={currentSelectId} chartLoading={chartLoading} leaveCallBack={leaveCallBack} /> ) : ( <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="当前未选中流程" /> )} </div> </div> {/* 添加流程弹窗 */} <FlowModal visible={visible.FlowModal} msg={editMsg} modalType={modalType} handleCancel={() => showModal('FlowModal', false)} treeData={treeData} keep={keep} onSubumit={() => { showModal('FlowModal', false); getFlowList(); }} /> {/* 创建分组弹窗 */} <FlowGroupModal visible={visible.FlowGroupModal} msg={editMsg} modalType={modalType} handleCancel={() => showModal('FlowGroupModal', false)} treeData={treeData} keep={keep} onSubumit={val => groupCallBack(val)} /> {/* 流程时限配置 */} {/* <Timelimit visible={visible.auxiliaryView} msg={editMsg} handleCancel={() => showModal('auxiliaryView', false)} /> */} </PageContainer> ); }; export default Workflow;