Skip to content

Commit

Permalink
feat: 增加合计栏功能
Browse files Browse the repository at this point in the history
  • Loading branch information
Barrior committed Jun 18, 2024
1 parent 2d23bab commit 0ef26f8
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 7 deletions.
11 changes: 11 additions & 0 deletions packages/search-table-react/src/SearchTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import useColumns from './hooks/useColumns'
import useRequest from './hooks/useRequest'
import useScrollY from './hooks/useScrollY'
import useSearch from './hooks/useSearch'
import useSummary from './hooks/useSummary'
import type { ISearchTableProps, ISearchTableRef } from './typings/index.d'

const { classNames, isPlainObject } = utils
Expand Down Expand Up @@ -49,6 +50,8 @@ const SearchTable = (
loading,
dataSource,
setDataSource,
summaryData,
setSummaryData,
innerPagination,
runRequest,
requestParamsRef,
Expand All @@ -59,6 +62,9 @@ const SearchTable = (
updateScrollY,
})

// 总结栏处理
const { finalSummary } = useSummary({ table, finalColumns, summaryData })

// 搜索栏
const {
handleSearchChange,
Expand Down Expand Up @@ -98,6 +104,10 @@ const SearchTable = (
setDataSource(data)
forceUpdate()
},
setSummaryDataAndRender: (data) => {
setSummaryData(data)
forceUpdate()
},
updateScrollY,
}))

Expand Down Expand Up @@ -149,6 +159,7 @@ const SearchTable = (
y: scrollY,
...table?.scroll,
}}
summary={finalSummary}
/>

{footer?.(comRenderParams)}
Expand Down
2 changes: 1 addition & 1 deletion packages/search-table-react/src/hooks/useColumns/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default function useColumns({ table }: IUseColumnsParams) {
columns.unshift({
title: '序号',
align: 'center',
width: 60,
width: 70,
fixed: 'left',
render: (_t: string, _r: object, index: number) => index + 1,
key: EColumnsKeys.rowNumber,
Expand Down
17 changes: 16 additions & 1 deletion packages/search-table-react/src/hooks/useRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,17 @@ export default function useRequest({
searchValueRef,
}: IUseRequest) {
// 分页参数
const paginationRef = useRef({ current: 1, pageSize: 10, total: 0 })
const paginationRef = useRef({
current: 1,
pageSize: (table.pagination !== false ? table.pagination?.defaultPageSize : 10) || 10,
total: 0,
})
// 请求参数
const requestParamsRef = useRef({})
// 表格数据源
const dataSourceRef = useRef<IObjectAny[]>([])
// 合计栏数据
const summaryDataRef = useRef<IObjectAny>({})
// 是否加载表格数据中
const [loading, setLoading] = useState(false)

Expand Down Expand Up @@ -95,6 +101,9 @@ export default function useRequest({
// 存储数据源
dataSourceRef.current = res.data || []

// 存储合计栏数据
summaryDataRef.current = res.summaryData || {}

// 成功返回数据
result = {
...res,
Expand Down Expand Up @@ -145,10 +154,16 @@ export default function useRequest({
dataSourceRef.current = data
})

const setSummaryData = useMemoizedFn((data: IObjectAny) => {
summaryDataRef.current = data
})

return {
loading,
dataSource: dataSourceRef.current,
setDataSource,
summaryData: summaryDataRef.current,
setSummaryData,
innerPagination,
requestParamsRef,
runRequest,
Expand Down
12 changes: 7 additions & 5 deletions packages/search-table-react/src/hooks/useScrollY.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,14 @@ export default function useScrollY({ table, rootElemRef }: IUseScrollYParams) {

const tableElem = rootElemRef.current.querySelector(`.${EClassNames.table}`)
const theadElem = tableElem?.querySelector('thead')
const tfootElem = tableElem?.querySelector('tfoot')
const paginationElem = tableElem?.querySelector(`.${EClassNames.pagination}`)
const tableElements = [theadElem, tfootElem, paginationElem]

// 内容元素的总高度
let elementsHeight = 0

// 累加子节点高度,排除 table
forEach(rootElemRef.current.children, (child) => {
// 表格元素的内容高度这里排除,需要单独计算
if (child !== tableElem) {
Expand All @@ -45,11 +48,10 @@ export default function useScrollY({ table, rootElemRef }: IUseScrollYParams) {
// 加上表格的 marginTop
elementsHeight += getNumericStyleValue(tableElem as HTMLElement, 'marginTop')

// 加上表头高度
elementsHeight += calcOuterHeight(theadElem)

// 加上分页高度
elementsHeight += calcOuterHeight(paginationElem as HTMLElement)
// 累加表格内元素
forEach(tableElements, (elem) => {
elementsHeight += calcOuterHeight(elem as HTMLElement)
})

// 设置 scrollY 的值
setScrollY(rootElemRef.current.clientHeight - elementsHeight)
Expand Down
129 changes: 129 additions & 0 deletions packages/search-table-react/src/hooks/useSummary/helpers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import type { IObjectAny } from '@schema-render/core-react'
import { utils } from '@schema-render/core-react'
import { Table } from 'antd'
import type { Key, ReactNode } from 'react'

import { EColumnsKeys } from '../../constants'
import type { IColumnType } from '../../typings/table.d'
import { forEach } from '../../utils/common'

const { isArray, isNil } = utils

export interface ICreateTableSummaryParams {
/** 平铺的列数据 */
flattenedColumns: IColumnType[]
/** 「合计」数据 */
summaryData: IObjectAny
/** 「合计」文案 */
summaryText?: ReactNode
/**
* 表格是否存在 checkbox 选择框,存在会给「合计」索引自动 +1
*/
hasRowSelection?: boolean
/**
* 是否存在序号栏
*/
hasRowNumber?: boolean
}

/**
* 获取默认文案
*/
function getSummaryDefaultText(dataKey: Key, summaryText: ReactNode) {
// 序号栏显示“合计”文案
if (dataKey === EColumnsKeys.rowNumber) {
return summaryText
}

// 操作栏默认为空
if (dataKey === EColumnsKeys.actions) {
return ''
}

// 其他列数据不存在显示中横线
return '-'
}

/**
* 获取平铺的 columns
*/
export function getFlattenedColumns(columns?: IColumnType[]) {
const flattened: IColumnType[] = []

function traverse(list?: IColumnType[]) {
forEach(list, (item) => {
if (isArray(item.children)) {
traverse(item.children)
} else {
flattened.push(item)
}
})
}

traverse(columns)

return flattened
}

/**
* 创建 Antd Table 总结栏列表数据
*/
function createTableSummaryItems({
flattenedColumns,
summaryData,
summaryText = '合计',
hasRowNumber = false,
hasRowSelection = false,
}: ICreateTableSummaryParams) {
const resultList: { index: number; text: ReactNode; colSpan?: number }[] = []

let index = -1

if (hasRowSelection) {
index++
resultList.push({
index,
text: hasRowNumber ? '' : summaryText,
})
}

forEach(flattenedColumns, ({ key, dataIndex }) => {
const strDataIndex = (isArray(dataIndex) ? dataIndex.join('.') : dataIndex) as string
const dataKey = key || strDataIndex
const content = summaryData[dataKey]

index++

resultList.push({
index,
text: isNil(content) ? getSummaryDefaultText(dataKey, summaryText) : content,
})
})

return resultList
}

/**
* 创建 antd table 总结栏
*/
export function createTableSummary(p: ICreateTableSummaryParams) {
const items = createTableSummaryItems(p)
return (
<Table.Summary fixed="bottom">
<Table.Summary.Row>
{items.map((item) => {
return (
<Table.Summary.Cell
align="center"
key={item.index}
index={item.index}
colSpan={item.colSpan}
>
{item.text}
</Table.Summary.Cell>
)
})}
</Table.Summary.Row>
</Table.Summary>
)
}
48 changes: 48 additions & 0 deletions packages/search-table-react/src/hooks/useSummary/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { IObjectAny } from '@schema-render/core-react'
import { useMemoizedFn } from '@schema-render/core-react'
import { useMemo } from 'react'

import type { ISearchTableProps } from '../../typings/index.d'
import type { IColumnType } from '../../typings/table'
import { isEmpty } from '../../utils/common'
import { createTableSummary, getFlattenedColumns } from './helpers'

interface IUseSummaryParams {
table: ISearchTableProps['table']
finalColumns: IColumnType[]
summaryData: IObjectAny
}

/**
* 总结栏处理:支持合计数据分布
*/
export default function useSummary({
table,
finalColumns,
summaryData,
}: IUseSummaryParams) {
const flattenedColumns = useMemo(
() => getFlattenedColumns(finalColumns),
[finalColumns]
)

const renderSummary = useMemoizedFn(() => {
return createTableSummary({
flattenedColumns,
summaryData,
summaryText: table.summaryText,
hasRowSelection: !!table.rowSelection,
hasRowNumber: table.showRowNumber,
})
})

const finalSummary = table.summary
? table.summary
: isEmpty(summaryData)
? undefined
: renderSummary

return {
finalSummary,
}
}
4 changes: 4 additions & 0 deletions packages/search-table-react/src/typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ export interface ISearchTableRef {
* 设置表格列表数据
*/
setDataSourceAndRender: (dataSource: IObjectAny[]) => void
/**
* 设置合计栏数据
*/
setSummaryDataAndRender: (data: IObjectAny) => void
/**
* 获取搜索参数
*/
Expand Down
9 changes: 9 additions & 0 deletions packages/search-table-react/src/typings/table.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ export type ITableProps = IAntdTableProps & {
* 自动计算表格 scrollY 属性,达到自动适配屏幕高度的效果
*/
autoScrollY?: boolean
/**
* 合计栏
*/
summaryText?: ReactNode

// 注册 valueType
// registerValueType?: {
// [type: string]: (text: string, record: IObjectAny, index: number) => ReactNode
// }
}

/**
Expand Down

0 comments on commit 0ef26f8

Please sign in to comment.