tableConfig.tsx 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. import { Space, TableProps, Typography } from "antd"
  2. import React from "react"
  3. const { Text, Title } = Typography;
  4. import style from './index.less'
  5. import VideoNews from "@/pages/launchSystemNew/components/newsModal/videoNews";
  6. import styles from './Material/index.less'
  7. import { OPTIMIZATIONGOAL_ENUM } from "../const";
  8. const columns = (): TableProps<any>['columns'] => {
  9. return [
  10. {
  11. title: '广告',
  12. dataIndex: 'adgroup',
  13. key: 'adgroup',
  14. align: 'center',
  15. children: [
  16. {
  17. title: '广告名称',
  18. dataIndex: 'adgroupName',
  19. key: 'adgroupName',
  20. width: 250,
  21. render: (_, b) => {
  22. return <Text style={{ fontSize: 12 }}>{b?.adgroupsDto?.adgroupName}</Text>
  23. },
  24. onCell: (record, index = 0) => ({
  25. rowSpan: record?.isRowSpan ? record.rowSpan : !(index % record.rowSpan) ? record.rowSpan : 0
  26. })
  27. },
  28. {
  29. title: '营销内容',
  30. dataIndex: 'productName',
  31. key: 'productName',
  32. width: 200,
  33. render: (_, b) => {
  34. if (['MARKETING_TARGET_TYPE_FICTION', 'MARKETING_TARGET_TYPE_SHORT_DRAMA'].includes(b.adgroupsDto?.marketingAssetOuterSpec?.marketingTargetType)) {
  35. return <Space size={0} direction="vertical">
  36. <Text style={{ fontSize: 12 }}>推广产品:{b?.productDto?.marketingAssetName}(产品ID:{b?.productDto?.marketingAssetId})</Text>
  37. {(b.adgroupsDto?.marketingCarrierType === 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT' && b?.marketingCarrierDto) && <Text style={{ fontSize: 12 }}>营销载体:{b.marketingCarrierDto.map((item: { wechatOfficialAccountName: any; wechatOfficialAccountId: any; }) => `${item?.wechatOfficialAccountName}(${item?.wechatOfficialAccountId})`)?.toString()}</Text>}
  38. <Text style={{ fontSize: 12 }}>转化归因:{b?.userActionSetsList ? b?.userActionSetsList.map((item: { name: any; }) => item.name).toString() : b?.conversionList ? b?.conversionList.map((item: { conversionName: any; conversionId: any; }) => `${item?.conversionName}(${item.conversionId})`).toString() : '暂未配置'}</Text>
  39. </Space>
  40. } else if (['MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT'].includes(b.adgroupsDto?.marketingAssetOuterSpec?.marketingTargetType)) {
  41. return <Space size={0} direction="vertical">
  42. <Text style={{ fontSize: 12 }}>推广产品:微信公众号</Text>
  43. <Text style={{ fontSize: 12 }}>营销载体:微信公众号</Text>
  44. <Text style={{ fontSize: 12 }}>应用:{b?.productDto?.wechatOfficialAccountName}({b?.productDto?.wechatOfficialAccountId})</Text>
  45. <Text style={{ fontSize: 12 }}>转化归因:{b?.userActionSetsList ? b?.userActionSetsList.map((item: { name: any; }) => item.name).toString() : b?.conversionList ? b?.conversionList.map((item: { conversionName: any; conversionId: any; }) => `${item?.conversionName}(${item.conversionId})`).toString() : '暂未配置'}</Text>
  46. </Space>
  47. } else if (['MARKETING_TARGET_TYPE_MINI_PROGRAM_WECHAT'].includes(b.adgroupsDto?.marketingAssetOuterSpec?.marketingTargetType)) {
  48. return <Space size={0} direction="vertical">
  49. <Text style={{ fontSize: 12 }}>推广产品:微信小程序(产品本地ID:{b?.adgroupsDto?.sysWechatAppId})</Text>
  50. <Text style={{ fontSize: 12 }}>转化归因:{b?.userActionSetsList ? b?.userActionSetsList.map((item: { name: any; }) => item.name).toString() : b?.conversionList ? b?.conversionList.map((item: { conversionName: any; conversionId: any; }) => `${item?.conversionName}(${item.conversionId})`).toString() : '暂未配置'}</Text>
  51. </Space>
  52. } else if (['MARKETING_TARGET_TYPE_WECHAT_WORK'].includes(b.adgroupsDto?.marketingAssetOuterSpec?.marketingTargetType)) {
  53. return <Space size={0} direction="vertical">
  54. <Text style={{ fontSize: 12 }}>推广产品:企业微信(产品本地ID:{b?.adgroupsDto?.sysCorpWechatId})</Text>
  55. <Text style={{ fontSize: 12 }}>转化归因:{b?.userActionSetsList ? b?.userActionSetsList.map((item: { name: any; }) => item.name).toString() : b?.conversionList ? b?.conversionList.map((item: { conversionName: any; conversionId: any; }) => `${item?.conversionName}(${item.conversionId})`).toString() : '暂未配置'}</Text>
  56. </Space>
  57. } else if (['MARKETING_TARGET_TYPE_WECHAT_MINI_GAME'].includes(b.adgroupsDto?.marketingAssetOuterSpec?.marketingTargetType)) {
  58. return <Space size={0} direction="vertical">
  59. <Text style={{ fontSize: 12 }}>推广产品:微信小游戏(appId:{b?.adgroupsDto?.wxGameAppId})</Text>
  60. <Text style={{ fontSize: 12 }}>转化归因:{b?.userActionSetsList ? b?.userActionSetsList.map((item: { name: any; }) => item.name).toString() : b?.conversionList ? b?.conversionList.map((item: { conversionName: any; conversionId: any; }) => `${item?.conversionName}(${item.conversionId})`).toString() : '暂未配置'}</Text>
  61. </Space>
  62. }
  63. return 'ERROR,请联系管理员'
  64. },
  65. onCell: (record, index = 0) => ({
  66. rowSpan: record?.isRowSpan ? record.rowSpan : !(index % record.rowSpan) ? record.rowSpan : 0
  67. }),
  68. },
  69. {
  70. title: '定向',
  71. dataIndex: 'targeting',
  72. key: 'targeting',
  73. width: 170,
  74. render: (_, b) => {
  75. return <Text style={{ fontSize: 12 }}>{b?.targetDto?.targetingName}</Text>
  76. },
  77. onCell: (record, index = 0) => ({
  78. rowSpan: record?.isRowSpan ? record.rowSpan : !(index % record.rowSpan) ? record.rowSpan : 0
  79. }),
  80. },
  81. {
  82. title: '预算与出价',
  83. dataIndex: 'dailyBudget',
  84. key: 'dailyBudget',
  85. width: 170,
  86. render: (_, b) => {
  87. let { optimizationGoal, dailyBudget, bidAmount, bidMode } = b?.adgroupsDto
  88. return <Space size={0} direction="vertical">
  89. <Text style={{ fontSize: 12 }}>广告日预算:{dailyBudget ? dailyBudget + '元/天' : '不限'}</Text>
  90. <Text style={{ fontSize: 12 }}>出价:{bidAmount}元/{optimizationGoal ? (OPTIMIZATIONGOAL_ENUM as any)[optimizationGoal] : ['BID_MODE_OCPM', 'BID_MODE_OCPC'].includes(bidMode) ? '千次曝光' : '点击'}</Text>
  91. </Space>
  92. },
  93. onCell: (record, index = 0) => ({
  94. rowSpan: record?.isRowSpan ? record.rowSpan : !(index % record.rowSpan) ? record.rowSpan : 0
  95. }),
  96. },
  97. ]
  98. },
  99. {
  100. title: '创意',
  101. dataIndex: 'dynamicDto',
  102. key: 'dynamicDto',
  103. align: 'center',
  104. children: [
  105. {
  106. title: '创意名称',
  107. dataIndex: 'dynamicCreativeName',
  108. key: 'dynamicCreativeName',
  109. width: 200,
  110. render: (_, b) => {
  111. return <Text style={{ fontSize: 12 }}>{b?.dynamicDto?.dynamicCreativeName}</Text>
  112. }
  113. },
  114. {
  115. title: '创意素材',
  116. dataIndex: 'dynamicGroup',
  117. key: 'dynamicGroup',
  118. width: 210,
  119. render: (_, b) => {
  120. let deliveryMode = b?.dynamicDto?.deliveryMode
  121. let dynamicGroup = b?.dynamicGroup
  122. if (dynamicGroup && Object.keys(dynamicGroup).length) {
  123. let keys = Object.keys(dynamicGroup)
  124. if (deliveryMode === "DELIVERY_MODE_CUSTOMIZE") {
  125. return <>
  126. <div className={style.detail_body_m}>
  127. {(keys.includes('video_id') || keys.includes('short_video1')) ? <>
  128. <Title style={{ fontSize: 12, color: '#1890ff', marginBottom: 0, width: '100%' }}>已选1个视频,0张图片</Title>
  129. <div className={style.video}>
  130. <VideoNews src={dynamicGroup?.video_id?.url || dynamicGroup?.short_video1?.url} keyFrameImageUrl={dynamicGroup?.video_id?.keyFrameImageUrl || dynamicGroup?.short_video1?.keyFrameImageUrl}/>
  131. {dynamicGroup?.cover_id && <div className={style.cover_image} style={{ marginLeft: 4 }}>
  132. <img src={dynamicGroup?.cover_id?.url} />
  133. </div>}
  134. </div>
  135. </> : keys.includes('image_id') ? <>
  136. <Title style={{ fontSize: 12, color: '#1890ff', marginBottom: 0, width: '100%' }}>已选0个视频,1张图片</Title>
  137. <div className={style.cover_image}>
  138. <img src={dynamicGroup?.image_id?.url} />
  139. </div>
  140. </> : (keys.includes('image_list') || keys.includes('element_story')) ? <>
  141. <Title style={{ fontSize: 12, color: '#1890ff', marginBottom: 0, width: '100%' }}>已选1个组图, 0个视频</Title>
  142. {dynamicGroup?.[keys.includes('image_list') ? 'image_list' : 'element_story']?.map((item: { url: string | undefined; }, index: undefined) => <div className={style.cover_image} key={index} style={{ width: 30, height: 24, minWidth: 32 }}>
  143. <img src={item?.url} />
  144. </div>)}
  145. </> : null}
  146. </div>
  147. </>
  148. } else {
  149. return <div style={{ display: 'flex', gap: 5, flexWrap: 'wrap' }}>
  150. {dynamicGroup?.list?.map((item: any, index: number) => {
  151. if (Array.isArray(item)) {
  152. let length = item.length
  153. return <div className={styles.boxList_body_item} key={index} style={{ width: 30, height: 30 }}>
  154. <div className={styles.content} style={{ width: 30, height: 30 }}>
  155. {item.map((l, i) => <img src={l?.url} key={i} style={{ width: length >= 6 ? 9.999 : 14.999 }} />)}
  156. </div>
  157. </div>
  158. } else if (item?.url?.includes('mp4') || item?.keyFrameImageUrl) {
  159. return <div className={styles.boxList_body_item} key={index} style={{ width: 30, height: 30 }}>
  160. <div className={styles.content} style={{ width: 30, height: 30 }}>
  161. <VideoNews src={item?.url} style={{ width: 30, height: 30 }} keyFrameImageUrl={item?.keyFrameImageUrl} maskBodyStyle={{ backgroundColor: "rgba(242, 246, 254, 0.1)" }} />
  162. </div>
  163. </div>
  164. } else {
  165. return <div className={styles.boxList_body_item} key={index} style={{ width: 30, height: 30 }}>
  166. <div className={styles.content} style={{ width: 30, height: 30 }}><img src={item?.url} /></div>
  167. </div>
  168. }
  169. })}
  170. </div>
  171. }
  172. } else {
  173. return <Text style={{ fontSize: 12 }}>无需配置</Text>
  174. }
  175. }
  176. },
  177. {
  178. title: '创意文案',
  179. dataIndex: 'textDto',
  180. key: 'textDto',
  181. width: 200,
  182. render: (value, b) => {
  183. let deliveryMode = b?.dynamicDto?.deliveryMode
  184. if (value && Object.keys(value).length) {
  185. if (deliveryMode === "DELIVERY_MODE_CUSTOMIZE") {
  186. return <div className={style.detail_body} style={{ height: 'auto' }}>
  187. {Object.keys(value)?.map((key, index: number) => {
  188. return <div key={index}>
  189. {key === 'description' ? <>
  190. <Title level={5} style={{ fontSize: 12 }}>{'文案'}</Title>
  191. {value['description'].map((t: string, index: number) => <div className={style.text} key={index}><Text ellipsis={{ tooltip: true }}>{t}</Text></div>)}
  192. </> : key === 'title' ? <>
  193. <Title level={5} style={{ fontSize: 12 }}>{'标题'}</Title>
  194. {value['title'].map((t: string, index: number) => <div className={style.text} key={index}><Text ellipsis={{ tooltip: true }}>{t}</Text></div>)}
  195. </> : null}
  196. </div>
  197. })}
  198. </div>
  199. } else {
  200. return <div className={style.detail_body} style={{ height: 'auto' }}>
  201. {Object.keys(value)?.map((key, index: number) => {
  202. return <div key={index}>
  203. {key === 'description' ? <>
  204. <Title level={5} style={{ fontSize: 12 }}>{'文案'}</Title>
  205. {value['description'].map((t: string, index: number) => <div className={style.text} key={index}><Text ellipsis={{ tooltip: true }}>{t}</Text></div>)}
  206. </> : key === 'title' ? <>
  207. <Title level={5} style={{ fontSize: 12 }}>{'标题'}</Title>
  208. {value['title'].map((t: string, index: number) => <div className={style.text} key={index}><Text ellipsis={{ tooltip: true }}>{t}</Text></div>)}
  209. </> : null}
  210. </div>
  211. })}
  212. </div>
  213. }
  214. } else {
  215. return <Text style={{ fontSize: 12 }}>无需配置</Text>
  216. }
  217. }
  218. },
  219. {
  220. title: '跳转类型',
  221. dataIndex: 'pageListDto',
  222. key: 'pageListDto',
  223. width: 200,
  224. render: (_, b) => {
  225. let pageListDto = b?.pageListDto
  226. let pageType = b?.dynamicDto?.creativeComponents?.mainJumpInfo?.[0]?.value?.pageType
  227. if (pageType === 'PAGE_TYPE_WECHAT_MINI_GAME') {
  228. return <Text style={{ fontSize: 12 }}>无需配置</Text>
  229. }
  230. return <Text style={{ fontSize: 12, wordBreak: 'break-all' }}>
  231. {pageType === 'PAGE_TYPE_OFFICIAL' ? '灵鹊落地页' : pageType === 'PAGE_TYPE_WECHAT_MINI_PROGRAM' ? '微信小程序' : '原生推广页'}:
  232. {pageListDto?.map((item: { pageName: any; }) => item?.pageName)?.join(',')}
  233. </Text>
  234. }
  235. }
  236. ]
  237. }
  238. ]
  239. }
  240. export const columnsAddDynamic = (): TableProps<any>['columns'] => {
  241. return [
  242. {
  243. title: '广告',
  244. dataIndex: 'adgroup',
  245. key: 'adgroup',
  246. align: 'center',
  247. children: [
  248. {
  249. title: '广告名称',
  250. dataIndex: 'adgroupName',
  251. key: 'adgroupName',
  252. width: 250,
  253. render: (_, b) => {
  254. return <Text style={{ fontSize: 12 }}>{b?.adgroupsDto?.adgroupName}</Text>
  255. },
  256. onCell: (record, index = 0) => ({
  257. rowSpan: !(index % record.rowSpan) ? record.rowSpan : 0
  258. }),
  259. },
  260. ]
  261. },
  262. {
  263. title: '创意',
  264. dataIndex: 'dynamicDto',
  265. key: 'dynamicDto',
  266. align: 'center',
  267. children: [
  268. {
  269. title: '创意名称',
  270. dataIndex: 'dynamicCreativeName',
  271. key: 'dynamicCreativeName',
  272. width: 200,
  273. render: (_, b) => {
  274. return <Text style={{ fontSize: 12 }}>{b?.dynamicDto?.dynamicCreativeName}</Text>
  275. }
  276. },
  277. {
  278. title: '创意素材',
  279. dataIndex: 'dynamicGroup',
  280. key: 'dynamicGroup',
  281. width: 200,
  282. render: (_, b) => {
  283. let deliveryMode = b?.dynamicDto?.deliveryMode
  284. let dynamicGroup = b?.dynamicGroup
  285. if (dynamicGroup && Object.keys(dynamicGroup).length) {
  286. let keys = Object.keys(dynamicGroup)
  287. if (deliveryMode === "DELIVERY_MODE_CUSTOMIZE") {
  288. // return <Text style={{ fontSize: 12, color: '#1890ff' }}>已选{(keys.includes('video_id') || keys.includes('short_video1')) ? '1个视频,0张图片' : keys.includes('image_id') ? '0个视频,1张图片' : (keys.includes('image_list') || keys.includes('element_story') ? '1个组图, 0个视频' : '')}</Text>
  289. return <>
  290. <div className={style.detail_body_m}>
  291. {(keys.includes('video_id') || keys.includes('short_video1')) ? <>
  292. <Title style={{ fontSize: 12, color: '#1890ff', marginBottom: 0, width: '100%' }}>已选1个视频,0张图片</Title>
  293. <div className={style.video}>
  294. <VideoNews src={dynamicGroup?.video_id?.url || dynamicGroup?.short_video1?.url} keyFrameImageUrl={dynamicGroup?.video_id?.keyFrameImageUrl || dynamicGroup?.short_video1?.keyFrameImageUrl}/>
  295. {dynamicGroup?.cover_id && <div className={style.cover_image} style={{ marginLeft: 4 }}>
  296. <img src={dynamicGroup?.cover_id?.url} />
  297. </div>}
  298. </div>
  299. </> : keys.includes('image_id') ? <>
  300. <Title style={{ fontSize: 12, color: '#1890ff', marginBottom: 0, width: '100%' }}>已选0个视频,1张图片</Title>
  301. <div className={style.cover_image}>
  302. <img src={dynamicGroup?.image_id?.url} />
  303. </div>
  304. </> : (keys.includes('image_list') || keys.includes('element_story')) ? <>
  305. <Title style={{ fontSize: 12, color: '#1890ff', marginBottom: 0, width: '100%' }}>已选1个组图, 0个视频</Title>
  306. {dynamicGroup?.[keys.includes('image_list') ? 'image_list' : 'element_story']?.map((item: { url: string | undefined; }, index: undefined) => <div className={style.cover_image} key={index} style={{ width: 30, height: 24, minWidth: 32 }}>
  307. <img src={item?.url} />
  308. </div>)}
  309. </> : null}
  310. </div>
  311. </>
  312. } else {
  313. return <div style={{ display: 'flex', gap: 5, flexWrap: 'wrap' }}>
  314. {dynamicGroup?.list?.map((item: any, index: number) => {
  315. if (Array.isArray(item)) {
  316. let length = item.length
  317. return <div className={styles.boxList_body_item} key={index} style={{ width: 30, height: 30 }}>
  318. <div className={styles.content} style={{ width: 30, height: 30 }}>
  319. {item.map((l, i) => <img src={l?.url} key={i} style={{ width: length === 6 ? 9.999 : 14.999 }} />)}
  320. </div>
  321. </div>
  322. } else if (item?.url?.includes('mp4') || item?.keyFrameImageUrl) {
  323. return <div className={styles.boxList_body_item} key={index} style={{ width: 30, height: 30 }}>
  324. <div className={styles.content} style={{ width: 30, height: 30 }}>
  325. <VideoNews src={item?.url} style={{ width: 30, height: 30 }} keyFrameImageUrl={item?.keyFrameImageUrl} maskBodyStyle={{ backgroundColor: "rgba(242, 246, 254, 0.1)" }} />
  326. </div>
  327. </div>
  328. } else {
  329. return <div className={styles.boxList_body_item} key={index} style={{ width: 30, height: 30 }}>
  330. <div className={styles.content} style={{ width: 30, height: 30 }}><img src={item?.url} /></div>
  331. </div>
  332. }
  333. })}
  334. </div>
  335. }
  336. } else {
  337. return <Text style={{ fontSize: 12 }}>无需配置</Text>
  338. }
  339. }
  340. },
  341. {
  342. title: '创意文案',
  343. dataIndex: 'textDto',
  344. key: 'textDto',
  345. width: 200,
  346. render: (value, b) => {
  347. let deliveryMode = b?.dynamicDto?.deliveryMode
  348. if (value && Object.keys(value).length) {
  349. if (deliveryMode === "DELIVERY_MODE_CUSTOMIZE") {
  350. return <div className={style.detail_body} style={{ height: 'auto' }}>
  351. {Object.keys(value)?.map((key, index: number) => {
  352. return <div key={index}>
  353. {key === 'description' ? <>
  354. <Title level={5} style={{ fontSize: 12 }}>{'文案'}</Title>
  355. {value['description'].map((t: string, index: number) => <div className={style.text} key={index}><Text ellipsis={{ tooltip: true }}>{t}</Text></div>)}
  356. </> : key === 'title' ? <>
  357. <Title level={5} style={{ fontSize: 12 }}>{'标题'}</Title>
  358. {value['title'].map((t: string, index: number) => <div className={style.text} key={index}><Text ellipsis={{ tooltip: true }}>{t}</Text></div>)}
  359. </> : null}
  360. </div>
  361. })}
  362. </div>
  363. } else {
  364. return <div className={style.detail_body} style={{ height: 'auto' }}>
  365. {Object.keys(value)?.map((key, index: number) => {
  366. return <div key={index}>
  367. {key === 'description' ? <>
  368. <Title level={5} style={{ fontSize: 12 }}>{'文案'}</Title>
  369. {value['description'].map((t: string, index: number) => <div className={style.text} key={index}><Text ellipsis={{ tooltip: true }}>{t}</Text></div>)}
  370. </> : key === 'title' ? <>
  371. <Title level={5} style={{ fontSize: 12 }}>{'标题'}</Title>
  372. {value['title'].map((t: string, index: number) => <div className={style.text} key={index}><Text ellipsis={{ tooltip: true }}>{t}</Text></div>)}
  373. </> : null}
  374. </div>
  375. })}
  376. </div>
  377. }
  378. } else {
  379. return <Text style={{ fontSize: 12 }}>无需配置</Text>
  380. }
  381. }
  382. },
  383. {
  384. title: '跳转类型',
  385. dataIndex: 'pageListDto',
  386. key: 'pageListDto',
  387. width: 200,
  388. render: (_, b) => {
  389. let pageListDto = b?.pageListDto
  390. let pageType = b?.dynamicDto?.creativeComponents?.mainJumpInfo?.[0]?.value?.pageType
  391. if (pageType === 'PAGE_TYPE_WECHAT_MINI_GAME') {
  392. return <Text style={{ fontSize: 12 }}>无需配置</Text>
  393. }
  394. return <Text style={{ fontSize: 12, wordBreak: 'break-all' }}>
  395. {pageType === 'PAGE_TYPE_OFFICIAL' ? '灵鹊落地页' : pageType === 'PAGE_TYPE_WECHAT_MINI_PROGRAM' ? '微信小程序' : '原生推广页'}:
  396. {pageListDto?.map((item: { pageName: any; }) => item?.pageName)?.join(',')}
  397. </Text>
  398. }
  399. }
  400. ]
  401. }
  402. ]
  403. }
  404. export default columns