import React, { useEffect, useState } from 'react'; import { useHistory } from 'react-router-dom'; import { reloadFlows, removeFlowExtend } from '@/services/flow/flow'; import { Tag, Card, Space, Table, Popconfirm, Spin, Tooltip, notification, message, Button, Input, } from 'antd'; import { DoubleLeftOutlined, DoubleRightOutlined, EditTwoTone, ApartmentOutlined, DeleteOutlined, OrderedListOutlined, ControlOutlined, EyeOutlined, } from '@ant-design/icons'; import classnames from 'classnames'; import PageContainer from '@/components/BasePageContainer'; import ProcessConfig from './flowComponents/ProcessConfig'; import Order from './flowComponents/Order'; import Timelimit from './flowComponents/Timelimit'; import styles from './flow.less'; const { Search } = Input; const Flow = () => { const history = useHistory(); const [tableData, setTableData] = useState([]); // 流程对应的回显的表格 const [processData, setProcessData] = useState([]); // 流程列表总 const [dataSource, setDataSource] = useState(''); // 是否是返回获取数据 const [processMsg, setProcessMsg] = useState({}); // 流程配置回显信息 const [treeLoading, setTreeLoading] = useState(false); const [treeVisible, setTreeVisible] = useState(true); const [pickItemIndex, setPickItemIndex] = useState(0); // 选中流程索引 const [hoverItemIndex, setHoverItemIndex] = useState(0); // hover流程索引 const [searchValue, setSearchValue] = useState(''); const [showSearchStyle, setShowSearchStyle] = useState(false); // 是否显示模糊查询样式 const [visible, setVisible] = useState({ processConfig: false, order: false, auxiliaryView: false, }); // 弹窗显示 // 初始化 useEffect(() => { if (history.location.state && history.location.state.dataSource) { setDataSource('back'); getProcessData(history.location.state.searchValue); } else { // 初始化流程列表 getProcessData(); } }, []); // 表格数据改变后处理 useEffect(() => { // 判断是否是返回回来的页面 if (processData.length === 0) { return; } if (dataSource === 'back') { setPickItemIndex(history.location.state.pickItemIndex); setTableData(processData[history.location.state.pickItemIndex].root); setSearchValue(history.location.state.searchValue); setDataSource(''); } else { setTableData(processData[pickItemIndex].root); } }, [processData]); // 弹窗显示控制 const showModal = (key, value) => { setVisible({ ...visible, [key]: value }); }; // 初始化流程列表 const getProcessData = (filter = '') => { setTreeLoading(true); if (searchValue) { setPickItemIndex(0); } reloadFlows({ filter, }) .then(res => { setTreeLoading(false); if (res.code === 0) { setProcessData(res.data); setTableData(res.data); } else { notification.error({ message: '提示', duration: 3, description: res.msg, }); } }) .catch(() => { setTreeLoading(false); notification.error({ message: '提示', duration: 3, description: '网络异常', }); }); }; // 删除流程 const delProcess = val => { removeFlowExtend({ flowIDs: val.extendID }) .then(res => { if (res.code === 0) { setDataSource('current'); getProcessData(); notification.success({ message: '提示', duration: 3, description: '清除成功', }); } else { notification.error({ message: '提示', duration: 3, description: res.msg, }); } }) .catch(() => { notification.error({ message: '提示', duration: 3, description: '网络异常', }); }); }; // 跳转到对应的流程节点 const toNode = flowName => { console.log(flowName); history.push({ pathname: '/biz/workflow/caseNode', state: { flowName, pickItemIndex, searchValue, allDisabled: true }, }); }; // 定义表格 const columns = [ { title: '名称', dataIndex: 'name', width: 150, align: 'center', render: (text, record) => ( <Tooltip placement="topLeft" title={text}> {searchStyle(text)} </Tooltip> ), }, { title: '办理样式', dataIndex: 'extendWebPage', align: 'center', render: text => ( <span style={{ color: text === '(默认)' ? 'grey' : '000000D9' }}>{text}</span> ), }, // { // title: '手持样式', // dataIndex: 'extendMobilePage', // align: 'center', // render: text => ( // <span style={{ color: text === '(默认)' ? 'grey' : '000000D9' }}>{text}</span> // ), // }, { title: '辅助视图', dataIndex: 'extendPageCount', align: 'center', width: 80, render: text => <span style={{ color: text === '(无)' ? 'grey' : '000000D9' }}>{text}</span>, }, { title: '流程结束后', dataIndex: 'flowEndBehavior', align: 'center', render: text => ( <span style={{ color: text === '(不做处理)' ? 'grey' : '000000D9' }}>{text}</span> ), }, { title: '12位编码', dataIndex: 'useFixedCodingRule', width: 80, align: 'center', render: record => { if (record == '是') { return <Tag color="success">{record}</Tag>; } return <Tag color="processing">{record}</Tag>; }, }, { title: '异常节点', dataIndex: 'errorNodes', align: 'center', render: text => <span style={{ color: text === '(无)' ? 'grey' : 'red' }}>{text}</span>, }, { title: '接口配置', dataIndex: 'interfaceConfig', align: 'center', // render: text => <span style={{ color: text === '(无)' ? 'grey' : '000000D9' }}>{text}</span>, render: record => { if (record != '(无)') { return ( <Tooltip title={record}> <Tag color="success">有</Tag> </Tooltip> ); } return <Tag color="processing">无</Tag>; }, }, { title: '操作', align: 'center', ellipsis: true, render: record => ( <> <Space> <Tooltip title="流程查看"> <EyeOutlined onClick={() => { showModal('processConfig', true, true); setProcessMsg(record); }} style={{ fontSize: '16px', color: '#1890FF' }} /> </Tooltip> <Tooltip title="时限配置查看"> <ControlOutlined onClick={() => { showModal('auxiliaryView', true); setProcessMsg(record); }} style={{ fontSize: '16px', color: '#1890FF' }} /> </Tooltip> <Tooltip title="节点配置查看"> <ApartmentOutlined onClick={() => toNode(record.name)} style={{ fontSize: '16px', color: '#1890FF' }} /> </Tooltip> {/* <Tooltip title="清除流程配置"> <Popconfirm title="是否清除该流程配置?" onConfirm={() => delProcess(record)} onCancel={() => message.error('取消清除')} okText="是" cancelText="否" > <DeleteOutlined style={{ fontSize: '16px', color: '#e86060' }} /> </Popconfirm> </Tooltip> */} </Space> </> ), }, ]; // 搜索 const handleSearch = text => { // loadTable(text, 'search'); // setSelectTableName(''); // setPickIndex(0); // setSelect(groupArr[0].type); getProcessData(text); setShowSearchStyle(true); }; // 搜索框改变时存储输入的值 const handleChange = e => { setSearchValue(e.target.value); }; // 模糊查询匹配的样式 const searchStyle = val => { let n; if (showSearchStyle) { n = val.replace( new RegExp(searchValue, 'g'), `<span style='color:red'>${searchValue}</span>`, ); } else { n = val; } return <div dangerouslySetInnerHTML={{ __html: n }} />; }; return ( <PageContainer> <div className={styles.flowContainer}> {/* 左侧事件树 */} <Spin spinning={treeLoading} tip="loading..."> <Card className={classnames({ [styles.orgContainer]: true, [styles.orgContainerHide]: !treeVisible, })} > <div style={{ height: '100%', display: `${treeVisible ? 'block' : 'none'}` }}> <span className={styles.processTitle}>流程列表</span> <hr className={styles.splitLine} /> {/* 流程列表 */} <div style={{ overflowY: 'scroll', height: 'calc(100% - 30px)' }}> {processData.length > 0 && processData.map((item, index) => ( <div className={classnames({ [styles.listItem]: true, [styles.pickItem]: index === pickItemIndex, [styles.listHover]: index !== pickItemIndex && index === hoverItemIndex, })} onMouseEnter={() => { setHoverItemIndex(index); }} onMouseLeave={() => { setHoverItemIndex(''); }} onClick={() => { setPickItemIndex(index); setTableData(item.root); }} key={item.goupName} > {item.goupName}({item.count ? item.count : ''}) </div> ))} </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.processContainer}> <div className={styles.buttonList}> <span> <span style={{ marginLeft: '20px', marginRight: '5px' }}>快速检索</span> <Search allowClear placeholder="请输入流程名称" onSearch={handleSearch} onChange={handleChange} value={searchValue} enterButton style={{ width: '300px' }} /> </span> <Button onClick={() => { showModal('order', true); }} > <OrderedListOutlined /> 排序 </Button> </div> <Table dataSource={tableData} columns={columns} rowKey={record => record.ID} bordered size="small" scroll={{ x: 'max-content', y: 'calc(100% - 40px)' }} onRow={record => ({ onDoubleClick: () => { toNode(record.name); }, })} pagination={{ showTotal: (total, range) => `第${range[0]}-${range[1]} 条/共 ${total} 条`, pageSizeOptions: [10, 20, 50, 100], defaultPageSize: 20, showQuickJumper: true, showSizeChanger: true, }} /> </div> </div> {/* 流程配置弹窗 */} <ProcessConfig visible={visible.processConfig} processMsg={processMsg} handleCancel={() => showModal('processConfig', false)} onSubumit={() => { showModal('processConfig', false); setDataSource('current'); getProcessData(); }} allDisabled /> {/* 排序弹窗 */} <Order visible={visible.order} tableData={tableData} processData={processData} handleCancel={() => showModal('order', false)} submitCallBack={() => { showModal('order', false); setDataSource('current'); getProcessData(); }} /> {/* 流程时限配置 */} <Timelimit visible={visible.auxiliaryView} msg={processMsg} handleCancel={() => showModal('auxiliaryView', false)} allDisabled /> </PageContainer> ); }; export default Flow;