index.tsx 5.5 KB

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