index.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. import React, { useCallback, useEffect, useMemo, useState } from 'react'
  2. import styles from './index.module.scss'
  3. import { Table } from 'antd'
  4. import ImageLazy from '../ImageLazy'
  5. import classNames from 'classnames'
  6. import { resJiLianFu } from '@/utils/history'
  7. type Props = {
  8. yHeight?: number //设置表格的高度
  9. list: any //表格数据
  10. columnsTemp: any[][] //表格展示
  11. total?: number //总数
  12. pageNum?: number
  13. pageSize?: number
  14. pagingInfo?: any | boolean
  15. onChange?: (pageNum: number, pageSize: number) => void
  16. lastBtn?: any //后面的操作按钮
  17. startBtn?: any
  18. classKey?: string //一个组件多次使用的时候要传递,分别设置style
  19. // 表格简单的合并
  20. merge?: { type: string; num: number; loc: 'rowSpan' | 'colSpan' }
  21. // 定制化表头
  22. myTitle?: { name: string; Com: React.ReactNode }
  23. // 为空的定制字段
  24. isNull?: string
  25. // 设置宽度
  26. widthSet?: any
  27. }
  28. function MyTable({
  29. yHeight,
  30. list,
  31. columnsTemp,
  32. total,
  33. pageNum = 1,
  34. pageSize = 10,
  35. pagingInfo = {
  36. showQuickJumper: true,
  37. position: ['bottomCenter'],
  38. showSizeChanger: true
  39. },
  40. onChange,
  41. lastBtn = [],
  42. startBtn = [],
  43. classKey = '',
  44. merge,
  45. myTitle,
  46. isNull = '(空)',
  47. widthSet
  48. }: Props) {
  49. // 点击操作高亮
  50. const [clickAc, setClickAc] = useState(0)
  51. // 表格内容定制化
  52. const tableComObj = useCallback(
  53. (key: string, val: string[], id?: any, backFu?: (id: number) => void) => {
  54. const obj = {
  55. // 超链接打开
  56. A: (
  57. <a href={val[1]} target='_blank' title={val[1]} rel='noreferrer'>
  58. {val[0]}
  59. </a>
  60. ),
  61. // 点击触发事件
  62. S: (
  63. <span
  64. className={classNames('MTclick', clickAc === id ? 'MTclickAc' : '')}
  65. onClick={() => {
  66. if (id && backFu) {
  67. backFu(id)
  68. setClickAc(id)
  69. }
  70. }}
  71. >
  72. {val[1]}
  73. </span>
  74. )
  75. }
  76. return Reflect.get(obj, key)
  77. },
  78. [clickAc]
  79. )
  80. useEffect(() => {
  81. const dom = document.querySelector(`.MyTable${classKey} .ant-table-body`) as HTMLDivElement
  82. if (dom && yHeight) dom.style.height = yHeight + 'px'
  83. }, [classKey, yHeight])
  84. // 页码变化
  85. const paginationChange = useCallback(
  86. () => (pageNum: number, pageSize: number) => {
  87. if (onChange) {
  88. onChange(pageNum, pageSize)
  89. }
  90. },
  91. [onChange]
  92. )
  93. const dataChangeFu = useCallback(
  94. (v: any) => {
  95. /**
  96. * index:序号
  97. * txt:正常数据
  98. * img:图片
  99. * txtChange:判断显示不同字段
  100. * text:文字比较多的情况
  101. */
  102. const obj = {
  103. index: (_: any, __: any, index: number) => index + 1 + (pageNum - 1) * pageSize,
  104. txt: (item: any) =>
  105. v[3] && !item[v[2]] ? (
  106. <div dangerouslySetInnerHTML={{ __html: v[3] }}></div>
  107. ) : (
  108. item[v[2]] || isNull
  109. ),
  110. // 多个字段拼接
  111. ping: (item: any) => item[v[2]] + resJiLianFu(item[v[3]]) || isNull,
  112. // 这个模块特有的级联控制
  113. txtC: (item: any) =>
  114. v[1] === '年代' && item[v[2]] === '其他' ? '其他' : resJiLianFu(item[v[2]]),
  115. img: (item: any) =>
  116. v[3] && !item[v[2]] ? (
  117. <div dangerouslySetInnerHTML={{ __html: v[3] }}></div>
  118. ) : (
  119. <div className='tableImgAuto'>
  120. <ImageLazy
  121. width={60}
  122. height={60}
  123. srcBig={item.thumbPc}
  124. src={item[v[2]] || item.thumb}
  125. offline={(item[v[2]] || item.thumb).includes('http')}
  126. />
  127. </div>
  128. ),
  129. txtChange: (item: any) => Reflect.get(v[3], item[v[2]]) || v[4] || isNull,
  130. text: (item: any) => {
  131. let tempCom: any = item[v[2]] || isNull
  132. if (tempCom.length >= v[3]) {
  133. tempCom = tempCom.substring(0, v[3]) + '...'
  134. }
  135. if (v[4]) {
  136. tempCom = tableComObj(v[4], [tempCom, item[v[2]]], item.id, v[5])
  137. } else if (item[v[2]].length >= v[3]) {
  138. tempCom = (
  139. <span style={{ cursor: 'pointer' }} title={item[v[2]]}>
  140. {tempCom}
  141. </span>
  142. )
  143. }
  144. return tempCom
  145. }
  146. }
  147. return Reflect.get(obj, v[0])
  148. },
  149. [isNull, pageNum, pageSize, tableComObj]
  150. )
  151. const columns = useMemo(() => {
  152. const arr: any = columnsTemp.map((v: any) => ({
  153. title: myTitle && v.includes(myTitle.name) ? myTitle.Com : v[1],
  154. render: dataChangeFu(v),
  155. width: widthSet && Reflect.get(widthSet, v[2]) ? Reflect.get(widthSet, v[2]) : 'auto',
  156. onCell:
  157. merge && v.includes(merge.type)
  158. ? // {rowSpan:3}
  159. (item: any, index: number) => ({
  160. rowSpan: index === 0 ? merge.num : 0
  161. })
  162. : ''
  163. }))
  164. return arr
  165. }, [columnsTemp, dataChangeFu, merge, myTitle, widthSet])
  166. return (
  167. <Table
  168. className={`${styles.MyTable} MyTable${classKey}`}
  169. scroll={{ y: yHeight ? yHeight : '' }}
  170. dataSource={list}
  171. columns={[...startBtn, ...columns, ...lastBtn]}
  172. rowKey='id'
  173. pagination={
  174. pagingInfo
  175. ? {
  176. ...pagingInfo,
  177. current: pageNum,
  178. pageSize: pageSize,
  179. total: total,
  180. onChange: paginationChange()
  181. }
  182. : false
  183. }
  184. />
  185. )
  186. }
  187. const MemoMyTable = React.memo(MyTable)
  188. export default MemoMyTable