fastlion-amis
Version:
一种MIS页面生成工具
177 lines (167 loc) • 7.66 kB
text/typescript
import { Condition } from "../../components/table/SecondFilter/types"
import { sortFn, filterFn } from "../../utils/utils"
import { numberFormatter } from "../../utils/helper"
import { IColumn as ITableColumn } from "../table"
import { IColumn as IBiTableColumn } from "../lionBiTable"
import { DATAKEYID } from "../crud"
import union from 'lodash/union'
import intersection from 'lodash/intersection'
import { isNil, flatMap } from "lodash"
type IColumn = ITableColumn | IBiTableColumn
export const CROSS_SPLIT_CHAR = '·'
export function handleSort(items: any[], columnNames: string[], orderMap: Map<string, { order?: 'asc' | 'desc', map?: object }>, modifiedData?: any) {
if (columnNames.length > 0) {
const name = columnNames.pop() ?? ''
items = items.sort((pre, next) => {
const map = orderMap.get(name)?.map
const order = orderMap.get(name)?.order
// 如果有编辑数据 用编辑数据排序 否则用正常的数据排序
// 判断字段类型是否是map,是的话取map值来排序
const preData = modifiedData?.[pre[DATAKEYID]] ? modifiedData[pre[DATAKEYID]]?.[name] : map ? map[pre[name]] : pre[name]
const nextData = modifiedData?.[next[DATAKEYID]] ? modifiedData[next[DATAKEYID]]?.[name] : map ? map[next[name]] : next[name]
return sortFn(preData, nextData, order)
})
handleSort(items, columnNames, orderMap, modifiedData)
}
return items
}
export function handleFilter(items: any[], columnNames: string[], filterMap: Map<string, { condition: Condition, value1?: string, value2?: string, value3?: string, relation?: 'and' | 'or' }[]>, caseSensitive = false) {
if (columnNames.length > 0) {
const name = columnNames.pop() ?? ''
const filters = filterMap.get(name)
if (filters) {
let temps: any[] = []
for (let i = 0; i < filters.length; i++) {
const filter = filters[i]
const relation = filters[i - 1]?.relation
const arr = filterFn(items.slice(), name, filter.condition, filter.value3 ?? filter.value1, filter.value2, caseSensitive)
if (relation == 'and') {
temps = intersection(temps, arr)
} else if (relation == 'or') {
temps = union(temps, arr)
} else {
temps = arr
}
}
items = handleFilter(temps, columnNames, filterMap)
}
}
return items
}
export function getHeadRows(filtedColumns: IColumn[]) {
if (filtedColumns.length <= 0) return []
const groupNames = filtedColumns.map(column => column.groupName.length > 0 ? column.groupName.split(',').length : 0)
const level = Math.max(...groupNames) + 1
const columns = filtedColumns.map((column, index) => {
if (column.type == '__checkme' || column.type == '__expandme' || column.type == '__pseudoColumn') {
const name = column.type == '__checkme' ? 'SF_CHECK' : 'SF_PSEUDO'
return { ...column, name: name, groupName: new Array(level - 1).fill(name).join(',') }
}
const name = column.name || ('空' + (index || ''))
const groupNameArr = column.groupName.split(',')
const diff = level - 1 - groupNameArr.length
const groupName = column.groupName.length == 0 ? new Array(level - 1).fill(name).join(',') : column.groupName.split(',').concat(new Array(diff).fill(groupNameArr[groupNameArr.length - 1])).join(',')
return { ...column, name, groupName: level > 1 ? groupName : '' }
})
const rows: { name: string, label: string, colspan: number, rowspan: number, column: IColumn, hidden: boolean }[][] = []
const array: { groupName: string, column: IColumn }[][] = []
for (let i = 0; i < level; i++) {
const row = columns.map(column => ({ groupName: (column.groupName.length > 0 ? column.groupName.split(',') : []).concat(column.name)[i], column }))
array.push(row)
}
const groupNamesArray = array.slice()
for (let rowIndex = 0; rowIndex < groupNamesArray.length; rowIndex++) {
const rowGroupNamesArray = groupNamesArray[rowIndex]
const rowResult = []
for (let colIndex = 0; colIndex < rowGroupNamesArray.length; colIndex++) {
const { groupName, column } = rowGroupNamesArray[colIndex]
const groupLabels = column.pristine.groupLabels ?? []
const label = groupLabels.length > 0 ? groupLabels[rowIndex] : groupName
if (rowIndex > 0) {
const upLevel = rows[rowIndex - 1][colIndex]
if (upLevel.name == groupName && upLevel.colspan == 1) {
rowResult.push({ name: groupName, label, rowspan: 1, colspan: 1, hidden: true, column })
continue
}
}
let rowspan = 1
const colGroupNamesArray = flatMap(groupNamesArray.slice(rowIndex + 1), (arr) => arr[colIndex])
for (let i = 0; i < colGroupNamesArray.length; i++) {
const item = colGroupNamesArray[i]
if (groupName == item.groupName) {
rowspan += 1
} else {
break
}
}
if (rowspan > 1) {
rowResult.push({ name: groupName, label, rowspan, colspan: 1, hidden: false, column })
continue
}
let colspan = 1
for (let i = colIndex + 1; i < rowGroupNamesArray.length; i++) {
const item = rowGroupNamesArray[i];
if (groupName == item.groupName) {
colspan += 1
} else {
break
}
}
colIndex += colspan - 1
for (let i = 1; i <= colspan; i++) {
rowResult.push({ name: groupName, label, rowspan, colspan, hidden: i > 1, column })
}
}
rows.push(rowResult)
}
return rows.map(row => row.filter(item => !item.hidden))
}
export function getCellValue(originValue: any, column?: IColumn, clearFormat: boolean = false, isCopyCell?: boolean) {
let value = originValue
const prefix = column?.pristine.prefix ?? ''
const suffix = column?.pristine.suffix ?? ''
if (column?.type === 'mapping') {
value = column?.map?.[originValue] ?? (originValue ?? '')
} else if (column?.type === 'number') {
if (isNil(value)) return ''
// 不需要清空格式化的逻辑
if (!clearFormat) {
const kilobitSeparator = column?.pristine.kilobitSeparator ?? false
const precision = column?.pristine.precision
if (kilobitSeparator && originValue != null) {
value = numberFormatter(originValue, precision)
} else if (originValue != null && typeof originValue == 'number') {
value = originValue.toFixed(precision)
}
return `${prefix || ''}${value}${suffix || ''}`
} else {
// 需要清空格式化的逻辑
if (suffix === '%') {
// 如果是百分比的逻辑
value = isNil(originValue) ? originValue : originValue / 100
}
return value
}
}
if (value != null) {
return typeof value == 'object' ? '[文件]' : `${clearFormat ? '' : prefix}${typeof value == 'string' && !isCopyCell ? value.replace(/\n|\r|<[^>]*>/g, '') : value}${clearFormat ? '' : suffix}`
}
return ''
}
/** 同步设置列信息 */
export const syncCrossColumnInfo = (columns: IColumn[], columnInfo?: Record<string, { index: number, hidden?: 0 | 1, fixed: string }>) => {
if (columnInfo && Object.keys(columnInfo).length) {
const newColumns = columns.slice()
const colsArr = Object.entries(columnInfo).sort((a, b) => a[1]?.index - b[1]?.index);
let newCols: any[] = []
colsArr.forEach(([k, v]) => {
const target = newColumns.find(colItem => colItem.name === k)
if (target) {
newCols.push({ ...target, ...(v as object) })
}
})
const restColumns = newColumns.filter(item => !newCols.find((col: any) => col.name === item.name))
return [...newCols, ...restColumns]
}
return columns
}