import { Table } from 'antd'; import { TableProps, TablePaginationConfig, ColumnType } from 'antd/lib/table'; import { TextAreaProps } from 'antd/es/input/TextArea'; import { IInputProps } from '../input/input.js'; import { IInputNumberProps } from '../inputnumber/inputNumber.js'; import { IDynamicItem } from '../dynamicsetting/interface.js'; import _default from './components/TitleDirectionColumn.js'; import TableDynamicHeader from './components/TableDynamicHeader.js'; import { IS_SUMMARY } from './constant.js'; import { IBadgeProps } from './components/Badge.js'; type IEditableConfigOtherProps = IInputProps & IInputNumberProps & TextAreaProps; interface IEditableConfig extends Partial { /** * 列编辑类型 */ type?: "input" | "inputNumber" | "textarea"; /** * 最大值函数 */ maxHandle?: (record: any) => any; /** * 最大值函数 */ minHandle?: (record: any) => any; /** * 禁用方法 */ disabledHandle?: (record: any) => boolean; /** * 去除空格 * trim 去除前后空格 * trimStart 去除前面空格 * trimEnd 去除后面空格 * trimAll 去除所有空格 */ trimType?: "trim" | "trimStart" | "trimEnd" | "trimAll" | ((value: any) => any); /** * 可以传入对应的input inputNumber的所有相关属性 */ [props: string]: any; } interface ValidateErrorObject { /** 这个必传,但是为了兼容之前的逻辑 无奈这么做 */ errors?: string; /** * @deprecated 这个类型即将被废弃,不要使用。本身文档里面就是需要用errors表示错误信息的. */ msg?: string; /** 其他任何值,当你需要的时候 */ [props: string]: any; } interface IColumnType extends Omit, "render"> { /** * 内部属性。如果要记录过滤等信息,需要从一个地方去取 */ __dynamicItem__?: IDynamicItem; /** * 是否禁止取消显示 */ dynamicDisabled?: boolean; /** * 默认是否不勾选当前选项 */ defaultUnChecked?: boolean; /** * 是否添加复制整列功能 * @description * 如果是一个boolean值。代表需不需要复制列的功能。复制列会以当前列配置的key为准 * 如果传递的是一个字符串或者字符串数组。那么复制列会用传入的值当前key来做复制 */ isCopy?: boolean | string | string[]; /** * 添加必填 */ isRequire?: boolean; /** * 是否显示 */ isDisplay?: boolean; /** * 单元格显示类型 * info 背景色为提示 * error 背景色为错误提示 */ showType?: "info" | "error"; /** * 是否开启编辑功能 */ editable?: ((record: any) => boolean) | boolean; editableConfig?: IEditableConfig; /** * 如果你不想使用表格内部提供的编辑功能,但是又想粘贴execl中的数据时,实现数据替换 * 可以添加这个属性 */ isPaste?: boolean; /** * 开启验证 */ validate?: { /** * 标题 默认取 column.title */ title?: string; /** * 验证的具体是哪个字段 默认取 column.key * 暂时没用到 */ key?: string; /** * 验证具体对应表格哪一列 默认取 column.key * 暂时没用到 */ columnKey?: string; /** 正则表达式 */ pattern?: RegExp | RegExp[]; /** 正则表达式时的提示信息 */ message?: string | string[]; /** 内部校验时,除了column.key(本字段)外,还需要触发校验的其他字段 */ triggerValidateKeys?: string[]; /** 是否初始校验条件 */ isInit?: (record: any) => boolean; /** * 自定义校验 * @param text * @param record * @param index * @param key * @returns 如果验证通过 resolve随便都可。 * 如果验证失败 必须返回 * Promise.reject({ * errors: `${tableName || ""} 第${innerCurrentI + 1}行 ${title} ${ (validate as any)?.message || "填写错误!" }`, }) */ validate?: (text: any, record: any, index: number, key: string) => Promise; }; /** * 开启往下填充 * 会在表头添加一个 向下的箭头。点击箭头将第一行的数据 往下填充 * 如果传入一个方法。那么该方法需要返回处理过后的数据 */ isFillDown?: boolean | ((info: { index: number; text: any; record: any; }) => any); /** * 是否开启自定义排序 * 排序的数据默认实际不会影响源数据,是一份新的数据。 * 如果想影响源数据,需要传入:onTableChange方法。 * 排序时,会触发这个方法。会把排序后数据、源数据以及排序信息传出给开发自行处理。 * 如果想实现服务端排序:需要传入:serviceOrder方法。 */ isOrder?: boolean; /** * 是否开启过滤功能 */ isFilter?: boolean; /** * 是否强调字段 */ isStress?: boolean; /** * 动态列配置的title * 当你传入的title是一个 组件时。组件再做动态列配置的时候,需要一个字符串的值,来充当动态列配置的title。这里可以传入一个字符串的值进来 */ dynamicTitle?: string; /** * 气泡提示框 */ popoverText?: string; /** * 代理render方法 * options里面会提供一些内部方法以供外部调用。 * @example 1. insertTableFromClipboard 将粘贴板中的数据插入到表格中。 * { * key: 'key1', * dataIndex: 'key1', * title: '测试', * render(text, record, index, options) { * const { insertTableFromClipboard } = options; * return { * const result = await insertTableFromClipboard(e, { * index, * // 默认传true * // 传true 表格如果传入了 onTableChange的话会直接调用这个方法。false则不会调用。 * // 你可以自行通过result的结果处理数据 * isUpdate: true, * }) * }} /> * } * } */ render?: (text: any, record: any, index: number, options: IRenderOptions) => any; /** * 是否开启维度自定义 */ isDimension?: boolean; /** * 自定义排序的优先级,数字越小,优先级越高,比如2的不能排序到1的前面 */ dimensionPriority?: number; /** * 维度优先级分组,同组内遵循 dimensionPriority,跨组自由排序 */ dimensionGroup?: string; /** * 自定义维度互斥的字段,多个需要逗号分隔,比如:name,age */ dimensionExclusive?: string; /** * 维度依赖关系配置 */ dimensionDependencies?: { /** AND关系:必须全部依赖这些字段 */ required?: string[]; /** OR关系:至少依赖其中一个 */ anyOf?: string[]; }; /** * 维度是否开启合计 */ isDimensionSum?: boolean; /** * 是否合并 */ isMerge?: boolean; /** * 开启合计 */ isSummary?: boolean; /** * 开启合并的字段,按其他字段维度合并 */ mergeKey?: string; /** * 添加角标 */ badge?: IBadgeProps | ((record: any) => IBadgeProps | undefined); /** * 导出excel的配置 */ excelConfig?: { /** * 表头背景色 */ headerBgColor?: string; /** * 表头字体颜色 */ headerFontColor?: string; }; dateFormat?: string; precision?: number; thousand?: boolean; /** * 空值时显示的文本,默认为 "—" */ emptyText?: string; } interface IRenderOptions { insertTableFromClipboard: IFuncInsertTableFromClipboard; } interface IInserTableFromClipboard { index: number; isUpdate?: boolean; } interface IFuncInsertTableFromClipboardReturn { /** 新数据 */ newDataSource: any; /** 老数据 */ oldDataSource: any; /** 粘贴规则。按照列对应key 以及插入到哪一行建立了对应关系 */ pasteConfig: any; } interface IFuncInsertTableFromClipboard { (e: any, options: IInserTableFromClipboard): Promise; } interface IColumnGroupType extends IColumnType { children?: IColumnsType; } type IColumnsTypeProp = IColumnGroupType; declare type IColumnsType = IColumnsTypeProp[]; interface ITableRefHandel { /** * 获取真实的index 当开启表格内部分页时 使用 * @param index 当前的index * @returns */ getRealyIndex?: (index: number) => number; /** * 获取表格动态列配置当前配置信息 */ getDynamicList?: () => any; /** * 触发表格验证 */ tableValidate?: (validateKeys?: string[]) => Promise; /** * 移除错误样式 */ clearErrorClass?: () => void; /** * 滚动到指定位置 * 虚拟滚动时:使用 virtuallist-antd 的 scrollTo 方法,需要传 row、y、vid * 普通滚动时:操作 DOM,可以传 y、x 或 index * @param options.row - 虚拟滚动时滚动到第几行 * @param options.y - 垂直滚动的像素值 * @param options.x - 水平滚动的像素值 * @param options.vid - 虚拟滚动的唯一标识符 * @param options.index - 滚动到指定行索引(普通滚动) */ scrollTo?: (options: { row?: number; y?: number; x?: number; vid?: string; index?: number; }) => void; /** * 获取滚动条位置信息 * @returns 包含 x(水平) 和 y(垂直) 滚动位置的对象 */ getScrollPosition?: () => { /** 水平滚动位置 */ x: number; /** 垂直滚动位置 */ y: number; }; /** * 重置 */ onResetDynamicList?: () => void; /** * 导出excel */ exportExcel?: (fileName: string, config?: { topDescription?: string; time?: string; topDescriptionRowHeight?: number; }) => void; } interface ITableProps extends Omit, "columns"> { /** * 实时验证 */ isRealTimeValidate?: boolean; /** * 是否是flex布局 常用于列表页 */ isFlex?: boolean; tablePreferences?: any; /** * 是否开启动态列配置 */ dynamicKey?: string; /** * 动态列配置版本。版本号高的可以覆盖用户本地配置。 * 就按数字往上递增的规则就行 1 2 3 4 5这种 */ dynamicVersion?: number; /** * 自定义动态列配置后的回调 */ customDynamicListHandle?: (dynamicList: any) => void; /** * 增加了column的表头过滤功能;如果想要过滤功能持久化,可以配置这个属性 * 同时也需要配置dynamicKey配置。 */ isRemeberFilter?: boolean; /** * 表格列的排序是否更新源数据。即是否触发onTableChange事件 * 变成受控模式 */ isOrderUpdateData?: boolean; /** * 如果想要开启动态列配置,但是不想要页面出现操作按钮 * 一般场景用于记录宽度的变化 */ hiddenDynamicIcon?: boolean; /** * 代理动态列配置的类型 */ columns?: IColumnsType; /** * 表格数据发生改变 * @param dataSource 表格最新数据 * @param preDataSource 表格改变前的数据 * @param other 一些其他属性,标识表格数据的改变因为什么原因引发 * @returns */ onTableChange?: (dataSource: any, preDataSource: any, other?: { currentIndex?: number; dragIndex?: number; hoverIndex?: number; type?: "paste" | "edit" | "move" | "add" | "del" | "delAll" | "fillDown" | "sort" | "custom"; field?: string; [prop: string]: any; }) => void; /** * 是否开启表格编辑功能 */ isEdit?: boolean; /** * 是否开启表格拖拽排序功能 */ isMove?: boolean; /** * 是否开启表头伸缩功能 */ isResizableColumn?: boolean; /** * 开启表头伸缩功能后,会为表头包裹一层div,并设置一些样式 * 可能会导致column设置的宽度不生效 * 可能开启这个属性 关闭这个样式 */ isResizableTitleEllipsis?: boolean; /** * 是否开启虚拟滚动 * 传入一个虚拟滚动得key值进来即可 */ virtualKey?: string; /** * 是否显示增加行功能 */ isAdd?: boolean; /** * 判断当前行是否隐藏添加按钮 isAdd默认所有行都加删除行按钮 * 返回true 隐藏增加按钮 * 返回false 显示增加按钮 */ hiddenAddBtnHandle?: (record: any, index: number) => boolean; /** * 是否显示表头的新增行按钮(当没有一条数据时,可以点击表头行实现数据的插入) */ isTheadTitleAdd?: boolean; /** * 新增的逻辑 默认生成一条空白数据 或者复制 */ addMode?: "blank" | "copy"; /** * 如果需要更高的自定义 自己返回新增的数据 可以自己设置新增行的数据 * @param record 当前数据 * @param info 一些其他配置 * @returns */ addCallback?: (record: any, info: { index: number; }) => any; /** * 是否显示删减行功能 */ isDel?: boolean; /** * 删除时的提示文字 */ delPopTitle?: string; /** * 判断当前行是否隐藏删除按钮 isDel默认所有行都加删除行按钮 * 返回true 隐藏删除按钮 * 返回false 显示删除按钮 */ hiddenDelBtnHandle?: (record: any, index: number) => boolean; /** * 是否显示删除所有功能 默认显示删除 */ isDelAll?: boolean; isAddAndDelAuto?: boolean; /** * 总结栏配置 */ summaryConfig?: ISummaryConfig[]; summaryFixed?: boolean; /** * 是否开启内部分页 */ isInnerPagination?: boolean; innerPaginationPageSize?: number; innerPaginationPosition?: string[]; innerPaginationPageSizeOptions?: TablePaginationConfig["pageSizeOptions"]; innerPaginationConfig?: TablePaginationConfig; tableRefHandle?: React.MutableRefObject; /** * 表格的名字 一个页面存在多个表格时 发起表格验证时,可以提示哪个表格出现问题 */ tableName?: string; /** * 服务端排序返回事件 * 如果开启服务端排序,那么前端这边不做排序处理,只返回设置的字段 */ serviceOrder?: (order: IOrder) => void; /** * 标明需要展示的差异数组 * 可以传入需要展示的差异行索引 [2,4,5] * 也可以传入一个函数 */ differences?: number[] | ((record: any, index: number) => boolean); isMarginTop?: boolean; isMarginBottom?: boolean; /** * 新增或删除行配置 */ addAndDelProps?: IColumnsTypeProp; /** * 是否开启自动计算Y轴高度 */ isAutoScrollY?: boolean; /** * 自动计算Y轴高度时,table下面留出的距离 */ autoScrollYMarginBottom?: number; /** * 表格id */ tableId?: string; /** * 固定前几行,后面的行使用虚拟滚动 * 当开启虚拟滚动时,可以设置固定前几行不参与虚拟滚动 */ fixedRowsCount?: number; /** * 固定行配置 */ fixedRowsConfig?: { /** * 固定行数量 */ count: number; /** * 行高,用于计算固定行的top位置 */ rowHeight?: number; /** * 固定行的样式 */ style?: React.CSSProperties; }; /** * 表头对齐方式 */ headerAlign?: "left" | "center" | "right"; /** * 开启维度自定义。开启后,会根据columns中的isDimension属性来是否开启维度自定义,需要合并行时,需要开启这个属性isAutoMerge */ isDimensionDynamic?: boolean; /** * 开启维度自定义后,是否合并子数据。默认为true,会将相同维度组合的子数据合并为一行;为false时保留所有原始记录 */ isDimensionMergeChildren?: boolean; /** * 开启维度自定义后,开启维度合计的字段,与column中的isSummary相同,主要用于自定义合计字段 */ dimensionCustomSumKeys?: (string | { /** 自定义合计的key */ key: string; /** 自定义合计的值 */ value?: (record: any) => string | number; /** 合计方式 */ summaryType?: "sum" | "first" | "computed"; /** 当summaryType为computed时,用于计算合计值的函数 */ computedSummary?: (items: any[], summaryRow: any) => string | number; })[]; /** * 开启自动合并行 */ isAutoMerge?: boolean; /** * 开启自动合并后,但不需要合并选择行和新增行 */ isAutoMergeAddAndDel?: boolean; /** * 导出文件是否添加合计行 */ isExportSummary?: boolean; /** * table模式 * 目前index的话会自动加个序号 */ mode?: "index"; /** * 是否开启右键功能 */ isContextMenu?: boolean; /** * 全屏后的一些事件 */ isFullscreenHandle?: (isFullscreen: boolean) => void; /** * 表格动态列配置是否显示文字 */ isDynamicColumnText?: boolean; /** * 表格合计是否可以控制展开收起 */ isTableSummaryCollapse?: boolean; /** * 表格合计是否默认展开 */ isTableSummaryDefaultExpand?: boolean; /** * 表格无数据时的紧凑模式 */ emptyCompact?: boolean; /** * 表格标题,显示在表格上方,背景色与表头一致 */ tableTitle?: React.ReactNode; } interface IFields { /** * 保留几位小数 */ toFixedNum?: number | number[]; /** * 字段键值 对应显示在表格的哪一列 */ key: string; /** * 需要显示的key,可能一个列字段 对应显示多个值 */ showKey?: string | string[]; /** * 如果存在value,那么直接显示value */ value?: string | number | (string | number)[]; /** * 对当前字段的值做最终处理,v 跟 showKey 或者 value的类型一一对应 如果传入的是数组 那么返回的即是数组 * @param v 当前处理值 * @param summaryTotalObj 总结栏总对象 * @returns */ callback?: (v: any, summaryTotalObj: any) => any; /** 对齐方式 */ align?: "left" | "center" | "right"; } interface ISummaryConfig { type: "subtotal" | "total"; /** * 字段的设置方式 */ fields: (string | IFields)[]; /** * 列头显示字段 */ title?: string; } interface TableComponent extends React.FC> { SELECTION_COLUMN: typeof Table.SELECTION_COLUMN; EXPAND_COLUMN: typeof Table.EXPAND_COLUMN; SELECTION_ALL: typeof Table.SELECTION_ALL; SELECTION_INVERT: typeof Table.SELECTION_INVERT; SELECTION_NONE: typeof Table.SELECTION_NONE; Column: typeof Table.Column; ColumnGroup: typeof Table.ColumnGroup; Summary: typeof Table.Summary; TitleDirectionColumn: typeof _default; TableDynamicHeader: typeof TableDynamicHeader; DifferencesClassName: string; IS_SUMMARY: typeof IS_SUMMARY; /** 表格动态配置的模板设置功能的表名 */ TABLE_DYNAMIC_TEMPLATE_KEY: string; } /** * 排序相关类型 */ interface IOrder { field: string; order: "ascend" | "descend" | undefined; } export { IColumnGroupType, IColumnType, IColumnsType, IColumnsTypeProp, IEditableConfig, IFields, IFuncInsertTableFromClipboard, IOrder, IRenderOptions, ISummaryConfig, ITableProps, ITableRefHandel, TableComponent, ValidateErrorObject };