123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- import React, {
- forwardRef,
- useCallback,
- useEffect,
- useImperativeHandle,
- useMemo,
- useRef,
- 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 { resJiLianFu } from '@/utils/history'
- import { baseURL } from '@/utils/http'
- import dayjs from 'dayjs'
- interface MyTableProps extends Omit<TableProps, 'onChange'> {
- 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<any>
- }
- export const myTableTransferSize = (item: any) => {
- let danWei = resJiLianFu(item.sizeUnit, ' ')
- let txt1 = item.sizeL ? `通长${item.sizeL}` : ''
- let txt2 = item.sizeW ? `通宽${item.sizeW}` : ''
- let txt3 = item.sizeH ? `通高${item.sizeH}` : ''
- txt1 = txt1 ? txt1 + danWei : ''
- txt2 = txt2 ? txt2 + danWei : ''
- txt3 = txt3 ? txt3 + danWei : ''
- let arr = [txt1, txt2, txt3]
- arr = arr.filter(v => v)
- if (!txt1 && !txt2 && !txt3) return '(空)'
- else return arr.join(' - ')
- }
- 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<MyTableMethods, MyTableProps>(
- (
- {
- 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: (
- <a href={val[1]} target='_blank' title={val[1]} rel='noreferrer'>
- {val[0]}
- </a>
- ),
- // 点击触发事件
- S: (
- <span
- className={classNames('MTclick', clickAc === id ? 'MTclickAc' : '')}
- onClick={() => {
- if (id && backFu) {
- backFu(id)
- setClickAc(id)
- }
- }}
- >
- {val[1]}
- </span>
- )
- }
- 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]] ? (
- <div dangerouslySetInnerHTML={{ __html: v[3] }}></div>
- ) : (
- item[v[2]] || isNull
- ),
- txtArr: (item: any) => (
- <div dangerouslySetInnerHTML={{ __html: (item[v[2]] || []).join('<br/>') }}></div>
- ),
- // 日期去掉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]]),
- // 尺寸
- size: myTableTransferSize,
- img: (item: any) =>
- v[3] && !item[v[2]] ? (
- <div dangerouslySetInnerHTML={{ __html: v[3] }}></div>
- ) : (
- <div className='tableImgAuto'>
- <ImageLazy
- width={60}
- height={60}
- srcBig={item.thumbPc || item.filePath}
- src={item[v[2]] || item.thumb}
- offline={(item[v[2]] || item.thumb).includes('http')}
- />
- </div>
- ),
- // 附件大小
- 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 = (
- <span style={{ cursor: 'pointer' }} title={item[v[2]]}>
- {tempCom}
- </span>
- )
- }
- return tempCom
- },
- input: (item: any) => {
- return (
- <Form.Item noStyle name={`${item.id}-${v[2]}`}>
- <Input
- allowClear
- readOnly={readOnly}
- maxLength={v[3]?.maxLength}
- placeholder={v[3]?.placeholder || '请输入'}
- />
- </Form.Item>
- )
- },
- datePicker: (item: any) => {
- return (
- <Form.Item noStyle name={`${item.id}-${v[2]}`}>
- <DatePicker disabled={readOnly} {...(v[3] || {})} />
- </Form.Item>
- )
- },
- custom: (item: any) => {
- return (
- <Form.Item noStyle name={`${item.id}-${v[2]}`}>
- {v[3].render(readOnly)}
- </Form.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)
- }
- }
- 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
- }))
- // 空数据列表会闪一下的问题
- const timerrRef = useRef(-1)
- const [isLoding, setIsLoding] = useState(false)
- useEffect(() => {
- timerrRef.current = window.setTimeout(() => {
- setIsLoding(true)
- }, 500)
- return () => {
- clearTimeout(timerrRef.current)
- }
- }, [])
- return (
- <Form form={form} component={false}>
- <Table
- className={classNames(
- `${styles.MyTable} MyTable${classKey}`,
- emptyText ? styles.MyTableNull : ''
- )}
- scroll={{ y: yHeight ? yHeight : '' }}
- dataSource={list}
- columns={[...startBtn, ...columns, ...lastBtn]}
- rowKey={rowKey}
- pagination={
- pagingInfo
- ? {
- ...pagingInfo,
- current: pageNum,
- pageSize: pageSize,
- total: total,
- onChange: paginationChange()
- }
- : false
- }
- {...rest}
- locale={
- emptyText
- ? {
- emptyText: (
- <div
- className='NODATA'
- style={{ height: yHeight ? yHeight : 500, opacity: isLoding ? '1' : '0' }}
- >
- <img src={baseURL + `/baseData/staImg/build.png`} alt='' />
- <p>暂无相关搜索结果,请更换关键字搜索</p>
- <div>
- <p>应用归属单位:义乌市博物馆</p>
- <p>应用管理员:李亮</p>
- <p>联系方式:18767178372</p>
- </div>
- </div>
- )
- }
- : {}
- }
- />
- </Form>
- )
- }
- )
- const MemoMyTable = React.memo(MyTable)
- export default MemoMyTable
|