import { ColumnGroupRecord, IndexColumn, IndexColumnWithoutIndexStatus, } from '@/lib/types'; import { assign, groupBy, map, sortBy, sumBy, values, find, findLast } from 'lodash'; import { COLUMN_MAX_WIDTH, COLUMN_MIN_WIDTH } from '@/lib/constants/dom-fixed'; import { ORDER_COLUMN_KEY, SELECTION_COLUMN_KEY } from '@/lib/constants/filler'; import { GroupPin } from '@/lib/types/group'; const getDefaultColumnGroupRecord = (): ColumnGroupRecord => ({ scroll: { ids: [], width: 0, }, left: { ids: [], width: 0, }, right: { ids: [], width: 0, }, }); const calculateColumnLeftAndIndex = ( columns: IndexColumnWithoutIndexStatus[], ): { indexColumn: IndexColumnWithoutIndexStatus[]; columnId2Index: Record; columnId2Field: Record; } => { let widthCount = 0; const columnsWithLeft = [] as IndexColumnWithoutIndexStatus[]; const columnId2Index = {} as Record; const columnId2Field = {} as Record; columns.forEach((itm, index) => { columnId2Index[itm.id as keyof typeof columnId2Index] = index; columnId2Field[itm.id as keyof typeof columnId2Index] = itm.field; columnsWithLeft.push({ ...itm, left: widthCount, index, }); widthCount = widthCount + itm.width; }); return { indexColumn: columnsWithLeft, columnId2Index, columnId2Field, }; }; const getColumnRecordWithIndexInfo = ( columnRecord: IndexColumnWithoutIndexStatus[], columnGroupRecord: ColumnGroupRecord, ) => { const featureColumnIds = [SELECTION_COLUMN_KEY, ORDER_COLUMN_KEY]; const firstLeftId = find( columnGroupRecord.left.ids, (item) => !featureColumnIds.includes(item), ); const lastLeftId = findLast( columnGroupRecord.left.ids, (item) => !featureColumnIds.includes(item), ); const firstScrollId = columnGroupRecord.scroll?.ids[0]; const lastScrollId = columnGroupRecord.scroll?.ids[columnGroupRecord.right?.ids.length - 1]; const firstRightId = columnGroupRecord.right?.ids[0]; const lastRightId = columnGroupRecord.right?.ids[columnGroupRecord.right?.ids.length - 1]; const firstId = firstLeftId || firstScrollId || firstRightId; const lastId = lastRightId || lastScrollId || lastLeftId; return map(columnRecord, (column) => { if (column.pin === GroupPin.left) { return { ...column, isFirst: column.id === firstId, isLast: column.id === lastId, isLastInGroup: column.id === firstLeftId, isFirstInGroup: column.id === lastLeftId, }; } if (column.pin === GroupPin.scroll) { return { ...column, isFirst: column.id === firstId, isLast: column.id === lastId, isLastInGroup: column.id === lastScrollId, isFirstInGroup: column.id === firstScrollId, }; } if (column.pin === GroupPin.right) { return { ...column, isFirst: column.id === firstId, isLast: column.id === lastId, isLastInGroup: column.id === lastRightId, isFirstInGroup: column.id === firstRightId, }; } }); }; export const calculateAllColumnLeftAndIndex = ( columns: IndexColumnWithoutIndexStatus[], ): { columnRecord: Record; columnGroupRecord: ColumnGroupRecord; columnId2Index: Record; columnId2Field: Record; } => { // 分组计算 const columnGroup = groupBy(columns, 'pin'); const fixedIndexColumns = [] as IndexColumnWithoutIndexStatus[]; const allColumnId2Index = {} as Record; const allColumnId2Field = {} as Record; const columnGroupRecord = getDefaultColumnGroupRecord(); Object.keys(columnGroup).forEach((key: IndexColumn['pin']) => { const { indexColumn, columnId2Index, columnId2Field } = calculateColumnLeftAndIndex( columnGroup[key], ); fixedIndexColumns.push(...indexColumn); assign(allColumnId2Index, columnId2Index); assign(allColumnId2Field, columnId2Field); const columnPinGroup = { ids: map(indexColumn, 'id'), width: sumBy(indexColumn, 'width'), }; if (key === GroupPin.scroll) { columnGroupRecord.scroll = columnPinGroup; } else { columnGroupRecord[key] = columnPinGroup; } }); // column 排序 确认 索引 const indexColumnRecord = getColumnRecordWithIndexInfo( fixedIndexColumns, columnGroupRecord, ).reduce((acc, indexColumn) => { return { ...acc, [indexColumn.id]: indexColumn, }; }, {}); return { columnGroupRecord, columnRecord: indexColumnRecord, columnId2Index: allColumnId2Index, columnId2Field: allColumnId2Field, }; }; export const resetColumnWidth = (columnRecord: Record) => { return (id: string, changeWidth: number) => { const targetWidth = columnRecord[id].width + changeWidth; if (targetWidth < COLUMN_MIN_WIDTH || targetWidth > COLUMN_MAX_WIDTH) { return null; } columnRecord[id].width = columnRecord[id].width + changeWidth; const sortedColumns = sortBy(values(columnRecord), 'index'); return calculateAllColumnLeftAndIndex(sortedColumns); }; };