tableConfig.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. import React from 'react'
  2. import { Space, Switch, Image, Popover, TableProps, Typography } from 'antd'
  3. import '../index.less'
  4. import { copy } from '@/utils/utils'
  5. import { DELIVERY_MODE, DYNAMIC_CREATIVE_TYPE } from '../const'
  6. import { ELEMENT_ENUM, SITE_SET_ENUM, creativeTemplate } from '../../tencentAdPutIn/const'
  7. import { AD_STATUS } from '.'
  8. const { Text } = Typography;
  9. function tableConfig(reviewStatusDetails: (value: any) => void): any {
  10. return [
  11. {
  12. title: '启停',
  13. dataIndex: 'configuredStatus',
  14. key: 'configuredStatus',
  15. align: 'center',
  16. width: 40,
  17. fixed: 'left',
  18. render: (a: string, b: any) => {
  19. return <Switch size="small" checked={a === 'AD_STATUS_NORMAL'} onChange={(checked) => { }} />
  20. }
  21. },
  22. {
  23. title: '品牌形象',
  24. dataIndex: 'brand',
  25. key: 'brand',
  26. width: 110,
  27. ellipsis: true,
  28. render: (_: any[], b: any) => {
  29. let brand = b?.creativeComponents?.brand
  30. return brand?.length > 0 ? <Space>
  31. <img src={brand?.[0]?.value?.brandImageUrl} height={18} />
  32. <span>{brand?.[0]?.value?.brandName}</span>
  33. </Space> : '--'
  34. }
  35. },
  36. {
  37. title: '文本标题',
  38. dataIndex: 'title',
  39. key: 'title',
  40. width: 140,
  41. ellipsis: true,
  42. render: (_: any[], b: any) => {
  43. let title = b?.creativeComponents?.title
  44. return title?.length > 0 ? title.map((item: { value: { content: any } }, index: number) => `标题${index + 1}:${item?.value?.content}`)?.toString() : '--'
  45. }
  46. },
  47. {
  48. title: '文本描述',
  49. dataIndex: 'description',
  50. key: 'description',
  51. width: 140,
  52. ellipsis: true,
  53. render: (_: any[], b: any) => {
  54. let description = b?.creativeComponents?.description
  55. return description?.length > 0 ? description.map((item: { value: { content: any } }, index: number) => `描述${index + 1}:${item?.value?.content}`)?.toString() : '--'
  56. }
  57. },
  58. {
  59. title: '单图片',
  60. dataIndex: 'image',
  61. key: 'image',
  62. width: 140,
  63. ellipsis: true,
  64. render: (_: any[], b: any) => {
  65. let image = b?.creativeComponents?.image
  66. return <div style={{ minHeight: 50, display: 'flex', alignItems: 'center' }}>
  67. {image?.length > 0 ? <div className='tableScrollbar' style={{ overflow: 'hidden', overflowX: 'auto' }}>
  68. <Image.PreviewGroup>
  69. {image?.map((item: { componentId: string; value: { imageUrl: string | undefined } }, index: string) => <Image key={item?.componentId + '_' + index} src={item?.value?.imageUrl} height={45} />)}
  70. </Image.PreviewGroup>
  71. </div> : '--'}
  72. </div>
  73. }
  74. },
  75. {
  76. title: '图集',
  77. dataIndex: 'imageList',
  78. key: 'imageList',
  79. width: 140,
  80. ellipsis: true,
  81. render: (_: any[], b: any) => {
  82. let imageList = b?.creativeComponents?.imageList
  83. return imageList?.length > 0 ? <div className='tableScrollbar' style={{ overflow: 'hidden', overflowX: 'auto', display: 'flex', gap: 10 }}>
  84. {imageList?.map((item: { value: { list: any[] } }, index: React.Key | null | undefined) => <Image.PreviewGroup key={index}>
  85. {item?.value?.list?.map((list: any, i: number) => <Image key={i} src={list?.imageUrl} height={45} />)}
  86. </Image.PreviewGroup>)}
  87. </div> : '--'
  88. }
  89. },
  90. {
  91. title: '视频',
  92. dataIndex: 'video',
  93. key: 'video',
  94. width: 140,
  95. ellipsis: true,
  96. render: (_: any[], b: any) => {
  97. let video = b?.creativeComponents?.video
  98. return video?.length > 0 ? <Popover
  99. placement='right'
  100. content={< div >
  101. <Space style={{ maxWidth: 300, display: 'flex', flexFlow: 'row wrap', margin: '10px 0' }}>
  102. {video?.map((item: { value: { videoUrl: string | undefined } }, index: React.Key | null | undefined) => <video key={index} src={item?.value?.videoUrl} style={{ width: 250 }} controls />)}
  103. </Space>
  104. </div >}
  105. destroyTooltipOnHide
  106. mouseEnterDelay={0.5}
  107. >
  108. <Space style={{ width: '100%' }}>
  109. <video src={video?.[0]?.value?.videoUrl} style={{ maxHeight: 40, maxWidth: 60 }} />
  110. </Space>
  111. </Popover> : '--'
  112. }
  113. },
  114. {
  115. title: '轮播',
  116. dataIndex: 'floatingZone',
  117. key: 'floatingZone',
  118. width: 150,
  119. ellipsis: true,
  120. render: (_: any[], b: any) => {
  121. let floatingZone = b?.creativeComponents?.floatingZone
  122. return floatingZone?.length > 0 ? <div className='tableScrollbar' style={{ overflow: 'hidden', overflowX: 'auto' }}>
  123. {floatingZone?.map((item: { value: { floatingZoneImageUrl: string | undefined; floatingZoneName: boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | null | undefined; floatingZoneDesc: boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | null | undefined } }, index: React.Key | null | undefined) => <div key={index} style={{ display: 'flex', alignItems: 'center', gap: 1 }}>
  124. <div style={{ width: 40 }}>
  125. <Image src={item?.value?.floatingZoneImageUrl} width={40} height={40} />
  126. </div>
  127. <div>
  128. <span>{item?.value?.floatingZoneName}</span><br />
  129. <span>{item?.value?.floatingZoneDesc}</span>
  130. </div>
  131. </div>)}
  132. </div> : '--'
  133. }
  134. },
  135. {
  136. title: '所属账号',
  137. dataIndex: 'accountId',
  138. key: 'accountId',
  139. align: 'center',
  140. width: 80,
  141. ellipsis: true,
  142. render: (a: string) => {
  143. return <Space>
  144. <a onClick={() => copy(a)} >{a}</a>
  145. </Space>
  146. }
  147. },
  148. {
  149. title: '广告ID',
  150. dataIndex: 'adgroupId',
  151. key: 'adgroupId',
  152. align: 'center',
  153. width: 100,
  154. ellipsis: true,
  155. render: (a: string, b: any) => {
  156. return <Space>
  157. <a onClick={() => copy(a)} >{a}</a>
  158. </Space>
  159. }
  160. },
  161. {
  162. title: '创意名称',
  163. dataIndex: 'dynamicCreativeName',
  164. key: 'dynamicCreativeName',
  165. align: 'center',
  166. width: 120,
  167. ellipsis: true
  168. },
  169. {
  170. title: '创意ID',
  171. dataIndex: 'dynamicCreativeId',
  172. key: 'dynamicCreativeId',
  173. align: 'center',
  174. width: 100,
  175. ellipsis: true,
  176. render: (a: string, b: any) => {
  177. return <a onClick={() => copy(a)} >{a}</a>
  178. }
  179. },
  180. {
  181. title: '投放模式',
  182. dataIndex: 'deliveryMode',
  183. key: 'deliveryMode',
  184. align: 'center',
  185. width: 120,
  186. render: (a: string) => {
  187. return DELIVERY_MODE[a]
  188. }
  189. },
  190. {
  191. title: '创意形式匹配方式',
  192. dataIndex: 'dynamicCreativeType',
  193. key: 'dynamicCreativeType',
  194. align: 'center',
  195. width: 120,
  196. render: (a: string) => {
  197. return DYNAMIC_CREATIVE_TYPE[a]
  198. }
  199. },
  200. {
  201. title: '创意形式',
  202. dataIndex: 'creativeTemplateId',
  203. key: 'creativeTemplateId',
  204. align: 'center',
  205. width: 120,
  206. ellipsis: true,
  207. render: (a: string) => {
  208. return creativeTemplate[a]
  209. }
  210. },
  211. {
  212. title: '审核状态',
  213. dataIndex: 'reviewStatusCn',
  214. key: 'reviewStatusCn',
  215. align: 'center',
  216. width: 100,
  217. render: (a: string, b: any) => {
  218. return <Space direction="vertical" size={0}>
  219. <span style={{ fontSize: 12 }}>{a}</span>
  220. <a style={{ fontSize: 12 }} onClick={() => { reviewStatusDetails(b) }}>详情</a>
  221. </Space>
  222. }
  223. }
  224. ]
  225. }
  226. export const tableConfigDetail = (): TableProps<any>['columns'] => {
  227. return [
  228. {
  229. title: '创意组件',
  230. dataIndex: 'componentInfo',
  231. key: 'componentInfo',
  232. width: 180,
  233. render: (value) => {
  234. if (value) {
  235. let { componentId, componentType } = value
  236. return <Space direction="vertical" size={0}>
  237. <Text style={{ fontSize: 12 }}>{ELEMENT_ENUM[componentType]}</Text>
  238. <Text type="secondary" style={{ fontSize: 12 }}>{componentId}</Text>
  239. </Space>
  240. }
  241. return null
  242. },
  243. onCell: (record) => ({
  244. rowSpan: record.rowSpan
  245. })
  246. },
  247. {
  248. title: '组件审核结果',
  249. dataIndex: 'reviewStatus',
  250. key: 'reviewStatus',
  251. width: 120,
  252. render: (value, records) => {
  253. if (!records?.componentInfo) {
  254. return null
  255. }
  256. return <span style={{ fontSize: 12 }}>{AD_STATUS[value]}</span>
  257. }
  258. },
  259. {
  260. title: '组件元素',
  261. dataIndex: 'elementName',
  262. key: 'elementName',
  263. width: 155,
  264. render: (value, records) => {
  265. return <>
  266. <Text type="secondary" style={{ fontSize: 12 }}>{value}</Text>
  267. <div style={{ maxWidth: 178 }}>
  268. {records.elementType === 'VIDEO' ? <Popover
  269. placement='right'
  270. content={< div >
  271. <Space style={{ maxWidth: 300, display: 'flex', flexFlow: 'row wrap', margin: '10px 0' }}>
  272. <video src={records.elementValue} style={{ width: 250 }} controls />
  273. </Space>
  274. </div >}
  275. destroyTooltipOnHide
  276. mouseEnterDelay={0.5}
  277. >
  278. <video src={records.elementValue} style={{ maxHeight: 40, maxWidth: 60 }} />
  279. </Popover> : records.elementType === 'IMAGE' ? <img src={records.elementValue} style={{ maxHeight: 40, maxWidth: 60 }} />
  280. : <Text style={{ fontSize: 12 }} ellipsis strong>{records.elementValue}</Text>}
  281. </div>
  282. </>
  283. }
  284. },
  285. {
  286. title: '驳回原因',
  287. dataIndex: 'elementRejectDetailInfo',
  288. key: 'elementRejectDetailInfo',
  289. width: 560,
  290. render: (value) => {
  291. return value ? <Text style={{ fontSize: 12 }}>{value?.map((item: { reason: any }) => item.reason)?.join(',')}</Text> : null
  292. }
  293. },
  294. {
  295. title: '影响版位',
  296. dataIndex: 'siteSetList',
  297. key: 'siteSetList',
  298. width: 125,
  299. render: (_, records) => {
  300. let siteSetList = records?.elementRejectDetailInfo?.siteSetList
  301. return siteSetList ? <Text style={{ fontSize: 12 }}>{siteSetList?.map((item: { siteSet: any }) => SITE_SET_ENUM[item?.siteSet])?.join(',')}</Text> : null
  302. }
  303. },
  304. ]
  305. }
  306. export default tableConfig