index.tsx 8.87 KB
import React, { useEffect, useMemo, useState } from 'react';
import {
  Button,
  Input,
  message,
  Modal,
  Space,
  Table,
  Tooltip,
  Typography,
  Avatar,
} from 'antd';

import { SettingOutlined } from '@ant-design/icons/lib';
import { useSearchParams } from 'react-router-dom';
import { useTitle } from 'ahooks';
import { QxIcon } from '@/components';
import { handleWindowOpen } from '@qx/utils';
import { FlowHeader, FlowVersion } from '@/components';

import { useFlowTableScrollY } from '@/utils';
import actions from '@/utils/actions';

import { isEmpty, cloneDeep } from 'lodash-es';

const { Text } = Typography;

// 样式
import cls from 'classnames';
import styles from '../index.module.less';
import { getProcessVersions } from '@/services';
import { FlowVersionStatusEnums } from '@/interface';
const prefix = 'qx-flow-setting';

const DataFlowVersion: React.FC = ({}) => {
  // @ts-ignore
  const [searchParams] = useSearchParams();
  const {
    processId, // 流程ID
    name, // 流程名称
    returnUrl, // 来自页面跳转返回可跳转
  } = {
    processId: searchParams.get('processId'),
    name: searchParams.get('name'),
    returnUrl: searchParams.get('returnUrl'),
  };
  const [pageData, setPageData] = useState<any[]>([]);
  const [tableLoading, setTableLoading] = useState<boolean>(true); // 表格loading
  // 表格是否添加scroll 属性
  const [isScrollY, setIsScrollY] = useState<boolean>(false);
  // 添加标题
  useTitle(name || '未命名流程');

  const handleClick = (
    type: string,
    data?: any,
    e?: React.MouseEvent<HTMLElement, MouseEvent>,
  ) => {
    const { host, pathname, protocol, hash } = location;

    if (!!e) {
      e.stopPropagation();
    }

    switch (type) {
      case 'RETURN':
        // 返回上一页
        if (!!returnUrl) {
          // 返回上一页
          handleWindowOpen(
            `${protocol}//${host}${pathname}${returnUrl}`,
            '_self',
          );
        } else {
          // history.goBack();
          window.history.back();
        }
        break;
      case 'VIEW':
        // 查看
        console.log('VIEW === ', data);
        break;
      case 'RESTORE':
        // 恢复
        console.log('RESTORE === ', data);
        break;
      default:
        break;
    }
  };

  const cols = useMemo(() => {
    return [
      {
        title: () => {
          return (
            <span className={cls(styles[`${prefix}__col-title`])}>
              流程版本
            </span>
          );
        },
        dataIndex: 'version',
        render: (text: any, row: any) => {
          return (
            <span
              className={cls(styles[`${prefix}__colspan`])}
              style={{ width: '100%' }}
            >
              <FlowVersion versionText={text} />
            </span>
          );
        },
        width: 170,
        className: 'qx-flow-table-cell',
      },
      {
        title: () => {
          return (
            <span className={cls(styles[`${prefix}__col-title`])}>状态</span>
          );
        },
        dataIndex: 'status',
        className: 'qx-flow-table-cell',
        render: (text: any) => {
          return (
            <span
              className={cls(styles[`${prefix}__colspan`])}
              style={{ width: '100%' }}
            >
              <FlowVersion status={text} statusEnums={FlowVersionStatusEnums} />
            </span>
          );
        },
        width: 170,
      },
      {
        title: () => {
          return (
            <span className={cls(styles[`${prefix}__col-title`])}>
              更新时间
            </span>
          );
        },
        dataIndex: 'updatedAt',
        width: 200,
        className: 'qx-flow-table-cell',
        render: (text: any) => {
          return (
            <span
              className={cls(styles[`${prefix}__colspan`])}
              style={{ width: '100%' }}
            >
              {text}
            </span>
          );
        },
        onCell: (record: any) => {
          return {
            colSpan: ['APP', 'FUN'].includes(record?.type || '') ? 0 : 1,
          };
        },
      },
      {
        title: () => {
          return (
            <span className={cls(styles[`${prefix}__col-title`])}>更新人</span>
          );
        },
        dataIndex: 'updatedByUser',
        className: 'qx-flow-table-cell qx-flow-table-cell-user',
        render: (text: any, row: any) => {
          if (isEmpty(text)) {
            return '--';
          }
          let _imgError = false;
          return (
            <span
              className={cls(styles[`${prefix}__colspan-user`])}
              style={{ width: '100%' }}
            >
              <Avatar
                className={'qx-flow-table-cell__avatar'}
                size={24}
                alt="avatar"
                src={row?.updatedByUser?.faceUrl || ''}
                onError={() => {
                  _imgError = true;
                  return true;
                }}
              >
                {(!!row?.updatedByUser?.faceUrl && _imgError) ||
                !row?.updatedByUser?.faceUrl
                  ? !!row?.updatedByUser?.name?.length
                    ? row?.updatedByUser?.name[
                        row?.updatedByUser?.name?.length - 1
                      ]
                    : null
                  : null}
              </Avatar>
              <Text
                className={'qx-flow-table-cell__avatar-name'}
                ellipsis={{ tooltip: row?.updatedByUser?.name || '' }}
              >
                {row?.updatedByUser?.name || ''}
              </Text>
            </span>
          );
        },
        width: 200,
      },
      {
        title: () => {
          return (
            <span className={cls(styles[`${prefix}__col-title`])}>操作</span>
          );
        },
        dataIndex: 'control',
        render: (text: any, row: any) => (
          <Space
            size={8}
            className={cls(styles[`${prefix}__colspan`])}
            style={{ width: '100%' }}
          >
            <Button
              type="link"
              size="small"
              onClick={(e: React.MouseEvent<HTMLElement, MouseEvent>) => {
                e.stopPropagation();
                handleClick('VIEW', row);
              }}
            >
              查看
            </Button>
            <Button
              type="link"
              size="small"
              onClick={(e: React.MouseEvent<HTMLElement, MouseEvent>) =>
                handleClick('RESTORE', row, e)
              }
            >
              恢复
            </Button>
          </Space>
        ),
        width: 140,
        className: 'qx-flow-table-cell',
      },
    ];
  }, [JSON.stringify(pageData)]);

  // 查询list
  const handleSearch = () => {
    setTableLoading(true);

    actions.cancelToken(); // 多次请求 取最新请求 其他取消

    getProcessVersions('')
      .then((res: any) => {
        // 处理数据 符合表格渲染格式
        const _cloneList: any[] = [];
        const getColumnList = (data: any[]) => {
          data.forEach((item: any) => {
            _cloneList.push(cloneDeep(item));
            if (!!item?.processes?.length) {
              getColumnList(item?.processes);
            }
          });
        };
        getColumnList(cloneDeep(res || []));
        setPageData(cloneDeep(_cloneList));
        // setExpandedKeys(_cloneList.map((item: any) => item.key));
        setTableLoading(false);
      })
      .catch(() => {
        console.warn('数据列表获取失败');
        setPageData([]);
        setTableLoading(false);
      });
  };

  // 表格滚动高度获取
  const [scrollY] = useFlowTableScrollY({
    columns: cols,
    listProps: {
      pageData,
    },
  }) as any[];

  return (
    <div className={cls(styles['qx-data-flow'])}>
      <FlowHeader
        title={name || '未命名流程'}
        handleClick={handleClick}
        type={'VERSION'}
      />
      <section className={cls(styles['qx-data-flow__main'])}>
        <section className={cls(styles['main-content'])}>
          <div
            className={cls(styles[`${prefix}-container`], 'qx-data-flow-table')}
          >
            <Table
              loading={tableLoading}
              columns={cols}
              dataSource={pageData}
              scroll={
                isScrollY
                  ? {
                      x: '100%',
                      y: scrollY,
                    }
                  : { x: '100%' }
              }
              pagination={false}
              size={'small'}
              bordered
              rowKey={(record: any) => {
                return `${record?.type || ''}${record?.id || ''}${Math.random()
                  .toString(36)
                  .replaceAll(/[0-9]/g, '')
                  .slice(2, 4)}`;
              }}
            />
          </div>
        </section>
      </section>
    </div>
  );
};

export default DataFlowVersion;