index.tsx 82 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310
  1. import Tables from "@/components/Tables"
  2. import { useAjax } from "@/Hook/useAjax"
  3. import { createAdBatchApi, CreateAdProps } from "@/services/launchAdq/createAd"
  4. import { getSysAdcreativeInfo } from "@/services/launchAdq/creative"
  5. import { PromotedObjectType } from "@/services/launchAdq/enum"
  6. import { getTagsList, get_adcreative_template } from "@/services/launchAdq/global"
  7. import { getSysAdgroupsInfo } from "@/services/launchAdq/localAd"
  8. import { getsysTargetingInfo } from "@/services/launchAdq/targeting"
  9. import { CheckOutlined, CloseOutlined, SearchOutlined } from "@ant-design/icons"
  10. import { Button, Card, Col, Empty, Row, Select, Space, Spin, Tooltip, Image, message, Tabs, Popconfirm, notification, Divider, Checkbox, Modal } from "antd"
  11. import React, { useCallback, useEffect, useState } from "react"
  12. import { useModel } from "umi"
  13. import Ad from "./ad"
  14. import DataSourceModal from "../../components/dataSourceModal"
  15. import GoodsModal from "../../components/goodsModal"
  16. import IdModal from "../../components/idModal"
  17. import LookLanding from "../../components/lookLanding"
  18. import PageModal from "../../components/pageModal"
  19. import SelectCloud from "../../components/selectCloud"
  20. import style from './index.less'
  21. import Selector from "./selector"
  22. import SubmitModal from "./submitModal"
  23. import columns from "./tableConfig"
  24. import TargetIng from './targeting'
  25. import Creative from './creative'
  26. import AddGroup from '../../components/addGroup'
  27. import CustomerServiceModal from "../../components/customerServiceModal"
  28. import { getTaskDetailsApi } from "@/services/launchAdq/taskList"
  29. import CreativeCL from "./creativeCL"
  30. import { groupBy } from "@/utils/utils"
  31. import { getAccountListApi, getGroupListApi } from "@/services/launchAdq/subgroup"
  32. const CreateAd: React.FC = () => {
  33. /*************************/
  34. const { getAllUserAccount } = useModel('useLaunchAdq.useAdAuthorize')
  35. const [queryForm, setQueryForm] = useState<Partial<CreateAdProps>>({
  36. campaignName: '', // 计划名称
  37. campaignType: 'CAMPAIGN_TYPE_NORMAL', // 计划类型 CAMPAIGN_TYPE_NORMAL CAMPAIGN_TYPE_SEARCH
  38. promotedObjectType: 'PROMOTED_OBJECT_TYPE_WECHAT_OFFICIAL_ACCOUNT', // 推广目标类型
  39. speedMode: 'SPEED_MODE_STANDARD', // 投放速度模式
  40. sysAdgroupId: undefined, // 广告组ID
  41. sysAdgroup: undefined,//广告组内容
  42. sysTargetingId: undefined, // 定向包 id
  43. sysTargeting: undefined, // 定向包 内容
  44. adgroupName: undefined, // 广告名称
  45. configuredStatus: 'AD_STATUS_SUSPEND', // 广告状态
  46. sysAdcreativeId: undefined, // 创意ID
  47. taskMediaMaps: [], // 创意内容
  48. pageList: [],//本地落地页详情入口
  49. adqPageList: [],//云落地页
  50. expandEnabled: false,
  51. expandTargeting: [],
  52. model: 'cross'
  53. })
  54. const [launchMode, setLaunchMode] = useState<number>(Number(localStorage.getItem('LAUNCHMODE')) || 1) // 投放模式 1 现在投放模式 2 创量模式
  55. const [accountCreateLogs, setAccountCreateLogs] = useState<{ adAccountId: number, id: number, userActionSetsList?: any[], productList?: any, conversionList?: any, customAudienceList?: any, excludedCustomAudienceList?: any, pageList?: any, coldStartAudienceList?: any[] }[]>([]) // 账户
  56. const { currentUser: { userId } }: any = useModel('@@initialState', model => ({ currentUser: model.initialState?.currentUser }))
  57. const [goodsVisible, setGoodsVisible] = useState<boolean>(false) // 选择商品弹窗控制
  58. const [sourceVisible, setSourceVisible] = useState<boolean>(false) // 选择数据源弹窗控制
  59. const [idVisible, setIdVisible] = useState<boolean>(false) // 选择转化ID弹窗控制
  60. const [selectImgVisible, setSelectImgVisible] = useState<boolean>(false) // 选择转化ID弹窗控制
  61. const [lookVisible, setLookVisible] = useState<boolean>(false) // 选择转化ID弹窗控制
  62. const [subVisible, setSubVisible] = useState<boolean>(false) // 选择设置名称弹窗控制
  63. const [pageVisible, setPageVisible] = useState<boolean>(false) // 选择云端落地页控制
  64. const [tableData, setTableData] = useState<any[]>([]) // 预览表格
  65. const [tableSelect, setTableSelect] = useState<any[]>([])
  66. const [geoLocationList, setGeoLocationList] = useState<any>({}) // 所有地域列表
  67. const [modelList, setModelList] = useState<any>({}) // 所有品牌手机
  68. const [targetKey, set_targetKey] = useState('0')//创意key
  69. const [page_checked, set_page_checked] = useState(false)//创意key
  70. const [usesArr, setUsersArr] = useState<any>(localStorage.getItem('ADQUSERS' + userId) ? JSON.parse(localStorage.getItem('ADQUSERS' + userId) as any) : [])
  71. const { init, get } = useModel('useLaunchAdq.useBdMediaPup')
  72. const [cloudParams, setCloudParams] = useState<{ adcreativeTemplateId?: number }>({})
  73. const [accSearch, setAccSearch] = useState<string>()
  74. const tagsList_REGION = useAjax((params) => getTagsList(params))
  75. const tagsList_MODEL = useAjax((params) => getTagsList(params))
  76. const getSysAdgroups = useAjax((params) => getSysAdgroupsInfo(params))
  77. const getsysTargeting = useAjax((params) => getsysTargetingInfo(params))
  78. const getSysAdcreative = useAjax((params) => getSysAdcreativeInfo(params))
  79. const createAdBatch = useAjax((params) => createAdBatchApi(params))
  80. const getTaskDetails = useAjax((params) => getTaskDetailsApi(params))
  81. const getAdcreativeTemplate = useAjax((params) => get_adcreative_template(params))
  82. const getGroupList = useAjax(() => getGroupListApi())
  83. /*************************/
  84. useEffect(() => {
  85. getGroupList.run()
  86. }, [])
  87. /** 判断出价方式,优化目标 “二方包”人群包仅能在出价方式为CPC(包含oCPM点击优化目标)、CPM场景下使用 */
  88. // useEffect(() => {
  89. // if (queryForm?.sysAdgroup && Object.keys(queryForm?.sysAdgroup).length > 0 && (!['BID_MODE_CPC', 'BID_MODE_CPM'].includes(queryForm?.sysAdgroup?.bidMode) || !(queryForm?.sysAdgroup?.bidMode === 'BID_MODE_OCPM' && queryForm?.sysAdgroup?.optimizationGoal === 'OPTIMIZATIONGOAL_CLICK'))) {
  90. // setAccountCreateLogs(() => accountCreateLogs.map(item => {
  91. // delete item?.customAudienceList
  92. // delete item?.excludedCustomAudienceList
  93. // return item
  94. // }))
  95. // }
  96. // }, [queryForm?.sysAdgroup])
  97. /**数据回填 */
  98. useEffect(() => {
  99. let taskId = sessionStorage.getItem('TASKID')
  100. if (taskId) {
  101. getTaskDetails.run(taskId).then(async res => {
  102. const { adCreateLogs, campaignType, promotedObjectType, speedMode, sysAdgroup, sysAdgroupId, sysTargeting, sysTargetingId } = res
  103. let adcreativeTemplateId = adCreateLogs[0]?.sysAdcreative?.adcreativeTemplateId
  104. let sysPageId = adCreateLogs[0]?.sysPageId
  105. let pageId = adCreateLogs[0]?.pageId
  106. // 账号信息相关
  107. let adCreateLogsData = adCreateLogs?.map((item: any) => {
  108. return {
  109. adAccountId: item?.accountId,
  110. id: item?.adAccountId,
  111. // 数据源
  112. userActionSetsList: item?.userActionSetList?.map((item: any) => ({ ...item, id: item?.userActionSetId })),
  113. // 商品
  114. productList: item?.product ? [{ ...item?.product, productCatalog: item?.productCatalog, id: Number(item?.product?.productOuterId?.replace(/\D/ig, '')) }] : undefined,
  115. coldStartAudienceList: item?.coldStartAudienceList?.map((item: any) => ({ ...item, id: item.audienceId })),
  116. // pageList: [item.page]
  117. // 定向用户群
  118. customAudienceList: item?.customAudienceList?.map((item: any) => ({ ...item, id: item.audienceId })),
  119. // 排除用户群
  120. excludedCustomAudienceList: item?.excludedCustomAudienceList?.map((item: any) => ({ ...item, id: item.audienceId }))
  121. }
  122. }).filter((item: any, index: number, self: any) => self.findIndex((i: any) => i.id == item.id) === index)
  123. setAccountCreateLogs(adCreateLogsData)
  124. let type: 1 | 2 = 1
  125. if (sysPageId && pageId) {
  126. type = 1
  127. } else if (sysPageId) {
  128. if (adCreateLogs?.every((item: { sysAdcreative: { adcreativeTemplateId: number }, sysPageId: number }) => item.sysAdcreative.adcreativeTemplateId === adcreativeTemplateId && (item.sysPageId === sysPageId))) {
  129. type = 2
  130. } else {
  131. type = 1
  132. }
  133. } else {
  134. if (adCreateLogs?.every((item: { sysAdcreative: { adcreativeTemplateId: number }, pageId: number }) => item.sysAdcreative.adcreativeTemplateId === adcreativeTemplateId)) {
  135. type = 2
  136. } else {
  137. type = 1
  138. }
  139. }
  140. setLaunchMode(type)
  141. /** 本地落地页处理 */
  142. let pageList: any = []
  143. /** 云端落地页 */
  144. let adqPageList: any[] = []
  145. let taskMediaMaps: any[] = []
  146. let type2Data = {}
  147. if (type === 1) {
  148. const sorted = groupBy(adCreateLogs, (item) => [item.sysAdcreativeId])
  149. pageList = sorted?.map((item: any[]) => {
  150. if (item.some((item1: { sysPageId: number }) => item1.sysPageId)) {
  151. return item[0].sysPage
  152. } else {
  153. return null
  154. }
  155. })
  156. adqPageList = sorted?.map((item: any[]) => {
  157. if (item.some((item1: { pageId: number }) => item1.pageId)) {
  158. return item.map((item1: any) => ({
  159. pageList: [{ ...item1.page, id: item1.page.pageId }],
  160. adAccountId: item1?.accountId,
  161. id: item1?.adAccountId,
  162. }))
  163. } else {
  164. return null
  165. }
  166. })
  167. taskMediaMaps = groupBy(adCreateLogs, (item) => [item.accountId])?.[0]?.map((item: any, index: number) => {
  168. let pageElementsSpecList = item?.sysPage?.pageSpecsList[0]?.pageElementsSpecList // 内容区
  169. let globalSpec = item?.sysPage?.globalSpec // 悬浮组件
  170. /** 处理客服 */
  171. let cropUserGroupMap: any[] = []
  172. if ((pageElementsSpecList as any[])?.some((item: { elementType: string }) => item?.elementType === 'ENTERPRISE_WX') || (globalSpec?.globalElementsSpecList?.length > 0 && globalSpec?.globalElementsSpecList?.some((item: { floatButtonSpec: { elementType: string } }) => item?.floatButtonSpec?.elementType === 'ENTERPRISE_WX'))) {
  173. let groupList: { type: number, name: string, cropList: any[], cropId?: number, groupId?: number }[] = [];
  174. (pageElementsSpecList as any[])?.forEach((item: { elementType: string, enterpriseWxSpec: { btnTitle: string } }) => {
  175. if (item?.elementType === 'ENTERPRISE_WX') {
  176. groupList.push({ type: 1, name: '联系商家', cropList: [] }) // item.enterpriseWxSpec.btnTitle
  177. }
  178. })
  179. if ((globalSpec?.globalElementsSpecList?.length > 0 && globalSpec?.globalElementsSpecList)) {
  180. groupList.push({ type: 2, name: '悬浮组件', cropList: [] })
  181. }
  182. cropUserGroupMap = sorted[0]?.map((item: any) => {
  183. let corpUserGroup1s = item?.corpUserGroup1s
  184. let corpUserGroup2s = item?.corpUserGroup2s
  185. return {
  186. adAccountId: item.accountId, id: item.adAccountId, data: groupList.map((crop: any, index: number) => {
  187. return { ...crop, cropList: crop.type === 1 ? corpUserGroup1s[index] ? [{ ...corpUserGroup1s[index], id: corpUserGroup1s[index].groupId }] : [] : corpUserGroup2s[0] ? [{ ...corpUserGroup2s[0], id: corpUserGroup2s[0].groupId }] : [] }
  188. })
  189. }
  190. })
  191. }
  192. // 落地页信息
  193. let accountPageIdMap: any = {}
  194. adCreateLogs?.forEach((item: any) => {
  195. if (item?.pageId) {
  196. accountPageIdMap[item.accountId] = item?.pageId
  197. }
  198. })
  199. return { sysAdcreative: item?.sysAdcreative, sysPageId: item?.sysPageId, cropUserGroupMap, accountPageIdMap }
  200. })
  201. } else {
  202. const sorted = groupBy(adCreateLogs, (item) => [item.accountId])
  203. let adCreateLog = adCreateLogs[0]
  204. if (adCreateLog?.sysPageId) {
  205. pageList = [adCreateLog?.sysPage]
  206. } else {
  207. pageList = [null]
  208. }
  209. if (adCreateLog?.pageId) {
  210. adqPageList = groupBy(adCreateLogs, (item) => [item.sysAdcreativeId])?.map((item: any[]) => {
  211. if (item.some((item1: { pageId: number }) => item1.pageId)) {
  212. return item.map((item1: any) => ({
  213. pageList: [{ ...item1.page, id: item1.page.pageId }],
  214. adAccountId: item1?.accountId,
  215. id: item1?.adAccountId,
  216. }))
  217. } else {
  218. return null
  219. }
  220. })
  221. } else {
  222. adqPageList = [null]
  223. }
  224. let template = await getAdcreativeTemplate.run({ promotedObjectType, adcreativeTemplateId, siteSet: sysAdgroup.siteSet })
  225. let states = { kp_show: false, xd_show: true, sj_show: false, bq_show: false, sp_show: false }
  226. if (template[0]) {
  227. let pageList = template[0]?.landingPageConfig?.supportPageTypeList?.filter((i: { description: string | string[] }) => i.description.includes('微信原生推广页'))//当前版本只获取微信原生页,后期改进
  228. let pageType = pageList?.length ? pageList[0]?.pageType : null
  229. //数据展示组件
  230. if (template[0].adcreativeAttributes.some((item: { name: string }) => item.name === 'conversion_data_type' || item.name === 'conversion_target_type')) {
  231. states = { ...states, sj_show: true }
  232. }
  233. //行动按钮组件存在
  234. if (states.xd_show) {
  235. let supportLinkNameTypeData = (pageList?.filter((item: { pageType: any; }) => item.pageType === pageType)[0] as any)?.supportLinkNameType
  236. let linkNameList = supportLinkNameTypeData?.list
  237. if (linkNameList) { // && !linkPageType
  238. } else {
  239. states = { ...states, xd_show: false }
  240. }
  241. if (supportLinkNameTypeData?.required) {
  242. states = { ...states, xd_show: true }
  243. }
  244. }
  245. // 视频结束页 end_page
  246. if (template[0].adcreativeElements.some((item: { name: string }) => item.name === 'end_page')) {
  247. states = { ...states, sp_show: true }
  248. }
  249. }
  250. if (adcreativeTemplateId === 2106) {
  251. template[0].adcreativeElements = template[0]?.adcreativeElements?.map((item: any) => {
  252. if (item.name === "description") {
  253. return { ...item, name: 'title', title: item['description'] }
  254. }
  255. return item
  256. })
  257. }
  258. type2Data['textData'] = template[0]?.adcreativeElements?.filter((item: any) => item.name === 'title' || (item.required && item.name === 'description')).map((item: any) => ({ ...item, pupState: states }))
  259. type2Data['materialData'] = template[0]?.adcreativeElements?.filter((item: any) => item.required && item.name === 'image_list' || item.name === 'short_video1' || item.name === 'video' || item.name === 'image' || item.name === 'element_story').map((item: any) => {
  260. return {
  261. label: item.description === '图片' && res[0]?.adcreativeElements?.some((item: any) => item.name === 'video') ? '视频封面图' : item.description,
  262. name: item.name,
  263. restriction: item.restriction,
  264. arrayProperty: item?.arrayProperty
  265. }
  266. })
  267. taskMediaMaps = [sorted[0][0]].map((item: any) => {
  268. let pageElementsSpecList = item?.sysPage?.pageSpecsList[0]?.pageElementsSpecList // 内容区
  269. let globalSpec = item?.sysPage?.globalSpec // 悬浮组件
  270. /** 处理客服 */
  271. let cropUserGroupMap: any[] = []
  272. if ((pageElementsSpecList as any[])?.some((item: { elementType: string }) => item?.elementType === 'ENTERPRISE_WX') || (globalSpec?.globalElementsSpecList?.length > 0 && globalSpec?.globalElementsSpecList?.some((item: { floatButtonSpec: { elementType: string } }) => item?.floatButtonSpec?.elementType === 'ENTERPRISE_WX'))) {
  273. let groupList: { type: number, name: string, cropList: any[], cropId?: number, groupId?: number }[] = [];
  274. (pageElementsSpecList as any[])?.forEach((item: { elementType: string, enterpriseWxSpec: { btnTitle: string } }) => {
  275. if (item?.elementType === 'ENTERPRISE_WX') {
  276. groupList.push({ type: 1, name: '联系商家', cropList: [] }) // item.enterpriseWxSpec.btnTitle
  277. }
  278. })
  279. if ((globalSpec?.globalElementsSpecList?.length > 0 && globalSpec?.globalElementsSpecList)) {
  280. groupList.push({ type: 2, name: '悬浮组件', cropList: [] })
  281. }
  282. cropUserGroupMap = groupBy(adCreateLogs, (item) => [item.sysAdcreativeId])[0]?.map((item: any) => {
  283. let corpUserGroup1s = item?.corpUserGroup1s
  284. let corpUserGroup2s = item?.corpUserGroup2s
  285. return {
  286. adAccountId: item.accountId, id: item.adAccountId, data: groupList.map((crop: any, index: number) => {
  287. return { ...crop, cropList: crop.type === 1 ? corpUserGroup1s[index] ? [{ ...corpUserGroup1s[index], id: corpUserGroup1s[index].groupId }] : [] : corpUserGroup2s[0] ? [{ ...corpUserGroup2s[0], id: corpUserGroup2s[0].groupId }] : [] }
  288. })
  289. }
  290. })
  291. }
  292. // 落地页信息
  293. let accountPageIdMap: any = {}
  294. adCreateLogs?.forEach((item: any) => {
  295. if (item?.pageId) {
  296. accountPageIdMap[item.accountId] = item?.pageId
  297. }
  298. })
  299. let { adcreativeElements, ...Adcreative } = JSON.parse(JSON.stringify(item?.sysAdcreative))
  300. delete adcreativeElements?.title
  301. delete adcreativeElements?.description
  302. delete adcreativeElements?.imageUrlList
  303. delete adcreativeElements?.elementStory
  304. delete adcreativeElements?.imageUrl
  305. delete adcreativeElements?.videoUrl
  306. delete adcreativeElements?.shortVideo1Url
  307. return { sysAdcreative: { ...Adcreative, adcreativeElements }, sysPageId: item?.sysPageId, cropUserGroupMap, accountPageIdMap }
  308. })
  309. // 处理 materials [] texts []
  310. let newMaterials: any[] = [], newTexts: any[] = []
  311. sorted[0].forEach((item: any) => {
  312. let { title, description, imageUrlList, elementStory, imageUrl, videoUrl, shortVideo1Url } = item?.sysAdcreative?.adcreativeElements
  313. let texts = {};
  314. let materials = {};
  315. if (title) texts['title'] = title;
  316. if (description) texts['description'] = description;
  317. if (imageUrlList) materials['imageUrlList'] = imageUrlList;
  318. if (elementStory) materials['elementStory'] = elementStory;
  319. if (imageUrl) materials['imageUrl'] = imageUrl;
  320. if (videoUrl) materials['videoUrl'] = videoUrl;
  321. if (shortVideo1Url) materials['shortVideo1Url'] = shortVideo1Url;
  322. newMaterials.push(materials)
  323. newTexts.push(texts)
  324. })
  325. let groupMaterials: any[] = []
  326. let groupTexts: any[] = []
  327. if (newMaterials.length > 0 && newMaterials?.every(item => Object.keys(item).length > 0)) {
  328. let firstField = Object.keys(newMaterials[0])[0]
  329. groupMaterials = groupBy(newMaterials, (item) => [item[firstField]])
  330. type2Data['materials'] = newMaterials
  331. }
  332. if (newTexts.length > 0 && newTexts?.every(item => Object.keys(item).length > 0)) {
  333. let firstField = Object.keys(newTexts[0])[0]
  334. groupTexts = groupBy(newTexts, (item) => [item[firstField]])
  335. type2Data['texts'] = newTexts
  336. }
  337. let mLength = groupMaterials.length || 1
  338. let tLength = groupTexts.length || 1
  339. if (mLength * tLength === sorted[0].length) { // 数量对上是 叉乘 否则 一对一
  340. if (groupMaterials.length > 0) type2Data['materials'] = groupMaterials.map((item: any[]) => item[0])
  341. if (groupTexts.length > 0) type2Data['texts'] = groupTexts.map((item: any[]) => item[0])
  342. type2Data['model'] = 'cross'
  343. } else {
  344. type2Data['model'] = 'corres'
  345. }
  346. }
  347. setQueryForm({
  348. ...queryForm,
  349. ...type2Data,
  350. campaignType,
  351. promotedObjectType,
  352. speedMode,
  353. sysAdgroup,
  354. sysAdgroupId,
  355. sysTargeting,
  356. sysTargetingId,
  357. adgroupName: sysAdgroup?.adgroupName,
  358. configuredStatus: sysAdgroup?.configuredStatus,
  359. expandEnabled: sysAdgroup?.expandEnabled || false,
  360. expandTargeting: sysAdgroup?.expandTargeting || [],
  361. taskMediaMaps: taskMediaMaps || [],
  362. pageList,
  363. adqPageList
  364. })
  365. })
  366. sessionStorage.removeItem('TASKID')
  367. } else {
  368. let adqAdData = localStorage.getItem('ADQAD')
  369. if (adqAdData) {
  370. const { queryForm, accountCreateLogs } = JSON.parse(adqAdData)
  371. setQueryForm({ ...queryForm })
  372. setAccountCreateLogs(accountCreateLogs)
  373. }
  374. }
  375. }, [])
  376. // 设置地域
  377. useEffect(() => {
  378. tagsList_REGION.run({ type: 'REGION' }).then(res => {
  379. if (res && Array.isArray(res)) {
  380. setGeoLocationList(() => (res as any[])?.reduce((prev: any, cur: { id: number }) => {
  381. prev[cur.id] = cur
  382. return prev
  383. }, {}))
  384. }
  385. })
  386. tagsList_MODEL.run({ type: 'DEVICE_BRAND_MODEL' }).then(res => {
  387. if (res && Array.isArray(res)) {
  388. setModelList(() => (res as any[])?.reduce((prev: any, cur: { id: number }) => {
  389. prev[cur.id] = cur
  390. return prev
  391. }, {}))
  392. }
  393. })
  394. }, [])
  395. // 获取账户列表
  396. useEffect(() => {
  397. getAllUserAccount.run()
  398. }, [])
  399. // 账号对比
  400. useEffect(() => {
  401. if (getAllUserAccount?.data?.data && accountCreateLogs) {
  402. if (accountCreateLogs.some(item => !getAllUserAccount?.data?.data?.find((item1: { accountId: number }) => item.adAccountId == item1.accountId))) {
  403. let errorData: any[] = []
  404. let newAccountCreateLogs = accountCreateLogs.filter(item => {
  405. let data = getAllUserAccount?.data?.data?.find((item1: { accountId: number }) => item.adAccountId == item1.accountId)
  406. if (data) {
  407. return true
  408. } else {
  409. errorData.push(item.adAccountId)
  410. return false
  411. }
  412. })
  413. notification.error({
  414. duration: 60 * 5,
  415. message: '重要提示',
  416. description: `本地媒体账户与你所拥有账户对不上,当前创建账号不符合账号及部分相关配置已清空。请把保存在本地的媒体账户或者媒体账户组清空,重新选择保存。问题账户:(${errorData.toString()})`
  417. })
  418. setAccountCreateLogs(newAccountCreateLogs)
  419. setQueryForm({ ...queryForm, adqPageList: [], taskMediaMaps: queryForm?.taskMediaMaps?.map(item => ({ ...item, accountPageIdMap: {} })) })
  420. }
  421. }
  422. }, [getAllUserAccount?.data, accountCreateLogs, queryForm])
  423. /** 获取广告详情 */
  424. useEffect(() => {
  425. if (getSysAdgroups?.data?.bidMode !== 'BID_MODE_CPM' && accountCreateLogs?.length > 0) {
  426. let newAccountCreateLogs = accountCreateLogs?.map((item: any) => {
  427. if (item?.customAudienceList) {
  428. delete item?.customAudienceList
  429. }
  430. return { ...item }
  431. })
  432. setAccountCreateLogs([...newAccountCreateLogs])
  433. }
  434. }, [getSysAdgroups?.data?.bidMode])
  435. /** 删除商品内容 */
  436. const goodsDel = (index: number) => {
  437. let newArr = JSON.parse(JSON.stringify(accountCreateLogs))
  438. delete newArr[index].productList
  439. setAccountCreateLogs(newArr)
  440. }
  441. /** 删除数据源 */
  442. const sourceDel = (index: number, num: number) => {
  443. let newArr = JSON.parse(JSON.stringify(accountCreateLogs))
  444. newArr[index].userActionSetsList?.splice(num, 1)
  445. setAccountCreateLogs(newArr)
  446. }
  447. /** 删除人群包 */
  448. const cpDel = (index: number, num: number, key: string) => {
  449. let newArr = JSON.parse(JSON.stringify(accountCreateLogs))
  450. newArr[index][key]?.splice(num, 1)
  451. setAccountCreateLogs(newArr)
  452. }
  453. // 创意素材与文案叉乘处理
  454. const whatever = (...arrs: any[]) => {
  455. if (arrs[0]?.length && arrs[1]?.length) {
  456. if (queryForm.model === 'corres') { // 一一对应
  457. return arrs[0].map((item: any, index: number) => ({ ...item, ...arrs[1][index] }))
  458. }
  459. return arrs.reduce((total, curr) => total.flatMap((e: any) => curr.map((e2: any) => ({ ...e2, ...e }))))
  460. } else if (arrs[0]?.length) {
  461. return arrs[0]
  462. } else if (arrs[1]?.length) {
  463. return arrs[1]
  464. } else {
  465. return ['']
  466. }
  467. }
  468. /** 预览 */
  469. const preview = () => {
  470. let newQueryForm: Partial<CreateAdProps> = JSON.parse(JSON.stringify(queryForm))
  471. if (accountCreateLogs?.length === 0) {
  472. message.error('请选择媒体账户')
  473. return
  474. }
  475. if (!newQueryForm.promotedObjectType) {
  476. message.error('请选择推广目标')
  477. return
  478. }
  479. if (!newQueryForm.sysAdgroup) {
  480. message.error('请先设置广告基本信息')
  481. return
  482. }
  483. if (!newQueryForm.sysTargeting) {
  484. message.error('请选择定向')
  485. return
  486. }
  487. if (!newQueryForm.taskMediaMaps?.every(item => item.sysAdcreative)) {
  488. message.error('请设置创意的基本信息')
  489. return
  490. }
  491. if (!newQueryForm.taskMediaMaps?.every(item => item.sysPageId || item.accountPageIdMap)) {
  492. message.error('请选择落地页')
  493. return
  494. }
  495. if (launchMode === 2) {
  496. if ((queryForm?.materialData && queryForm?.materialData?.length > 0) && !(newQueryForm?.materials && newQueryForm?.materials?.length > 0)) {
  497. message.error('请选择创意素材')
  498. return
  499. }
  500. if ((queryForm?.textData && queryForm.textData?.length > 0) && !(newQueryForm?.texts && newQueryForm?.texts?.length > 0)) {
  501. message.error('请选择创意文案')
  502. return
  503. }
  504. if (queryForm.model === 'corres' && (queryForm?.materialData && queryForm?.materialData?.length > 0) && (queryForm?.textData && queryForm.textData?.length > 0) && queryForm.texts?.length !== queryForm?.materials?.length) {
  505. message.error('素材文案一一对应模式下,素材数量与文案数量要相等,请修改')
  506. return
  507. }
  508. }
  509. if (newQueryForm?.taskMediaMaps && newQueryForm?.taskMediaMaps?.some((item: { cropUserGroupMap: any[] }) => item?.cropUserGroupMap?.length > 0)) {
  510. let cropData = newQueryForm?.taskMediaMaps?.filter((item: { cropUserGroupMap: any[] }) => item?.cropUserGroupMap?.length > 0)
  511. if (cropData?.some((item: { cropUserGroupMap: { data: { cropList: any[] }[] }[] }) => {
  512. return item?.cropUserGroupMap?.some((item1: { data: { cropList: any[] }[] }) => item1?.data?.some((item2: { cropList: any[] }) => item2?.cropList?.length === 0))
  513. })) {
  514. message.error('请完善落地页企微客服组')
  515. return
  516. }
  517. }
  518. let data: any[] = []
  519. if (launchMode === 2) {
  520. if (Array.isArray(newQueryForm.materials) && Array.isArray(newQueryForm?.texts)) {
  521. let taskMediaMap = JSON.parse(JSON.stringify(newQueryForm.taskMediaMaps[0]))
  522. let adcreativeElements = taskMediaMap.sysAdcreative?.adcreativeElements || {}
  523. let newTaskMediaMaps = whatever(newQueryForm.materials, newQueryForm.texts).map((item: any) => {
  524. taskMediaMap.sysAdcreative.adcreativeElements = { ...adcreativeElements, ...item }
  525. return JSON.parse(JSON.stringify(taskMediaMap))
  526. })
  527. newQueryForm.taskMediaMaps = newTaskMediaMaps
  528. }
  529. }
  530. accountCreateLogs.forEach((item: any) => {
  531. newQueryForm.taskMediaMaps?.forEach((task, index) => {
  532. let obj = {
  533. ...item,
  534. ...newQueryForm,
  535. sysAdGroupData: newQueryForm.sysAdgroup,
  536. targetingData: newQueryForm.sysTargeting,
  537. sysAdcreativeData: task.sysAdcreative,
  538. pageData: launchMode === 2 ? (newQueryForm.pageList as any)[0] || (newQueryForm.adqPageList as any)[0]?.find((adq: { adAccountId: any }) => adq.adAccountId === item.adAccountId)?.pageList[0] : (newQueryForm.pageList as any)[index] || (newQueryForm.adqPageList as any)[index]?.find((adq: { adAccountId: any }) => adq.adAccountId === item.adAccountId)?.pageList[0],
  539. myId: Number(item.id + '' + index)
  540. }
  541. data.push(obj)
  542. })
  543. })
  544. setTableData(data)
  545. }
  546. const submit = (props: { campaignName: string, count?: number }) => {
  547. let newQueryForm = JSON.parse(JSON.stringify(queryForm))
  548. if (launchMode === 2) {
  549. if (Array.isArray(newQueryForm.materials) && Array.isArray(newQueryForm?.texts)) {
  550. let taskMediaMap = JSON.parse(JSON.stringify(newQueryForm.taskMediaMaps[0]))
  551. let adcreativeElements = taskMediaMap.sysAdcreative?.adcreativeElements || {}
  552. let newTaskMediaMaps = whatever(newQueryForm.materials, newQueryForm.texts).map((item: any) => {
  553. if (item) {
  554. taskMediaMap.sysAdcreative.adcreativeElements = { ...adcreativeElements, ...item }
  555. } else {
  556. taskMediaMap.sysAdcreative.adcreativeElements = { ...adcreativeElements }
  557. }
  558. return JSON.parse(JSON.stringify(taskMediaMap))
  559. })
  560. newQueryForm.taskMediaMaps = newTaskMediaMaps
  561. }
  562. }
  563. let newtaskMediaMaps = newQueryForm.taskMediaMaps.map((item1: { cropUserGroupMap?: any[] }) => {
  564. let { cropUserGroupMap, ...data } = item1
  565. if (cropUserGroupMap && cropUserGroupMap?.length > 0) {
  566. let corpUserGroup1Map: any = {}
  567. let corpUserGroup2Map: any = {}
  568. cropUserGroupMap.forEach((cropData: { id: number, data: any[] }) => {
  569. let cropData1: { corpId: string, groupId: number }[] = []
  570. let cropData2: { corpId: string, groupId: number }[] = []
  571. cropData?.data.forEach((crop: { type: 1 | 2, cropList: { corpId: string, groupId: number }[] }) => {
  572. let cropList = crop.cropList
  573. if (crop.type === 1) {
  574. cropData1.push({ corpId: cropList[0].corpId, groupId: cropList[0].groupId })
  575. } else {
  576. cropData2.push({ corpId: cropList[0].corpId, groupId: cropList[0].groupId })
  577. }
  578. })
  579. if (cropData1.length > 0) {
  580. corpUserGroup1Map[cropData.id.toString()] = cropData1
  581. }
  582. if (cropData2.length > 0) {
  583. corpUserGroup2Map[cropData.id.toString()] = cropData2
  584. }
  585. })
  586. return { ...data, corpUserGroup1Map: Object.keys(corpUserGroup1Map)?.length > 0 ? corpUserGroup1Map : null, corpUserGroup2Map: Object.keys(corpUserGroup2Map)?.length > 0 ? corpUserGroup2Map : null }
  587. }
  588. return data
  589. })
  590. newQueryForm.taskMediaMaps = newtaskMediaMaps
  591. let params = { ...newQueryForm, ...props }
  592. let accountLogs = accountCreateLogs.map((item: any, index) => {
  593. // userActionSetsList 数据源 productList 商品
  594. let data: any = { adAccountId: item.id, count: props.count || 1 }
  595. if (item?.userActionSetsList?.length > 0) { // 数据源
  596. data.userActionSets = item?.userActionSetsList?.map((item: any) => ({ id: item?.id, type: item?.type }))
  597. }
  598. if (item?.productList?.length > 0) { // 商品
  599. data.productId = item?.productList[0].productOuterId
  600. data.productCatalogId = item?.productList[0].productCatalogId
  601. }
  602. if (item?.customAudienceList?.length > 0) {
  603. data.customAudience = item?.customAudienceList?.map((item: any) => item.id)
  604. }
  605. if (item?.excludedCustomAudienceList?.length > 0) {
  606. data.excludedCustomAudience = item?.excludedCustomAudienceList?.map((item: any) => item.id)
  607. }
  608. if (item?.pageList) {
  609. data.pageId = item?.pageData?.id
  610. }
  611. if (item?.coldStartAudienceList?.length > 0) {
  612. data.coldStartAudience = item?.coldStartAudienceList?.map((item: any) => item.id)
  613. }
  614. return data
  615. })
  616. if (params?.expandEnabled) {
  617. params.sysAdgroup.expandEnabled = params?.expandEnabled
  618. params.sysAdgroup.expandTargeting = []
  619. }
  620. if (params?.expandTargeting?.length > 0) {
  621. params.sysAdgroup.expandTargeting = params?.expandTargeting
  622. }
  623. params.accountCreateLogs = accountLogs
  624. delete params.sysAdgroupId
  625. delete params.sysAdcreativeId
  626. delete params.sysTargetingId
  627. delete params.pageList
  628. delete params.adqPageList
  629. delete params.count
  630. delete params?.expandEnabled
  631. delete params?.expandTargeting
  632. delete params?.texts
  633. delete params?.textData
  634. delete params?.materialData
  635. delete params?.materials
  636. delete params?.model
  637. console.log('paramsSubmit====>', params)
  638. createAdBatch.run(params).then(res => {
  639. if (res) {
  640. Modal.success({
  641. content: '任务提交成功',
  642. bodyStyle: { fontWeight: 700 },
  643. okText: '跳转任务列表',
  644. closable: true,
  645. onOk: () => {
  646. sessionStorage.setItem('CAMP', props?.campaignName)
  647. window.location.href = '/#/launchSystemNew/launchManage/taskList'
  648. },
  649. onCancel: () => {
  650. setSubVisible(false)
  651. }
  652. })
  653. }
  654. })
  655. }
  656. /** 清除数据 */
  657. const clearData = () => {
  658. setTableData([])
  659. setTableSelect([])
  660. }
  661. /** 存为预设 */
  662. const severBd = () => {
  663. // queryForm accountCreateLogs
  664. localStorage.setItem('ADQAD', JSON.stringify({
  665. queryForm,
  666. accountCreateLogs
  667. }))
  668. message.success('存储成功')
  669. }
  670. /** 清除 */
  671. const delBdPlan = () => {
  672. localStorage.removeItem('ADQAD')
  673. setAccountCreateLogs([])
  674. setQueryForm({
  675. campaignName: '', // 计划名称
  676. campaignType: 'CAMPAIGN_TYPE_NORMAL', // 计划类型 CAMPAIGN_TYPE_NORMAL CAMPAIGN_TYPE_SEARCH
  677. promotedObjectType: 'PROMOTED_OBJECT_TYPE_WECHAT_OFFICIAL_ACCOUNT', // 推广目标类型
  678. speedMode: 'SPEED_MODE_STANDARD', // 投放速度模式
  679. sysAdgroupId: undefined, // 广告组内容
  680. sysTargetingId: undefined, // 定向包 id
  681. adgroupName: undefined, // 广告名称
  682. configuredStatus: 'AD_STATUS_SUSPEND', // 广告状态
  683. sysAdcreativeId: undefined, // 创意ID
  684. expandEnabled: false,
  685. expandTargeting: [],
  686. model: 'cross'
  687. })
  688. }
  689. /** 设置落地页 */
  690. const setPage = (e: any) => {
  691. let arr: any = queryForm.taskMediaMaps || []
  692. function setUrl(item: { sysAdcreative: { overrideCanvasHeadOption: string, adcreativeElements: any } }) {
  693. if (item?.sysAdcreative?.overrideCanvasHeadOption && item?.sysAdcreative?.overrideCanvasHeadOption === "OPTION_CANVAS_OVERRIDE_CREATIVE") {
  694. let adcreativeElementsNew = { ...item.sysAdcreative.adcreativeElements }
  695. let obj = e[0].pageSpecsList[0].pageElementsSpecList[0]
  696. let { topImageSpec, topVideoSpec, topSliderSpec } = obj
  697. Object.keys(adcreativeElementsNew).forEach(key => {
  698. switch (key) {
  699. case 'imageUrl'://图素材
  700. adcreativeElementsNew[key] = topImageSpec?.imageUrl
  701. break;
  702. case 'videoUrl'://视频素材
  703. adcreativeElementsNew[key] = topVideoSpec?.videoUrl
  704. break;
  705. case 'imageUrlList'://图素材
  706. adcreativeElementsNew[key] = topSliderSpec?.imageUrlList || [topImageSpec?.imageUrl]
  707. break;
  708. case 'shortVideoStruct'://视频素材
  709. adcreativeElementsNew[key] = { shortVideo1Url: topVideoSpec?.videoUrl }
  710. break;
  711. }
  712. })
  713. return { ...item, sysPageId: e[0]?.id, accountPageIdMap: null, sysAdcreative: { ...item.sysAdcreative, adcreativeElements: adcreativeElementsNew } }
  714. }
  715. return { ...item, sysPageId: e[0]?.id, accountPageIdMap: null, }
  716. }
  717. if (page_checked) {
  718. arr = queryForm.taskMediaMaps?.map(item => {
  719. return setUrl(item)
  720. })
  721. } else {
  722. arr[targetKey as string] = setUrl(arr[targetKey as string])
  723. }
  724. getPageInfo(arr)
  725. setSelectImgVisible(false)
  726. }
  727. /** 获取落地页详情 */
  728. const getPageInfo = useCallback((arrList) => {
  729. console.log('arrList====>', arrList)
  730. if (arrList && arrList[targetKey]?.sysPageId) {
  731. get.run({ mediaType: 'PAGE', sysMediaId: arrList[targetKey]?.sysPageId }).then(res => {
  732. if (!Object.keys(res)?.includes('fail')) {
  733. let data = res
  734. let pageElementsSpecList = data?.pageSpecsList[0]?.pageElementsSpecList // 内容区
  735. let globalSpec = data?.globalSpec // 悬浮组件
  736. let arr: any = queryForm.pageList || []
  737. let adqPageArr: any = queryForm.adqPageList || []
  738. adqPageArr[targetKey] = null
  739. arr[targetKey] = data
  740. /** 处理客服 */
  741. let cropUserGroupMap: any[] = []
  742. if ((pageElementsSpecList as any[])?.some((item: { elementType: string }) => item?.elementType === 'ENTERPRISE_WX') || (globalSpec?.globalElementsSpecList?.length > 0 && globalSpec?.globalElementsSpecList?.some((item: { floatButtonSpec: { elementType: string } }) => item?.floatButtonSpec?.elementType === 'ENTERPRISE_WX'))) {
  743. let groupList: { type: number, name: string, cropList: any[], cropId?: number, groupId?: number }[] = [];
  744. (pageElementsSpecList as any[])?.forEach((item: { elementType: string, enterpriseWxSpec: { btnTitle: string } }) => {
  745. if (item?.elementType === 'ENTERPRISE_WX') {
  746. groupList.push({ type: 1, name: '联系商家', cropList: [] }) // item.enterpriseWxSpec.btnTitle
  747. }
  748. })
  749. if ((globalSpec?.globalElementsSpecList?.length > 0 && globalSpec?.globalElementsSpecList)) {
  750. groupList.push({ type: 2, name: '悬浮组件', cropList: [] })
  751. }
  752. cropUserGroupMap = accountCreateLogs?.map((item: any) => ({ adAccountId: item.adAccountId, id: item.id, data: groupList }))
  753. }
  754. arrList[targetKey].cropUserGroupMap = cropUserGroupMap
  755. setQueryForm({ ...queryForm, pageList: arr, taskMediaMaps: arrList, adqPageList: adqPageArr })//设置落地页详情数组
  756. } else {
  757. //清空对应创意中的落地页ID
  758. let arr = queryForm.taskMediaMaps || []
  759. arr[targetKey].sysPageId = ''
  760. setQueryForm({ ...queryForm, taskMediaMaps: arr })
  761. }
  762. })
  763. }
  764. }, [queryForm, targetKey, accountCreateLogs])
  765. // 设置云端落地页
  766. const setAdqPage = useCallback((data) => {
  767. if (Array.isArray(data) && data.length > 0) {
  768. let objMap = {}
  769. data?.forEach(item => {
  770. objMap[item.adAccountId] = item.pageList[0].pageId
  771. })
  772. let arr: any = queryForm.taskMediaMaps || []
  773. let adqPageArr: any = queryForm.adqPageList || []
  774. let pageArr: any = queryForm.pageList || []
  775. adqPageArr[targetKey as string] = data
  776. pageArr[targetKey as string] = null
  777. delete arr[targetKey as string]?.cropUserGroupMap
  778. arr[targetKey as string] = { ...arr[targetKey as string], sysPageId: '', accountPageIdMap: objMap }
  779. // 重新设置云端数据并清空本地数据
  780. setQueryForm({ ...queryForm, taskMediaMaps: arr, adqPageList: adqPageArr, pageList: pageArr })
  781. }
  782. }, [queryForm, targetKey])
  783. // tabs新增和删除
  784. const onEdit = useCallback((targetKey: string | React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<Element>, action: 'add' | 'remove') => {
  785. if (queryForm.taskMediaMaps) {
  786. if (action === 'remove') {
  787. let arr = queryForm.taskMediaMaps
  788. let adqPageArr: any = queryForm.adqPageList || []
  789. let pageArr: any = queryForm.pageList || []
  790. adqPageArr[targetKey as string] = null
  791. pageArr[targetKey as string] = null
  792. arr[targetKey as string] = { ...arr[targetKey as string], sysPageId: '', accountPageIdMap: null }
  793. setQueryForm({ ...queryForm, taskMediaMaps: arr, pageList: pageArr, adqPageList: adqPageArr })
  794. }
  795. }
  796. }, [queryForm, targetKey])
  797. // 媒体组更新通知
  798. const usersChange = useCallback(() => {
  799. let data = JSON.parse(localStorage.getItem('ADQUSERS' + userId) as any)
  800. setUsersArr(data)
  801. }, [])
  802. // 切换投放模式
  803. const switchLaunchMode = () => {
  804. if (launchMode === 1) {
  805. setLaunchMode(2)
  806. localStorage.setItem('LAUNCHMODE', '2')
  807. } else {
  808. setLaunchMode(1)
  809. localStorage.setItem('LAUNCHMODE', '1')
  810. }
  811. delBdPlan()
  812. set_targetKey('0')
  813. }
  814. /** 获取分组里账号 */
  815. const getGroupAccountList = (ids: number[]) => {
  816. if (ids.length > 0) {
  817. let data = ids.map(id => getAccountListApi(id))
  818. Promise.all(data).then(res => {
  819. if (res?.length > 0 && res.every((item: { code: number }) => item.code === 200)) {
  820. let userArr: any[] = []
  821. res.forEach((item: { data: { adAccountList: { accountId: number, id: number }[] } }) => {
  822. item.data.adAccountList.forEach(acc => {
  823. let obj = userArr.find((item: { accountId: number }) => item.accountId === acc.accountId)
  824. if (!obj) {
  825. userArr.push(acc)
  826. }
  827. })
  828. })
  829. setAccountCreateLogs(userArr?.map((item) => ({ adAccountId: item?.accountId, id: item.id })))
  830. clearData()
  831. setQueryForm({ ...queryForm, adqPageList: [], pageList: [], taskMediaMaps: queryForm?.taskMediaMaps?.map((item: { sysPageId: number }) => ({ ...item, sysPageId: '', accountPageIdMap: {}, cropUserGroupMap: [] })) })
  832. } else {
  833. message.error('操作异常')
  834. }
  835. })
  836. } else {
  837. setAccountCreateLogs([])
  838. }
  839. }
  840. return <Space direction="vertical" style={{ width: '100%' }}>
  841. <Card
  842. title={<Space>
  843. <div className={style.cardTitle}>配置区</div>
  844. <Popconfirm
  845. title="数据部分不会保存,是否切换?"
  846. onConfirm={switchLaunchMode}
  847. okText="是"
  848. cancelText="否"
  849. >
  850. <Button type="link" style={{ padding: 0 }}>切换投放模式</Button>
  851. </Popconfirm>
  852. </Space>}
  853. className={style.createAd}
  854. hoverable
  855. // extra={<AddGroup onChange={usersChange} pitcherData={getAdAccount?.data?.data} />}
  856. >
  857. <Space wrap>
  858. <Selector label="媒体账户组">
  859. <Select
  860. mode="multiple"
  861. style={{ minWidth: 200 }}
  862. placeholder="快捷选择媒体账户组"
  863. maxTagCount={1}
  864. allowClear
  865. bordered={false}
  866. filterOption={(input: any, option: any) => {
  867. return option!.children?.toString().toLowerCase().includes(input.toLowerCase())
  868. }}
  869. onChange={(e, option) => { getGroupAccountList(e) }}
  870. >
  871. {getGroupList?.data?.map((item: any) => <Select.Option value={item.groupId} key={item.groupId}>{item.groupName}</Select.Option>)}
  872. </Select>
  873. </Selector>
  874. <Selector label="媒体账户">
  875. <Select
  876. mode="multiple"
  877. style={{ minWidth: 200, maxWidth: 500 }}
  878. placeholder="请选择媒体账户"
  879. maxTagCount={1}
  880. allowClear
  881. bordered={false}
  882. maxTagPlaceholder={<Tooltip color="#FFF" title={<span style={{ color: '#000' }}>{accountCreateLogs?.filter((item, index) => index !== 0)?.map(item => item.adAccountId).toString()}</span>}>
  883. <span>+{accountCreateLogs?.length > 1 ? accountCreateLogs.length - 1 : 0}</span>
  884. </Tooltip>}
  885. dropdownMatchSelectWidth={false}
  886. autoClearSearchValue={false}
  887. filterOption={(input: any, option: any) => {
  888. let newInput: string[] = input ? input?.split(/[,,\n\s]+/ig) : []
  889. return newInput?.some(val => option!.children?.toString().toLowerCase()?.includes(val))
  890. }}
  891. value={accountCreateLogs?.map((item: { id: number }) => item?.id)}
  892. onChange={(e, option) => {
  893. setQueryForm({ ...queryForm, adqPageList: [], pageList: [], taskMediaMaps: queryForm?.taskMediaMaps?.map((item: { sysPageId: number }) => ({ ...item, sysPageId: '', accountPageIdMap: {}, cropUserGroupMap: [] })) })
  894. setAccountCreateLogs(option?.map((item: any) => ({ adAccountId: item?.children?.toString()?.split('_')[0], id: item?.value })))
  895. clearData()
  896. }}
  897. searchValue={accSearch}
  898. onSearch={(val) => {
  899. setAccSearch(val)
  900. }}
  901. dropdownRender={menu => (
  902. <>
  903. {menu}
  904. <Divider style={{ margin: '8px 0' }} />
  905. <Space style={{ padding: '0 8px 4px' }}>
  906. <Checkbox onChange={(e) => {
  907. let data = []
  908. if (e.target.checked) {
  909. data = JSON.parse(JSON.stringify(getAllUserAccount?.data?.data))
  910. if (accSearch) {
  911. let newAccSearch = accSearch?.split(/[,,\n\s]+/ig)
  912. data = data?.filter((item: any) => newAccSearch?.some(val => item!.accountId?.toString().toLowerCase()?.includes(val)))
  913. }
  914. }
  915. setQueryForm({ ...queryForm, adqPageList: [], pageList: [], taskMediaMaps: queryForm?.taskMediaMaps?.map((item: { sysPageId: number }) => ({ ...item, sysPageId: '', accountPageIdMap: {}, cropUserGroupMap: [] })) })
  916. setAccountCreateLogs(data?.map((item: any) => ({ adAccountId: item?.accountId, id: item?.id })))
  917. clearData()
  918. }}>全选</Checkbox>
  919. </Space>
  920. </>
  921. )}
  922. >
  923. {getAllUserAccount?.data?.data?.map((item: any) => <Select.Option value={item.id} key={item.id}>{item.remark ? item.accountId + '_' + item.remark : item.accountId}</Select.Option>)}
  924. </Select>
  925. </Selector>
  926. <Selector label="推广目标">
  927. <Select style={{ width: 200 }} value={queryForm?.promotedObjectType} placeholder="请选择推广目标" bordered={false} showSearch filterOption={(input: any, option: any) =>
  928. (option!.children as unknown as string).toLowerCase().includes(input.toLowerCase())
  929. } onChange={(e) => { setQueryForm({ ...queryForm, promotedObjectType: e, sysAdgroup: null, sysAdgroupId: undefined, taskMediaMaps: [], sysAdcreativeId: undefined, materials: [], textData: [], texts: [] }); clearData() }}>
  930. {Object.keys(PromotedObjectType).map(key => {
  931. return <Select.Option value={key} key={key}>{PromotedObjectType[key]}</Select.Option>
  932. })}
  933. </Select>
  934. </Selector>
  935. {launchMode === 2 && accountCreateLogs?.length > 0 && <>
  936. <Button onClick={() => { setGoodsVisible(true) }}>商品广告(选填){accountCreateLogs?.some(item => item?.productList?.length) && <CheckOutlined style={{ color: '#1890ff' }} />}</Button>
  937. <Button onClick={() => { setSourceVisible(true) }}>精准匹配归因(选填){accountCreateLogs?.some(item => item?.userActionSetsList?.length) && <CheckOutlined style={{ color: '#1890ff' }} />}</Button>
  938. </>}
  939. </Space>
  940. <div className={style.cardBody}>
  941. <Row className={style.content}>
  942. <Col span={launchMode === 1 ? 12 : 8} xl={launchMode === 1 ? 12 : 8} lg={24} md={24} sm={24} xs={24} className={style.conLeft}>
  943. <Row className={`${style.conTitle} ${style.conRightBorder}`}><Col span={24}>广告</Col></Row>
  944. <Row className={style.items}>
  945. {/* =============广告基本信息=========== */}
  946. <Ad queryForm={queryForm} setQueryForm={setQueryForm} getSysAdgroups={getSysAdgroups} clearData={clearData} />
  947. {/* =============定向包=========== */}
  948. <TargetIng
  949. queryForm={queryForm}
  950. setQueryForm={setQueryForm}
  951. getSysAdgroups={getSysAdgroups}
  952. clearData={clearData}
  953. setAccountCreateLogs={setAccountCreateLogs}
  954. getsysTargeting={getsysTargeting}
  955. geoLocationList={geoLocationList}
  956. modelList={modelList}
  957. cpDel={cpDel}
  958. accountCreateLogs={accountCreateLogs}
  959. />
  960. {launchMode === 1 && <>
  961. {/* =============商品=========== */}
  962. <Col className={style.conRightBorder} span={5}>
  963. <div className={style.top}>
  964. 商品
  965. </div>
  966. <div className={style.center}>
  967. <div className={style.centerContent}>
  968. {accountCreateLogs?.map((item: any, index: number) => {
  969. if (item?.productList) {
  970. return <div className={style.acc} key={index}>
  971. <div className={style.accName} style={{ fontWeight: 800 }}>{item.adAccountId}</div>
  972. {
  973. item?.productList?.map((pack: { productName: string, author: string, id: number }, index: number) => {
  974. return <div className={style.accCon} key={pack.id}>{pack.productName}<CloseOutlined className={style.close} onClick={() => {
  975. goodsDel(index)
  976. }} /></div>
  977. })
  978. }
  979. </div>
  980. } else {
  981. return null
  982. }
  983. })}
  984. </div>
  985. </div>
  986. <div className={style.bottom}>
  987. {accountCreateLogs?.length > 0 ? <span onClick={() => { setGoodsVisible(true) }}>编辑</span> : <Tooltip title="请先选择媒体账户">
  988. <span>编辑</span>
  989. </Tooltip>}
  990. </div>
  991. </Col>
  992. {/* 数据源 */}
  993. <Col className={style.conRightBorder} span={5}>
  994. <div className={style.top}>
  995. 数据源
  996. </div>
  997. <div className={style.center}>
  998. <div className={style.centerContent}>
  999. {accountCreateLogs?.map((item: any, index: number) => {
  1000. if (item?.userActionSetsList && item?.userActionSetsList?.length > 0) {
  1001. return <div className={style.acc} key={index}>
  1002. <div className={style.accName} style={{ fontWeight: 800 }}>{item.adAccountId}</div>
  1003. {
  1004. item?.userActionSetsList?.map((pack: { name: string, type: string, id: number }, index1: number) => {
  1005. return <div className={style.accCon} key={pack.id}> <span className={style.title}>{pack.name}{' > '}{pack.type?.replace('USER_ACTION_SET_TYPE_', '')}</span> <CloseOutlined className={style.close} onClick={() => {
  1006. sourceDel(index, index1)
  1007. }} /></div>
  1008. })
  1009. }
  1010. </div>
  1011. } else {
  1012. return null
  1013. }
  1014. })}
  1015. </div>
  1016. </div>
  1017. <div className={style.bottom}>
  1018. {accountCreateLogs?.length > 0 ? <span onClick={() => { setSourceVisible(true) }}>编辑</span> : <Tooltip title="请先选择媒体账户">
  1019. <span>编辑</span>
  1020. </Tooltip>}
  1021. </div>
  1022. </Col>
  1023. </>}
  1024. </Row>
  1025. </Col>
  1026. {/* =============广告创意=========== */}
  1027. {launchMode === 1 ? <Col span={12} xl={12} lg={24} md={24} sm={24} xs={24} className={style.conRight}>
  1028. <Row className={style.conTitle}><Col span={24}>广告创意</Col></Row>
  1029. <Row className={style.items}>
  1030. {/* 创意 */}
  1031. <Creative queryForm={queryForm} setQueryForm={setQueryForm} getSysAdgroups={getSysAdgroups} clearData={clearData} getSysAdcreative={getSysAdcreative} set_targetKey={set_targetKey} targetKey={targetKey} page_checked={page_checked} />
  1032. {/* 落地页 */}
  1033. <Col span={12} >
  1034. <div className={style.top}>
  1035. 落地页
  1036. {(queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.cropUserGroupMap?.length > 0) && <CustomerServiceModal data={queryForm?.taskMediaMaps[targetKey]?.cropUserGroupMap} onChange={(data) => {
  1037. let newQueryForm = JSON.parse(JSON.stringify(queryForm))
  1038. newQueryForm.taskMediaMaps[targetKey].cropUserGroupMap = data
  1039. setQueryForm(newQueryForm)
  1040. }} />}
  1041. </div>
  1042. <div className={style.center}>
  1043. <Tabs size={'small'} onEdit={onEdit} type="editable-card" activeKey={targetKey} onChange={(key) => { set_targetKey(key) }} hideAdd >
  1044. {
  1045. queryForm?.taskMediaMaps?.map((item, index) => {
  1046. return <Tabs.TabPane tab={'创意' + (index + 1)} key={index} >
  1047. <Spin spinning={get.loading}>
  1048. <div className={style.centerContent}>
  1049. {
  1050. item?.sysPageId || item?.accountPageIdMap ? <>
  1051. {
  1052. (item?.sysPageId && queryForm?.pageList) && <>
  1053. <div>落地页名称:{queryForm?.pageList[targetKey]?.pageName || ''}</div>
  1054. <div>分享名称:{queryForm?.pageList[targetKey]?.shareContentSpec?.shareTitle || ''}</div>
  1055. <div>分享描述:{queryForm?.pageList[targetKey]?.shareContentSpec?.shareDescription || ''}</div>
  1056. <div style={{ marginBottom: 10 }}>原生推广页顶部素材预览:
  1057. <div>{queryForm?.pageList[targetKey]?.pageSpecsList && queryForm?.pageList[targetKey]?.pageSpecsList[0]?.pageElementsSpecList?.filter((item: any, index: number) => index === 0)?.map((item: { elementType: 'TOP_IMAGE' | 'TOP_VIDEO' | 'TOP_SLIDER', topImageSpec: any, topSliderSpec: any, topVideoSpec: any }, index: number) => {
  1058. switch (item?.elementType) {
  1059. case 'TOP_IMAGE':
  1060. return <Image width={80} src={item?.topImageSpec?.imageUrl} style={{ borderRadius: 8, overflow: 'hidden' }} key={index} />
  1061. case 'TOP_SLIDER':
  1062. return <Space wrap key={index}>
  1063. {item?.topSliderSpec?.imageUrlList?.map((url: string, index: number) => <Image width={70} src={url} style={{ borderRadius: 8 }} key={'TOP_SLIDER' + index} />)}
  1064. </Space>
  1065. case 'TOP_VIDEO':
  1066. return <video src={item?.topVideoSpec?.videoUrl} width={150} controls key={index}></video>
  1067. }
  1068. })}</div>
  1069. </div>
  1070. </>
  1071. }
  1072. {
  1073. queryForm?.adqPageList && queryForm?.adqPageList[targetKey]?.map((adq: any) => {
  1074. return <div className={style.acc} key={adq.adAccountId}>
  1075. <div className={style.accName} style={{ fontWeight: 800 }}>{adq.adAccountId}</div>
  1076. <div className={style.accCon}>
  1077. <span className={style.title}>{adq.pageList[0].pageName}</span>
  1078. </div>
  1079. </div>
  1080. })
  1081. }
  1082. </> : <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
  1083. </div>
  1084. </Spin>
  1085. </Tabs.TabPane>
  1086. })
  1087. }
  1088. </Tabs>
  1089. </div>
  1090. <div className={style.bottom}>{
  1091. (queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysAdcreative) ? <>
  1092. {queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysPageId && <Button type="link" onClick={() => { setLookVisible(true) }}>查看</Button>}
  1093. <Button type="link" onClick={() => {
  1094. setSelectImgVisible(true)
  1095. // 判定是否用原生页顶部替换外部素材
  1096. if (queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.overrideCanvasHeadOption === 'OPTION_CANVAS_OVERRIDE_CREATIVE') {
  1097. init({ mediaType: 'PAGE', cloudSize: undefined, adcreativeTemplateId: queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.adcreativeTemplateId })
  1098. } else {
  1099. init({ mediaType: 'PAGE', cloudSize: undefined })
  1100. }
  1101. }}>{queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysPageId ? '修改' : '选择落地页'}</Button>
  1102. {accountCreateLogs?.length > 0 ? <Button type="link" onClick={() => {
  1103. setPageVisible(true)
  1104. if (queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.overrideCanvasHeadOption === 'OPTION_CANVAS_OVERRIDE_CREATIVE') {
  1105. setCloudParams({ adcreativeTemplateId: queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.adcreativeTemplateId })
  1106. } else {
  1107. setCloudParams({})
  1108. }
  1109. }}>云端落地页</Button> : <Tooltip title="请先选择媒体账户">
  1110. <Button type="link">云端落地页</Button>
  1111. </Tooltip>}
  1112. </> : <Tooltip title="请先设置创意">
  1113. <Button type="link"><span>选择落地页</span></Button>
  1114. </Tooltip>}
  1115. </div>
  1116. </Col>
  1117. </Row>
  1118. </Col> : <Col span={16} xl={16} lg={24} md={24} sm={24} xs={24} className={style.conRight}>
  1119. <Row className={style.conTitle}><Col span={24}>广告创意</Col></Row>
  1120. <Row className={style.items}>
  1121. {/* 创意 */}
  1122. <CreativeCL queryForm={queryForm} setQueryForm={setQueryForm} clearData={clearData} getSysAdcreative={getSysAdcreative} targetKey={targetKey} />
  1123. {/* 落地页 */}
  1124. <Col className={style.conRightBorder} style={{ maxWidth: '25%', border: 'none' }}>
  1125. <div className={style.top}>
  1126. 落地页
  1127. {(queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.cropUserGroupMap?.length > 0) && <CustomerServiceModal data={queryForm?.taskMediaMaps[targetKey]?.cropUserGroupMap} onChange={(data) => {
  1128. let newQueryForm = JSON.parse(JSON.stringify(queryForm))
  1129. newQueryForm.taskMediaMaps[targetKey].cropUserGroupMap = data
  1130. setQueryForm(newQueryForm)
  1131. }} />}
  1132. </div>
  1133. <div className={style.center}>
  1134. {queryForm?.taskMediaMaps?.filter((item, index) => index === 0)?.map((item, index) => {
  1135. return <Spin spinning={get.loading} key={index}>
  1136. <div className={style.centerContent}>
  1137. {item?.sysPageId || item?.accountPageIdMap ? <>
  1138. {(item?.sysPageId && queryForm?.pageList) && <>
  1139. <div>落地页名称:{queryForm?.pageList[targetKey]?.pageName || ''}</div>
  1140. <div>分享名称:{queryForm?.pageList[targetKey]?.shareContentSpec?.shareTitle || ''}</div>
  1141. <div>分享描述:{queryForm?.pageList[targetKey]?.shareContentSpec?.shareDescription || ''}</div>
  1142. <div style={{ marginBottom: 10 }}>原生推广页顶部素材预览:
  1143. <div>{queryForm?.pageList[targetKey]?.pageSpecsList && queryForm?.pageList[targetKey]?.pageSpecsList[0]?.pageElementsSpecList?.filter((item: any, index: number) => index === 0)?.map((item: { elementType: 'TOP_IMAGE' | 'TOP_VIDEO' | 'TOP_SLIDER', topImageSpec: any, topSliderSpec: any, topVideoSpec: any }, index: number) => {
  1144. switch (item?.elementType) {
  1145. case 'TOP_IMAGE':
  1146. return <Image width={80} src={item?.topImageSpec?.imageUrl} style={{ borderRadius: 8, overflow: 'hidden' }} key={index} />
  1147. case 'TOP_SLIDER':
  1148. return <Space wrap key={index}>
  1149. {item?.topSliderSpec?.imageUrlList?.map((url: string, index: number) => <Image width={70} src={url} style={{ borderRadius: 8 }} key={'TOP_SLIDER' + index} />)}
  1150. </Space>
  1151. case 'TOP_VIDEO':
  1152. return <video src={item?.topVideoSpec?.videoUrl} width={150} controls key={index}></video>
  1153. }
  1154. })}</div>
  1155. </div>
  1156. </>}
  1157. {queryForm?.adqPageList && queryForm?.adqPageList[targetKey]?.map((adq: any) => {
  1158. return <div className={style.acc} key={adq.adAccountId}>
  1159. <div className={style.accName} style={{ fontWeight: 800 }}>{adq.adAccountId}</div>
  1160. <div className={style.accCon}>
  1161. <span className={style.title}>{adq.pageList[0].pageName}</span>
  1162. </div>
  1163. </div>
  1164. })}
  1165. </> : <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
  1166. </div>
  1167. </Spin>
  1168. })}
  1169. </div>
  1170. <div className={style.bottom}>{
  1171. (queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysAdcreative) ? <>
  1172. {queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysPageId && <Button type="link" onClick={() => { setLookVisible(true) }}>查看</Button>}
  1173. <Button type="link" onClick={() => {
  1174. setSelectImgVisible(true)
  1175. // 判定是否用原生页顶部替换外部素材
  1176. if (queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.overrideCanvasHeadOption === 'OPTION_CANVAS_OVERRIDE_CREATIVE') {
  1177. init({ mediaType: 'PAGE', cloudSize: undefined, adcreativeTemplateId: queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.adcreativeTemplateId })
  1178. } else {
  1179. init({ mediaType: 'PAGE', cloudSize: undefined })
  1180. }
  1181. }}>{queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysPageId ? '修改' : '选择落地页'}</Button>
  1182. {accountCreateLogs?.length > 0 ? <Button type="link" onClick={() => {
  1183. setPageVisible(true)
  1184. if (queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.overrideCanvasHeadOption === 'OPTION_CANVAS_OVERRIDE_CREATIVE') {
  1185. setCloudParams({ adcreativeTemplateId: queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.adcreativeTemplateId })
  1186. } else {
  1187. setCloudParams({})
  1188. }
  1189. }}>云端落地页</Button> : <Tooltip title="请先选择媒体账户">
  1190. <Button type="link">云端落地页</Button>
  1191. </Tooltip>}
  1192. </> : <Tooltip title="请先设置创意">
  1193. <Button type="link"><span>选择落地页</span></Button>
  1194. </Tooltip>}
  1195. </div>
  1196. </Col>
  1197. </Row>
  1198. </Col>}
  1199. </Row>
  1200. {/* =============广告底部按钮=========== */}
  1201. <Space className={style.bts}>
  1202. <Button type='primary' onClick={severBd}>存为预设</Button>
  1203. <Button type='primary' onClick={preview}><SearchOutlined /> 批量预览广告</Button>
  1204. <Button onClick={delBdPlan}>清空配置/预设</Button>
  1205. </Space>
  1206. </div>
  1207. </Card>
  1208. <Card
  1209. className={style.createAd}
  1210. hoverable
  1211. extra={tableData?.length > 0 ? <Space>
  1212. <span>推广计划总数:{tableData?.length}</span>
  1213. <span>广告总数:{tableData?.length}</span>
  1214. {/* {tableSelect?.length > 0 && <span> 已选:<span style={{ color: '#1890FF' }}>{tableSelect?.length}</span> 条</span>} */}
  1215. {
  1216. <Button type='primary' onClick={() => {
  1217. // if (tableSelect.length === 0) {
  1218. // message.error('请选择要提交的计划!')
  1219. // return
  1220. // };
  1221. setSubVisible(true)
  1222. }}>批量提交审核</Button>
  1223. }
  1224. </Space> : false
  1225. }
  1226. >
  1227. {tableData?.length > 0 ? <div className={style.cardBody}>
  1228. <div className={style.content} style={{ marginTop: 20 }}>
  1229. <Tables
  1230. columns={columns()}
  1231. dataSource={tableData}
  1232. total={0}
  1233. size="small"
  1234. bordered
  1235. scroll={{ x: 2000 }}
  1236. myKey={'myId'}
  1237. // rowSelection={{
  1238. // selectedRowKeys: tableSelect?.map((item: any) => item?.myId.toString()),
  1239. // onChange: (selectedRowKeys: React.Key[], selectedRows: any) => {
  1240. // setTableSelect(selectedRows)
  1241. // }
  1242. // }}
  1243. />
  1244. </div>
  1245. </div> : <div style={{ minHeight: 400, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
  1246. <Empty description="请先完成模块配置后,再预览广告计划" />
  1247. </div>}
  1248. </Card>
  1249. {/* 选择商品 */}
  1250. {goodsVisible && <GoodsModal visible={goodsVisible} data={accountCreateLogs} onClose={() => setGoodsVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setGoodsVisible(false); clearData() }} />}
  1251. {/* 选择数据源 */}
  1252. {sourceVisible && <DataSourceModal visible={sourceVisible} promotedObjectType={queryForm.promotedObjectType} data={accountCreateLogs} onClose={() => setSourceVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setSourceVisible(false); clearData() }} />}
  1253. {/* 选择转化ID */}
  1254. {idVisible && <IdModal visible={idVisible} data={accountCreateLogs} onClose={() => setIdVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setSourceVisible(false); clearData() }} />}
  1255. {/* 选择ADQ落地页 */}
  1256. {pageVisible && <PageModal cloudParams={cloudParams} visible={pageVisible} data={queryForm?.adqPageList?.[targetKey] || accountCreateLogs} onClose={() => setPageVisible(false)} onChange={(e) => { setAdqPage(e); setPageVisible(false); clearData() }} />}
  1257. {/* 选择素材 */}
  1258. {selectImgVisible && <SelectCloud visible={selectImgVisible} onClose={() => setSelectImgVisible(false)} onChange={setPage} isBack={false} />}
  1259. {/* 查看落地页 */}
  1260. {lookVisible && <LookLanding visible={lookVisible} onClose={() => setLookVisible(false)} id={queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey].sysPageId} />}
  1261. {/* 设置名称 */}
  1262. {subVisible && <SubmitModal data={getSysAdgroups?.data} visible={subVisible} onClose={() => setSubVisible(false)} onChange={submit} ajax={createAdBatch} />}
  1263. </Space>
  1264. }
  1265. export default CreateAd