UNPKG

fastlion-amis

Version:

一种MIS页面生成工具

242 lines (229 loc) 10.5 kB
import { Condition } from "../../components/table/SecondFilter/types" import { sortFn, filterFn, translateNumber } from "../../utils/utils" import { numberFormatter } from "../../utils/helper" import { IColumn as ITableColumn } from "../table" import { DATAKEYID } from "../crud" import union from 'lodash/union' import intersection from 'lodash/intersection' import { isNil, flatMap, isEqual } from "lodash" import { resolveVariable } from "../../utils/tpl-builtin" type IColumn = ITableColumn 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[], saveHidden = false) { 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 saveHidden ? rows : 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') { const delimiter = column.pristine.delimiter if (typeof delimiter === 'string') { const originValues = String(originValue).split(delimiter) value = originValues.map(value => column?.map?.[value] ?? (value ?? '')).join(delimiter) } else { value = column?.map?.[originValue] ?? (originValue ?? '') } } else if (column?.type === 'number') { if (isNil(value)) return '' // 不需要清空格式化的逻辑 if (!clearFormat) { const showUppercase = column?.pristine.showUppercase ?? 0 const kilobitSeparator = column?.pristine.kilobitSeparator ?? false const precision = !isNil(column?.pristine.precision) ? column?.pristine.precision : (value + '').split('.')[1]?.length ?? 0 if (showUppercase !== 0) { value = translateNumber(value, showUppercase) } else if (kilobitSeparator && originValue != null) { value = numberFormatter(originValue, precision) } else if (originValue != null && typeof originValue == 'number') { value = originValue.toFixed(precision) } else if (typeof originValue === 'string') { 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 } export const getColumnShowLabel = (column: IColumn) => { const names = column.name?.split(CROSS_SPLIT_CHAR) const label = column.label || column.name const groupNames = column.groupName ? column.groupName.split(',') : [] if (names?.length == 1 && (groupNames.length == 0 || groupNames.every(item => item == names[0]))) { return label } const labels = column.pristine.groupLabels ?? [] if (labels.length > 0) { return labels.join(CROSS_SPLIT_CHAR) + CROSS_SPLIT_CHAR + label } if (groupNames.length > 0) { return (column.groupName.includes(CROSS_SPLIT_CHAR) ? groupNames[groupNames.length - 1] : groupNames.join(CROSS_SPLIT_CHAR)) + CROSS_SPLIT_CHAR + label } return label } export const getColumnClassNameExprData = (column: IColumn, data: any) => { const isCrossColumn = typeof column.name == 'string' && column.name.includes(CROSS_SPLIT_CHAR) if (isCrossColumn && column.pristine.classNameExpr) { const classNameExprData = { ...data } const levelNames: any[] = column.name!.split(CROSS_SPLIT_CHAR) const groupName = levelNames.slice(0, levelNames.length - 1).join(CROSS_SPLIT_CHAR) Object.keys(classNameExprData).forEach(key => { if (key.startsWith(groupName)) { const name = key.replace(`${groupName}${CROSS_SPLIT_CHAR}`, '') classNameExprData[name] = classNameExprData[key] } }) return classNameExprData } return data } export const combineCell = (arr: { rowSpans: Record<string, number>; [key: string]: any }[], combinedColumns: { name: string, combinedNull: boolean }[]) => { for (const { name, combinedNull = true } of combinedColumns) { let i = 0 while (i < arr.length) { if (arr[i].rowSpans[name] !== 0) { arr[i].rowSpans[name] = 1 } let j = i + 1 while (j < arr.length && isEqual(combinedNull ? resolveVariable(name, arr[i]) : resolveVariable(name, arr[i]) ?? Math.random(), combinedNull ? resolveVariable(name, arr[j]) : resolveVariable(name, arr[j]) ?? Math.random())) { arr[i].rowSpans[name]++ arr[j].rowSpans[name] = 0 j++ } i = j } } return arr }