index.tsx 17 KB

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