index.tsx 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. import React, { useEffect, useState } from "react"
  2. import { useAjax } from "@/Hook/useAjax"
  3. import { getNovelGDTListApi, GetNovelGDTListProps, getNovelGDTTotalApi } from "@/services/iaaData"
  4. import TablePro from "@/components/TablePro"
  5. import columns12 from "./tableConfig"
  6. import moment from "moment"
  7. import { useModel } from "umi"
  8. import { Button, Dropdown, message, Select, Space, Switch } from "antd"
  9. import { modifyStatusBatchApi } from "@/services/gameData"
  10. import { DeleteOutlined, DownOutlined, PauseCircleOutlined, PlayCircleOutlined } from "@ant-design/icons"
  11. import DayAd from "./dayAd"
  12. import QueryFormNovel from "@/components/QueryForm/queryFormNovel"
  13. import UpdateAd3 from "@/pages/iaaData/components/UpdateAd3"
  14. import AutoAcquisitionSet from "./autoAcquisitionSet"
  15. /**
  16. * 腾讯广告列表
  17. * @returns
  18. */
  19. const TencentNovelAd: React.FC<{ configName?: string, dayConfigName?: string }> = ({ configName, dayConfigName }) => {
  20. /****************************************/
  21. const { initialState } = useModel('@@initialState');
  22. const [selectedRows, setSelectedRows] = useState<any[]>([])
  23. const [queryForm, setQueryForm] = useState<GetNovelGDTListProps>({
  24. pageNum: 1,
  25. pageSize: 30,
  26. dataTimeMin: moment().format('YYYY-MM-DD'),
  27. dataTimeMax: moment().format('YYYY-MM-DD'),
  28. })
  29. const [totalData, setTotalData] = useState<any[]>([])
  30. const [visible, setVisible] = useState<boolean>(false)
  31. const [promotionId, setPromotionId] = useState<number>()
  32. const [adName, setAdName] = useState<string>('')
  33. const [updateData, setUpdateDate] = useState<{ visible: boolean, type: '修改出价' | '修改名称' | '修改日限额' | '修改投放时间' | '删除' | '深度优化ROI' | '修改投放首日开始时间' }>({ visible: false, type: '修改出价' })
  34. const [autoAcqVisible, setAutoAcqVisible] = useState<boolean>(false)
  35. const [handleType, setHandleType] = useState<number>(1)
  36. const [isZj, setIsZj] = useState<boolean>(true)
  37. const modifyStatusBatch = useAjax((params) => modifyStatusBatchApi(params))
  38. const getGDTList = useAjax((params) => getNovelGDTListApi(params))
  39. const getGDTTotal = useAjax((params) => getNovelGDTTotalApi(params))
  40. /****************************************/
  41. useEffect(() => {
  42. getList()
  43. }, [queryForm, initialState?.iaaApp])
  44. const getList = () => {
  45. if (initialState?.iaaApp) {
  46. const [appId, productType] = initialState.iaaApp.split('||')
  47. getGDTList.run({ ...queryForm, appId, productType })
  48. getGDTTotal.run({ ...queryForm, appId, productType }).then((res: { data: { id: number; accountId: string } }) => {
  49. if (res?.data) {
  50. let data = res?.data
  51. data.id = 1
  52. data.accountId = '总计'
  53. setTotalData([data])
  54. } else {
  55. setTotalData([{ id: 1, accountId: '总计' }])
  56. }
  57. })
  58. }
  59. }
  60. const dayHandle = (data: any) => {
  61. setVisible(true)
  62. setAdName(data.adgroupName)
  63. setPromotionId(data.adgroupId)
  64. }
  65. // 批量启停
  66. const adStatus = (type: boolean) => {
  67. let newSelectedRows = []
  68. if (type) {
  69. newSelectedRows = selectedRows.filter((item: { configuredStatus: string, adgroupId: number }) => item.configuredStatus === 'AD_STATUS_SUSPEND')
  70. } else {
  71. newSelectedRows = selectedRows.filter((item: { configuredStatus: string, adgroupId: number }) => item.configuredStatus === 'AD_STATUS_NORMAL')
  72. }
  73. if (newSelectedRows.length === 0) {
  74. message.warn(`所有广告都是${type ? '启动' : '暂停'}状态,无需${type ? '启动' : '暂停'}操作`)
  75. return
  76. }
  77. let accountAdgroupMaps = [...new Set(newSelectedRows?.map(item => item.accountId + ',' + item.adgroupId))]
  78. modifyStatusBatch.run({ accountAdgroupMaps, suspend: !type }).then(res => {
  79. if (res?.data?.failIdList?.length === 0) {
  80. message.success(`${type ? '启动' : '暂停'}成功`)
  81. getGDTList.refresh()
  82. setSelectedRows([])
  83. } else {
  84. message.success(`${type ? '启动' : '暂停'}失败,${JSON.stringify(res?.data?.list)}`)
  85. }
  86. })
  87. }
  88. return <div>
  89. <TablePro
  90. czChild={<Space>
  91. <Switch checkedChildren="开启全选" unCheckedChildren="关闭全选" checked={!isZj} onChange={(e) => { setIsZj(!e); }} />
  92. <Select
  93. style={{ width: 120 }}
  94. onChange={(e) => {
  95. setHandleType(e)
  96. setSelectedRows([])
  97. }}
  98. value={handleType}
  99. dropdownMatchSelectWidth={false}
  100. options={[{ label: '广告操作', value: 1 }, { label: '修改首日付费 ROI', value: 3 }, { label: '修改首日变现 ROI', value: 4 }]}
  101. />
  102. <Button type='primary' style={{ background: '#67c23a', borderColor: '#67c23a' }} loading={modifyStatusBatch.loading} icon={<PlayCircleOutlined />} disabled={selectedRows.length === 0} onClick={() => adStatus(true)}>启动</Button>
  103. <Button type='primary' style={{ background: '#e6a23c', borderColor: '#e6a23c' }} loading={modifyStatusBatch.loading} icon={<PauseCircleOutlined />} disabled={selectedRows.length === 0} onClick={() => adStatus(false)}>暂停</Button>
  104. {handleType === 1 ? <>
  105. <Button type='primary' danger icon={<DeleteOutlined />} disabled={selectedRows.length === 0} onClick={() => {
  106. setUpdateDate({ visible: true, type: '删除' })
  107. }}>删除</Button>
  108. <Dropdown
  109. menu={{
  110. items: [
  111. {
  112. label: <span style={{ display: 'inline-block', width: 120 }}>修改出价</span>,
  113. key: '1',
  114. disabled: selectedRows.length === 0,
  115. onClick: () => { setUpdateDate({ visible: true, type: '修改出价' }) }
  116. },
  117. {
  118. label: '修改名称',
  119. key: '2',
  120. disabled: selectedRows.length === 0,
  121. onClick: () => { setUpdateDate({ visible: true, type: '修改名称' }) }
  122. },
  123. {
  124. label: '修改日限额',
  125. key: '3',
  126. disabled: selectedRows.length === 0,
  127. onClick: () => { setUpdateDate({ visible: true, type: '修改日限额' }) }
  128. },
  129. {
  130. label: '修改投放日期',
  131. key: '4',
  132. disabled: selectedRows.length === 0,
  133. onClick: () => { setUpdateDate({ visible: true, type: '修改投放时间' }) }
  134. },
  135. {
  136. label: '修改投放首日开始时间',
  137. key: '5',
  138. disabled: selectedRows.length === 0,
  139. onClick: () => { setUpdateDate({ visible: true, type: '修改投放首日开始时间' }) }
  140. },
  141. {
  142. label: '一键起量',
  143. key: '6',
  144. disabled: selectedRows.length === 0,
  145. onClick: () => { setAutoAcqVisible(true) }
  146. }
  147. ]
  148. }}
  149. placement="bottomLeft"
  150. arrow
  151. >
  152. <Button>
  153. <Space>
  154. 修改广告
  155. <DownOutlined />
  156. </Space>
  157. </Button>
  158. </Dropdown>
  159. </> : handleType === 3 ? <>
  160. <Button type='primary' disabled={selectedRows.length === 0} onClick={() => {
  161. setUpdateDate({ visible: true, type: '深度优化ROI' })
  162. }}>修改首日付费 ROI</Button>
  163. </> : handleType === 4 ? <>
  164. <Button type='primary' disabled={selectedRows.length === 0} onClick={() => {
  165. setUpdateDate({ visible: true, type: '深度优化ROI' })
  166. }}>修改首日变现 ROI</Button>
  167. </> : null}
  168. <span style={{ color: 'red' }}>操作完数据结果延时5分钟之内,即时结果去腾讯后台查看</span>
  169. </Space>}
  170. leftChild={<QueryFormNovel
  171. initialValues={{ day3: [moment(), moment()] }}
  172. isAccountId
  173. isPutUserId
  174. isAdgroupId
  175. isAdgroupName
  176. isMarketingGoal
  177. isMarketingTargetType
  178. isMemo
  179. isRemark
  180. isDeleted
  181. isStatus
  182. isPromotedObjectName
  183. isPromotedObjectType
  184. isOptimizationGoal
  185. isCostTotalMin
  186. isThousandDisplayPriceTotalMin
  187. isConversionsCountTotalMin
  188. isIncomeRoi1
  189. isRegCost
  190. isRegCostPla
  191. isCpc
  192. day1={{ placeholder: ['广告创建日期开始', '广告创建日期结束'] }}
  193. day2={{ placeholder: ['投放日期开始', '投放日期结束'] }}
  194. day3={{ placeholder: ['消耗日期开始', '消耗日期结束'] }}
  195. onChange={(data: any) => {
  196. console.log(data)
  197. const { day1, day2, day3, ...params } = data
  198. let newQueryForm = JSON.parse(JSON.stringify(queryForm))
  199. newQueryForm.pageNum = 1
  200. if (day1 && day1?.length === 2) {
  201. newQueryForm['adCreateTimeMin'] = moment(day1[0]).format('YYYY-MM-DD')
  202. newQueryForm['adCreateTimeMax'] = moment(day1[1]).format('YYYY-MM-DD')
  203. } else {
  204. delete newQueryForm['adCreateTimeMin']
  205. delete newQueryForm['adCreateTimeMax']
  206. }
  207. if (day2 && day2?.length === 2) {
  208. newQueryForm['putDateBegin'] = moment(day2[0]).format('YYYY-MM-DD')
  209. newQueryForm['putDateEnd'] = moment(day2[1]).format('YYYY-MM-DD')
  210. } else {
  211. delete newQueryForm['putDateBegin']
  212. delete newQueryForm['putDateEnd']
  213. }
  214. if (day3 && day3?.length === 2) {
  215. newQueryForm['dataTimeMin'] = moment(day3[0]).format('YYYY-MM-DD')
  216. newQueryForm['dataTimeMax'] = moment(day3[1]).format('YYYY-MM-DD')
  217. } else {
  218. delete newQueryForm['dataTimeMin']
  219. delete newQueryForm['dataTimeMax']
  220. }
  221. setQueryForm({ ...newQueryForm, ...params })
  222. }}
  223. />}
  224. isZj={isZj}
  225. totalData={totalData}
  226. config={columns12(dayHandle, () => { getList() })}
  227. configName={configName || '腾讯小说广告列表'}
  228. fixed={{ left: 4, right: 2 }}
  229. scroll={{ x: 1000, y: 620 }}
  230. title='腾讯广告列表'
  231. loading={getGDTList.loading}
  232. ajax={getGDTList}
  233. page={queryForm?.pageNum || 1}
  234. pageSize={queryForm?.pageSize || 20}
  235. total={getGDTList?.data?.data?.total || 0}
  236. dataSource={getGDTList?.data?.data?.records?.map((item: any) => ({ ...item, id: item.adgroupId, deepConversionSpec: item?.deepConversionSpecJson ? JSON.parse(item.deepConversionSpecJson) : {} }))}
  237. onChange={(pagination: any, _: any, sortData: any) => {
  238. let { current, pageSize } = pagination
  239. let newQueryForm = JSON.parse(JSON.stringify(queryForm))
  240. if (sortData && sortData?.order) {
  241. newQueryForm['sortAsc'] = sortData?.order === 'ascend' ? true : false
  242. newQueryForm['sortFiled'] = sortData?.field
  243. } else {
  244. delete newQueryForm['sortAsc']
  245. delete newQueryForm['sortFiled']
  246. }
  247. newQueryForm.pageNum = current || newQueryForm.pageNum
  248. newQueryForm.pageSize = pageSize || newQueryForm.pageSize
  249. setQueryForm({ ...newQueryForm })
  250. }}
  251. rowSelection={{
  252. selectedRowKeys: selectedRows.map(item => item.adgroupId + ''),
  253. getCheckboxProps: (record: any) => ({
  254. disabled:
  255. handleType === 3 ? record.status === 'STATUS_DELETED' || record?.accountId === '总计' || !(record?.deepConversionSpec?.deepConversionWorthSpec?.goal === 'GOAL_1DAY_PURCHASE_ROAS') :
  256. handleType === 4 ? record.status === 'STATUS_DELETED' || record?.accountId === '总计' || !(record?.deepConversionSpec?.deepConversionWorthSpec?.goal === 'GOAL_1DAY_MONETIZATION_ROAS') :
  257. record.status === 'STATUS_DELETED' || record?.accountId === '总计'
  258. }),
  259. onSelect: (record: { adgroupId: number }, selected: boolean) => {
  260. if (selected) {
  261. selectedRows.push({ ...record })
  262. setSelectedRows([...selectedRows])
  263. } else {
  264. let newSelectAccData = selectedRows.filter((item: { adgroupId: number }) => item.adgroupId !== record.adgroupId)
  265. setSelectedRows([...newSelectAccData])
  266. }
  267. },
  268. onSelectAll: (selected: boolean, selectedRowss: { adgroupId: number }[], changeRows: { adgroupId: number }[]) => {
  269. if (selected) {
  270. let newSelectAccData = [...selectedRows]
  271. changeRows.forEach((item: { adgroupId: number }) => {
  272. let index = newSelectAccData.findIndex((ite: { adgroupId: number }) => ite.adgroupId === item.adgroupId)
  273. if (index === -1) {
  274. newSelectAccData.push({ ...item })
  275. }
  276. })
  277. setSelectedRows([...newSelectAccData])
  278. } else {
  279. let newSelectAccData = selectedRows.filter((item: { adgroupId: number }) => {
  280. let index = changeRows.findIndex((ite: { adgroupId: number }) => ite.adgroupId === item.adgroupId)
  281. if (index !== -1) {
  282. return false
  283. } else {
  284. return true
  285. }
  286. })
  287. setSelectedRows([...newSelectAccData])
  288. }
  289. }
  290. }}
  291. />
  292. {visible && <DayAd configName={dayConfigName} iaaApp={initialState?.iaaApp as string} adName={adName} visible={visible} onClose={() => { setVisible(false); setPromotionId(undefined) }} queryForm={{ costDayBegin: queryForm?.dataTimeMin, costDayEnd: queryForm?.dataTimeMax }} promotionId={promotionId} />}
  293. {/* 修改广告 */}
  294. {updateData.visible && <UpdateAd3
  295. {...updateData}
  296. updateData={selectedRows}
  297. onClose={() => {
  298. setUpdateDate({ visible: false, type: '修改出价' })
  299. }}
  300. onChange={() => {
  301. setUpdateDate({ visible: false, type: '修改出价' })
  302. getGDTList.refresh()
  303. if (updateData.type === '删除') {
  304. setSelectedRows([])
  305. }
  306. }}
  307. />}
  308. {/* 批量一键起量 */}
  309. {autoAcqVisible && <AutoAcquisitionSet
  310. selectAdList={selectedRows}
  311. visible={autoAcqVisible}
  312. onClose={() => {
  313. setAutoAcqVisible(false)
  314. }}
  315. onChange={() => {
  316. setAutoAcqVisible(false)
  317. getGDTList.refresh()
  318. setSelectedRows([])
  319. }}
  320. />}
  321. </div>
  322. }
  323. export default TencentNovelAd