You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
5.6 KiB
TypeScript

1 year ago
import type { VueKey, VueText } from '#/types'
import type { SortOrder } from 'ant-design-vue/es/table/interface'
import type {
ActionType,
Bordered,
BorderedType,
ProColumns,
ProColumnType,
UseFetchDataAction
} from '../typing'
import type { TablePaginationConfig } from 'ant-design-vue'
import type { IntlType } from '#/provider'
import { arrayMoveImmutable } from '#/utils/array-move'
import type { Ref } from 'vue'
/**
* props props
*/
export function mergePagination<T>(
pagination: TablePaginationConfig | boolean | undefined,
pageInfo: UseFetchDataAction<T>['pageInfo'] & {
setPageInfo: any
},
intl: IntlType
): TablePaginationConfig | false | undefined {
if (pagination === false) {
return false
}
const { total, current, pageSize, setPageInfo } = pageInfo
const defaultPagination: TablePaginationConfig = typeof pagination === 'object' ? pagination : {}
return {
showTotal: (all, range) =>
`${intl.getMessage('pagination.total.range', '第')} ${range[0]}-${range[1]} ${intl.getMessage(
'pagination.total.total',
'条/总共'
)} ${all} ${intl.getMessage('pagination.total.item', '条')}`,
total,
...(defaultPagination as TablePaginationConfig),
current,
pageSize,
showSizeChanger: true,
onChange: (page: number, newPageSize?: number) => {
const { onChange } = pagination as TablePaginationConfig
onChange?.(page, newPageSize || 10)
// pageSize 改变之后就没必要切换页码
if (newPageSize !== pageSize || current !== page) {
setPageInfo({ pageSize: newPageSize, current: page })
}
}
}
}
/**
* action
*/
export function useActionType<T>(
ref: Ref<ActionType | undefined>,
action: UseFetchDataAction<T>,
props: {
fullScreen: () => void
onCleanSelected: () => void
resetAll: () => void
editableUtils: any
}
) {
/** 这里生成action的映射保证 action 总是使用的最新 只需要渲染一次即可 */
const userAction: ActionType = {
...props.editableUtils,
pageInfo: action.pageInfo,
reload: async (resetPageIndex?: boolean) => {
// 如果为 true回到第一页
if (resetPageIndex) {
await action.setPageInfo({
current: 1
})
}
action?.reload()
},
reloadAndRest: async () => {
// reload 之后大概率会切换数据,清空一下选择。
props.onCleanSelected()
await action.setPageInfo({
current: 1
})
await action?.reload()
},
reset: async () => {
await props.resetAll()
await action?.reset?.()
await action?.reload()
},
fullScreen: () => props.fullScreen(),
clearSelected: () => props.onCleanSelected(),
// @ts-ignore
setPageInfo: rest => action.setPageInfo(rest)
}
ref.value = userAction
}
type PostDataType<T> = (data: T) => T
/**
* pipeline
*
* @param data
* @param pipeline
*/
export function postDataPipeline<T>(data: T, pipeline: PostDataType<T>[]) {
if (pipeline.filter(item => item).length < 1) {
return data
}
return pipeline.reduce((pre, postData) => {
return postData(pre)
}, data)
}
export const isBordered = (borderType: BorderedType, border?: Bordered) => {
if (border === undefined) {
return false
}
// debugger
if (typeof border === 'boolean') {
return border
}
return border[borderType]
}
export const isMergeCell = (
dom: any // 如果是合并单元格的,直接返回对象
) => dom && typeof dom === 'object' && dom?.props?.colSpan
/**
* key dataIndex id
*
* @param key key
* @param index
*/
export const genColumnKey = (key?: VueKey | undefined, index?: number): string => {
if (key) {
return Array.isArray(key) ? key.join('-') : key.toString()
}
return `${index}`
}
/**
* ProTable - column - dataIndex
*
* @param dataIndex Column dataIndex
*/
function parseDataIndex(dataIndex: ProColumnType['dataIndex']): string | undefined {
if (Array.isArray(dataIndex)) {
return dataIndex.join(',')
}
return dataIndex?.toString()
}
/**
* ProColumns
*
* @param columns ProColumns
*/
export function parseDefaultColumnConfig<T, Value>(columns: ProColumns<T, Value>[]) {
const filter: Record<string, VueText[] | null> = {}
const sort: Record<string, SortOrder> = {}
columns.forEach(column => {
// 转换 dataIndex
const dataIndex = parseDataIndex(column.dataIndex)
if (!dataIndex) {
return
}
// 当 column 启用 filters 功能时,取出默认的筛选值
if (column.filters) {
const defaultFilteredValue = column.defaultFilteredValue as VueText[]
if (defaultFilteredValue === undefined) {
filter[dataIndex] = null
} else {
filter[dataIndex] = column.defaultFilteredValue as VueText[]
}
}
// 当 column 启用 sorter 功能时,取出默认的排序值
if (column.sorter && column.defaultSortOrder) {
sort[dataIndex] = column.defaultSortOrder!
}
})
return { sort, filter }
}
export type SortDataParams = { oldIndex: number; newIndex: number }
/**
*
*
* @param oldIndex
* @param newIndex
* @param data
*/
export function sortData<T>({ oldIndex, newIndex }: SortDataParams, data: T[]): T[] | null {
if (oldIndex !== newIndex) {
const newData = arrayMoveImmutable([...(data || [])], oldIndex, newIndex).filter(el => !!el)
return [...newData]
}
return null
}