You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

table.tsx 3.8 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * @Author: 赵伟
  3. * @Date: 2024-06-26 10:05:52
  4. * @Description: Table cell 自定义 render
  5. */
  6. import { formatDate } from '@/utils/date';
  7. import { Tooltip } from 'antd';
  8. import dayjs from 'dayjs';
  9. export enum TableCellValueType {
  10. Index = 'Index',
  11. Text = 'Text',
  12. Date = 'Date',
  13. Array = 'Array',
  14. Link = 'Link',
  15. Custom = 'Custom',
  16. }
  17. export type TableCellValueOptions<T> = {
  18. page?: number; // 类型为 Index 时有效
  19. pageSize?: number; // 类型为 Index 时有效
  20. property?: string; // 类型为 Array 时有效
  21. dateFormat?: string; // 类型为 Date 时有效
  22. onClick?: (record: T, e: React.MouseEvent) => void; // 类型为 Link 时有效
  23. format?: (value: any | undefined | null, record: T, index: number) => string | undefined | null; // 类型为 Custom 时有效
  24. };
  25. type TableCellFormatter = (value: any | undefined | null) => string | undefined | null;
  26. // 日期转换函数
  27. function formatDateText(dateFormat?: string): TableCellFormatter {
  28. return (value: any | undefined | null): ReturnType<TableCellFormatter> => {
  29. if (value === undefined || value === null || value === '') {
  30. return null;
  31. }
  32. if (!dayjs(value).isValid()) {
  33. return null;
  34. }
  35. return formatDate(value, dateFormat);
  36. };
  37. }
  38. /**
  39. * 数组转换函数,将数组元素转换为字符串,用逗号分隔
  40. * @param {string} property 如果数组元素是对象,那么取数组元素的某个属性
  41. * @returns {TableCellFormatter} Table cell 渲染函数
  42. */
  43. function formatArray(property?: string): TableCellFormatter {
  44. return (value: any | undefined | null): ReturnType<TableCellFormatter> => {
  45. if (
  46. value === undefined ||
  47. value === null ||
  48. Array.isArray(value) === false ||
  49. value.length === 0
  50. ) {
  51. return null;
  52. }
  53. const list =
  54. property && typeof value[0] === 'object' ? value.map((item) => item[property]) : value;
  55. return list.join(',');
  56. };
  57. }
  58. function tableCellRender<T>(
  59. ellipsis: boolean = false,
  60. type: TableCellValueType = TableCellValueType.Text,
  61. options?: TableCellValueOptions<T>,
  62. ) {
  63. return (value: any | undefined | null, record: T, index: number) => {
  64. let text = value;
  65. switch (type) {
  66. case TableCellValueType.Index:
  67. text = (options?.page ?? 0) * (options?.pageSize ?? 0) + index + 1;
  68. break;
  69. case TableCellValueType.Text:
  70. case TableCellValueType.Link:
  71. text = value;
  72. break;
  73. case TableCellValueType.Date:
  74. text = formatDateText(options?.dateFormat)(value);
  75. break;
  76. case TableCellValueType.Array:
  77. text = formatArray(options?.property)(value);
  78. break;
  79. case TableCellValueType.Custom:
  80. text = options?.format?.(value, record, index);
  81. break;
  82. default:
  83. break;
  84. }
  85. if (ellipsis && text) {
  86. return (
  87. <Tooltip title={text} placement="topLeft" overlayStyle={{ maxWidth: '400px' }}>
  88. {renderCell(text, type === TableCellValueType.Link, record, options?.onClick)}
  89. </Tooltip>
  90. );
  91. } else {
  92. return renderCell(text, type === TableCellValueType.Link, record, options?.onClick);
  93. }
  94. };
  95. }
  96. function renderCell<T>(
  97. text: any | undefined | null,
  98. isLink: boolean,
  99. record: T,
  100. onClick?: (record: T, e: React.MouseEvent) => void,
  101. ) {
  102. return isLink ? renderLink(text, record, onClick) : renderText(text);
  103. }
  104. function renderText(text: any | undefined | null) {
  105. return <span>{text ?? '--'}</span>;
  106. }
  107. function renderLink<T>(
  108. text: any | undefined | null,
  109. record: T,
  110. onClick?: (record: T, e: React.MouseEvent) => void,
  111. ) {
  112. return (
  113. <a className="kf-table-row-link" onClick={(e) => onClick?.(record, e)}>
  114. {text}
  115. </a>
  116. );
  117. }
  118. export default tableCellRender;