tableMonitorConfig.tsx 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. import useCopy from '@/Hook/useCopy'
  2. import { DownOutlined, RiseOutlined } from '@ant-design/icons'
  3. import { Dropdown, Menu, Progress, Statistic, Tooltip} from 'antd'
  4. import { ColumnsType } from 'antd/lib/table'
  5. import React from 'react'
  6. import { ReactComponent as RocketSvg } from '@/assets/rocket.svg'
  7. import './index.less'
  8. import { CHUANGYIZHUANGTAI, GOUMAILEIXING, GUANGGAOZHUANGTAI, TUIGUANGMUBIAO, YOUHUAMUBIAO } from './enum'
  9. import Box from './components/box'
  10. function columnsMonitor(planDetail: (id: number) => void, getDetailList: (adId: any, accountId: any[]) => void, details: (id: number) => void, getMinuList: (id: number, accountId: any[]) => void, mode: string) {
  11. const { copy } = useCopy()
  12. return function columns() {
  13. let newArr: ColumnsType<any> = [
  14. {
  15. title: '时间',
  16. dataIndex: 'currTime',
  17. key: 'currTime',
  18. align: 'center',
  19. width: 160,
  20. ellipsis: true
  21. },
  22. {
  23. title: '广告名称',
  24. dataIndex: 'adgroupName',
  25. key: 'adgroupName',
  26. align: 'center',
  27. width: 170,
  28. ellipsis: true,
  29. render: (str, b) => {
  30. return <a style={{ color: '#1890ff', fontSize: 12 }} onClick={() => { getDetailList(b.adgroupId, [b.accountId]) }}>{str}</a>
  31. }
  32. },
  33. {
  34. title: '广告ID',
  35. dataIndex: 'adgroupId',
  36. key: 'adgroupId',
  37. align: 'center',
  38. width: 100,
  39. ellipsis: true,
  40. render: (a: any) => {
  41. return <a onClick={() => { copy(a) }} style={{ color: '#3946c3' }}>{a}</a>
  42. }
  43. },
  44. {
  45. title: '计划名称',
  46. dataIndex: 'campaignName',
  47. key: 'campaignName',
  48. align: 'center',
  49. width: 170,
  50. ellipsis: true,
  51. render: (str, b) => {
  52. return str
  53. }
  54. },
  55. {
  56. title: '计划ID',
  57. dataIndex: 'campaignId',
  58. key: 'campaignId',
  59. align: 'center',
  60. width: 100,
  61. ellipsis: true,
  62. render: (a: any) => {
  63. return <a onClick={() => { copy(a) }} style={{ color: '#3946c3' }}>{a}</a>
  64. }
  65. },
  66. {
  67. title: '广告账户',
  68. dataIndex: 'accountId',
  69. key: 'accountId',
  70. width: 70,
  71. ellipsis: true,
  72. align: 'center'
  73. },
  74. {
  75. title: '投手',
  76. dataIndex: 'putUserName',
  77. key: 'putUserName',
  78. align: 'center',
  79. ellipsis: true,
  80. width: 65
  81. },
  82. {
  83. title: '创意预览',
  84. dataIndex: 'creativePreview',
  85. key: 'creativePreview',
  86. width: 110,
  87. align: 'center',
  88. render: (a: any, b: any) => {
  89. return <Box b={b}/>
  90. }
  91. },
  92. // {
  93. // title: '投放位置',
  94. // dataIndex: 'pitchSeat',
  95. // key: 'pitchSeat',
  96. // width: 110,
  97. // align: 'center',
  98. // render: (a: any) => {
  99. // return a
  100. // }
  101. // },
  102. // {
  103. // title: '自动扩量',
  104. // dataIndex: 'autoExpand',
  105. // key: 'autoExpand',
  106. // width: 110,
  107. // align: 'center',
  108. // render: (a: any) => {
  109. // return a
  110. // }
  111. // },
  112. // {
  113. // title: '深度优化目标',
  114. // dataIndex: 'depthOptimizeTarget',
  115. // key: 'depthOptimizeTarget',
  116. // width: 110,
  117. // align: 'center',
  118. // render: (a: any) => {
  119. // return a
  120. // }
  121. // },
  122. // {
  123. // title: '曝光评估',
  124. // dataIndex: 'impressionAppraise',
  125. // key: 'impressionAppraise',
  126. // width: 110,
  127. // align: 'center',
  128. // render: (a: any) => {
  129. // return a
  130. // }
  131. // },
  132. {
  133. title: '投放时间',
  134. dataIndex: 'adBeginTime',
  135. key: 'adBeginTime',
  136. width: 110,
  137. align: 'center',
  138. ellipsis: true
  139. },
  140. {
  141. title: '广告状态',
  142. dataIndex: 'adStatus',
  143. key: 'adStatus',
  144. align: 'center',
  145. width: 105,
  146. ellipsis: true,
  147. render: (a: any) => {
  148. return GUANGGAOZHUANGTAI[a] || '--'
  149. }
  150. },
  151. // {
  152. // title: '创意状态',
  153. // dataIndex: 'adCreativeStatus',
  154. // key: 'adCreativeStatus',
  155. // align: 'center',
  156. // width: 115,
  157. // render: (a: any) => {
  158. // return CHUANGYIZHUANGTAI[a] || '--'
  159. // }
  160. // },
  161. {
  162. title: '推广目标',
  163. dataIndex: 'promotedObjectType',
  164. key: 'promotedObjectType',
  165. align: 'center',
  166. width: 80,
  167. ellipsis: true,
  168. render: (a: any) => {
  169. return TUIGUANGMUBIAO[a]
  170. }
  171. },
  172. // {
  173. // title: '购买类型',
  174. // dataIndex: 'adBuyType',
  175. // key: 'adBuyType',
  176. // align: 'center',
  177. // width: 110,
  178. // render: (a: any) => {
  179. // return GOUMAILEIXING[a] || '--'
  180. // }
  181. // },
  182. {
  183. title: '广告预算',
  184. dataIndex: 'dailyBudget',
  185. key: 'dailyBudget',
  186. width: 110,
  187. align: 'center',
  188. ellipsis: true,
  189. render: (a: any) => {
  190. return <Statistic value={a || 0} />
  191. }
  192. },
  193. // {
  194. // title: '出价方式',
  195. // dataIndex: 'biddingMethod',
  196. // key: 'biddingMethod',
  197. // width: 110,
  198. // align: 'center',
  199. // render: (a: any) => {
  200. // return a
  201. // }
  202. // },
  203. {
  204. title: '当前出价',
  205. dataIndex: 'bidAmount',
  206. key: 'bidAmount',
  207. width: 110,
  208. align: 'center',
  209. ellipsis: true,
  210. render: (a: any) => {
  211. return <div style={a >= 500 ? { backgroundColor: 'rgba(255, 80, 82, .72)', height: 26, color: '#fff', display: 'flex', justifyContent: 'center', alignItems: 'center', fontWeight: 600 } : {}}><Statistic value={a || 0} valueStyle={a >= 500 ? { fontSize: 14 } : {}} /></div>
  212. }
  213. },
  214. // {
  215. // title: '计划预算',
  216. // dataIndex: 'planBudget',
  217. // key: 'planBudget',
  218. // width: 110,
  219. // align: 'center',
  220. // render: (a: any) => {
  221. // return a
  222. // }
  223. // },
  224. {
  225. title: '广告总消耗',
  226. dataIndex: 'costTotal',
  227. key: 'costTotal',
  228. align: 'center',
  229. width: 100,
  230. ellipsis: true,
  231. sorter: true,
  232. render: (a: any) => {
  233. return <div style={{ height: 26, position: 'relative' }}>
  234. <Progress
  235. strokeColor={{
  236. from: '#10c1e9',
  237. to: '#6892d0',
  238. }}
  239. status="active"
  240. showInfo={false}
  241. percent={a ? a / 30000 * 100 : 0}
  242. />
  243. <span style={{ position: 'absolute', left: 0, top: 2, bottom: 0, right: 0 }}><Statistic value={a || 0} valueStyle={a >= 30000 ? { color: '#000', fontWeight: 500 } : { fontWeight: 500 }} /></span>
  244. </div>
  245. }
  246. },
  247. {
  248. title: '今日消耗',
  249. dataIndex: 'costDay',
  250. key: 'costDay',
  251. align: 'center',
  252. width: 105,
  253. sorter: true,
  254. render: (a: any) => {
  255. return <div style={{ height: 26, position: 'relative' }}>
  256. <Progress
  257. strokeColor={{
  258. from: '#ff5900',
  259. to: '#ffd380',
  260. }}
  261. status="active"
  262. showInfo={false}
  263. percent={a ? a / 2000 * 100 : 0}
  264. />
  265. <span style={{ position: 'absolute', left: 0, top: 2, bottom: 0, right: 0 }}><Statistic value={a || 0} valueStyle={a >= 2000 ? { color: '#000', fontWeight: 500 } : { fontWeight: 500 }} /></span>
  266. </div>
  267. }
  268. },
  269. {
  270. title: '当前小时消耗',
  271. dataIndex: 'costHour',
  272. key: 'costHour',
  273. align: 'center',
  274. width: 110,
  275. ellipsis: true,
  276. sorter: true,
  277. render: (a: any) => {
  278. return <div style={{ height: 26, position: 'relative' }}>
  279. <Progress
  280. strokeColor={{
  281. from: '#e7a0f5',
  282. to: '#d161f7',
  283. }}
  284. status="active"
  285. showInfo={false}
  286. percent={a ? a / 300 * 100 : 0}
  287. />
  288. <span style={{ position: 'absolute', left: 0, top: 2, bottom: 0, right: 0 }}><Statistic value={a || 0} valueStyle={a >= 300 ? { color: '#000', fontWeight: 500, fontSize: 15 } : { fontWeight: 500, fontSize: 15 }} /></span>
  289. </div>
  290. }
  291. },
  292. {
  293. title: '前第1小时消耗',
  294. dataIndex: 'costLastHour',
  295. key: 'costLastHour',
  296. align: 'center',
  297. width: 110,
  298. sorter: true,
  299. render: (a: any) => {
  300. return <Statistic value={a || 0} />
  301. }
  302. },
  303. {
  304. title: '前第2小时消耗',
  305. dataIndex: 'costLastTwoHour',
  306. key: 'costLastTwoHour',
  307. align: 'center',
  308. width: 80,
  309. sorter: true,
  310. render: (a: any) => {
  311. return <Statistic value={a || 0} />
  312. }
  313. },
  314. {
  315. title: '前第3小时消耗',
  316. dataIndex: 'costLastThreeHour',
  317. key: 'costLastThreeHour',
  318. align: 'center',
  319. width: 110,
  320. sorter: true,
  321. render: (a: number) => {
  322. return <Statistic value={a || 0} />
  323. },
  324. },
  325. {
  326. title: '当前小时消耗差额',
  327. dataIndex: 'costDiffBeforeHour',
  328. key: 'costDiffBeforeHour',
  329. align: 'center',
  330. width: 125,
  331. sorter: true,
  332. render: (a: any) => {
  333. return <Statistic value={a || 0} valueStyle={a > 0 ? { color: 'red' } : { color: 'green' }} />
  334. }
  335. },
  336. {
  337. title: '前第1小时消耗差额',
  338. dataIndex: 'costDiffBeforeTwoHour',
  339. key: 'costDiffBeforeTwoHour',
  340. align: 'center',
  341. width: 125,
  342. sorter: true,
  343. render: (a: any) => {
  344. return <Statistic value={a || 0} valueStyle={a > 0 ? { color: 'red' } : { color: 'green' }} />
  345. }
  346. },
  347. {
  348. title: "前第2小时消耗差额",
  349. dataIndex: 'costDiffBeforeThreeHour',
  350. key: 'costDiffBeforeThreeHour',
  351. align: 'center',
  352. width: 125,
  353. sorter: true,
  354. render: (a: number) => {
  355. return <Statistic value={a || 0} valueStyle={a > 0 ? { color: 'red' } : { color: 'green' }} />
  356. },
  357. },
  358. {
  359. title: "前三小时消耗趋势",
  360. dataIndex: 'costTrendLastThreeHour',
  361. key: 'costTrendLastThreeHour',
  362. align: 'center',
  363. width: 75,
  364. render: (a: number) => {
  365. return a > 0 ? <RiseOutlined style={{ color: 'red', fontWeight: 900, fontSize: 22 }} /> : '--'
  366. },
  367. },
  368. {
  369. title: '当前5min消耗流速',
  370. dataIndex: 'costSpeed',
  371. key: 'costSpeed',
  372. align: 'center',
  373. width: 115,
  374. render: (a: any) => {
  375. a = a ? parseFloat(a.toFixed(2)) : 0
  376. return <div style={{ height: 26, position: 'relative' }}>
  377. <Progress
  378. strokeColor={{
  379. from: '#00DDFF',
  380. to: '#37A2FF',
  381. }}
  382. status="active"
  383. showInfo={false}
  384. percent={a ? a / 100 * 100 : 0}
  385. />
  386. <span style={{ position: 'absolute', left: 0, top: 2, bottom: 0, right: 0 }}><Statistic value={a || 0} valueStyle={a >= 100 ? { color: '#000', fontWeight: 500 } : { fontWeight: 500 }} /></span>
  387. </div>
  388. }
  389. },
  390. {
  391. title: '曝光量',
  392. dataIndex: 'viewDay',
  393. key: 'viewDay',
  394. align: 'center',
  395. width: 70,
  396. sorter: true,
  397. render: (a: number) => {
  398. return <Statistic value={a || 0} />
  399. },
  400. },
  401. {
  402. title: '千次曝光成本',
  403. dataIndex: 'thousandDisplayPriceDay',
  404. key: 'thousandDisplayPriceDay',
  405. align: 'center',
  406. width: 115,
  407. sorter: true,
  408. render: (a: any) => {
  409. return <Statistic value={a || 0} />
  410. }
  411. },
  412. {
  413. title: '点击量',
  414. dataIndex: 'clickDay',
  415. key: 'clickDay',
  416. align: 'center',
  417. width: 70,
  418. sorter: true,
  419. render: (a: number) => {
  420. return <Statistic value={a || 0} />
  421. },
  422. },
  423. {
  424. title: '点击均价',
  425. dataIndex: 'cpcDay',
  426. key: 'cpcDay',
  427. align: 'center',
  428. width: 115,
  429. sorter: true,
  430. render: (a: any) => {
  431. return <Statistic value={a || 0} />
  432. }
  433. },
  434. {
  435. title: '点击率',
  436. dataIndex: 'ctrDay',
  437. key: 'ctrDay',
  438. align: 'center',
  439. width: 115,
  440. sorter: true,
  441. render: (a: any) => {
  442. a = a ? parseFloat((a * 100).toFixed(2)) : 0
  443. return a + '%'
  444. }
  445. },
  446. {
  447. title: '优化目标',
  448. dataIndex: 'optimizationGoal',
  449. key: 'optimizationGoal',
  450. align: 'center',
  451. width: 115,
  452. render: (a: any) => {
  453. return YOUHUAMUBIAO[a] || '--'
  454. }
  455. },
  456. {
  457. title: '转化目标量',
  458. dataIndex: 'conversionsCountDay',
  459. key: 'conversionsCountDay',
  460. align: 'center',
  461. width: 115,
  462. sorter: true,
  463. render: (a: any) => {
  464. return <Statistic value={a || 0} />
  465. }
  466. },
  467. {
  468. title: '转化目标成本',
  469. dataIndex: 'conversionsCostDay',
  470. key: 'conversionsCostDay',
  471. align: 'center',
  472. width: 115,
  473. sorter: true,
  474. render: (a: any) => {
  475. return <div style={a > 500 ? { backgroundColor: '#efea5b', height: 26, color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', fontWeight: 600 } : {}}><Statistic value={a || 0} /></div>
  476. }
  477. },
  478. {
  479. title: '目标转化率',
  480. dataIndex: 'conversionsRateDay',
  481. key: 'conversionsRateDay',
  482. align: 'center',
  483. width: 115,
  484. sorter: true,
  485. render: (a: any) => {
  486. a = a ? parseFloat((a * 100).toFixed(2)) : 0
  487. return a + '%'
  488. }
  489. },
  490. {
  491. title: '下单量',
  492. dataIndex: 'orderCountDay',
  493. key: 'orderCountDay',
  494. align: 'center',
  495. width: 115,
  496. sorter: true,
  497. render: (a: any) => {
  498. return <Statistic value={a || 0} />
  499. }
  500. },
  501. {
  502. title: '首日新增下单量',
  503. dataIndex: 'firstDayOrderCountDay',
  504. key: 'firstDayOrderCountDay',
  505. align: 'center',
  506. width: 115,
  507. sorter: true,
  508. render: (a: any) => {
  509. return <Statistic value={a || 0} />
  510. }
  511. },
  512. {
  513. title: '下单成本',
  514. dataIndex: 'orderCostDay',
  515. key: 'orderCostDay',
  516. align: 'center',
  517. width: 115,
  518. sorter: true,
  519. render: (a: any) => {
  520. return <Statistic value={a || 0} />
  521. }
  522. },
  523. {
  524. title: '下单率',
  525. dataIndex: 'orderRateDay',
  526. key: 'orderRateDay',
  527. align: 'center',
  528. width: 115,
  529. sorter: true,
  530. render: (a: any) => {
  531. a = a ? parseFloat((a * 100).toFixed(2)) : 0
  532. return a + '%'
  533. }
  534. },
  535. {
  536. title: '下单金额',
  537. dataIndex: 'orderAmountDay',
  538. key: 'orderAmountDay',
  539. align: 'center',
  540. width: 115,
  541. sorter: true,
  542. render: (a: any) => {
  543. return <Statistic value={a || 0} />
  544. }
  545. },
  546. {
  547. title: '首日新增下单金额',
  548. dataIndex: 'firstDayOrderAmountDay',
  549. key: 'firstDayOrderAmountDay',
  550. align: 'center',
  551. width: 115,
  552. sorter: true,
  553. render: (a: any) => {
  554. return <Statistic value={a || 0} />
  555. }
  556. },
  557. {
  558. title: '下单客单价',
  559. dataIndex: 'atvDay',
  560. key: 'atvDay',
  561. align: 'center',
  562. width: 115,
  563. sorter: true,
  564. render: (a: any) => {
  565. return <Statistic value={a || 0} />
  566. }
  567. },
  568. {
  569. title: '下单ROI',
  570. dataIndex: 'orderRoiDay',
  571. key: 'orderRoiDay',
  572. align: 'center',
  573. width: 115,
  574. sorter: true,
  575. render: (a: any) => {
  576. a = a ? parseFloat((a * 100).toFixed(2)) : 0
  577. return a + '%'
  578. }
  579. },
  580. {
  581. title: '首日新增下单ROI',
  582. dataIndex: 'firstDayOrderRoiDay',
  583. key: 'firstDayOrderRoiDay',
  584. align: 'center',
  585. width: 115,
  586. sorter: true,
  587. render: (a: any) => {
  588. a = a ? parseFloat((a * 100).toFixed(2)) : 0
  589. return a + '%'
  590. }
  591. },
  592. {
  593. title: '公众号关注人数',
  594. dataIndex: 'mpFollowUvDay',
  595. key: 'mpFollowUvDay',
  596. align: 'center',
  597. width: 115,
  598. sorter: true,
  599. render: (a: any) => {
  600. return a
  601. }
  602. },
  603. {
  604. title: '公众号关注率',
  605. dataIndex: 'mpFollowRateDay',
  606. key: 'mpFollowRateDay',
  607. align: 'center',
  608. width: 115,
  609. sorter: true,
  610. render: (a: any) => {
  611. a = a ? parseFloat((a * 100).toFixed(2)) : 0
  612. return a + '%'
  613. }
  614. },
  615. {
  616. title: '公众号关注成本',
  617. dataIndex: 'mpFollowCostDay',
  618. key: 'mpFollowCostDay',
  619. align: 'center',
  620. width: 115,
  621. sorter: true,
  622. render: (a: any) => {
  623. return <Statistic value={a || 0} />
  624. }
  625. },
  626. // {
  627. // title: '注册人数',
  628. // dataIndex: 'mpRegisterUserCount',
  629. // key: 'mpRegisterUserCount',
  630. // align: 'center',
  631. // width: 115,
  632. // sorter: true,
  633. // render: (a: any) => {
  634. // return a
  635. // }
  636. // },
  637. // {
  638. // title: '注册次数',
  639. // dataIndex: 'mpRegisterCount',
  640. // key: 'mpRegisterCount',
  641. // align: 'center',
  642. // width: 115,
  643. // sorter: true,
  644. // render: (a: any) => {
  645. // return a
  646. // }
  647. // },
  648. // {
  649. // title: '注册成本',
  650. // dataIndex: 'mpRegisterCost',
  651. // key: 'mpRegisterCost',
  652. // align: 'center',
  653. // width: 115,
  654. // sorter: true,
  655. // render: (a: any) => {
  656. // return <Statistic value={a || 0} />
  657. // }
  658. // },
  659. {
  660. title: '操作',
  661. dataIndex: 'event',
  662. key: 'event',
  663. align: 'center',
  664. width: 90,
  665. render: (a: string, b: any) => (
  666. // <a style={{ color: '#1890ff' }} onClick={() => { planDetail(b) }}>广告详情</a>
  667. <Dropdown overlay={
  668. <Menu>
  669. <Menu.Item key="0">
  670. <a style={{ color: '#1890ff' }} onClick={() => { planDetail(b) }}>广告详情</a>
  671. </Menu.Item>
  672. {mode === 'minute' ? <Menu.Item key="1">
  673. <a style={{ color: '#1890ff' }} onClick={() => { getDetailList(b.adgroupId, [b.accountId]) }}>小时</a>
  674. </Menu.Item> : <Menu.Item key="1">
  675. <a style={{ color: '#1890ff' }} onClick={() => { getMinuList(b?.adgroupId, [b.accountId]) }}>5min</a>
  676. </Menu.Item>}
  677. <Menu.Item key="2">
  678. <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }} onClick={() => details(b)}>
  679. <RocketSvg /><a style={{ marginLeft: 4, color: '#1890ff' }}>详情</a>
  680. </div>
  681. </Menu.Item>
  682. </Menu>
  683. } trigger={['click']}>
  684. <a className="ant-dropdown-link" onClick={e => e.preventDefault()}>
  685. 更多 <DownOutlined />
  686. </a>
  687. </Dropdown>
  688. )
  689. }
  690. ]
  691. return newArr
  692. }
  693. }
  694. export default columnsMonitor