index.jsx 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import React, { Fragment } from 'react';
  2. import { Spin, Popover, Checkbox, Pagination } from 'antd';
  3. import cx from 'classnames';
  4. import styles from './index.less';
  5. import { ArrowUpOutlined, ArrowDownOutlined, CheckSquareOutlined } from '@ant-design/icons';
  6. export default ({
  7. pagination = true,
  8. loading,
  9. columns,
  10. dataSource,
  11. rowKey,
  12. page,
  13. total,
  14. rowSelection,
  15. showRowSelection,
  16. minHeight = 200,
  17. onRowClick,
  18. expandable = function () {},
  19. onPageChange,
  20. onSortChange,
  21. onFilterChange,
  22. classname = '',
  23. }) => {
  24. return (
  25. <div className={cx(styles.table, classname)}>
  26. <Spin spinning={loading} delay={600}>
  27. <table>
  28. <thead>
  29. <tr>
  30. {columns.map((col) => {
  31. return (
  32. <th
  33. key={col.dataIndex}
  34. style={{ ...col.titleStyle, width: col.width }}
  35. width={col.width}
  36. >
  37. {col.sorter && (
  38. <span
  39. className={cx(styles.sorter, {
  40. [styles.sortered]: !!col.sortered,
  41. })}
  42. onClick={() => {
  43. onSortChange(col, col.sortered === 'DESC' ? 'ASC' : 'DESC');
  44. }}
  45. >
  46. {col.title}
  47. {/* <Icon type={col.sortered === 'DESC' ? 'downward' : 'upward'} weight={col.sortered ? 600 : 400} />
  48. */}
  49. {col.sortered === 'DESC' ? (
  50. <ArrowDownOutlined weight={col.sortered ? 600 : 400} />
  51. ) : (
  52. <ArrowUpOutlined weight={col.sortered ? 600 : 400} />
  53. )}
  54. </span>
  55. )}
  56. {col.filters && (
  57. <Popover
  58. trigger="click"
  59. placement="bottomLeft"
  60. // arrowPointAtCenter
  61. content={
  62. <div className={styles.filterList}>
  63. {col.filters.map((f) => {
  64. return (
  65. <div
  66. key={f.value}
  67. className={cx(styles.filterItem, {
  68. [styles.filterItemChecked]: col.filteredValue.includes(f.value),
  69. })}
  70. onClick={() => {
  71. let newList = [...col.filteredValue];
  72. if (col.filteredValue.includes(f.value)) {
  73. if (col.single) {
  74. newList = [];
  75. } else {
  76. newList = col.filteredValue.filter(
  77. (item) => item !== f.value,
  78. );
  79. }
  80. } else {
  81. if (col.single) {
  82. newList = [f.value];
  83. } else {
  84. newList.push(f.value);
  85. }
  86. }
  87. onFilterChange(col.dataIndex, newList);
  88. }}
  89. >
  90. <Checkbox checked={col.filteredValue.includes(f.value)} />
  91. <span className={styles.filterItemValue}>{f.label}</span>
  92. </div>
  93. );
  94. })}
  95. </div>
  96. }
  97. >
  98. <span className={cx(styles.filter)}>
  99. {col.filteredValue.length > 0 && (
  100. <span className={cx(styles.fangxing)}>
  101. <span className={cx(styles.circle)}></span>
  102. </span>
  103. )}
  104. {col.filteredValue.length == 0 && (
  105. <span className={cx(styles.filterTitlePic)}>
  106. <CheckSquareOutlined style={{ fontSize: '16px' }} />
  107. </span>
  108. )}
  109. <span>{col.title}</span>
  110. </span>
  111. </Popover>
  112. )}
  113. {!col.sorter && !col.filters && <span>{col.title}</span>}
  114. </th>
  115. );
  116. })}
  117. </tr>
  118. </thead>
  119. <tbody>
  120. {loading && dataSource.length === 0 && (
  121. <tr>
  122. <td colSpan={columns.length}>
  123. <div style={{ height: minHeight }} />
  124. </td>
  125. </tr>
  126. )}
  127. <tr></tr>
  128. {dataSource.map((item, index) => {
  129. return (
  130. <Fragment key={item[rowKey]}>
  131. <tr
  132. onClick={() => onRowClick && onRowClick(item)}
  133. className={cx({ [styles.canClick]: !!onRowClick })}
  134. >
  135. {columns.map((col) => {
  136. return (
  137. <td key={col.dataIndex}>
  138. {col.render && col.render(item[col.dataIndex], item, index)}
  139. {!col.render &&
  140. (item[col.dataIndex] === undefined ? '-' : item[col.dataIndex])}
  141. </td>
  142. );
  143. })}
  144. </tr>
  145. <tr>{expandable(item)}</tr>
  146. </Fragment>
  147. );
  148. })}
  149. </tbody>
  150. </table>
  151. {pagination && (
  152. <div className={styles.page}>
  153. <div>
  154. <Pagination
  155. current={page.pageNum}
  156. pageSize={page.pageSize}
  157. total={total}
  158. showSizeChanger={false}
  159. itemRender={(c, t, o) => {
  160. if (t === 'prev') {
  161. return <a>上一页</a>;
  162. }
  163. if (t === 'next') {
  164. return <a>下一页</a>;
  165. }
  166. return o;
  167. }}
  168. onChange={(current, pageSize) => {
  169. window.scrollTo(0, 0);
  170. onPageChange({
  171. pageNum: current,
  172. pageSize,
  173. });
  174. }}
  175. />
  176. </div>
  177. </div>
  178. )}
  179. </Spin>
  180. </div>
  181. );
  182. };