index.tsx 4.3 KB
Newer Older
陈帅's avatar
陈帅 committed
1
import React, { Component, Fragment } from 'react';
ddcat1115's avatar
ddcat1115 committed
2
import { Table, Alert } from 'antd';
陈帅's avatar
陈帅 committed
3
import { TableProps, ColumnProps, SorterResult } from 'antd/lib/table';
4
import styles from './index.less';
陈帅's avatar
陈帅 committed
5
import { TableListItem } from '../../data';
6

陈帅's avatar
陈帅 committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

export interface StandardTableProps<T> extends Omit<TableProps<T>, 'columns'> {
  columns: StandardTableColumnProps[];
  data: {
    list: Array<TableListItem>;
    pagination: StandardTableProps<TableListItem>['pagination'];
  };
  selectedRows: TableListItem[];
  onSelectRow: (rows: any) => void;
}

export type StandardTableColumnProps = ColumnProps<TableListItem> & {
  needTotal?: boolean;
  total?: number;
};

function initTotalList(columns: StandardTableColumnProps[]) {
  if (!columns) {
    return [];
  }
  const totalList: StandardTableColumnProps[] = [];
jim's avatar
jim committed
29
  columns.forEach(column => {
ddcat1115's avatar
ddcat1115 committed
30 31 32 33 34 35 36
    if (column.needTotal) {
      totalList.push({ ...column, total: 0 });
    }
  });
  return totalList;
}

陈帅's avatar
陈帅 committed
37 38 39 40 41 42 43
interface StandardTableState {
  selectedRowKeys: string[];
  needTotalList: StandardTableColumnProps[];
}

class StandardTable extends Component<StandardTableProps<TableListItem>, StandardTableState> {
  constructor(props: StandardTableProps<TableListItem>) {
jim's avatar
jim committed
44 45 46 47 48 49 50 51 52
    super(props);
    const { columns } = props;
    const needTotalList = initTotalList(columns);

    this.state = {
      selectedRowKeys: [],
      needTotalList,
    };
  }
陈帅's avatar
陈帅 committed
53

陈帅's avatar
陈帅 committed
54
  static getDerivedStateFromProps(nextProps: StandardTableProps<TableListItem>) {
jim's avatar
jim committed
55 56 57 58 59 60 61 62 63 64
    // clean state
    if (nextProps.selectedRows.length === 0) {
      const needTotalList = initTotalList(nextProps.columns);
      return {
        selectedRowKeys: [],
        needTotalList,
      };
    }
    return null;
  }
陈帅's avatar
陈帅 committed
65

陈帅's avatar
陈帅 committed
66
  handleRowSelectChange = (selectedRowKeys: string[], selectedRows: TableListItem[]) => {
陈帅's avatar
陈帅 committed
67
    let { needTotalList } = this.state;
68 69 70 71
    needTotalList = needTotalList.map(item => ({
      ...item,
      total: selectedRows.reduce((sum, val) => sum + parseFloat(val[item.dataIndex], 10), 0),
    }));
陈帅's avatar
陈帅 committed
72 73 74
    const { onSelectRow } = this.props;
    if (onSelectRow) {
      onSelectRow(selectedRows);
75 76
    }

ddcat1115's avatar
ddcat1115 committed
77
    this.setState({ selectedRowKeys, needTotalList });
jim's avatar
jim committed
78
  };
79

陈帅's avatar
陈帅 committed
80 81 82 83 84 85
  handleTableChange = (
    pagination: StandardTableProps<TableListItem>['pagination'],
    filters: Record<keyof TableListItem, string[]>,
    sorter: SorterResult<TableListItem>,
    ...rest
  ) => {
陈帅's avatar
陈帅 committed
86 87
    const { onChange } = this.props;
    if (onChange) {
陈帅's avatar
陈帅 committed
88
      onChange(pagination, filters, sorter, ...rest);
陈帅's avatar
陈帅 committed
89
    }
jim's avatar
jim committed
90
  };
91 92 93

  cleanSelectedKeys = () => {
    this.handleRowSelectChange([], []);
jim's avatar
jim committed
94
  };
95 96

  render() {
ddcat1115's avatar
ddcat1115 committed
97
    const { selectedRowKeys, needTotalList } = this.state;
陈帅's avatar
陈帅 committed
98 99
    const { data, rowKey, ...rest } = this.props;
    const { list = [], pagination = false } = data || {};
100 101 102 103 104 105 106 107 108 109

    const paginationProps = {
      showSizeChanger: true,
      showQuickJumper: true,
      ...pagination,
    };

    const rowSelection = {
      selectedRowKeys,
      onChange: this.handleRowSelectChange,
陈帅's avatar
陈帅 committed
110
      getCheckboxProps: (record: TableListItem) => ({
nikogu's avatar
nikogu committed
111 112
        disabled: record.disabled,
      }),
113 114 115 116 117 118
    };

    return (
      <div className={styles.standardTable}>
        <div className={styles.tableAlert}>
          <Alert
jim's avatar
jim committed
119
            message={
陈帅's avatar
陈帅 committed
120
              <Fragment>
ddcat1115's avatar
ddcat1115 committed
121
                已选择 <a style={{ fontWeight: 600 }}>{selectedRowKeys.length}</a>&nbsp;&nbsp;
陈帅's avatar
陈帅 committed
122
                {needTotalList.map((item, index) => (
jim's avatar
jim committed
123
                  <span style={{ marginLeft: 8 }} key={item.dataIndex}>
陈帅's avatar
陈帅 committed
124 125
                    {item.title}
                    总计&nbsp;
jim's avatar
jim committed
126
                    <span style={{ fontWeight: 600 }}>
陈帅's avatar
陈帅 committed
127 128 129
                      {item.render
                        ? item.render(item.total, item as TableListItem, index)
                        : item.total}
ddcat1115's avatar
ddcat1115 committed
130
                    </span>
jim's avatar
jim committed
131 132 133 134 135
                  </span>
                ))}
                <a onClick={this.cleanSelectedKeys} style={{ marginLeft: 24 }}>
                  清空
                </a>
陈帅's avatar
陈帅 committed
136
              </Fragment>
jim's avatar
jim committed
137
            }
138 139 140 141 142
            type="info"
            showIcon
          />
        </div>
        <Table
143
          rowKey={rowKey || 'key'}
144 145 146 147
          rowSelection={rowSelection}
          dataSource={list}
          pagination={paginationProps}
          onChange={this.handleTableChange}
148
          {...rest}
149 150 151 152 153 154 155
        />
      </div>
    );
  }
}

export default StandardTable;