/** * @description 表格行相关的功能 */ import React from "react" import { Form, Input, Tag, message, Modal, Popconfirm, Menu, Dropdown, Button } from "antd" import uniqBy from "lodash/uniqBy" import { btncodeIconMap } from "./TableHeader" import { DownOutlined } from "@ant-design/icons"; function findData(dataSource, rowKey, value) { if (!dataSource) { return; } for (const item of dataSource) { if (item[rowKey] === value) { return item; } const child = findData(item.children, rowKey, value); if (child) { return child; } } } export const RowSelection = { rowSelection: function (this: any) { const { rowSelection: config, dataSource } = this.getProps() const { show } = config || {} const rowKey = this.getRowKey() if (show === false) return null let { mode, checkedKeys = [], onClick, checkedRows = [] } = config || {} if (checkedRows.length > 0) { checkedKeys = checkedRows.map((item: any) => item[rowKey]) } return { type: mode || "checkbox", selectedRowKeys: checkedKeys, onSelect: (record: any, selected: boolean, selectedRows: any[]) => { const key = record[rowKey] if (mode === "radio") { const nextProps = { checkedKeys: [key], checkedRows: selectedRows, currentRow: record } const { checkedTags } = this.renderCheckedUIbyCheckedRows(selectedRows) if (onClick) { onClick.call(this, { ...nextProps, checkedTags, currentRow: nextProps.currentRow }) } } if (mode !== "radio") { let { checkedKeys = [], checkedRows = [] } = config if (selected) { checkedKeys.push(key) checkedRows.push(record) } else { checkedKeys = checkedKeys.filter((item: any) => item !== key) checkedRows = checkedRows.filter((item: any) => item[rowKey] !== key) } const nextProps = { checkedKeys, checkedRows, currentRow: record } const { checkedTags } = this.renderCheckedUIbyCheckedRows(checkedRows) if (onClick) { onClick.call(this, { ...nextProps, checkedTags, currentRow: nextProps.currentRow }) } } }, onSelectAll: (selected: boolean, selectedRows: any[], changeRows: any[]) => { let { checkedKeys = [], checkedRows = [] } = config if (selected) { const selectedKeys = selectedRows.filter(item => item).map(item => item[rowKey]) checkedKeys = [...checkedKeys, ...selectedKeys] checkedRows = [...checkedRows, ...selectedRows] } else { const changedKeys = changeRows.map(item => item[rowKey]) checkedKeys = checkedKeys.filter((item: any) => !changedKeys.includes(item)) checkedRows = checkedRows.filter((item: any) => !changedKeys.includes(item[rowKey])) } checkedKeys = Array.from(new Set(checkedKeys)) checkedRows = uniqBy(checkedRows, rowKey) const nextProps = { checkedKeys, checkedRows } const { checkedTags } = this.renderCheckedUIbyCheckedRows(checkedRows) if (onClick) { onClick.call(this, { ...nextProps, checkedTags, currentRow: null }) } } } }, // 获取行展开功能的配置 getExpandableConfig: function (this: any) { const { expandable: config = {}, columns } = this.getProps() const { show } = config || {} if (show === false) return false const { nestingMode, httpConfig = {}, dataSource } = this.getProps() const { onExpand, rowExpandable } = config || {} const rowKey = this.getRowKey() const resultConfig: any = { rowExpandable, columnWidth: 30 } // 继承模式 if (nestingMode === "inherit") { resultConfig.onExpand = (expanded: boolean, record: any) => { if (httpConfig.onExpand && expanded && !record["children"].length) { this.setProps({ loading: true }); httpConfig.onExpand({ expanded, record }).then((res: any) => { const target = findData(dataSource, rowKey, record[rowKey]) if (target) { target.children = res } const expandedKeys = this.getExpandedKeys(expanded, record) this.setProps({ loading: false, dataSource, expandedKeys }) }) } else { const expandedKeys = this.getExpandedKeys(expanded, record) this.setProps({ expandedKeys }) } } } // 自定义模式 if (nestingMode === "customer") { resultConfig.expandedRowRender = (record: object, index: number, indent: boolean, expanded: boolean) => { if (!onExpand) { return
{Object.keys(record).map(key => { const col = columns.filter((item: any) => item.dataIndex === key)[0] || {} return })}
} return onExpand({ record, expanded, index }) } resultConfig.onExpand = (expanded: boolean, record: number) => { const expandedKeys = this.getExpandedKeys(expanded, record) this.setProps({ expandedKeys }) } } return resultConfig }, // 渲染删除按钮,支持行按钮和表头按钮的删除 renderDeleteTag(this: any, rows: any[], config: any, index?: number) { const { httpConfig: { delete: deleteHttp } } = this.getProps() let { rowSelection: { checkedRows = [] } } = this.getProps() const { onClick, color, text, btnCode = "", icon } = config // 表头删除按钮 if (btnCode.toUpperCase() === "HEADER_DELETE_BUTTON") { return { ev.stopPropagation() if (checkedRows.length <= 0) { message.info("至少选中一条数据") return } Modal.confirm({ title: "确认删除选中数据?", width: "250px", cancelText: "取消", okButtonProps: { size: "small", type: "primary" }, cancelButtonProps: { size: "small" }, okText: "确定", onOk: () => { if (deleteHttp) { this.deleteRows(checkedRows) } if (onClick) { onClick({ checkedRows, btnCode }) } } }) }}> {text || "批量删除"} } // 行删除按钮 return { ev.stopPropagation() }} onConfirm={(ev: any) => { ev.stopPropagation() if (deleteHttp) { this.deleteRows(rows) } if (onClick) { onClick({ record: rows[0], index, btnCode }) } }}> }, // 渲染行按钮 renderRowButton(this: any, params: { rowButton: any, record: any, index: number }) { let { rowButton, record, index } = params const { buttonConfig: { maxRowButton = 2 } } = this.getProps() rowButton = rowButton.filter(item => { if (item["show"] === false) return false if (item["isRender"]) { return item["isRender"](record) !== false } return true }) if (rowButton.length <= maxRowButton) { return rowButton.map((item: any) => { if (item["btnCode"] === "ROW_DELETE_BUTTON") { return this.renderDeleteTag.call(this, [record], item, index) } else { const { btnCode, text, color, onClick, icon } = item return { ev.stopPropagation() if (onClick) { onClick({ record, index, btnCode }) } }}> {text || "自定义按钮"} } }) } else { const firstButton = rowButton[0] const filterButton = rowButton.filter((item, index) => index >= 1) return
{filterButton.map((item: any) => { return {item["btnCode"] === "ROW_DELETE_BUTTON" ? this.renderDeleteTag.call(this, [record], item) : } })} }>
} }, // 行点击事件的处理 onClickRow(this: any, record: any, index: number) { let { footer = {}, rowSelection: { show, mode = "checkbox", onClick, checkedKeys = [], checkedRows = [], }, } = this.getProps() const rowKey = this.getRowKey() return { onClick: (event: any) => { const { tagName } = event.target if (tagName !== "TD") return const key = record[rowKey] if (!show) { if (onClick) { onClick({ checkedKeys: [], checkedRows: [], checkedTags: [], currentRow: record, index }) } return } if (mode === "radio") { checkedKeys = checkedKeys.includes(key) ? [] : [key] checkedRows = checkedKeys.length ? [record] : [] } if (mode === "checkbox") { if (checkedKeys.includes(key)) { checkedKeys = checkedKeys.filter((item: any) => item !== key) checkedRows = checkedRows.filter((item: any) => checkedKeys.includes(item[rowKey])) } else { checkedKeys.push(key) checkedRows.push(record) } } const checkedTags = checkedRows.map((item: any) => { return { key: item[footer.key], label: item[footer.label] } }) this.setProps({ "rowSelection.checkedKeys": checkedKeys, "rowSelection.checkedRows": checkedRows, "rowSelection.checkedTags": footer.show ? checkedTags : [] }) if (onClick) { onClick({ checkedKeys, checkedRows, checkedTags, currentRow: record, index }) } } } }, // 删除数据,走接口删除 deleteRows(this: any, rows: any[] = []) { const { httpConfig = {} } = this.getProps() const deleteHttp = httpConfig.delete let { rowSelection: { checkedRows = [] } } = this.getProps() const rowKey = this.getRowKey() const deleteKeys: any = rows.map(item => item[rowKey]) if (deleteHttp) { this.setProps({ loading: true }) deleteHttp({ checkedRows: rows }).then((res: any) => { if (res.result === true) { message.success("删除成功") checkedRows = checkedRows.filter((item: any) => deleteKeys.includes(item[rowKey]) === false) this.renderCheckedUIbyCheckedRows(checkedRows) } else { message.error(res.message || "删除失败") } this.setProps({ loading: false }) }) } }, // 删除数据,页面删除 deleteRows2(this: any, rows: []) { const rowKey = this.getRowKey() const deleteIds = rows.map(item => item[rowKey]) const { dataSource } = this.getProps() const nextDataSource = dataSource.filter((data: any) => deleteIds.find(id => data[rowKey] == id) == null) this.setProps({ dataSource: nextDataSource }) } }