tableConfig.tsx 26 KB

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