flow.jsx 13 KB
Newer Older
邓超's avatar
邓超 committed
1 2
import React, { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom';
邓超's avatar
邓超 committed
3
import { reloadFlows, removeFlowExtend } from '@/services/flow/flow';
4 5 6 7 8 9 10 11 12 13 14
import {
  Tag,
  Card,
  Space,
  Table,
  Popconfirm,
  Spin,
  Tooltip,
  notification,
  message,
  Button,
15
  Input,
16
} from 'antd';
邓超's avatar
邓超 committed
17 18 19 20 21 22 23
import {
  DoubleLeftOutlined,
  DoubleRightOutlined,
  EditTwoTone,
  ApartmentOutlined,
  DeleteOutlined,
  OrderedListOutlined,
邓超's avatar
邓超 committed
24
  ControlOutlined,
25
  EyeOutlined,
邓超's avatar
邓超 committed
26 27 28 29 30
} from '@ant-design/icons';
import classnames from 'classnames';
import PageContainer from '@/components/BasePageContainer';
import ProcessConfig from './flowComponents/ProcessConfig';
import Order from './flowComponents/Order';
邓超's avatar
邓超 committed
31
import Timelimit from './flowComponents/Timelimit';
邓超's avatar
邓超 committed
32 33
import styles from './flow.less';

34
const { Search } = Input;
邓超's avatar
邓超 committed
35 36 37 38 39 40 41 42 43
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); // 选中流程索引
44
  const [hoverItemIndex, setHoverItemIndex] = useState(0); // hover流程索引
45 46
  const [searchValue, setSearchValue] = useState('');
  const [showSearchStyle, setShowSearchStyle] = useState(false); // 是否显示模糊查询样式
邓超's avatar
邓超 committed
47 48 49
  const [visible, setVisible] = useState({
    processConfig: false,
    order: false,
邓超's avatar
邓超 committed
50
    auxiliaryView: false,
邓超's avatar
邓超 committed
51 52 53
  }); // 弹窗显示
  // 初始化
  useEffect(() => {
54
    if (history.location.state && history.location.state.dataSource) {
邓超's avatar
邓超 committed
55
      setDataSource('back');
56 57 58 59
      getProcessData(history.location.state.searchValue);
    } else {
      // 初始化流程列表
      getProcessData();
邓超's avatar
邓超 committed
60 61 62 63 64 65 66 67 68 69 70
    }
  }, []);
  // 表格数据改变后处理
  useEffect(() => {
    // 判断是否是返回回来的页面
    if (processData.length === 0) {
      return;
    }
    if (dataSource === 'back') {
      setPickItemIndex(history.location.state.pickItemIndex);
      setTableData(processData[history.location.state.pickItemIndex].root);
71 72
      setSearchValue(history.location.state.searchValue);
      setDataSource('');
邓超's avatar
邓超 committed
73 74 75 76 77 78 79 80 81
    } else {
      setTableData(processData[pickItemIndex].root);
    }
  }, [processData]);
  // 弹窗显示控制
  const showModal = (key, value) => {
    setVisible({ ...visible, [key]: value });
  };
  // 初始化流程列表
82
  const getProcessData = (filter = '') => {
邓超's avatar
邓超 committed
83
    setTreeLoading(true);
84 85 86 87 88 89
    if (searchValue) {
      setPickItemIndex(0);
    }
    reloadFlows({
      filter,
    })
邓超's avatar
邓超 committed
90 91 92 93
      .then(res => {
        setTreeLoading(false);
        if (res.code === 0) {
          setProcessData(res.data);
94
          setTableData(res.data);
邓超's avatar
邓超 committed
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
        } 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,
邓超's avatar
邓超 committed
122
            description: '清除成功',
邓超's avatar
邓超 committed
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
          });
        } else {
          notification.error({
            message: '提示',
            duration: 3,
            description: res.msg,
          });
        }
      })
      .catch(() => {
        notification.error({
          message: '提示',
          duration: 3,
          description: '网络异常',
        });
      });
  };
  // 跳转到对应的流程节点
  const toNode = flowName => {
142
    console.log(flowName);
邓超's avatar
邓超 committed
143
    history.push({
144
      pathname: '/biz/workflow/caseNode',
145
      state: { flowName, pickItemIndex, searchValue, allDisabled: true },
邓超's avatar
邓超 committed
146 147 148 149
    });
  };
  // 定义表格
  const columns = [
150 151 152 153 154 155 156 157 158 159 160
    {
      title: '名称',
      dataIndex: 'name',
      width: 150,
      align: 'center',
      render: (text, record) => (
        <Tooltip placement="topLeft" title={text}>
          {searchStyle(text)}
        </Tooltip>
      ),
    },
邓超's avatar
邓超 committed
161
    {
162
      title: '办理样式',
邓超's avatar
邓超 committed
163 164 165
      dataIndex: 'extendWebPage',
      align: 'center',
      render: text => (
166
        <span style={{ color: text === '(默认)' ? 'grey' : '000000D9' }}>{text}</span>
邓超's avatar
邓超 committed
167 168
      ),
    },
169 170 171 172 173 174 175 176
    // {
    //   title: '手持样式',
    //   dataIndex: 'extendMobilePage',
    //   align: 'center',
    //   render: text => (
    //     <span style={{ color: text === '(默认)' ? 'grey' : '000000D9' }}>{text}</span>
    //   ),
    // },
邓超's avatar
邓超 committed
177
    {
邓超's avatar
邓超 committed
178
      title: '辅助视图',
邓超's avatar
邓超 committed
179 180
      dataIndex: 'extendPageCount',
      align: 'center',
邓超's avatar
邓超 committed
181
      width: 80,
182
      render: text => <span style={{ color: text === '(无)' ? 'grey' : '000000D9' }}>{text}</span>,
邓超's avatar
邓超 committed
183 184 185 186 187 188
    },
    {
      title: '流程结束后',
      dataIndex: 'flowEndBehavior',
      align: 'center',
      render: text => (
189
        <span style={{ color: text === '(不做处理)' ? 'grey' : '000000D9' }}>{text}</span>
邓超's avatar
邓超 committed
190 191 192 193 194 195 196
      ),
    },
    {
      title: '12位编码',
      dataIndex: 'useFixedCodingRule',
      width: 80,
      align: 'center',
197
      render: record => {
198 199 200 201 202
        if (record == '是') {
          return <Tag color="success">{record}</Tag>;
        }
        return <Tag color="processing">{record}</Tag>;
      },
邓超's avatar
邓超 committed
203 204 205 206 207
    },
    {
      title: '异常节点',
      dataIndex: 'errorNodes',
      align: 'center',
208
      render: text => <span style={{ color: text === '(无)' ? 'grey' : 'red' }}>{text}</span>,
邓超's avatar
邓超 committed
209 210 211 212 213
    },
    {
      title: '接口配置',
      dataIndex: 'interfaceConfig',
      align: 'center',
214 215
      // render: text => <span style={{ color: text === '(无)' ? 'grey' : '000000D9' }}>{text}</span>,
      render: record => {
216
        if (record != '(无)') {
217 218 219 220 221 222 223 224
          return (
            <Tooltip title={record}>
              <Tag color="success"></Tag>
            </Tooltip>
          );
        }
        return <Tag color="processing"></Tag>;
      },
邓超's avatar
邓超 committed
225 226 227 228 229 230 231 232
    },
    {
      title: '操作',
      align: 'center',
      ellipsis: true,
      render: record => (
        <>
          <Space>
233 234
            <Tooltip title="流程查看">
              <EyeOutlined
邓超's avatar
邓超 committed
235
                onClick={() => {
236
                  showModal('processConfig', true, true);
邓超's avatar
邓超 committed
237 238 239 240 241
                  setProcessMsg(record);
                }}
                style={{ fontSize: '16px', color: '#1890FF' }}
              />
            </Tooltip>
242
            <Tooltip title="时限配置查看">
邓超's avatar
邓超 committed
243 244 245 246 247 248 249 250
              <ControlOutlined
                onClick={() => {
                  showModal('auxiliaryView', true);
                  setProcessMsg(record);
                }}
                style={{ fontSize: '16px', color: '#1890FF' }}
              />
            </Tooltip>
251
            <Tooltip title="节点配置查看">
邓超's avatar
邓超 committed
252 253 254 255 256
              <ApartmentOutlined
                onClick={() => toNode(record.name)}
                style={{ fontSize: '16px', color: '#1890FF' }}
              />
            </Tooltip>
257
            {/* <Tooltip title="清除流程配置">
邓超's avatar
邓超 committed
258 259 260 261 262 263 264
              <Popconfirm
                title="是否清除该流程配置?"
                onConfirm={() => delProcess(record)}
                onCancel={() => message.error('取消清除')}
                okText="是"
                cancelText="否"
              >
265
                <DeleteOutlined style={{ fontSize: '16px', color: '#e86060' }} />
邓超's avatar
邓超 committed
266
              </Popconfirm>
267
            </Tooltip> */}
邓超's avatar
邓超 committed
268 269 270 271 272
          </Space>
        </>
      ),
    },
  ];
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299

  // 搜索
  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 }} />;
  };
邓超's avatar
邓超 committed
300 301 302 303 304 305 306 307 308 309 310
  return (
    <PageContainer>
      <div className={styles.flowContainer}>
        {/* 左侧事件树 */}
        <Spin spinning={treeLoading} tip="loading...">
          <Card
            className={classnames({
              [styles.orgContainer]: true,
              [styles.orgContainerHide]: !treeVisible,
            })}
          >
311
            <div style={{ height: '100%', display: `${treeVisible ? 'block' : 'none'}` }}>
312 313 314
              <span className={styles.processTitle}>流程列表</span>
              <hr className={styles.splitLine} />
              {/* 流程列表 */}
315
              <div style={{ overflowY: 'scroll', height: 'calc(100% - 30px)' }}>
316 317 318 319 320 321
                {processData.length > 0 &&
                  processData.map((item, index) => (
                    <div
                      className={classnames({
                        [styles.listItem]: true,
                        [styles.pickItem]: index === pickItemIndex,
322
                        [styles.listHover]: index !== pickItemIndex && index === hoverItemIndex,
323
                      })}
324 325 326 327 328 329
                      onMouseEnter={() => {
                        setHoverItemIndex(index);
                      }}
                      onMouseLeave={() => {
                        setHoverItemIndex('');
                      }}
330 331 332 333 334 335 336 337 338 339
                      onClick={() => {
                        setPickItemIndex(index);
                        setTableData(item.root);
                      }}
                      key={item.goupName}
                    >
                      {item.goupName}{item.count ? item.count : ''}
                    </div>
                  ))}
              </div>
340
            </div>
邓超's avatar
邓超 committed
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
            <div className={styles.switcher}>
              {treeVisible && (
                <Tooltip title="隐藏流程列表">
                  <DoubleLeftOutlined onClick={() => setTreeVisible(false)} />
                </Tooltip>
              )}
              {!treeVisible && (
                <Tooltip title="显示流程列表">
                  <DoubleRightOutlined onClick={() => setTreeVisible(true)} />
                </Tooltip>
              )}
            </div>
          </Card>
        </Spin>
        {/* 右侧流程表 */}
356

邓超's avatar
邓超 committed
357 358
        <div className={styles.processContainer}>
          <div className={styles.buttonList}>
359 360 361 362 363 364 365 366 367 368 369 370
            <span>
              <span style={{ marginLeft: '20px', marginRight: '5px' }}>快速检索</span>
              <Search
                allowClear
                placeholder="请输入流程名称"
                onSearch={handleSearch}
                onChange={handleChange}
                value={searchValue}
                enterButton
                style={{ width: '300px' }}
              />
            </span>
邓超's avatar
邓超 committed
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
            <Button
              onClick={() => {
                showModal('order', true);
              }}
            >
              <OrderedListOutlined />
              排序
            </Button>
          </div>

          <Table
            dataSource={tableData}
            columns={columns}
            rowKey={record => record.ID}
            bordered
            size="small"
387
            scroll={{ x: 'max-content', y: 'calc(100% - 40px)' }}
邓超's avatar
邓超 committed
388 389 390 391 392 393
            onRow={record => ({
              onDoubleClick: () => {
                toNode(record.name);
              },
            })}
            pagination={{
394
              showTotal: (total, range) => `第${range[0]}-${range[1]} 条/共 ${total} 条`,
邓超's avatar
邓超 committed
395
              pageSizeOptions: [10, 20, 50, 100],
396
              defaultPageSize: 20,
邓超's avatar
邓超 committed
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
              showQuickJumper: true,
              showSizeChanger: true,
            }}
          />
        </div>
      </div>
      {/* 流程配置弹窗 */}
      <ProcessConfig
        visible={visible.processConfig}
        processMsg={processMsg}
        handleCancel={() => showModal('processConfig', false)}
        onSubumit={() => {
          showModal('processConfig', false);
          setDataSource('current');
          getProcessData();
        }}
413
        allDisabled
邓超's avatar
邓超 committed
414 415 416 417 418
      />
      {/* 排序弹窗 */}
      <Order
        visible={visible.order}
        tableData={tableData}
皮倩雯's avatar
皮倩雯 committed
419
        processData={processData}
邓超's avatar
邓超 committed
420 421 422 423 424 425 426
        handleCancel={() => showModal('order', false)}
        submitCallBack={() => {
          showModal('order', false);
          setDataSource('current');
          getProcessData();
        }}
      />
邓超's avatar
邓超 committed
427 428 429 430 431
      {/* 流程时限配置 */}
      <Timelimit
        visible={visible.auxiliaryView}
        msg={processMsg}
        handleCancel={() => showModal('auxiliaryView', false)}
432
        allDisabled
邓超's avatar
邓超 committed
433
      />
邓超's avatar
邓超 committed
434 435 436 437 438
    </PageContainer>
  );
};

export default Flow;