diff --git a/components/apolloTable/component/DragFixed.tsx b/components/apolloTable/component/DragFixed.tsx index 7b3284b93a187f6c540dabd789d5fdceee52050b..9832791e966900973f4c5f5e89160ee01380dee3 100644 --- a/components/apolloTable/component/DragFixed.tsx +++ b/components/apolloTable/component/DragFixed.tsx @@ -1,9 +1,20 @@ import React from 'react'; import { ResizableBox } from 'react-resizable'; import styles from './DragFixed.less'; +import { getCache, saveCache } from '../utils/cache'; const DragFixed = (props: any) => { - const { tableId, initLeft, initTop, onResizeStart, showColumns, columnWidth, columns, onResizeStop } = props; + const { + tableId, + initLeft, + initTop, + onResizeStart, + showColumns, + columnWidth, + columns, + onResizeStop, + cachedFeAttr, + } = props; // 表格 const container: any = document.querySelector(`#apolloTable_${tableId}`); // 滑块wrap @@ -109,6 +120,16 @@ const DragFixed = (props: any) => { item.fixed = ''; } } + if (cachedFeAttr) { + const cachedCols = getCache({ tableId }); + if (cachedCols) { + cachedCols[item.columnName] = { + ...cachedCols[item.columnName], + fixed: item.fixed, + }; + saveCache({ tableId, data: cachedCols }); + } + } newColumns.push(item); }); if (typeof onResizeStop === 'function') { diff --git a/components/apolloTable/component/DragResized.less b/components/apolloTable/component/DragResized.less index a2f973cb21a4f18c98361e1c4134f21fc06639d7..773456f0693999064d3cc0f377bf33fa420fd346 100644 --- a/components/apolloTable/component/DragResized.less +++ b/components/apolloTable/component/DragResized.less @@ -9,4 +9,7 @@ cursor: ew-resize; z-index: 1; background: #ececec; + &:hover { + background-color: rgb(33, 150, 243); + } } diff --git a/components/apolloTable/component/RightDragFixed.tsx b/components/apolloTable/component/RightDragFixed.tsx index 655cb822e6487df6f4b96b7929ddb0b540c1347e..22e1f5273018a1ccdb8108607d8efcccf6f7f917 100644 --- a/components/apolloTable/component/RightDragFixed.tsx +++ b/components/apolloTable/component/RightDragFixed.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { ResizableBox } from 'react-resizable'; import styles from './DragFixed.less'; +import { getCache, saveCache } from '../utils/cache'; const DragFixed = (props: any) => { const { @@ -13,6 +14,7 @@ const DragFixed = (props: any) => { columns, onResizeStop, paddingRight, + cachedFeAttr, } = props; // 表格 const container: any = document.querySelector(`#apolloTable_${tableId}`); @@ -124,6 +126,16 @@ const DragFixed = (props: any) => { item.fixed = ''; } } + if (cachedFeAttr) { + const cachedCols = getCache({ tableId }); + if (cachedCols) { + cachedCols[item.columnName] = { + ...cachedCols[item.columnName], + fixed: item.fixed, + }; + saveCache({ tableId, data: cachedCols }); + } + } newColumns.push(item); }); if (typeof onResizeStop === 'function') { diff --git a/components/apolloTable/component/Table.tsx b/components/apolloTable/component/Table.tsx index 576cf53d6989d04f16d4bd9fdd751874eec8de46..033796cf07feb9c10eabf9642926d2205b3bcdb8 100644 --- a/components/apolloTable/component/Table.tsx +++ b/components/apolloTable/component/Table.tsx @@ -14,7 +14,15 @@ import RightDragFixed from './RightDragFixed'; import DragSorted from './DragSorted'; import DragResized from './DragResized'; import { getMergeClassName, getMergeStyle } from '../utils/utils'; -import { saveCache, getCache } from '../utils/cache'; +import { + getLeftColumns, + getRightColumns, + getShowColumns, + getLeftWidth, + getTotalWidth, + getFormatColumns, +} from '../utils/memCols'; +import { getDefaultTableConfig } from './defaultConfig'; import { Consumer } from './context'; const borderStyle = '1px solid #ececec'; @@ -64,127 +72,23 @@ export default class AirTable extends Component { constructor(props: TableProps) { super(props); - const { columns, dataSource, width = 0, height = 0, rowHeight, headerHeight, columnWidth } = props; + const { columns, dataSource, width, height } = props; this.state = { columns, dataSource, - tableWidth: width, - tableHeight: height, + tableWidth: width || 0, + tableHeight: height || 0, }; - this.config = { - overscanColumnCount: 5, - overscanRowCount: 5, - columnWidth: columnWidth || 150, - rowHeight: rowHeight || 80, - headerHeight: headerHeight || 60, - }; - this.memoizeFormatColumns = memoizeOne(this.getFormatColumns); - this.memoizeLeftColumns = memoizeOne(this.getLeftColumns); - this.memoizeRightColumns = memoizeOne(this.getRightColumns); - this.memoizeColumns = memoizeOne(this.getShowColumns); - - this.memoizeLeftWidth = memoizeOne(this.getLeftWidth); - this.memoizeTotalWidth = memoizeOne(this.getTotalWidth); - + this.config = getDefaultTableConfig(props); + this.memoizeFormatColumns = memoizeOne(getFormatColumns); + this.memoizeLeftColumns = memoizeOne(getLeftColumns); + this.memoizeRightColumns = memoizeOne(getRightColumns); + this.memoizeColumns = memoizeOne(getShowColumns); + this.memoizeLeftWidth = memoizeOne(getLeftWidth); + this.memoizeTotalWidth = memoizeOne(getTotalWidth); this.memoizeData = memoizeOne(this.filterData); } - // 格式化列数据(添加缓存的前端属性) - getFormatColumns = (columns: ColumnProps[]) => { - columns.sort((a, b) => { - return a.orderNo - b.orderNo; - }); - const { cachedFeAttr, tableId } = this.props; - if (cachedFeAttr) { - const cachedCols = getCache({ tableId }); - if (cachedCols) { - columns = columns.map((item: any) => { - return { - ...item, - ...cachedCols[item.columnName], - }; - }); - } else { - const data: any = {}; - columns.map((item: any) => { - data[item.columnName] = { - columnName: item.columnName, - width: item.width, - align: item.align, - fixed: item.fixed, - hideScope: item.hideScope, - orderNo: item.orderNo, - }; - }); - saveCache({ tableId, data }); - } - } - return columns; - }; - - // 获取左侧固定列数量 - getLeftColumns = (columns: ColumnProps[]) => { - return columns.filter((item) => { - return !!item.showStatus && item.fixed && item.fixed !== 'right'; - }); - }; - - // 获取右侧固定列数量 - getRightColumns = (columns: ColumnProps[]) => { - return columns.filter((item) => { - return !!item.showStatus && item.fixed === 'right'; - }); - }; - - // 获取表格显示列 - getShowColumns = (columns: ColumnProps[]) => { - return columns.filter((item) => { - return !!item.showStatus && (!item.hideScope || item.hideScope.indexOf('LIST') === -1); - }); - }; - - // 获取左侧固定列总宽度 - getLeftWidth = (leftColumns: ColumnProps[], columns: ColumnProps[]) => { - const { tableWidth = 0 } = this.state; - const { totalWidth, configWidth, defaultWidthLen } = this.memoizeTotalWidth(columns); - const { columnWidth } = this.config; - let colWidth = columnWidth; - if (totalWidth < tableWidth) { - colWidth = _.floor((tableWidth - configWidth) / defaultWidthLen); - } - let total = 0; - leftColumns.map((item) => { - total += item.width || colWidth; - }); - return total; - }; - - // 获取右侧列总宽度 - getTotalWidth = (columns: ColumnProps[]) => { - const { columnWidth } = this.config; - let configWidth = 0; - let configWidthLen = 0; - let defaultWidth = 0; - let defaultWidthLen = 0; - columns.map((item: any) => { - if (item.width) { - configWidth += item.width; - configWidthLen += 1; - } else { - defaultWidth += columnWidth; - defaultWidthLen += 1; - } - }); - const totalWidth = configWidth + defaultWidth; - return { - configWidth, - defaultWidth, - totalWidth, - configWidthLen, - defaultWidthLen, - }; - }; - // 获取表格显示数据 filterData = (columns: ColumnProps[], dataSource: RowProps[]) => { if (columns.length === 0 || dataSource.length === 0) { @@ -208,8 +112,8 @@ export default class AirTable extends Component { { index }: { index: number }, ) => { const { tableWidth = 0 } = this.state; - const { totalWidth, configWidth, defaultWidthLen } = this.memoizeTotalWidth(columns); const { columnWidth } = this.config; + const { totalWidth, configWidth, defaultWidthLen } = this.memoizeTotalWidth(columns, columnWidth); let colWidth = columnWidth; if (totalWidth < tableWidth) { colWidth = _.floor((tableWidth - configWidth) / defaultWidthLen); @@ -299,19 +203,29 @@ export default class AirTable extends Component { this.grid4.scrollToCell({ columnIndex: showColumns.length - 1 }); } }; + // 拖拽自定义固定列后置动作 + onResizeStopRightDragFixed = ({ columns }) => { + this.setState( + { + columns, + }, + () => { + this.grid5 && this.grid5.recomputeGridSize(); + this.grid6 && this.grid6.recomputeGridSize(); + }, + ); + }; // 拖拽滚动表格 onScrollHor = (direction: string, step: number) => { // 拖动超过视图范围,将表格左右滚动 if (this.grid4) { if (direction === 'right') { if (this.grid4.state.scrollLeft >= this.grid4.getTotalColumnsWidth() - this.state.tableWidth - 100) { - console.log('已经到最右侧了'); return; } this.grid4.scrollToPosition({ scrollLeft: this.grid4.state.scrollLeft + step }); } else { if (this.grid4.state.scrollLeft <= 0) { - console.log('已经到最左侧了'); return; } this.grid4.scrollToPosition({ scrollLeft: this.grid4.state.scrollLeft - step }); @@ -383,6 +297,7 @@ export default class AirTable extends Component { } = showColumns[columnIndex]; return ( { onDropFinish={this.onDragSorted} onScroll={this.onScrollHor} className={styles.headerCell} - key={key} canDrag={!!onDragSorted} tableId={tableId} > @@ -523,11 +437,11 @@ export default class AirTable extends Component { }; render() { - const { loading, noDataPlaceholder, loadComp, canFixed, tableId } = this.props; + const { loading, noDataPlaceholder, loadComp, canFixed, tableId, cachedFeAttr } = this.props; const { columns, dataSource, tableWidth = 0, tableHeight = 0 } = this.state; const { overscanColumnCount, overscanRowCount, rowHeight, headerHeight, columnWidth } = this.config; const scrollbarWidth = scrollbarSize() || 0; - const formatColumns = this.memoizeFormatColumns(columns); + const formatColumns = this.memoizeFormatColumns(columns, cachedFeAttr, tableId); const showColumns = this.memoizeColumns(formatColumns); const leftColumns = this.memoizeLeftColumns(showColumns); const rightColumns = this.memoizeRightColumns(showColumns); @@ -540,10 +454,10 @@ export default class AirTable extends Component { const rightCount = rightColumns.length; const columnCount = showColumns.length; const rowCount = showData.length; - const leftWidth = this.memoizeLeftWidth(leftColumns, showColumns); - const rightWidth = this.memoizeLeftWidth(rightColumns, showColumns); - let totalHeight: number = tableHeight - headerHeight; - const { totalWidth } = this.memoizeTotalWidth(showColumns); + const leftWidth = this.memoizeLeftWidth(leftColumns, showColumns, columnWidth, tableWidth); + const rightWidth = this.memoizeLeftWidth(rightColumns, showColumns, columnWidth, tableWidth); + const totalHeight: number = tableHeight - headerHeight; + const { totalWidth } = this.memoizeTotalWidth(showColumns, columnWidth); let realWidth = tableWidth; let paddingRight = 0; if (rowCount > 0 && rowCount * rowHeight > totalHeight) { @@ -653,6 +567,7 @@ export default class AirTable extends Component { columns={columns} onResizeStart={this.onResizeStartLeftDragFixed} onResizeStop={this.onResizeStopLeftDragFixed} + cachedFeAttr={cachedFeAttr} /> )}
@@ -756,7 +671,8 @@ export default class AirTable extends Component { columns={columns} paddingRight={paddingRight} onResizeStart={this.onResizeStartRightDragFixed} - onResizeStop={this.onResizeStopLeftDragFixed} + onResizeStop={this.onResizeStopRightDragFixed} + cachedFeAttr={cachedFeAttr} /> )} {totalWidth > tableWidth && rightCount > 0 && ( diff --git a/components/apolloTable/component/defaultConfig.ts b/components/apolloTable/component/defaultConfig.ts new file mode 100644 index 0000000000000000000000000000000000000000..554e91bdf42be641a641a4c052b15955595aee92 --- /dev/null +++ b/components/apolloTable/component/defaultConfig.ts @@ -0,0 +1,10 @@ +export const getDefaultTableConfig = (config: any) => { + const { rowHeight, headerHeight, columnWidth } = config; + return { + overscanColumnCount: 5, + overscanRowCount: 5, + columnWidth: columnWidth || 150, + rowHeight: rowHeight || 80, + headerHeight: headerHeight || 60, + }; +}; diff --git a/components/apolloTable/utils/memCols.ts b/components/apolloTable/utils/memCols.ts new file mode 100644 index 0000000000000000000000000000000000000000..dc3f232b335a886b47bc253436c814627f2b5219 --- /dev/null +++ b/components/apolloTable/utils/memCols.ts @@ -0,0 +1,100 @@ +import memoizeOne from 'memoize-one'; +import { ColumnProps } from '../component/interface'; +import { getCache, saveCache } from '@/submodule/components/apolloTable/utils/cache'; + +// 获取左侧固定列数量 +export const getLeftColumns = (columns: ColumnProps[]) => { + return columns.filter((item) => { + return !!item.showStatus && item.fixed && item.fixed !== 'right'; + }); +}; + +// 获取右侧固定列数量 +export const getRightColumns = (columns: ColumnProps[]) => { + return columns.filter((item) => { + return !!item.showStatus && item.fixed === 'right'; + }); +}; + +// 获取表格显示列 +export const getShowColumns = (columns: ColumnProps[]) => { + return columns.filter((item) => { + return !!item.showStatus && (!item.hideScope || item.hideScope.indexOf('LIST') === -1); + }); +}; + +// 获取右侧列总宽度 +export const getTotalWidth = (columns: ColumnProps[], columnWidth: number) => { + let configWidth = 0; + let configWidthLen = 0; + let defaultWidth = 0; + let defaultWidthLen = 0; + columns.map((item: any) => { + if (item.width) { + configWidth += item.width; + configWidthLen += 1; + } else { + defaultWidth += columnWidth; + defaultWidthLen += 1; + } + }); + const totalWidth = configWidth + defaultWidth; + return { + configWidth, + defaultWidth, + totalWidth, + configWidthLen, + defaultWidthLen, + }; +}; + +// 获取左侧固定列总宽度 +export const getLeftWidth = ( + leftColumns: ColumnProps[], + columns: ColumnProps[], + columnWidth: number, + tableWidth: number, +) => { + const { totalWidth, configWidth, defaultWidthLen } = memoizeOne(getTotalWidth(columns, columnWidth)); + let colWidth = columnWidth; + if (totalWidth < tableWidth) { + colWidth = Math.floor((tableWidth - configWidth) / defaultWidthLen); + } + let total = 0; + leftColumns.map((item) => { + total += item.width || colWidth; + }); + return total; +}; + +// 格式化列数据(添加缓存的前端属性) +export const getFormatColumns = (columns: ColumnProps[], cachedFeAttr: boolean, tableId: number | string) => { + columns.sort((a, b) => { + return a.orderNo - b.orderNo; + }); + if (cachedFeAttr) { + const cachedCols = getCache({ tableId }); + if (cachedCols) { + columns = columns.map((item: any) => { + return { + ...item, + ...cachedCols[item.columnName], + }; + }); + } else { + const data: any = {}; + columns.map((item: any) => { + data[item.columnName] = { + columnName: item.columnName, + width: item.width, + align: item.align, + fixed: item.fixed, + hideScope: item.hideScope, + orderNo: item.orderNo, + }; + }); + saveCache({ tableId, data }); + } + } + return columns; +};