import { forEach, remove } from 'lodash'; import { AndOr, CellType, ColumnFilter, ColumnGroup, ColumnLocation, DragDirection, IndexColumn, IndexRow, RowData, RowSelectionStatus, } from '@/lib/types'; import { markRaw } from '@vue/composition-api'; import { GroupPin, GroupSelection } from '@/lib/types/group'; import { StoreState } from '@/lib/store/types'; import { RowIndex, RowSelection, TotalBar, TreeData } from '@/lib/types/feature'; import { fnData, removeBy } from '@/lib/utils/object'; import Vue from 'vue'; import { log } from '@/lib/utils/log'; /** * 对于 store state 的最细粒度修改 * @param state */ export const createMutation = (state: StoreState) => ({ setIdKey(idKey: string) { state.config.idKey = idKey; }, setRowSelection(rowId: string, rowSelection: RowSelectionStatus) { if (state.index.rowSelection[rowId]) { state.index.rowSelection[rowId] = rowSelection; } else { Vue.set(state.index.rowSelection, rowId, rowSelection); } }, setTreeFuture(treeData: Partial) { fnData(state.featureConfig, 'treeData', markRaw(treeData)); }, deleteRows(rowIds: string[]) { // 对 index 修改 forEach(rowIds, (id) => { removeBy(state.index.rowRecord, id); removeBy(state.index.data2D, id); removeBy(state.index.rowSelection, id); remove(state.index.rowIndex2Id, (n) => n === id); removeBy(state.columnTotal, id); }); }, setRowSelectionFuture(rowSelection: Partial) { fnData(state.featureConfig, 'rowSelection', markRaw(rowSelection)); }, setRowIndexFuture(rowIndex: Partial) { fnData(state.featureConfig, 'rowIndex', markRaw(rowIndex)); }, setTotalBarFuture(totalBar: Partial) { fnData(state.featureConfig, 'totalBar', markRaw(totalBar)); }, setIndexColumnRecord( indexColumnRecord: Record, columnId2Index: Record, columnId2Field: Record, ) { log(`[mutation][setIndexColumnRecord]`); state.index.columnRecord = indexColumnRecord; state.index.columnId2Index = columnId2Index; state.index.columnId2Field = markRaw(columnId2Field); }, setIndexColumnGroup(left: ColumnGroup, right: ColumnGroup, scroll: ColumnGroup) { log(`[mutation][setIndexColumnGroup]`); state.index.columnGroupRecord = { left, right, scroll, }; }, setIndexRow(rowRecord: Record, rowIndex2Id: string[]) { log(`[mutation][setIndexRow]`); Object.defineProperty(state.index, 'rowRecord', { configurable: false, value: rowRecord, }); Object.defineProperty(state.index, 'rowIndex2Id', { configurable: false, value: rowIndex2Id, }); }, setViewRow(rowRecord: Record, rowIndex2Id: string[]) { log(`[mutation][setViewRow]`); state.view.rowRecord = rowRecord; state.view.rowIndex2Id = markRaw(rowIndex2Id); }, setIndexData(editingDataRecord: Record) { log(`[mutation][setIndexData]`); state.index.data2D = editingDataRecord; }, setTableWidthAndHeight(width: number, height: number, autoHeight?: boolean) { log(`[mutation][setTableWidthAndHeight]`); state.config.width = width; state.config.height = height; if (autoHeight !== undefined) { state.config.autoHeight = autoHeight; } }, setRowHeight(height: number) { log(`[mutation][setRowHeight]`); state.config.rowHeight = height; }, setHeaderHeight(headerHeight: number, headerGroupLevel: number) { log(`[mutation][setHeaderHeight]`); state.config.headerHeight = headerHeight; state.config.headerGroupLevel = headerGroupLevel; }, setBodyViewHeight(bodyViewHeight: number) { log(`[mutation][setBodyViewHeight]`); state.config.bodyViewHeight = bodyViewHeight; }, setBodyHeight(bodyHeight: number) { log(`[mutation][setBodyHeight]`); state.config.bodyHeight = bodyHeight; }, changeVirtualScroll(startIndex: number, endIndex: number) { if ( startIndex === state.virtualScroll.y.startIndex && endIndex === state.virtualScroll.y.endIndex ) { return; } log(`[mutation][changeVirtualScroll]${startIndex}-${endIndex}`); state.virtualScroll.y = { startIndex, endIndex, }; }, changeVirtualScrollX(startXLeft: number, endXLeft: number) { if ( startXLeft === state.virtualScroll.xStartLeft && endXLeft === state.virtualScroll.xEndLeft ) { return; } log(`[mutation][changeVirtualScrollX]`); state.virtualScroll.xStartLeft = startXLeft; state.virtualScroll.xEndLeft = endXLeft; }, inactiveClicked() { log(`[mutation][inactiveClicked]`); state.activeStatus.clickedBodyCell = null; }, clickedBodyCell(pin: GroupPin, rowId: string, columnId: string) { if ( state.activeStatus.clickedBodyCell?.pin === pin && state.activeStatus.clickedBodyCell?.columnId === columnId && state.activeStatus.clickedBodyCell?.rowId === rowId ) { return; } log(`[mutation][clickedBodyCell]`); state.activeStatus.dbClickedBodyCell = null; state.activeStatus.clickedBodyCell = markRaw({ columnId, rowId, pin }); }, dbClickedBodyCell(pin: GroupPin, rowId: string, columnId: string) { log(`[mutation][dbClickedBodyCell]`); if ( state.activeStatus.dbClickedBodyCell?.pin === pin && state.activeStatus.dbClickedBodyCell?.columnId === columnId && state.activeStatus.dbClickedBodyCell?.rowId === rowId ) { return; } state.activeStatus.clickedBodyCell = null; state.activeStatus.dbClickedBodyCell = markRaw({ columnId, rowId, pin }); }, activeRightMenu(top: number, left: number) { log(`[mutation][activeRightMenu]`); state.rightMenu.active = true; state.rightMenu.top = top; state.rightMenu.left = left; }, inactiveRightMenu() { log(`[mutation][inactiveRightMenu]`); state.rightMenu.active = false; state.rightMenu.top = -1; state.rightMenu.left = -1; }, triggerSelectingChanging(changing: boolean) { log(`[mutation][triggerSelectingChanging]`); state.selectionStatus.changing = changing; }, triggerCalculationChanging(changing: boolean) { log(`[mutation][triggerCalculationChanging]`); state.dragCalculateStatus.changing = changing; }, activeSelecting(rowId: string, columnId: string) { log(`[mutation][activeSelecting]`); const rowIndex = state.view.rowRecord[rowId].index; const column = state.index.columnRecord[columnId]; state.selectionStatus.startRowIndex = rowIndex; state.selectionStatus.endRowIndex = rowIndex; state.selectionStatus.startColumn = markRaw({ pin: column.pin, index: column.index, }); state.selectionStatus.endColumn = markRaw({ pin: column.pin, index: column.index, }); log('[action] activeSelecting', rowIndex, `${column.pin}_${column.index}`); }, updateSelecting(rowId: string, columnId: string) { const rowIndex = state.view.rowRecord[rowId].index; const column = state.index.columnRecord[columnId]; // 防止插入重复数据,引发不必要渲染 if ( state.selectionStatus.endRowIndex === rowIndex && column.pin === state.selectionStatus.endColumn.pin && column.index === state.selectionStatus.endColumn.index ) { return; } log(`[mutation][updateSelecting]`); state.selectionStatus.endRowIndex = rowIndex; state.selectionStatus.endColumn = markRaw({ pin: column.pin, index: column.index, }); log('[mutation] updateSelecting', `${column.pin}_${column.index}`); }, updateSelectArea({ leftArea, rightArea, scrollArea, }: { leftArea: undefined | GroupSelection; rightArea: undefined | GroupSelection; scrollArea: undefined | GroupSelection; }) { log(`[mutation][updateSelectArea]`); state.selectionStatus.active = true; state.selectionStatus.leftArea = { hit: false }; state.selectionStatus.rightArea = { hit: false }; state.selectionStatus.scrollArea = { hit: false }; if (leftArea) { state.selectionStatus.leftArea = leftArea; } if (rightArea) { state.selectionStatus.rightArea = rightArea; } if (scrollArea) { state.selectionStatus.scrollArea = scrollArea; } log('[mutation]updateSelectArea', [leftArea, scrollArea, rightArea]); }, destroySelecting() { log(`[mutation][destroySelecting]`); state.selectionStatus.active = false; state.selectionStatus.leftArea = { hit: false, }; state.selectionStatus.rightArea = { hit: false, }; state.selectionStatus.scrollArea = { hit: false, }; }, activeDragCalculate( columnIndex: number, rowIndex: number, pin: GroupPin, direction: DragDirection, ) { log(`[mutation][activeDragCalculate]`); state.dragCalculateStatus.direction = direction; state.dragCalculateStatus.startRowIndex = rowIndex; state.dragCalculateStatus.endRowIndex = rowIndex; state.dragCalculateStatus.startColumn = markRaw({ pin: pin, index: columnIndex, }); state.dragCalculateStatus.endColumn = markRaw({ pin: pin, index: columnIndex, }); log( '[action][DragCalculate] activeDragCalculate', rowIndex, `${pin.toString()}_${columnIndex}_${rowIndex}`, ); }, updateDragCalculate(columnIndex: number, rowIndex: number, pin: GroupPin) { // 防止插入重复数据,引发不必要渲染 if ( state.dragCalculateStatus.endRowIndex === rowIndex && pin.toString() === state.dragCalculateStatus.endColumn.pin && columnIndex === state.dragCalculateStatus.endColumn.index ) { return; } log(`[mutation][updateDragCalculate]`); state.dragCalculateStatus.endRowIndex = rowIndex; state.dragCalculateStatus.endColumn = markRaw({ pin: pin, index: columnIndex, }); log( '[action][DragCalculate] updateDragCalculate', `${pin.toString()}_${columnIndex}_${rowIndex}`, ); }, destroyDragCalculate() { log(`[mutation][destroyDragCalculate]`); state.dragCalculateStatus.active = false; state.dragCalculateStatus.leftArea = { hit: false, }; state.dragCalculateStatus.rightArea = { hit: false, }; state.dragCalculateStatus.scrollArea = { hit: false, }; }, updateDragCalculateArea({ leftArea, rightArea, scrollArea, }: { leftArea: undefined | GroupSelection; rightArea: undefined | GroupSelection; scrollArea: undefined | GroupSelection; }) { log(`[mutation][updateDragCalculateArea]`); state.dragCalculateStatus.active = true; state.dragCalculateStatus.leftArea = { hit: false }; state.dragCalculateStatus.rightArea = { hit: false }; state.dragCalculateStatus.scrollArea = { hit: false }; if (leftArea) { state.dragCalculateStatus.leftArea = leftArea; } if (rightArea) { state.dragCalculateStatus.rightArea = rightArea; } if (scrollArea) { state.dragCalculateStatus.scrollArea = scrollArea; } log('[mutation]updateSelectArea', [leftArea, scrollArea, rightArea]); }, changeData2DType(rowId: string, columnId: string, type: CellType) { state.index.data2D[rowId].fieldData[columnId].type = type; }, inputEditingValue(rowId: string, columnId: string, value: string | number | boolean) { log(`[mutation][inputEditingValue]`); state.index.data2D[rowId].fieldData[columnId].value = value; }, setFilters(columnFilters: Record, adnOr: AndOr) { state.filter.filters = columnFilters; state.filter.andOr = adnOr; }, setColumnTotal(columnId: string, value: string | Object) { if (state.columnTotal[columnId] !== undefined) { state.columnTotal[columnId] = value; } else { Vue.set(state.columnTotal, columnId, value); } }, });