import {type Options, type Column, type Record} from "./type" import RowColumnSelection from "./RowColumnSelection"; import { getCurrentInstance } from 'vue' import { isNumber, isUndeOrNull } from "./util"; export default class Sort extends RowColumnSelection { constructor(options: Options){ super(options) this.internalInstance = getCurrentInstance() } internalInstance: any; sortHandel(column: Column) { const index = this.tileColumns.value.findIndex(item => item.sortKey === column.sortKey) if (!column.sorter) return; this.tileColumns.value.forEach(item => { if(item !== column) item.sortOrder = undefined }); if(this.selectedState.cells){ this.sorterBeforeSelectedKeys = undefined; } else { this.sorterBeforeSelectedKeys = this.getSelectRows().map(row => row[this.props.rowKey]).filter(v => v !== undefined); } const nextSortOrder = column.sortOrder === 'ascend' ? 'descend' : column.sortOrder === 'descend' ? false : 'ascend' // 开启服务端排序 if (this.props.serviceSorter) { this.resetSelectedState(); this.tileColumns.value[index].sortOrder = nextSortOrder this.emitChange('sort'); return; } if(typeof column.sorter === 'function') { this.dataSource.value.sort(column.sorter) } else { if (column.sortOrder === 'ascend') { this.dataSource.value.sort(this.descendHandel(column)) } else if (column.sortOrder === 'descend'){ this.restoreSort() } else { this.sorterBeforeDataKeys = this.dataSource.value.map(row => row[this.props.rowKey]).filter(v => v !== undefined); this.dataSource.value.sort(this.ascendHandel(column)) } } this.tileColumns.value[index].sortOrder = nextSortOrder // 转换选择行的记录 if (this.sorterBeforeSelectedKeys?.length) { this.resetSelectedState() this.selectedState.rows = this.dataSource.value.map((row, rowindex) => { if(this.sorterBeforeSelectedKeys?.includes(row[this.props.rowKey])) return rowindex }).filter(v => v !== undefined) as number[] } else if (this.sorterBeforeSelectedKeys === undefined){ this.resetSelectedState() } // 本地排序完成后回调 if (typeof column.sortCallback === 'function') { column.sortCallback(nextSortOrder, column, this.dataSource.value) } if (typeof this.props.sortCallback === 'function') { this.props.sortCallback(nextSortOrder, column, this.dataSource.value) } } // 排序前的选择行的key顺序 sorterBeforeSelectedKeys?: any[] // 排序前的key顺序 private sorterBeforeDataKeys: any[] = [] // 升序 private ascendHandel(column: Column){ return (a: Record, b: Record) => { // 空行不参与排序 if (this.props.keepLastRowEmpty) { const lastRow = this.dataSource.value.at(-1) if (a === lastRow ){ return 0; } } const param1 = column.sortValue?.(column, a) ?? this.getValueByModel(column.dataIndex, a); const param2 = column.sortValue?.(column, b) ?? this.getValueByModel(column.dataIndex, b); // 空数据都将排列在最后 if (isUndeOrNull(param1) || param1 === '') return 1; if (isUndeOrNull(param2) || param2 === '') return -1; return this.sorterComper(param1, param2, 'ascend') }; } // 降序 private descendHandel(column: Column){ return (a: Record, b: Record) => { // 空行不参与排序 if (this.props.keepLastRowEmpty) { const lastRow = this.dataSource.value.at(-1) if (a === lastRow ){ return 0; } } const param1 = column.sortValue?.(column, a) ?? this.getValueByModel(column.dataIndex, a); const param2 = column.sortValue?.(column, b) ?? this.getValueByModel(column.dataIndex, b); // 空数据都将排列在最后 if (isUndeOrNull(param1) || param1 === '') return 1; if (isUndeOrNull(param2) || param2 === '') return -1; return this.sorterComper(param1, param2, 'descend') }; } // 比较函数 private sorterComper(a: number | string = 0, b: number | string = 0, type: 'ascend' | 'descend'){ if (isNumber(a) && isNumber(b)) { return type === 'ascend' ? Number(a) - Number(b) : Number(b) - Number(a); } else { a = a.toString() b = b.toString() // 都以数字结尾时 if(/\d$/.test(a) && /\d$/.test(b)){ const beforeA = a.slice(0, a.match(/\d+$/)!.index); const beforeB = b.slice(0, b.match(/\d+$/)!.index); // 前半部分相同时 if (beforeA === beforeB) { const afterA = Number(a.match(/\d+$/)![0]) const afterB = Number(b.match(/\d+$/)![0]) return type === 'ascend' ? afterA - afterB : afterB - afterA; } } return type === 'ascend' ? a.localeCompare(b) : b.localeCompare(a) } } // 取消排序 private restoreSort(){ let newFragment: any[] = [] this.dataSource.value.forEach(row => { newFragment.push(row) const index = this.sorterBeforeDataKeys.findIndex(key => key === row[this.props.rowKey]); if(index >= 0) { this.sorterBeforeDataKeys.splice(index, 1, ...newFragment) newFragment = [] } }) if(newFragment.length){ this.sorterBeforeDataKeys.push(...newFragment); } // 排序前数据(含插入新行数据、不含已删除的数据) const data = this.sorterBeforeDataKeys.filter(item => typeof item !== 'string') this.dataSource.value.splice(0, this.dataSource.value.length, ...data) this.sorterBeforeDataKeys = [] } }