index.tsx 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. import React, { useCallback, useEffect, useMemo } from 'react'
  2. import styles from './index.module.scss'
  3. import { Table } from 'antd'
  4. import ImageLazy from '../ImageLazy'
  5. import dayjs from 'dayjs'
  6. import { myTableTransferSize, resJiLianFu } from '@/utils/dataChange'
  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. staBtn?: any
  17. lastBtn?: 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. // antd Table rowSelection 配置,支持跨页多选等
  29. rowSelection?: any
  30. }
  31. // 表格内容定制化
  32. const tableComObj = (key: string, val: string[]) => {
  33. const obj = {
  34. A: (
  35. <a href={val[1]} target='_blank' title={val[1]} rel='noreferrer'>
  36. {val[0]}
  37. </a>
  38. )
  39. }
  40. return Reflect.get(obj, key)
  41. }
  42. function MyTable({
  43. yHeight,
  44. list,
  45. columnsTemp,
  46. total,
  47. pageNum = 1,
  48. pageSize = 10,
  49. pagingInfo = {
  50. showQuickJumper: true,
  51. position: ['bottomCenter'],
  52. showSizeChanger: true
  53. },
  54. onChange,
  55. lastBtn = [],
  56. staBtn = [],
  57. classKey = '',
  58. merge,
  59. myTitle,
  60. isNull = '(空)',
  61. widthSet,
  62. rowKey,
  63. rowSelection
  64. }: Props) {
  65. useEffect(() => {
  66. const dom = document.querySelector(`.MyTable${classKey} .ant-table-body`) as HTMLDivElement
  67. if (dom && yHeight) dom.style.height = yHeight + 'px'
  68. }, [classKey, yHeight])
  69. // 页码变化
  70. const paginationChange = useCallback(
  71. () => (pageNum: number, pageSize: number) => {
  72. if (onChange) {
  73. onChange(pageNum, pageSize)
  74. }
  75. },
  76. [onChange]
  77. )
  78. const dataChangeFu = useCallback(
  79. (v: any) => {
  80. /**
  81. * index:序号
  82. * txt:正常数据
  83. * img:图片
  84. * txtChange:判断显示不同字段
  85. * text:文字比较多的情况
  86. */
  87. const obj = {
  88. index: (_: any, __: any, index: number) => index + 1 + (pageNum - 1) * pageSize,
  89. txt: (item: any) => item[v[2]] || isNull,
  90. adiutTxt: (item: any) => {
  91. let txt1 = item.status === 1 ? '同意' : item.status === 2 ? '不同意' : '待处理'
  92. if (item.isUse === 0) txt1 = '(空)'
  93. const txt2 = item.isAuto === 1 ? '(自动)' : ''
  94. return txt1 + txt2
  95. },
  96. // 日期去掉00:00:00
  97. dateRes: (item: any) => {
  98. let res = item[v[2]] ? dayjs(item[v[2]]).format('YYYY-MM-DD') : isNull
  99. return res
  100. },
  101. // 多个字段拼接
  102. ping: (item: any) => (item[v[2]] || '') + (resJiLianFu(item[v[3]]) || '') || isNull,
  103. // 这个模块特有的级联控制
  104. txtC: (item: any) => resJiLianFu(item[v[2]]),
  105. txtCTag: (item: any) => resJiLianFu(item[v[2]], 'tag'),
  106. // 尺寸
  107. size: myTableTransferSize,
  108. img: (item: any) => (
  109. <div className='tableImgAuto'>
  110. <ImageLazy
  111. width={60}
  112. height={60}
  113. src={item[v[2]] || item.thumb || item.thumbPc}
  114. srcBig={item.thumbPc || item.thumb}
  115. />
  116. </div>
  117. ),
  118. select: (item: any) => {
  119. let txt = isNull
  120. const data = v[3]
  121. const id = item[v[2]]
  122. const obj = data.find((v: any) => v.value === id)
  123. if (obj) txt = obj.label
  124. return txt
  125. },
  126. txtChange: (item: any) => Reflect.get(v[3], item[v[2]]) || v[4] || isNull,
  127. text: (item: any) => {
  128. let tempCom: any = item[v[2]] || isNull
  129. if (tempCom.length >= v[3]) {
  130. tempCom = tempCom.substring(0, v[3]) + '...'
  131. }
  132. if (v[4]) {
  133. tempCom = tableComObj(v[4], [tempCom, item[v[2]]])
  134. } else if (item[v[2]] && item[v[2]].length >= v[3]) {
  135. tempCom = (
  136. <span style={{ cursor: 'pointer' }} title={item[v[2]]}>
  137. {tempCom}
  138. </span>
  139. )
  140. }
  141. return tempCom
  142. },
  143. custom: (item: any) => v[2]?.(item) || isNull
  144. }
  145. return Reflect.get(obj, v[0])
  146. },
  147. [isNull, pageNum, pageSize]
  148. )
  149. const columns = useMemo(() => {
  150. const arr: any = columnsTemp.map((v: any) => ({
  151. title: myTitle && v.includes(myTitle.name) ? myTitle.Com : v[1],
  152. render: dataChangeFu(v),
  153. width: widthSet && Reflect.get(widthSet, v[2]) ? Reflect.get(widthSet, v[2]) : 'auto',
  154. onCell:
  155. merge && v.includes(merge.type)
  156. ? // {rowSpan:3}
  157. (item: any, index: number) => ({
  158. rowSpan: index === 0 ? merge.num : 0
  159. })
  160. : ''
  161. }))
  162. return arr
  163. }, [columnsTemp, dataChangeFu, merge, myTitle, widthSet])
  164. return (
  165. <Table
  166. className={`${styles.MyTable} MyTable${classKey}`}
  167. scroll={{ y: yHeight ? yHeight : '' }}
  168. dataSource={list}
  169. columns={[...staBtn, ...columns, ...lastBtn]}
  170. rowKey={rowKey ? rowKey : 'id'}
  171. rowSelection={rowSelection}
  172. pagination={
  173. pagingInfo
  174. ? {
  175. ...pagingInfo,
  176. current: pageNum,
  177. pageSize: pageSize,
  178. total: total,
  179. onChange: paginationChange()
  180. }
  181. : false
  182. }
  183. />
  184. )
  185. }
  186. const MemoMyTable = React.memo(MyTable)
  187. export default MemoMyTable