|
- /*
- * @Author: 赵伟
- * @Date: 2024-06-26 10:05:52
- * @Description: Table Cell 自定义 render
- */
-
- import { isEmpty } from '@/utils';
- import { formatDate } from '@/utils/date';
- import { Tooltip, TooltipProps, Typography } from 'antd';
- import dayjs from 'dayjs';
-
- export enum TableCellValueType {
- Index = 'Index',
- Text = 'Text',
- Date = 'Date',
- Array = 'Array',
- Link = 'Link',
- Custom = 'Custom',
- }
-
- export type TableCellValueOptions<T> = {
- page?: number; // 类型为 Index 时有效
- pageSize?: number; // 类型为 Index 时有效
- property?: string; // 类型为 Array 时有效
- dateFormat?: string; // 类型为 Date 时有效
- onClick?: (record: T, e: React.MouseEvent) => void; // 类型为 Link 时有效
- format?: (value: any | undefined | null, record: T, index: number) => string | undefined | null; // 类型为 Custom 时有效
- };
-
- type TableCellFormatter = (value: any | undefined | null) => string | undefined | null;
-
- // 日期转换函数
- function formatDateText(dateFormat?: string): TableCellFormatter {
- return (value: any | undefined | null): ReturnType<TableCellFormatter> => {
- if (value === undefined || value === null || value === '') {
- return null;
- }
- if (!dayjs(value).isValid()) {
- return null;
- }
- return formatDate(value, dateFormat);
- };
- }
-
- /**
- * 数组转换函数,将数组元素转换为字符串,用逗号分隔
- * @param {string} property 如果数组元素是对象,那么取数组元素的某个属性
- * @returns {TableCellFormatter} Table cell 渲染函数
- */
- function formatArray(property?: string): TableCellFormatter {
- return (value: any | undefined | null): ReturnType<TableCellFormatter> => {
- if (
- value === undefined ||
- value === null ||
- Array.isArray(value) === false ||
- value.length === 0
- ) {
- return null;
- }
-
- const list =
- property && typeof value[0] === 'object' ? value.map((item) => item[property]) : value;
- return list.join(',');
- };
- }
-
- function tableCellRender<T>(
- ellipsis: boolean | TooltipProps | 'auto' = false,
- type: TableCellValueType = TableCellValueType.Text,
- options?: TableCellValueOptions<T>,
- ) {
- return (value: any | undefined | null, record: T, index: number) => {
- let text = value;
- switch (type) {
- case TableCellValueType.Index:
- text = (options?.page ?? 0) * (options?.pageSize ?? 0) + index + 1;
- break;
- case TableCellValueType.Text:
- case TableCellValueType.Link:
- text = value;
- break;
- case TableCellValueType.Date:
- text = formatDateText(options?.dateFormat)(value);
- break;
- case TableCellValueType.Array:
- text = formatArray(options?.property)(value);
- break;
- case TableCellValueType.Custom:
- text = options?.format?.(value, record, index);
- break;
- default:
- break;
- }
-
- if (ellipsis === 'auto' && text) {
- return renderCell(type, text, 'auto', record, options?.onClick);
- } else if (ellipsis && text) {
- const tooltipProps = typeof ellipsis === 'object' ? ellipsis : {};
- const { overlayStyle, ...rest } = tooltipProps;
- return (
- <Tooltip {...rest} overlayStyle={{ maxWidth: 400, ...overlayStyle }} title={text}>
- {renderCell(type, text, true, record, options?.onClick)}
- </Tooltip>
- );
- } else {
- return renderCell(type, text, false, record, options?.onClick);
- }
- };
- }
-
- function renderCell<T>(
- type: TableCellValueType,
- text: any | undefined | null,
- ellipsis: boolean | 'auto',
- record: T,
- onClick?: (record: T, e: React.MouseEvent) => void,
- ) {
- return type === TableCellValueType.Link
- ? renderLink(text, ellipsis, record, onClick)
- : renderText(text, ellipsis);
- }
-
- function renderLink<T>(
- text: any | undefined | null,
- ellipsis: boolean | 'auto',
- record: T,
- onClick?: (record: T, e: React.MouseEvent) => void,
- ) {
- return (
- <a className="kf-table-row-link" onClick={(e) => onClick?.(record, e)}>
- {renderText(text, ellipsis)}
- </a>
- );
- }
-
- function renderText(text: any | undefined | null, ellipsis: boolean | 'auto') {
- if (ellipsis === 'auto') {
- return (
- <Typography.Paragraph
- style={{ marginBottom: 0 }}
- ellipsis={{
- tooltip: {
- title: text,
- destroyTooltipOnHide: true,
- overlayStyle: { maxWidth: 400 },
- },
- }}
- >
- {!isEmpty(text) ? text : '--'}
- </Typography.Paragraph>
- );
- }
-
- return (
- <span
- style={
- ellipsis
- ? {
- whiteSpace: 'nowrap',
- overflow: 'hidden',
- textOverflow: 'ellipsis',
- wordBreak: 'break-all',
- display: 'inline-block',
- maxWidth: '100%',
- verticalAlign: 'middle',
- }
- : undefined
- }
- >
- {!isEmpty(text) ? text : '--'}
- </span>
- );
- }
-
- export default tableCellRender;
|