diff --git a/packages/amis-core/src/store/table.ts b/packages/amis-core/src/store/table.ts index 875ca4ef4..e1ba4f423 100644 --- a/packages/amis-core/src/store/table.ts +++ b/packages/amis-core/src/store/table.ts @@ -202,6 +202,40 @@ export const Row = types return table && table.itemDraggableOn ? evalExpression(table.itemDraggableOn, (self as IRow).locals) : true; + }, + + /** + * 判断当前行点击后是否应该继续触发check + * 用于限制checkOnItemClick触发的check事件 + */ + get isCheckAvaiableOnClick(): boolean { + const table = getParent(self, self.depth * 2) as ITableStore; + const keepItemSelectionOnPageChange = + table?.keepItemSelectionOnPageChange; + const selectionUpperLimit = table?.maxKeepItemSelectionLength; + + // 如果未做配置,或者配置不合法直接通过检查 + if ( + !keepItemSelectionOnPageChange || + !Number.isInteger(selectionUpperLimit) + ) { + return true; + } + + // 使用内置ID,不会重复 + const selectedIds = (table?.selectedRows ?? []).map( + (item: IRow) => item.id + ); + // 此时syncSelected还没有触发,所以需要比较点击之后的数量 + const selectedCount = selectedIds.includes(self.id) + ? selectedIds.length - 1 + : selectedIds.length + 1; + + if (selectedCount > selectionUpperLimit) { + return false; + } + + return true; } })) .actions(self => ({ @@ -688,7 +722,8 @@ export const TableStore = iRendererStore return getHovedRow(); }, - get disabledHeadCheckbox() { + /** 已选择item是否达到数量上限 */ + get isSelectionThresholdReached() { const selectedLength = self.data?.selectedItems?.length; const maxLength = self.maxKeepItemSelectionLength; @@ -696,7 +731,7 @@ export const TableStore = iRendererStore return false; } - return maxLength === selectedLength; + return maxLength <= selectedLength; }, get firstToggledColumnIndex() { diff --git a/packages/amis/src/renderers/Table/TableRow.tsx b/packages/amis/src/renderers/Table/TableRow.tsx index 5f4b69e0a..c5e87c4ca 100644 --- a/packages/amis/src/renderers/Table/TableRow.tsx +++ b/packages/amis/src/renderers/Table/TableRow.tsx @@ -1,12 +1,13 @@ import {observer} from 'mobx-react'; import React from 'react'; +import uniq from 'lodash/uniq'; import type {IColumn, IRow} from 'amis-core/lib/store/table'; import {RendererProps} from 'amis-core'; import {Action} from '../Action'; import {isClickOnInput, createObject} from 'amis-core'; interface TableRowProps extends Pick { - onCheck: (item: IRow) => void; + onCheck: (item: IRow) => Promise; classPrefix: string; renderCell: ( region: string, @@ -42,7 +43,8 @@ export class TableRow extends React.Component { return; } - const {itemAction, onAction, item, data, dispatchEvent} = this.props; + const {itemAction, onAction, item, data, dispatchEvent, onCheck} = + this.props; const rendererEvent = await dispatchEvent( 'rowClick', @@ -59,7 +61,9 @@ export class TableRow extends React.Component { onAction && onAction(e, itemAction, item?.data); item.toggle(); } else { - this.props.onCheck(this.props.item); + if (item.checkable && item.isCheckAvaiableOnClick) { + onCheck?.(item); + } } } diff --git a/packages/amis/src/renderers/Table/index.tsx b/packages/amis/src/renderers/Table/index.tsx index 089c2dfdb..fae164942 100644 --- a/packages/amis/src/renderers/Table/index.tsx +++ b/packages/amis/src/renderers/Table/index.tsx @@ -1876,7 +1876,7 @@ export default class Table extends React.Component { classPrefix={ns} partial={store.someChecked && !store.allChecked} checked={store.someChecked} - disabled={store.disabledHeadCheckbox} + disabled={store.isSelectionThresholdReached} onChange={this.handleCheckAll} /> ) : (