import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useState } from 'react' import styles from './index.module.scss' import { DatePicker, Form, FormInstance, Input, Table, TableProps } from 'antd' import ImageLazy from '../ImageLazy' import classNames from 'classnames' import dayjs from 'dayjs' import { resJiLianFu, resTagFu } from '@/utils/dataChange' interface MyTableProps extends Omit { yHeight?: number //设置表格的高度 list: any //表格数据 columnsTemp: any[][] //表格展示 total?: number //总数 pageNum?: number pageSize?: number pagingInfo?: any | boolean onChange?: (pageNum: number, pageSize: number) => void lastBtn?: any //后面的操作按钮 startBtn?: any classKey?: string //一个组件多次使用的时候要传递,分别设置style // 表格简单的合并 merge?: { type: string; num: number; loc: 'rowSpan' | 'colSpan' } // 定制化表头 myTitle?: { name: string; Com: React.ReactNode } // 为空的定制字段 isNull?: string // 设置宽度 widthSet?: any rowKey?: string readOnly?: boolean // 没有数据的时候展示 emptyText?: boolean } export interface MyTableMethods { form: FormInstance } export const getDesensitizeTxt = (txt: string, frontLen = 3, endLen = 4) => { if (!txt) return txt const totalVisible = frontLen + endLen if (txt.length <= totalVisible) { return txt } const frontStr = txt.substring(0, frontLen) const endStr = endLen > 0 ? txt.substring(txt.length - endLen) : '' const maskStr = '*'.repeat(txt.length - frontLen - endLen) return frontStr + maskStr + endStr } const MyTable = forwardRef( ( { yHeight, list, columnsTemp, total, pageNum = 1, pageSize = 10, pagingInfo = { showQuickJumper: true, position: ['bottomCenter'], showSizeChanger: true }, onChange, lastBtn = [], startBtn = [], classKey = '', merge, myTitle, isNull = '(空)', widthSet, rowKey = 'id', readOnly, emptyText, ...rest }, ref ) => { // 点击操作高亮 const [clickAc, setClickAc] = useState(0) const [form] = Form.useForm() // 表格内容定制化 const tableComObj = useCallback( (key: string, val: string[], id?: any, backFu?: (id: number) => void) => { const obj = { // 超链接打开 A: ( {val[0]} ), // 点击触发事件 S: ( { if (id && backFu) { backFu(id) setClickAc(id) } }} > {val[1]} ) } return Reflect.get(obj, key) }, [clickAc] ) useEffect(() => { const dom = document.querySelector(`.MyTable${classKey} .ant-table-body`) as HTMLDivElement if (dom && yHeight) dom.style.height = yHeight + 'px' }, [classKey, yHeight]) // 页码变化 const paginationChange = useCallback( () => (pageNum: number, pageSize: number) => { if (onChange) { onChange(pageNum, pageSize) } }, [onChange] ) const dataChangeFu = useCallback( (v: any) => { /** * index:序号 * txt:正常数据 * img:图片 * txtChange:判断显示不同字段 * text:文字比较多的情况 */ const obj = { index: (_: any, __: any, index: number) => index + 1 + (pageNum - 1) * pageSize, txt: (item: any) => v[3] && !item[v[2]] ? (
) : item[v[2]] && item[v[2]] !== '0' ? ( item[v[2]] ) : ( isNull ), txtArr: (item: any) => (
') }}>
), // 日期去掉00:00:00 dateRes: (item: any) => { let res = item[v[2]] ? dayjs(item[v[2]]).format('YYYY-MM-DD') : isNull return res }, // 多个字段拼接 ping: (item: any) => (item[v[2]] || '') + (resJiLianFu(item[v[3]]) || '') || isNull, // 这个模块特有的级联控制 txtC: (item: any) => v[1] === '年代' && item[v[2]] === '其他' ? '其他' : resJiLianFu(item[v[2]]), txtCTag: (item: any) => { // resJiLianFu(item[v[2]], 'tag'), let resTxt = item[v[2]] || isNull if (resTxt) { return resTagFu(resTxt, v[3] || '藏品') || isNull } return resTxt || isNull }, img: (item: any) => v[3] && !item[v[2]] ? (
) : (
), // 附件大小 fileSize: (item: any) => { if (item[v[2]]) { const resTxt = (item[v[2]] / 1024).toFixed(2) if (resTxt === '0.00') return '0.01' else return resTxt } else return isNull }, txtChange: (item: any) => Reflect.get(v[3], item[v[2]]) || v[4] || isNull, text: (item: any) => { let tempCom: any = item[v[2]] || isNull if (tempCom.length >= v[3]) { tempCom = tempCom.substring(0, v[3]) + '...' } if (v[4]) { tempCom = tableComObj(v[4], [tempCom, item[v[2]]], item.id, v[5]) } else if ((item[v[2]] || '').length >= v[3]) { tempCom = ( {tempCom} ) } return tempCom }, input: (item: any) => { return ( ) }, datePicker: (item: any) => { return ( ) }, custom: (item: any) => { return ( {v[3].render(readOnly, item)} ) }, desensitize: (item: any) => { const txt = item[v[2]] if (!txt) return isNull const frontLen = v[3]?.frontLen || 3 const endLen = v[3]?.endLen || 4 return getDesensitizeTxt(txt, frontLen, endLen) }, select: (item: any) => { let txt = isNull const data = v[3] const id = item[v[2]] const obj = data.find((v: any) => v.value === id) if (obj) txt = obj.label return txt }, connectTxt: (item: any) => { const txt1 = v[2] ? item[v[2]] || isNull : isNull const txt2 = v[3] ? item[v[3]] || isNull : isNull console.log(txt1, txt2, item[v[2]], item[v[3]]) return !item[v[2]] && !item[v[3]] ? isNull : `${txt1}-${txt2}` } } return Reflect.get(obj, v[0]) }, [isNull, pageNum, pageSize, readOnly, tableComObj] ) const columns = useMemo(() => { const arr: any = columnsTemp.map((v: any) => ({ title: myTitle && v.includes(myTitle.name) ? myTitle.Com : v[1], render: dataChangeFu(v), width: widthSet && Reflect.get(widthSet, v[2]) ? Reflect.get(widthSet, v[2]) : 'auto', onCell: merge && v.includes(merge.type) ? // {rowSpan:3} (item: any, index: number) => ({ rowSpan: index === 0 ? merge.num : 0 }) : '' })) return arr }, [columnsTemp, dataChangeFu, merge, myTitle, widthSet]) useImperativeHandle(ref, () => ({ form })) return (
) } ) const MemoMyTable = React.memo(MyTable) export default MemoMyTable