import { Button, Card, Checkbox, Divider, Empty, Modal, Popconfirm, Radio, Select, Space, Spin, Table, Tabs, Tag, Tooltip, message, notification } from "antd" import React, { useEffect, useState } from "react" import style from './index.less' import '../index.less' import Selector from "@/pages/launchSystemNew/launchManage/createAd/selector" import { CheckOutlined, SearchOutlined } from "@ant-design/icons" import Ad from "./Ad" import Target from "./Target" import { getAccountListApi, getGroupListApi } from "@/services/launchAdq/subgroup" import { useAjax } from "@/Hook/useAjax" import { useModel } from "umi" import GoodsModal from "../../components/GoodsModal" import DataSourceModal from "../../components/DataSourceModal" import moment from "moment" import Dynamic from "./Dynamic" import Material from "./Material" import MaterialText from "./MaterialText" import PageList from "./PageList" import { cartesianProduct, distributeArray, processData, randomString, splitArrayIntoRandomChunks } from "@/utils/utils" import columns from "./tableConfig" import SubmitModal from "./submitModal" import { createAdgroupTaskApi, getSelectTaskDetailApi } from "@/services/adqV3" import WechatAccount from "../../components/WechatAccount" import Title from "antd/lib/typography/Title" import { getCreativeDetailsApi } from "@/services/adqV3/global" import ConversionSelect from "../../components/ConversionSelect" import VideoChannel from "../../components/VideoChannel" import Save from "./Save" import { useLocalStorageState } from "ahooks" export const DispatchAddelivery = React.createContext(null); /** * 创建广告 * @returns */ const Create: React.FC = () => { /*******************************************/ const { initialState } = useModel('@@initialState'); const { getAllUserAccount } = useModel('useLaunchAdq.useAdAuthorize') const { initTargeting } = useModel('useLaunchV3.useTargeting') const [addelivery, setAddelivery] = useState({ adgroups: {}, targeting: [], dynamic: {}, dynamicMaterialDTos: {}, dynamicCreativesTextDTOS: {}, mediaType: 0 }) const { marketingAssetOuterSpec, marketingCarrierType, marketingGoal, siteSet, automaticSiteEnabled, sceneSpec, isConversion } = addelivery.adgroups const { deliveryMode, creativeTemplateId, creativeComponents } = addelivery.dynamic const [accSearch, setAccSearch] = useState() const [accountCreateLogs, setAccountCreateLogs] = useState([]) // 账户 const [goodsVisible, setGoodsVisible] = useState(false) // 选择小说弹窗控制 const [wechatVisible, setWechatVisible] = useState(false) // 选择微信公众号弹窗控制 const [channelsProfileVisible, setChannelsProfileVisible] = useState(false) // 选择微信公众号弹窗控制 const [sourceVisible, setSourceVisible] = useState(false) // 选择数据源弹窗控制 const [conversionVisible, setConversionVisible] = useState(false) // 选择转化归因控制 const [materialData, setMaterialData] = useState({}) // 素材数据 const [textData, setTextData] = useState({}) const [tableData, setTableData] = useState({}) const [activeKey, setActiveKey] = useState() const [subVisible, setSubVisible] = useState(false) // 选择设置名称弹窗控制 const [adCount, setAdCount] = useState(0) const [dynamicCount, setDynamicCount] = useState(0) const [creativeTemplateAppellation, setCreativeTemplateAppellation] = useState() const [creativeTemplateStyle, setCreativeTemplateStyle] = useState() const [putInTypeList, setPutInTypeList] = useState<{ label: string, value: string }[]>([]) const [putInType, setPutInType] = useLocalStorageState<'NOVEL' | 'GAME'>('PUTINTYPE'); const [copyTask, setCopyTask] = useState<{ copyTaskId?: number, uuid?: string }>({}) const getGroupList = useAjax(() => getGroupListApi()) const createAdgroupTask = useAjax((params) => createAdgroupTaskApi(params)) const getSelectTaskDetail = useAjax((params) => getSelectTaskDetailApi(params)) const getCreativeDetails = useAjax((params) => getCreativeDetailsApi(params)) /*******************************************/ // 判断游戏还是小说短剧 useEffect(() => { if (initialState?.menu?.data?.length) { const menu = initialState?.menu?.data const ADLAUNCH3 = menu.find((item: { path: string }) => item.path === "/launchSystemV3") const ADLAUNCH2 = menu.find((item: { path: string }) => item.path === "/launchSystemNew") const ACCOUNTLIST = ADLAUNCH3?.routes?.find((item: { path: string }) => item.path === "/launchSystemV3/account") || ADLAUNCH2?.routes?.find((item: { path: string }) => item.path === "/launchSystemNew/account") let newputInTypeList: { label: string, value: string }[] = [] ACCOUNTLIST?.routes.forEach((item: { path: string }) => { if (item.path.includes('novel')) { newputInTypeList.push({ label: '小说/短剧投放', value: 'NOVEL' }) } else if (item.path.includes('game')) { newputInTypeList.push({ label: '游戏投放', value: 'GAME' }) } }) setPutInTypeList(newputInTypeList); newputInTypeList.length > 0 && setPutInType(type => (type && newputInTypeList.some(item => item.value === type) ? type : newputInTypeList[0].value) as 'NOVEL' | 'GAME'); } }, [initialState?.menu]) useEffect(() => { // 获取账户组 getGroupList.run() // 获取账户列表 getAllUserAccount.run() initTargeting() }, []) useEffect(() => { if (creativeTemplateId) { let params: any = { marketingGoal, marketingTargetType: marketingAssetOuterSpec.marketingTargetType, marketingCarrierType, deliveryMode, creativeTemplateId, wechatSceneSpecPosition: sceneSpec?.wechatPosition, dynamicCreativeType: deliveryMode === 'DELIVERY_MODE_COMPONENT' ? 'DYNAMIC_CREATIVE_TYPE_PROGRAM' : 'DYNAMIC_CREATIVE_TYPE_COMMON' } if (automaticSiteEnabled) { params.automaticSiteEnabled = automaticSiteEnabled } else { params.siteSet = siteSet } getCreativeDetails.run(params).then(res => { if (res?.adcreativeTemplateStructAdpermits?.length > 0) { let adcreativeTemplateStructAdpermits = res?.adcreativeTemplateStructAdpermits[0] setCreativeTemplateAppellation(adcreativeTemplateStructAdpermits.creativeTemplateAppellation) setCreativeTemplateStyle(adcreativeTemplateStructAdpermits.creativeTemplateStyle) let creativeComponents = adcreativeTemplateStructAdpermits?.creativeComponents || [] let result = processData(creativeComponents); let newMaterialData: any = {}; let newTextData: any = {}; Object.keys(result).forEach(key => { let data = result[key] if ((key === 'image_list' || key === 'short_video' || key === 'video' || key === 'image' || key === 'element_story') && data.required) { newMaterialData[key] = data } else if (key === 'title' || (data.required && key === 'description')) { newTextData[key] = data } }) setMaterialData(newMaterialData) setTextData(newTextData) } }) } }, [creativeTemplateId, deliveryMode, marketingGoal, marketingAssetOuterSpec, marketingCarrierType, siteSet, sceneSpec?.wechatPosition, automaticSiteEnabled]) /** 获取分组里账号 */ const getGroupAccountList = (ids: number[]) => { if (ids.length > 0) { let data = ids.map(id => getAccountListApi(id)) Promise.all(data).then(res => { if (res?.length > 0 && res.every((item: { code: number }) => item.code === 200)) { let userArr: any[] = [] res.forEach((item: { data: { adAccountList: { accountId: number, id: number }[] } }) => { item.data.adAccountList.forEach(acc => { let obj = userArr.find((item: { accountId: number }) => item.accountId === acc.accountId) if (!obj) { userArr.push(acc) } }) }) setAccountCreateLogs(userArr?.filter((item: any) => putInType === 'NOVEL' ? ['NOVEL', 'NOVEL_IAA'].includes(item.adUnitType) : putInType === 'GAME' ? ['GAME', 'GAME_IAA'].includes(item.adUnitType) : false)?.map((item) => ({ accountId: item?.accountId }))) clearData() setAddelivery({ adgroups: {}, targeting: [], dynamic: {}, dynamicMaterialDTos: {}, dynamicCreativesTextDTOS: {}, mediaType: 0 }) } else { message.error('操作异常') } }) } else { setAccountCreateLogs([]) } } /** 存为预设 */ const severBd = () => { if (putInType) { localStorage.setItem(putInType === 'GAME' ? 'ADQADV3_GAME' : 'ADQADV3', JSON.stringify({ addelivery, accountCreateLogs, materialData, textData, putInType })) message.success('存储成功') } } /** 清除 */ const delBdPlan = ({ isRemoveItem = true }: { isRemoveItem?: boolean }) => { if (isRemoveItem) { localStorage.removeItem(putInType === 'GAME' ? 'ADQADV3_GAME' : 'ADQADV3') } setAccountCreateLogs([]) setMaterialData({}) setTextData({}) setAddelivery({ adgroups: {}, targeting: [], dynamic: {}, dynamicMaterialDTos: {}, dynamicCreativesTextDTOS: {}, mediaType: 0 }) setCopyTask({}) setTableData({}) } /**数据回填 */ useEffect(() => { if (putInTypeList?.length > 0) { let taskId = sessionStorage.getItem('TASKID3.0') let adqAdData = localStorage.getItem(putInType === 'GAME' ? 'ADQADV3_GAME' : 'ADQADV3') if (taskId) { getSelectTaskDetail.run(taskId).then(res => { if (res) { const { adgroupDTO, accountIdParamVOMap, targetings, dynamicCreativesDTO: { mediaType, ...dynamic }, dynamicCreativesTextDTO, dynamicMaterialDTOS, taskType = 'NOVEL', id, uuid } = res setCopyTask({ copyTaskId: id, uuid }) if (putInTypeList.some(item => item.value === taskType)) { setPutInType(() => taskType) let beginDate = adgroupDTO.beginDate let endDate = adgroupDTO.endDate if (adgroupDTO?.deepConversionSpec) { adgroupDTO.depthConversionEnabled = true } else { adgroupDTO.depthConversionEnabled = false } if (beginDate && moment(beginDate) < moment()) { beginDate = moment().format('YYYY-MM-DD') endDate = moment().add(7, 'day').format('YYYY-MM-DD') message.warning('请注意,检测投放开始日期小于今天,已自动改成今天,如需修改,请重新设置') } let dynamicGroup: any[] = [] if (dynamic.deliveryMode === 'DELIVERY_MODE_CUSTOMIZE') { dynamicGroup = dynamicMaterialDTOS?.map((item: any[]) => { let { type, valueJson } = item[0] let value = JSON.parse(valueJson).value if (type === 'image') { return { image_id: { id: value.imageId, url: value.imageUrl, materialType: value.materialType } } } else if (type === 'image_list' || type === 'element_story') { return { [type]: value.list.map((l: { imageUrl: any; imageId: any; materialType: any }) => ({ url: l.imageUrl, id: l.imageId, materialType: l.materialType })) } } else if (type === 'short_video' || type === 'video') { let field = type === 'video' ? 'video_id' : 'short_video1' let videoData: any = {} videoData[field] = { materialType: value.materialType, url: value.videoUrl, id: value.videoId } if (value.imageUrl) { videoData['cover_id'] = { materialType: value.materialCoverType, url: value.imageUrl, id: value.iamgeId } } return videoData } else { return {} } }) } else { // 组件化创意 dynamicGroup = dynamicMaterialDTOS?.map((item: any[]) => { return { list: item?.map((i: any) => { let { type, valueJson } = i let value = JSON.parse(valueJson).value if (type === 'image') { return { id: value.imageId, url: value.imageUrl, materialType: value.materialType } } else if (type === 'image_list') { return value.list.map((l: { imageUrl: any; imageId: any; materialType: any }) => ({ url: l.imageUrl, id: l.imageId, materialType: l.materialType })) } else if (type === 'video') { return { materialType: value.materialType, url: value.videoUrl, id: value.videoId } } else { return {} } }) } }) } let isConversion = false setAccountCreateLogs(Object.keys(accountIdParamVOMap || {}).map(accountId => { const { productDTOS, wechatOfficialAccountsVO, pageList, landingPageVOS, userActionSetsList, conversionInfo, wechatChannelVO, wechatAppletList } = accountIdParamVOMap[accountId] let data: PULLIN.AccountCreateLogsProps = { accountId: Number(accountId), productList: productDTOS } if (wechatOfficialAccountsVO) { data.wechatChannelList = [wechatOfficialAccountsVO] } if (pageList || landingPageVOS || wechatAppletList) { data.pageList = pageList || landingPageVOS || wechatAppletList?.map((item: { appletName: any; id: any }) => ({ ...item, pageName: item.appletName, pageId: item.id })) } if (userActionSetsList) { data.userActionSetsList = userActionSetsList } if (conversionInfo) { isConversion = true data.newConversionList = [conversionInfo] } if (wechatChannelVO) { data.videoChannelList = [wechatChannelVO] } return data })) setAddelivery({ adgroups: { ...adgroupDTO, isConversion, adgroupName: adgroupDTO.adgroupName + '_副本' + randomString(true, 3, 5), endDate, beginDate }, targeting: targetings.map((item: any) => { const { targetingName, ...targeting } = item return { targetingName, targeting } }), dynamic, dynamicMaterialDTos: dynamicGroup.length > 0 ? { dynamicGroup } : {}, dynamicCreativesTextDTOS: dynamicCreativesTextDTO, mediaType: mediaType || 0 }) } else { message.error(`没有${taskType === 'NOVEL' ? '小说/短剧' : taskType === 'GAME' ? '游戏' : taskType}投放权限`) } sessionStorage.removeItem('TASKID3.0') } }) } else if (adqAdData) { const { addelivery, accountCreateLogs, materialData, textData } = JSON.parse(adqAdData) if (addelivery?.adgroups) { if (addelivery?.adgroups?.beginDate && moment(addelivery?.adgroups?.beginDate) < moment()) { addelivery.adgroups.beginDate = moment().format('YYYY-MM-DD') message.warning('请注意,检测投放开始日期小于今天,已自动改成今天,如需修改,请重新设置') } if (addelivery?.adgroups?.endDate && moment(addelivery?.adgroups?.endDate) < moment()) { addelivery.adgroups.endDate = moment().format('YYYY-MM-DD') message.warning('请注意,检测投放结束日期小于今天,已自动改成今天,如需修改,请重新设置') } } setAddelivery({ ...addelivery }) setAccountCreateLogs(accountCreateLogs) setMaterialData(materialData) setTextData(textData) } } }, [putInType, putInTypeList]) // 预览 const preview = () => { if (accountCreateLogs?.length === 0) { message.error('请先选择媒体账户') return } const { adgroups, targeting, dynamic, dynamicMaterialDTos, dynamicCreativesTextDTOS, mediaType } = addelivery if (["OPTIMIZATIONGOAL_FOLLOW", "OPTIMIZATIONGOAL_PAGE_SCAN_CODE"].includes(adgroups?.optimizationGoal)) { if (!adgroups?.depthConversionEnabled) { message.error('应公司要求,”关注和加企微“请开启深度转化优化') return } if (adgroups?.deepConversionSpec?.deepConversionWorthSpec?.expectedRoi < 0.03) { notification.warning({ message: '请注意', description: `当前ROI出价小于0.03,当前${adgroups?.deepConversionSpec?.deepConversionWorthSpec?.expectedRoi}` }) } } if (!(adgroups && Object.keys(adgroups).length)) { message.error('请先配置广告信息') return } if (!(targeting?.length)) { message.error('请先添加定向') return } if (!(dynamic && Object.keys(dynamic).length)) { message.error('请先配置创意') return } if ((materialData && Object.keys(materialData).length) && !(dynamicMaterialDTos && Object.keys(dynamicMaterialDTos).length)) { message.error('请先配置创意素材') return } if ((textData && Object.keys(textData).length) && !(dynamicCreativesTextDTOS && Object.keys(dynamicCreativesTextDTOS).length)) { message.error('请先配置创意文案') return } if (['MARKETING_TARGET_TYPE_FICTION', 'MARKETING_TARGET_TYPE_SHORT_DRAMA'].includes(marketingAssetOuterSpec?.marketingTargetType) && !accountCreateLogs?.some(item => item?.productList?.length)) { message.error(marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_FICTION' ? '请先选择小说' : '请先选择短剧') return } if ((['MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT'].includes(marketingAssetOuterSpec?.marketingTargetType) || marketingCarrierType === 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT' || dynamic?.creativeComponents?.brand?.[0]?.value?.jumpInfo?.pageType === 'PAGE_TYPE_WECHAT_OFFICIAL_ACCOUNT_DETAIL') && !accountCreateLogs?.some(item => item?.wechatChannelList?.length)) { message.error('请先选择公众号') return } if (creativeComponents?.brand?.[0]?.value?.jumpInfo?.pageType === 'PAGE_TYPE_WECHAT_CHANNELS_PROFILE' && !accountCreateLogs?.some(item => item?.videoChannelList?.length)) { message.error('请先选择视频号') return } if (isConversion && !accountCreateLogs?.some(item => item?.newConversionList?.length)) { message.error('请先选择转化归因') return } if (!accountCreateLogs?.some(item => item?.pageList?.length)) { message.error('请先选择落地页') return } let newTableData: any = {} let newAdCount = 0, newdynamicCount = 0 let textType = dynamicCreativesTextDTOS.type let textDto = dynamicCreativesTextDTOS?.dynamicCreativesTextDetailDTOList || [] let textDtoLenth = textDto.length let dynamicGroupLength = dynamicMaterialDTos?.dynamicGroup?.length || 0 let newDynamicGroup: any = [] if (![910].includes(dynamic.creativeTemplateId)) { newDynamicGroup = dynamicMaterialDTos?.dynamicGroup || [] if (newDynamicGroup.length > 0 && [0, 1, 2, 3, 4].includes(textType)) { if (textType === 0) { newDynamicGroup = newDynamicGroup.map((item: any) => ({ ...item, textDto: textDto?.[0] })) } else if (textType === 1) { newDynamicGroup = newDynamicGroup.map((item: any, index: number) => ({ ...item, textDto: textDto?.[index] })) } else if (textType === 2) { newDynamicGroup = newDynamicGroup.map((item: any, index: number) => ({ ...item, textDto: textDto?.[index % textDtoLenth] })) } else if ((textType === 3 && mediaType === 0) || (textType === 4 && mediaType === 1)) { newDynamicGroup = cartesianProduct(newDynamicGroup, textDto || [{}]).map((item) => { let [dynamicGroup, textDtoData] = item return { ...dynamicGroup as any, textDto: textDtoData } }) } } } // 创意组平均分配到广告逻辑 let averageAdDynamicList: any[] = [] if ((mediaType === 1 || mediaType === 2) && newDynamicGroup.length) { let adLength = 0 accountCreateLogs.forEach(item => { let productList: any[] = [] if (['MARKETING_TARGET_TYPE_FICTION', 'MARKETING_TARGET_TYPE_SHORT_DRAMA'].includes(marketingAssetOuterSpec?.marketingTargetType)) { // 小说 短剧 productList = item?.productList || [] } else if (['MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT'].includes(marketingAssetOuterSpec?.marketingTargetType)) { // 公众号 productList = item?.wechatChannelList || [] } else { productList = [{}] } adLength += productList.length * targeting.length }) if (mediaType === 1) { if (textType === 4) { if (adLength > newDynamicGroup.length) { message.error(`创意组分配规则选择“平均分配到广告”时,创意组总数必须大于等于广告总数。当前创意组数量:${dynamicGroupLength},广告数量:${adLength}`) return } averageAdDynamicList = splitArrayIntoRandomChunks(newDynamicGroup, adLength) } else { if (adLength > dynamicGroupLength) { message.error(`创意组分配规则选择“平均分配到广告”时,创意组总数必须大于等于广告总数。当前创意组数量:${dynamicGroupLength},广告数量:${adLength}`) return } averageAdDynamicList = distributeArray(newDynamicGroup, adLength) } } else if (mediaType === 2) { if (adLength < dynamicGroupLength) { message.error(`创意组分配规则选择“顺序分配到广告”时,创意组总数必须小于等于广告总数。当前创意组数量:${dynamicGroupLength},广告数量:${adLength}`) return } } } if (textType === 1) { if (dynamicGroupLength !== textDtoLenth) { message.error(`当前创意文案是“创意组一一对应”模式,创意组总数(${dynamicGroupLength})要等于创意文案总数(${textDtoLenth})`) return } if (!dynamicCreativesTextDTOS.dynamicCreativesTextDetailDTOList.every((item: {}) => item && Object.keys(item).length)) { message.error('创意文案配置错误,内容空') return } } // 落地页平均分配判断数量 if ([910].includes(dynamic.creativeTemplateId) && dynamic?.landingPageType === 1) { let targetingLength = targeting.length if (accountCreateLogs.some(item => { let productListLength = item?.productList?.length || 1 let total = targetingLength * productListLength let pageLength = item.pageList.length if (total > pageLength) { message.error(`当前${item.accountId}下的广告总数(${total})大于落地页总数(${pageLength}),平均分配需要落地页总数大于广告总数`) return true } return false })) { return } } let accountIndex = 0, accountIndex1 = 0 accountCreateLogs.forEach(item => { let productList: any[] = [{}] if (['MARKETING_TARGET_TYPE_FICTION', 'MARKETING_TARGET_TYPE_SHORT_DRAMA'].includes(marketingAssetOuterSpec?.marketingTargetType)) { // 小说 productList = item?.productList || [] } else if (['MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT'].includes(marketingAssetOuterSpec?.marketingTargetType)) { // 公众号 productList = item?.wechatChannelList || [] } let data = cartesianProduct(productList, targeting).map(newD => { let [productDto, targetDto, index] = newD let suffix = '_' + item.accountId + '_' + index let averageAdDynamic = averageAdDynamicList?.[accountIndex] let dat: any = { id: item.accountId + '_' + index, accountId: item.accountId, // 账户 userActionSetsList: item.userActionSetsList, // 数据源 conversionList: item.newConversionList, // 转化归因 pageListDto: item.pageList, // 落地页 productDto, // 商品 targetDto: { // 定向 ...targetDto, targetingName: targetDto.targetingName + suffix }, adgroupsDto: { // 广告信息 ...adgroups, adgroupName: adgroups.adgroupName + suffix }, dynamicDto: dynamic, // 创意信息 averageAdDynamic, rowSpan: (mediaType === 1 && textType !== 4) ? averageAdDynamic.length : ([910].includes(dynamic.creativeTemplateId) ? item.pageList?.length : (textType === 3 ? textDtoLenth * dynamicGroupLength : dynamicGroupLength)) || 1 } if (marketingCarrierType === 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT') { // 营销载体 dat.marketingCarrierDto = item?.wechatChannelList } accountIndex += 1 return dat }) newAdCount += data.length let newData: any[] = [] if ([910].includes(dynamic.creativeTemplateId)) { if (dynamic?.landingPageType === 1) { let averageAdPageList: any[] = distributeArray(item.pageList, productList.length * targeting.length) data.forEach((item, aIndex) => { let aPageList: any[] = averageAdPageList[aIndex] aPageList.forEach((page, index) => { newData.push({ ...item, id: item.id + '_' + index, pageListDto: [page], dynamicDto: { ...item.dynamicDto, dynamicCreativeName: item.dynamicDto.dynamicCreativeName + index }, rowSpan: index === 0 ? aPageList.length : 0, adLength: data.length, isRowSpan: true }) }) }) } else { newData = cartesianProduct(data, item.pageList).map((item, index) => { let [d1, pageList, num] = item return { ...d1, id: d1.id + '_' + index, pageListDto: [pageList], dynamicDto: { ...d1.dynamicDto, dynamicCreativeName: d1.dynamicDto.dynamicCreativeName + num } } }) } } else { if (mediaType === 1) { data.forEach(item => { const { averageAdDynamic, ...ad } = item if (textType === 3) { let rowSpan = textDtoLenth * averageAdDynamic.length cartesianProduct(textDto, averageAdDynamic).forEach((taad: any, index) => { let [textValue, aad] = taad newData.push({ ...ad, id: ad.id + '_' + index, dynamicGroup: aad, textDto: textValue, rowSpan: index === 0 ? rowSpan : 0, adLength: data.length, isRowSpan: true }) }) } else if (textType === 4) { averageAdDynamic.forEach((aad: any, index: number) => { newData.push({ ...ad, id: ad.id + '_' + index, dynamicGroup: aad, textDto: aad?.textDto, adLength: data.length, rowSpan: index === 0 ? averageAdDynamic.length : 0, isRowSpan: true }) }) } else { averageAdDynamic.forEach((aad: any, index: number) => { newData.push({ ...ad, id: ad.id + '_' + index, dynamicGroup: aad, textDto: aad?.textDto, adLength: data.length }) }) } }) } else if (mediaType === 2) { data.forEach((item) => { const { averageAdDynamic, ...ad } = item if (textType === 3) { cartesianProduct(textDto, [newDynamicGroup[accountIndex1 % newDynamicGroup.length]]).forEach((taad: any, i) => { let [textValue, aad, index] = taad newData.push({ ...ad, id: ad.id + '_' + index, dynamicGroup: aad, textDto: textValue, rowSpan: i === 0 ? textDto.length : 0, adLength: data.length, isRowSpan: true }) }) } else { let { textDto, ...dynamicGroup } = newDynamicGroup[accountIndex1 % newDynamicGroup.length] newData.push({ ...ad, dynamicGroup, textDto, rowSpan: 1, adLength: data.length }) } accountIndex1 += 1 }) } else { // 全账号复用创意组 所有广告一样的创意组 newData = cartesianProduct(data, newDynamicGroup.length > 0 ? newDynamicGroup : [{}]).map((item, index) => { let [d1, group] = item return { ...d1, id: d1.id + '_' + index, dynamicGroup: group, textDto: (group as any)?.textDto, adLength: data.length } }) } } newdynamicCount = newdynamicCount + newData.length newTableData[item.accountId] = newData }) setAdCount(newAdCount) setDynamicCount(newdynamicCount) setActiveKey(accountCreateLogs?.[0].accountId?.toString()) console.log('newTableData-->', newTableData) setTableData(newTableData) } // 提交 const onSubmit = (values: any) => { const { adgroups, targeting, dynamic, dynamicMaterialDTos, dynamicCreativesTextDTOS, mediaType } = JSON.parse(JSON.stringify(addelivery)) as PULLIN.AddeliveryProps let dynamicMaterialDTOS = [] if (dynamic.deliveryMode === 'DELIVERY_MODE_CUSTOMIZE') { if ((materialData && Object.keys(materialData).length && dynamicMaterialDTos && Object.keys(dynamicMaterialDTos).length)) { let mType = Object.keys(materialData)[0]; dynamicMaterialDTOS = dynamicMaterialDTos.dynamicGroup?.map((item: any) => { if (mType === 'image') { return [{ type: mType, valueJson: JSON.stringify({ value: { imageUrl: item?.image_id?.url, imageId: item?.image_id?.id, materialType: item?.image_id?.materialType } }) }] } else if (mType === 'image_list' || mType === 'element_story') { let key = 'image_list' if (mType === 'element_story') { key = 'element_story' } let list = item?.[key]?.map((l: any) => { return { imageUrl: l?.url, imageId: l?.id, materialType: l?.materialType } }) return [{ type: mType, valueJson: JSON.stringify({ value: { list } }) }] } else if (['short_video', 'video'].includes(mType)) { let value: any = { materialType: item?.video_id?.materialType || item?.short_video1?.materialType || 0, videoUrl: item?.video_id?.url || item?.short_video1?.url, videoId: item?.video_id?.id || item?.short_video1?.id } if (item?.cover_id?.url) { value.imageUrl = item?.cover_id?.url value.imageId = item?.cover_id?.id value.materialCoverType = item?.cover_id?.materialType } return [{ type: mType, valueJson: JSON.stringify({ value }) }] } return [{ type: mType, valueJson: '' }] }) } } else { if (dynamicMaterialDTos && Object.keys(dynamicMaterialDTos).length) { dynamicMaterialDTOS = dynamicMaterialDTos.dynamicGroup?.map((item: { list: any[] }) => { return item.list.map(l => { if (Array.isArray(l)) { return { type: 'image_list', valueJson: JSON.stringify({ value: { list: l?.map((i: any) => { return { imageUrl: i?.url, imageId: i?.id, materialType: i?.materialType } }) } }) } } else if (l?.url?.includes('mp4')) { return { type: 'video', valueJson: JSON.stringify({ value: { materialType: l?.materialType, videoUrl: l?.url, videoId: l?.id } }) } } else { return { type: 'image', valueJson: JSON.stringify({ value: { imageUrl: l?.url, imageId: l?.id, materialType: l?.materialType } }) } } }) }) } } let accountIdParamDTOMap: any = {} accountCreateLogs.forEach(item => { let { pageList, productList, userActionSetsList, accountId, wechatChannelList, newConversionList, videoChannelList } = item let userActionSetsListDto = userActionSetsList?.map((item: any) => ({ id: item?.userActionSetId, type: item?.type })) // dataSourceId let map: any = { userActionSetsList: userActionSetsListDto, pageList: pageList?.map((item: { pageId: any }) => item.pageId) } if (productList && ['MARKETING_TARGET_TYPE_FICTION', 'MARKETING_TARGET_TYPE_SHORT_DRAMA'].includes(marketingAssetOuterSpec?.marketingTargetType)) { map.productDTOS = productList?.map(item => { return { productId: item.marketingAssetId } }) } if (wechatChannelList && (['MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT'].includes(marketingAssetOuterSpec?.marketingTargetType) || marketingCarrierType === 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT' || dynamic?.creativeComponents?.brand?.[0]?.value?.jumpInfo?.pageType === 'PAGE_TYPE_WECHAT_OFFICIAL_ACCOUNT_DETAIL')) { map.wechatChannelId = wechatChannelList?.[0]?.wechatOfficialAccountId } if (newConversionList && isConversion) { map.conversionId = newConversionList?.[0]?.conversionId } if (videoChannelList && creativeComponents?.brand?.[0]?.value?.jumpInfo?.pageType === 'PAGE_TYPE_WECHAT_CHANNELS_PROFILE') { map.videoChannelId = videoChannelList?.[0]?.wechatChannelsAccountId } accountIdParamDTOMap[accountId] = map }) let dynamicCreativesDTO = { ...dynamic, mediaType } if (dynamic.deliveryMode === 'DELIVERY_MODE_COMPONENT') { dynamicCreativesDTO.creativeTemplateId = 711 } delete adgroups?.isConversion // 前端控制新链路字段 let params = { ...values, adgroupDTO: adgroups, targetings: targeting.map(item => ({ targetingName: item.targetingName, ...item?.targeting || {} })), dynamicCreativesDTO, dynamicCreativesTextDTOS, dynamicMaterialDTOS, accountIdParamDTOMap, taskType: putInType, ...copyTask } createAdgroupTask.run(params).then(res => { if (res) { Modal.success({ content: '任务提交成功', bodyStyle: { fontWeight: 700 }, okText: '跳转任务列表', closable: true, onOk: () => { sessionStorage.setItem('CAMPV3', values?.taskName) window.location.href = '/#/launchSystemV3/tencentAdPutIn/taskList' }, onCancel: () => { setSubVisible(false) } }) } }) } const clearData = () => { setTableData({}) } return
配置区
{putInTypeList.length >= 1 && { setPutInType(e.target.value) delBdPlan({ isRemoveItem: false }) }} options={putInTypeList} optionType='button' size="small" />}
} className={style.createAd} > {accountCreateLogs?.length > 0 && <> {['MARKETING_TARGET_TYPE_FICTION', 'MARKETING_TARGET_TYPE_SHORT_DRAMA'].includes(marketingAssetOuterSpec?.marketingTargetType) && } {(marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT' || marketingCarrierType === 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT' || creativeComponents?.brand?.[0]?.value?.jumpInfo?.pageType === 'PAGE_TYPE_WECHAT_OFFICIAL_ACCOUNT_DETAIL') && } {creativeComponents?.brand?.[0]?.value?.jumpInfo?.pageType === 'PAGE_TYPE_WECHAT_CHANNELS_PROFILE' && } {!isConversion ? : } }
{/* 广告信息 */} {/* 定向 */} {/* 创意 */} {/* 创意素材 */}
{/* 创意文案 */} {/* 落地页 */}
delBdPlan({})} > {/* 选择小说 */} {goodsVisible && setGoodsVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setGoodsVisible(false); clearData() }} />} {/* 选择数据源 */} {sourceVisible && setSourceVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setSourceVisible(false); clearData() }} />} {/* 选择公众号 */} {wechatVisible && setWechatVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setWechatVisible(false); clearData() }} />} {/* 选择视频号 */} {channelsProfileVisible && setChannelsProfileVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setChannelsProfileVisible(false); clearData() }} />} {/* 转化归因 */} {conversionVisible && setConversionVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setConversionVisible(false); clearData() }} />} {activeKey && tableData && Object.keys(tableData)?.length > 0 ?
{ setActiveKey(e) }} type="card" activeKey={activeKey} tabBarExtraContent={ 广告总数:{adCount} 创意总数:{dynamicCount} } items={accountCreateLogs.map(item => ({ label: item.accountId, key: item.accountId })) as any[]} /> {addelivery?.dynamicCreativesTextDTOS?.type === 4 && 因为选择的是“创意组和文案叉乘打乱后分配”模式,会随机打乱,当前预览广告下创意内容会与实际建出来的创意有偏差,请以建出来的为准}
当前共{total}个创意,{tableData[activeKey]?.[0]?.adLength}个广告, }} /> :
} {/* 提交任务 */} {subVisible && { onSubmit(e) }} onClose={() => { setSubVisible(false) }} />} } export default Create