123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329 |
- import Tables from "@/components/Tables"
- import { useAjax } from "@/Hook/useAjax"
- import { createAdBatchApi, CreateAdProps } from "@/services/launchAdq/createAd"
- import { getSysAdcreativeInfo } from "@/services/launchAdq/creative"
- import { PromotedObjectType } from "@/services/launchAdq/enum"
- import { getTagsList, get_adcreative_template } from "@/services/launchAdq/global"
- import { getSysAdgroupsInfo } from "@/services/launchAdq/localAd"
- import { getsysTargetingInfo } from "@/services/launchAdq/targeting"
- import { CheckOutlined, CloseOutlined, SearchOutlined } from "@ant-design/icons"
- import { Button, Card, Col, Empty, Row, Select, Space, Spin, Tooltip, Image, message, Tabs, Popconfirm, notification, Divider, Checkbox, Modal } from "antd"
- import React, { useCallback, useEffect, useState } from "react"
- import { useModel } from "umi"
- import Ad from "./ad"
- import DataSourceModal from "../../components/dataSourceModal"
- import GoodsModal from "../../components/goodsModal"
- import IdModal from "../../components/idModal"
- import LookLanding from "../../components/lookLanding"
- import PageModal from "../../components/pageModal"
- import SelectCloud from "../../components/selectCloud"
- import style from './index.less'
- import Selector from "./selector"
- import SubmitModal from "./submitModal"
- import columns from "./tableConfig"
- import TargetIng from './targeting'
- import Creative from './creative'
- import AddGroup from '../../components/addGroup'
- import CustomerServiceModal from "../../components/customerServiceModal"
- import { getTaskDetailsApi } from "@/services/launchAdq/taskList"
- import CreativeCL from "./creativeCL"
- import { groupBy } from "@/utils/utils"
- import moment from "moment"
- import { getAccountListApi, getGroupListApi } from "@/services/launchAdq/subgroup"
- const CreateAd: React.FC = () => {
- /*************************/
- const { getAllUserAccount } = useModel('useLaunchAdq.useAdAuthorize')
- const [queryForm, setQueryForm] = useState<Partial<CreateAdProps>>({
- campaignName: '', // 计划名称
- campaignType: 'CAMPAIGN_TYPE_NORMAL', // 计划类型 CAMPAIGN_TYPE_NORMAL CAMPAIGN_TYPE_SEARCH
- promotedObjectType: 'PROMOTED_OBJECT_TYPE_WECHAT_OFFICIAL_ACCOUNT', // 推广目标类型
- speedMode: 'SPEED_MODE_STANDARD', // 投放速度模式
- sysAdgroupId: undefined, // 广告组ID
- sysAdgroup: undefined,//广告组内容
- sysTargetingId: undefined, // 定向包 id
- sysTargeting: undefined, // 定向包 内容
- adgroupName: undefined, // 广告名称
- configuredStatus: 'AD_STATUS_SUSPEND', // 广告状态
- sysAdcreativeId: undefined, // 创意ID
- taskMediaMaps: [], // 创意内容
- pageList: [],//本地落地页详情入口
- adqPageList: [],//云落地页
- expandEnabled: false,
- expandTargeting: [],
- model: 'cross'
- })
- const [launchMode, setLaunchMode] = useState<number>(Number(localStorage.getItem('LAUNCHMODE')) || 1) // 投放模式 1 现在投放模式 2 创量模式
- const [accountCreateLogs, setAccountCreateLogs] = useState<{ adAccountId: number, id: number, userActionSetsList?: any[], productList?: any, conversionList?: any, customAudienceList?: any, excludedCustomAudienceList?: any, pageList?: any, coldStartAudienceList?: any[] }[]>([]) // 账户
- const { currentUser: { userId } }: any = useModel('@@initialState', model => ({ currentUser: model.initialState?.currentUser }))
- const [goodsVisible, setGoodsVisible] = useState<boolean>(false) // 选择商品弹窗控制
- const [sourceVisible, setSourceVisible] = useState<boolean>(false) // 选择数据源弹窗控制
- const [idVisible, setIdVisible] = useState<boolean>(false) // 选择转化ID弹窗控制
- const [selectImgVisible, setSelectImgVisible] = useState<boolean>(false) // 选择转化ID弹窗控制
- const [lookVisible, setLookVisible] = useState<boolean>(false) // 选择转化ID弹窗控制
- const [subVisible, setSubVisible] = useState<boolean>(false) // 选择设置名称弹窗控制
- const [pageVisible, setPageVisible] = useState<boolean>(false) // 选择云端落地页控制
- const [tableData, setTableData] = useState<any[]>([]) // 预览表格
- const [tableSelect, setTableSelect] = useState<any[]>([])
- const [geoLocationList, setGeoLocationList] = useState<any>({}) // 所有地域列表
- const [modelList, setModelList] = useState<any>({}) // 所有品牌手机
- const [targetKey, set_targetKey] = useState('0')//创意key
- const [page_checked, set_page_checked] = useState(false)//创意key
- const [usesArr, setUsersArr] = useState<any>(localStorage.getItem('ADQUSERS' + userId) ? JSON.parse(localStorage.getItem('ADQUSERS' + userId) as any) : [])
- const { init, get } = useModel('useLaunchAdq.useBdMediaPup')
- const [cloudParams, setCloudParams] = useState<{ adcreativeTemplateId?: number }>({})
- const [accSearch, setAccSearch] = useState<string>()
- const tagsList_REGION = useAjax((params) => getTagsList(params))
- const tagsList_MODEL = useAjax((params) => getTagsList(params))
- const getSysAdgroups = useAjax((params) => getSysAdgroupsInfo(params))
- const getsysTargeting = useAjax((params) => getsysTargetingInfo(params))
- const getSysAdcreative = useAjax((params) => getSysAdcreativeInfo(params))
- const createAdBatch = useAjax((params) => createAdBatchApi(params))
- const getTaskDetails = useAjax((params) => getTaskDetailsApi(params))
- const getAdcreativeTemplate = useAjax((params) => get_adcreative_template(params))
- const getGroupList = useAjax(() => getGroupListApi())
- /*************************/
-
- useEffect(() => {
- getGroupList.run()
- }, [])
- /** 判断出价方式,优化目标 “二方包”人群包仅能在出价方式为CPC(包含oCPM点击优化目标)、CPM场景下使用 */
- // useEffect(() => {
- // 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'))) {
- // setAccountCreateLogs(() => accountCreateLogs.map(item => {
- // delete item?.customAudienceList
- // delete item?.excludedCustomAudienceList
- // return item
- // }))
- // }
- // }, [queryForm?.sysAdgroup])
- /**数据回填 */
- useEffect(() => {
- let taskId = sessionStorage.getItem('TASKID')
- if (taskId) {
- getTaskDetails.run(taskId).then(async res => {
- const { adCreateLogs, campaignType, promotedObjectType, speedMode, sysAdgroup, sysAdgroupId, sysTargeting, sysTargetingId } = res
- let adcreativeTemplateId = adCreateLogs[0]?.sysAdcreative?.adcreativeTemplateId
- let sysPageId = adCreateLogs[0]?.sysPageId
- let pageId = adCreateLogs[0]?.pageId
- // 账号信息相关
- let adCreateLogsData = adCreateLogs?.map((item: any) => {
- return {
- adAccountId: item?.accountId,
- id: item?.accountId,
- // 数据源
- userActionSetsList: item?.userActionSetList?.map((item: any) => ({ ...item, id: item?.userActionSetId })),
- // 商品
- productList: item?.product ? [{ ...item?.product, productCatalog: item?.productCatalog, id: Number(item?.product?.productOuterId?.replace(/\D/ig, '')) }] : undefined,
- coldStartAudienceList: item?.coldStartAudienceList?.map((item: any) => ({ ...item, id: item.audienceId })),
- // pageList: [item.page]
- // 定向用户群
- customAudienceList: item?.customAudienceList?.map((item: any) => ({ ...item, id: item.audienceId })),
- // 排除用户群
- excludedCustomAudienceList: item?.excludedCustomAudienceList?.map((item: any) => ({ ...item, id: item.audienceId }))
- }
- }).filter((item: any, index: number, self: any) => self.findIndex((i: any) => i.id == item.id) === index)
- setAccountCreateLogs(adCreateLogsData)
- let type: 1 | 2 = 1
- if (sysPageId && pageId) {
- type = 1
- } else if (sysPageId) {
- if (adCreateLogs?.every((item: { sysAdcreative: { adcreativeTemplateId: number }, sysPageId: number }) => item.sysAdcreative.adcreativeTemplateId === adcreativeTemplateId && (item.sysPageId === sysPageId))) {
- type = 2
- } else {
- type = 1
- }
- } else {
- if (adCreateLogs?.every((item: { sysAdcreative: { adcreativeTemplateId: number }, pageId: number }) => item.sysAdcreative.adcreativeTemplateId === adcreativeTemplateId)) {
- type = 2
- } else {
- type = 1
- }
- }
- setLaunchMode(type)
- /** 本地落地页处理 */
- let pageList: any = []
- /** 云端落地页 */
- let adqPageList: any[] = []
- let taskMediaMaps: any[] = []
- let type2Data = {}
- if (type === 1) {
- const sorted = groupBy(adCreateLogs, (item) => [item.sysAdcreativeId])
- pageList = sorted?.map((item: any[]) => {
- if (item.some((item1: { sysPageId: number }) => item1.sysPageId)) {
- return item[0].sysPage
- } else {
- return null
- }
- })
- adqPageList = sorted?.map((item: any[]) => {
- if (item.some((item1: { pageId: number }) => item1.pageId)) {
- return item.map((item1: any) => ({
- pageList: [{ ...item1.page, id: item1.page.pageId }],
- adAccountId: item1?.accountId,
- id: item1?.accountId,
- }))
- } else {
- return null
- }
- })
- taskMediaMaps = groupBy(adCreateLogs, (item) => [item.accountId])?.[0]?.map((item: any, index: number) => {
- let pageElementsSpecList = item?.sysPage?.pageSpecsList[0]?.pageElementsSpecList // 内容区
- let globalSpec = item?.sysPage?.globalSpec // 悬浮组件
- /** 处理客服 */
- let cropUserGroupMap: any[] = []
- 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'))) {
- let groupList: { type: number, name: string, cropList: any[], cropId?: number, groupId?: number }[] = [];
- (pageElementsSpecList as any[])?.forEach((item: { elementType: string, enterpriseWxSpec: { btnTitle: string } }) => {
- if (item?.elementType === 'ENTERPRISE_WX') {
- groupList.push({ type: 1, name: '联系商家', cropList: [] }) // item.enterpriseWxSpec.btnTitle
- }
- })
- if ((globalSpec?.globalElementsSpecList?.length > 0 && globalSpec?.globalElementsSpecList)) {
- groupList.push({ type: 2, name: '悬浮组件', cropList: [] })
- }
- cropUserGroupMap = sorted[0]?.map((item: any) => {
- let corpUserGroup1s = item?.corpUserGroup1s
- let corpUserGroup2s = item?.corpUserGroup2s
- return {
- adAccountId: item.accountId, id: item.accountId, data: groupList.map((crop: any, index: number) => {
- return { ...crop, cropList: crop.type === 1 ? corpUserGroup1s[index] ? [{ ...corpUserGroup1s[index], id: corpUserGroup1s[index].groupId }] : [] : corpUserGroup2s[0] ? [{ ...corpUserGroup2s[0], id: corpUserGroup2s[0].groupId }] : [] }
- })
- }
- })
- }
- // 落地页信息
- let accountPageIdMap: any = {}
- adCreateLogs?.forEach((item: any) => {
- if (item?.pageId) {
- accountPageIdMap[item.accountId] = item?.pageId
- }
- })
- return { sysAdcreative: item?.sysAdcreative, sysPageId: item?.sysPageId, cropUserGroupMap, accountPageIdMap }
- })
- } else {
- const sorted = groupBy(adCreateLogs, (item) => [item.accountId])
- let adCreateLog = adCreateLogs[0]
- if (adCreateLog?.sysPageId) {
- pageList = [adCreateLog?.sysPage]
- } else {
- pageList = [null]
- }
- if (adCreateLog?.pageId) {
- adqPageList = groupBy(adCreateLogs, (item) => [item.sysAdcreativeId])?.map((item: any[]) => {
- if (item.some((item1: { pageId: number }) => item1.pageId)) {
- return item.map((item1: any) => ({
- pageList: [{ ...item1.page, id: item1.page.pageId }],
- adAccountId: item1?.accountId,
- id: item1?.accountId,
- }))
- } else {
- return null
- }
- })
- } else {
- adqPageList = [null]
- }
- let template = await getAdcreativeTemplate.run({ promotedObjectType, adcreativeTemplateId, siteSet: sysAdgroup.siteSet })
- let states = { kp_show: false, xd_show: true, sj_show: false, bq_show: false, sp_show: false }
- if (template[0]) {
- let pageList = template[0]?.landingPageConfig?.supportPageTypeList?.filter((i: { description: string | string[] }) => i.description.includes('微信原生推广页'))//当前版本只获取微信原生页,后期改进
- let pageType = pageList?.length ? pageList[0]?.pageType : null
- //数据展示组件
- if (template[0].adcreativeAttributes.some((item: { name: string }) => item.name === 'conversion_data_type' || item.name === 'conversion_target_type')) {
- states = { ...states, sj_show: true }
- }
- //行动按钮组件存在
- if (states.xd_show) {
- let supportLinkNameTypeData = (pageList?.filter((item: { pageType: any; }) => item.pageType === pageType)[0] as any)?.supportLinkNameType
- let linkNameList = supportLinkNameTypeData?.list
- if (linkNameList) { // && !linkPageType
- } else {
- states = { ...states, xd_show: false }
- }
- if (supportLinkNameTypeData?.required) {
- states = { ...states, xd_show: true }
- }
- }
- // 视频结束页 end_page
- if (template[0].adcreativeElements.some((item: { name: string }) => item.name === 'end_page')) {
- states = { ...states, sp_show: true }
- }
- }
- if (adcreativeTemplateId === 2106) {
- template[0].adcreativeElements = template[0]?.adcreativeElements?.map((item: any) => {
- if (item.name === "description") {
- return { ...item, name: 'title', title: item['description'] }
- }
- return item
- })
- }
- type2Data['textData'] = template[0]?.adcreativeElements?.filter((item: any) => item.name === 'title' || (item.required && item.name === 'description')).map((item: any) => ({ ...item, pupState: states }))
- 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) => {
- return {
- label: item.description === '图片' && res[0]?.adcreativeElements?.some((item: any) => item.name === 'video') ? '视频封面图' : item.description,
- name: item.name,
- restriction: item.restriction,
- arrayProperty: item?.arrayProperty
- }
- })
- taskMediaMaps = [sorted[0][0]].map((item: any) => {
- let pageElementsSpecList = item?.sysPage?.pageSpecsList[0]?.pageElementsSpecList // 内容区
- let globalSpec = item?.sysPage?.globalSpec // 悬浮组件
- /** 处理客服 */
- let cropUserGroupMap: any[] = []
- 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'))) {
- let groupList: { type: number, name: string, cropList: any[], cropId?: number, groupId?: number }[] = [];
- (pageElementsSpecList as any[])?.forEach((item: { elementType: string, enterpriseWxSpec: { btnTitle: string } }) => {
- if (item?.elementType === 'ENTERPRISE_WX') {
- groupList.push({ type: 1, name: '联系商家', cropList: [] }) // item.enterpriseWxSpec.btnTitle
- }
- })
- if ((globalSpec?.globalElementsSpecList?.length > 0 && globalSpec?.globalElementsSpecList)) {
- groupList.push({ type: 2, name: '悬浮组件', cropList: [] })
- }
- cropUserGroupMap = groupBy(adCreateLogs, (item) => [item.sysAdcreativeId])[0]?.map((item: any) => {
- let corpUserGroup1s = item?.corpUserGroup1s
- let corpUserGroup2s = item?.corpUserGroup2s
- return {
- adAccountId: item.accountId, id: item.accountId, data: groupList.map((crop: any, index: number) => {
- return { ...crop, cropList: crop.type === 1 ? corpUserGroup1s[index] ? [{ ...corpUserGroup1s[index], id: corpUserGroup1s[index].groupId }] : [] : corpUserGroup2s[0] ? [{ ...corpUserGroup2s[0], id: corpUserGroup2s[0].groupId }] : [] }
- })
- }
- })
- }
- // 落地页信息
- let accountPageIdMap: any = {}
- adCreateLogs?.forEach((item: any) => {
- if (item?.pageId) {
- accountPageIdMap[item.accountId] = item?.pageId
- }
- })
- let { adcreativeElements, ...Adcreative } = JSON.parse(JSON.stringify(item?.sysAdcreative))
- delete adcreativeElements?.title
- delete adcreativeElements?.description
- delete adcreativeElements?.imageUrlList
- delete adcreativeElements?.elementStory
- delete adcreativeElements?.imageUrl
- delete adcreativeElements?.videoUrl
- delete adcreativeElements?.shortVideo1Url
- return { sysAdcreative: { ...Adcreative, adcreativeElements }, sysPageId: item?.sysPageId, cropUserGroupMap, accountPageIdMap }
- })
- // 处理 materials [] texts []
- let newMaterials: any[] = [], newTexts: any[] = []
- sorted[0].forEach((item: any) => {
- let { title, description, imageUrlList, elementStory, imageUrl, videoUrl, shortVideo1Url } = item?.sysAdcreative?.adcreativeElements
- let texts = {};
- let materials = {};
- if (title) texts['title'] = title;
- if (description) texts['description'] = description;
- if (imageUrlList) materials['imageUrlList'] = imageUrlList;
- if (elementStory) materials['elementStory'] = elementStory;
- if (imageUrl) materials['imageUrl'] = imageUrl;
- if (videoUrl) materials['videoUrl'] = videoUrl;
- if (shortVideo1Url) materials['shortVideo1Url'] = shortVideo1Url;
- newMaterials.push(materials)
- newTexts.push(texts)
- })
- let groupMaterials: any[] = []
- let groupTexts: any[] = []
- if (newMaterials.length > 0 && newMaterials?.every(item => Object.keys(item).length > 0)) {
- let firstField = Object.keys(newMaterials[0])[0]
- groupMaterials = groupBy(newMaterials, (item) => [item[firstField]])
- type2Data['materials'] = newMaterials
- }
- if (newTexts.length > 0 && newTexts?.every(item => Object.keys(item).length > 0)) {
- let firstField = Object.keys(newTexts[0])[0]
- groupTexts = groupBy(newTexts, (item) => [item[firstField]])
- type2Data['texts'] = newTexts
- }
- let mLength = groupMaterials.length || 1
- let tLength = groupTexts.length || 1
- if (mLength * tLength === sorted[0].length) { // 数量对上是 叉乘 否则 一对一
- if (groupMaterials.length > 0) type2Data['materials'] = groupMaterials.map((item: any[]) => item[0])
- if (groupTexts.length > 0) type2Data['texts'] = groupTexts.map((item: any[]) => item[0])
- type2Data['model'] = 'cross'
- } else {
- type2Data['model'] = 'corres'
- }
- }
- if (sysAdgroup?.beginDate && moment(sysAdgroup?.beginDate) < moment()) {
- sysAdgroup.beginDate = moment().format('YYYY-MM-DD')
- message.warning('请注意,检测投放开始日期小于今天,以自动改成今天,如需修改,请重新设置')
- }
- if (sysAdgroup?.endDate && moment(sysAdgroup?.endDate) < moment()) {
- sysAdgroup.endDate = moment().format('YYYY-MM-DD')
- message.warning('请注意,检测投放结束日期小于今天,以自动改成今天,如需修改,请重新设置')
- }
- setQueryForm({
- ...queryForm,
- ...type2Data,
- campaignType,
- promotedObjectType,
- speedMode,
- sysAdgroup,
- sysAdgroupId,
- sysTargeting,
- sysTargetingId,
- adgroupName: sysAdgroup?.adgroupName,
- configuredStatus: sysAdgroup?.configuredStatus,
- expandEnabled: sysAdgroup?.expandEnabled || false,
- expandTargeting: sysAdgroup?.expandTargeting || [],
- taskMediaMaps: taskMediaMaps || [],
- pageList,
- adqPageList
- })
- })
- sessionStorage.removeItem('TASKID')
- } else {
- let adqAdData = localStorage.getItem('ADQAD')
- if (adqAdData) {
- const { queryForm, accountCreateLogs } = JSON.parse(adqAdData)
- if (queryForm?.sysAdgroup) {
- if (queryForm?.sysAdgroup?.beginDate && moment(queryForm?.sysAdgroup?.beginDate) < moment()) {
- queryForm.sysAdgroup.beginDate = moment().format('YYYY-MM-DD')
- message.warning('请注意,检测投放开始日期小于今天,已自动改成今天,如需修改,请重新设置')
- }
- if (queryForm?.sysAdgroup?.endDate && moment(queryForm?.sysAdgroup?.endDate) < moment()) {
- queryForm.sysAdgroup.endDate = moment().format('YYYY-MM-DD')
- message.warning('请注意,检测投放结束日期小于今天,已自动改成今天,如需修改,请重新设置')
- }
- }
- setQueryForm({ ...queryForm })
- setAccountCreateLogs(accountCreateLogs)
- }
- }
- }, [])
- // 设置地域
- useEffect(() => {
- tagsList_REGION.run({ type: 'REGION' }).then(res => {
- if (res && Array.isArray(res)) {
- setGeoLocationList(() => (res as any[])?.reduce((prev: any, cur: { id: number }) => {
- prev[cur.id] = cur
- return prev
- }, {}))
- }
- })
- tagsList_MODEL.run({ type: 'DEVICE_BRAND_MODEL' }).then(res => {
- if (res && Array.isArray(res)) {
- setModelList(() => (res as any[])?.reduce((prev: any, cur: { id: number }) => {
- prev[cur.id] = cur
- return prev
- }, {}))
- }
- })
- }, [])
- // 获取账户列表
- useEffect(() => {
- getAllUserAccount.run()
- }, [])
- // 账号对比
- useEffect(() => {
- if (getAllUserAccount?.data?.data && accountCreateLogs) {
- if (accountCreateLogs.some(item => !getAllUserAccount?.data?.data?.find((item1: { accountId: number }) => item.adAccountId == item1.accountId))) {
- let errorData: any[] = []
- let newAccountCreateLogs = accountCreateLogs.filter(item => {
- let data = getAllUserAccount?.data?.data?.find((item1: { accountId: number }) => item.adAccountId == item1.accountId)
- if (data) {
- return true
- } else {
- errorData.push(item.adAccountId)
- return false
- }
- })
- notification.error({
- duration: 60 * 5,
- message: '重要提示',
- description: `本地媒体账户与你所拥有账户对不上,当前创建账号不符合账号及部分相关配置已清空。请把保存在本地的媒体账户或者媒体账户组清空,重新选择保存。问题账户:(${errorData.toString()})`
- })
- setAccountCreateLogs(newAccountCreateLogs)
- setQueryForm({ ...queryForm, adqPageList: [], taskMediaMaps: queryForm?.taskMediaMaps?.map(item => ({ ...item, accountPageIdMap: {} })) })
- }
- }
- }, [getAllUserAccount?.data, accountCreateLogs, queryForm])
- /** 获取广告详情 */
- useEffect(() => {
- if (getSysAdgroups?.data?.bidMode !== 'BID_MODE_CPM' && accountCreateLogs?.length > 0) {
- let newAccountCreateLogs = accountCreateLogs?.map((item: any) => {
- if (item?.customAudienceList) {
- delete item?.customAudienceList
- }
- return { ...item }
- })
- setAccountCreateLogs([...newAccountCreateLogs])
- }
- }, [getSysAdgroups?.data?.bidMode])
- /** 删除商品内容 */
- const goodsDel = (index: number) => {
- let newArr = JSON.parse(JSON.stringify(accountCreateLogs))
- delete newArr[index].productList
- setAccountCreateLogs(newArr)
- }
- /** 删除数据源 */
- const sourceDel = (index: number, num: number) => {
- let newArr = JSON.parse(JSON.stringify(accountCreateLogs))
- newArr[index].userActionSetsList?.splice(num, 1)
- setAccountCreateLogs(newArr)
- }
- /** 删除人群包 */
- const cpDel = (index: number, num: number, key: string) => {
- let newArr = JSON.parse(JSON.stringify(accountCreateLogs))
- newArr[index][key]?.splice(num, 1)
- setAccountCreateLogs(newArr)
- }
- // 创意素材与文案叉乘处理
- const whatever = (...arrs: any[]) => {
- if (arrs[0]?.length && arrs[1]?.length) {
- if (queryForm.model === 'corres') { // 一一对应
- return arrs[0].map((item: any, index: number) => ({ ...item, ...arrs[1][index] }))
- }
- return arrs.reduce((total, curr) => total.flatMap((e: any) => curr.map((e2: any) => ({ ...e2, ...e }))))
- } else if (arrs[0]?.length) {
- return arrs[0]
- } else if (arrs[1]?.length) {
- return arrs[1]
- } else {
- return ['']
- }
- }
- /** 预览 */
- const preview = () => {
- let newQueryForm: Partial<CreateAdProps> = JSON.parse(JSON.stringify(queryForm))
- if (accountCreateLogs?.length === 0) {
- message.error('请选择媒体账户')
- return
- }
- if (!newQueryForm.promotedObjectType) {
- message.error('请选择推广目标')
- return
- }
- if (!newQueryForm.sysAdgroup) {
- message.error('请先设置广告基本信息')
- return
- }
- if (!newQueryForm.sysTargeting) {
- message.error('请选择定向')
- return
- }
- if (!newQueryForm.taskMediaMaps?.every(item => item.sysAdcreative)) {
- message.error('请设置创意的基本信息')
- return
- }
- if (!newQueryForm.taskMediaMaps?.every(item => item.sysPageId || item.accountPageIdMap)) {
- message.error('请选择落地页')
- return
- }
- if (launchMode === 2) {
- if ((queryForm?.materialData && queryForm?.materialData?.length > 0) && !(newQueryForm?.materials && newQueryForm?.materials?.length > 0)) {
- message.error('请选择创意素材')
- return
- }
- if ((queryForm?.textData && queryForm.textData?.length > 0) && !(newQueryForm?.texts && newQueryForm?.texts?.length > 0)) {
- message.error('请选择创意文案')
- return
- }
- if (queryForm.model === 'corres' && (queryForm?.materialData && queryForm?.materialData?.length > 0) && (queryForm?.textData && queryForm.textData?.length > 0) && queryForm.texts?.length !== queryForm?.materials?.length) {
- message.error('素材文案一一对应模式下,素材数量与文案数量要相等,请修改')
- return
- }
- }
- if (newQueryForm?.taskMediaMaps && newQueryForm?.taskMediaMaps?.some((item: { cropUserGroupMap: any[] }) => item?.cropUserGroupMap?.length > 0)) {
- let cropData = newQueryForm?.taskMediaMaps?.filter((item: { cropUserGroupMap: any[] }) => item?.cropUserGroupMap?.length > 0)
- if (cropData?.some((item: { cropUserGroupMap: { data: { cropList: any[] }[] }[] }) => {
- return item?.cropUserGroupMap?.some((item1: { data: { cropList: any[] }[] }) => item1?.data?.some((item2: { cropList: any[] }) => item2?.cropList?.length === 0))
- })) {
- message.error('请完善落地页企微客服组')
- return
- }
- }
- let data: any[] = []
- if (launchMode === 2) {
- if (Array.isArray(newQueryForm.materials) && Array.isArray(newQueryForm?.texts)) {
- let taskMediaMap = JSON.parse(JSON.stringify(newQueryForm.taskMediaMaps[0]))
- let adcreativeElements = taskMediaMap.sysAdcreative?.adcreativeElements || {}
- let newTaskMediaMaps = whatever(newQueryForm.materials, newQueryForm.texts).map((item: any) => {
- taskMediaMap.sysAdcreative.adcreativeElements = { ...adcreativeElements, ...item }
- return JSON.parse(JSON.stringify(taskMediaMap))
- })
- newQueryForm.taskMediaMaps = newTaskMediaMaps
- }
- }
- accountCreateLogs.forEach((item: any) => {
- newQueryForm.taskMediaMaps?.forEach((task, index) => {
- let obj = {
- ...item,
- ...newQueryForm,
- sysAdGroupData: newQueryForm.sysAdgroup,
- targetingData: newQueryForm.sysTargeting,
- sysAdcreativeData: task.sysAdcreative,
- 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],
- myId: Number(item.id + '' + index)
- }
- data.push(obj)
- })
- })
- setTableData(data)
- }
- const submit = (props: { campaignName: string, count?: number }) => {
- let newQueryForm = JSON.parse(JSON.stringify(queryForm))
- if (launchMode === 2) {
- if (Array.isArray(newQueryForm.materials) && Array.isArray(newQueryForm?.texts)) {
- let taskMediaMap = JSON.parse(JSON.stringify(newQueryForm.taskMediaMaps[0]))
- let adcreativeElements = taskMediaMap.sysAdcreative?.adcreativeElements || {}
- let newTaskMediaMaps = whatever(newQueryForm.materials, newQueryForm.texts).map((item: any) => {
- if (item) {
- taskMediaMap.sysAdcreative.adcreativeElements = { ...adcreativeElements, ...item }
- } else {
- taskMediaMap.sysAdcreative.adcreativeElements = { ...adcreativeElements }
- }
- return JSON.parse(JSON.stringify(taskMediaMap))
- })
- newQueryForm.taskMediaMaps = newTaskMediaMaps
- }
- }
- let newtaskMediaMaps = newQueryForm.taskMediaMaps.map((item1: { cropUserGroupMap?: any[] }) => {
- let { cropUserGroupMap, ...data } = item1
- if (cropUserGroupMap && cropUserGroupMap?.length > 0) {
- let corpUserGroup1Map: any = {}
- let corpUserGroup2Map: any = {}
- cropUserGroupMap.forEach((cropData: { id: number, data: any[] }) => {
- let cropData1: { corpId: string, groupId: number }[] = []
- let cropData2: { corpId: string, groupId: number }[] = []
- cropData?.data.forEach((crop: { type: 1 | 2, cropList: { corpId: string, groupId: number }[] }) => {
- let cropList = crop.cropList
- if (crop.type === 1) {
- cropData1.push({ corpId: cropList[0].corpId, groupId: cropList[0].groupId })
- } else {
- cropData2.push({ corpId: cropList[0].corpId, groupId: cropList[0].groupId })
- }
- })
- if (cropData1.length > 0) {
- corpUserGroup1Map[cropData.id.toString()] = cropData1
- }
- if (cropData2.length > 0) {
- corpUserGroup2Map[cropData.id.toString()] = cropData2
- }
- })
- return { ...data, corpUserGroup1Map: Object.keys(corpUserGroup1Map)?.length > 0 ? corpUserGroup1Map : null, corpUserGroup2Map: Object.keys(corpUserGroup2Map)?.length > 0 ? corpUserGroup2Map : null }
- }
- return data
- })
- newQueryForm.taskMediaMaps = newtaskMediaMaps
- let params = { ...newQueryForm, ...props }
- let accountLogs = accountCreateLogs.map((item: any, index) => {
- // userActionSetsList 数据源 productList 商品
- let data: any = { adAccountId: item.adAccountId, count: props.count || 1 }
- if (item?.userActionSetsList?.length > 0) { // 数据源
- data.userActionSets = item?.userActionSetsList?.map((item: any) => ({ id: item?.id, type: item?.type }))
- }
- if (item?.productList?.length > 0) { // 商品
- data.productId = item?.productList[0].productOuterId
- data.productCatalogId = item?.productList[0].productCatalogId
- }
- if (item?.customAudienceList?.length > 0) {
- data.customAudience = item?.customAudienceList?.map((item: any) => item.id)
- }
- if (item?.excludedCustomAudienceList?.length > 0) {
- data.excludedCustomAudience = item?.excludedCustomAudienceList?.map((item: any) => item.id)
- }
- if (item?.pageList) {
- data.pageId = item?.pageData?.id
- }
- if (item?.coldStartAudienceList?.length > 0) {
- data.coldStartAudience = item?.coldStartAudienceList?.map((item: any) => item.id)
- }
- return data
- })
- if (params?.expandEnabled) {
- params.sysAdgroup.expandEnabled = params?.expandEnabled
- params.sysAdgroup.expandTargeting = []
- }
- if (params?.expandTargeting?.length > 0) {
- params.sysAdgroup.expandTargeting = params?.expandTargeting
- }
- params.accountCreateLogs = accountLogs
- delete params.sysAdgroupId
- delete params.sysAdcreativeId
- delete params.sysTargetingId
- delete params.pageList
- delete params.adqPageList
- delete params.count
- delete params?.expandEnabled
- delete params?.expandTargeting
- delete params?.texts
- delete params?.textData
- delete params?.materialData
- delete params?.materials
- delete params?.model
- console.log('paramsSubmit====>', params)
- createAdBatch.run(params).then(res => {
- if (res) {
- Modal.success({
- content: '任务提交成功',
- bodyStyle: { fontWeight: 700 },
- okText: '跳转任务列表',
- closable: true,
- onOk: () => {
- sessionStorage.setItem('CAMP', props?.campaignName)
- window.location.href = '/#/launchSystemNew/launchManage/taskList'
- },
- onCancel: () => {
- setSubVisible(false)
- }
- })
- }
- })
- }
- /** 清除数据 */
- const clearData = () => {
- setTableData([])
- setTableSelect([])
- }
- /** 存为预设 */
- const severBd = () => {
- // queryForm accountCreateLogs
- localStorage.setItem('ADQAD', JSON.stringify({
- queryForm,
- accountCreateLogs
- }))
- message.success('存储成功')
- }
- /** 清除 */
- const delBdPlan = () => {
- localStorage.removeItem('ADQAD')
- setAccountCreateLogs([])
- setQueryForm({
- campaignName: '', // 计划名称
- campaignType: 'CAMPAIGN_TYPE_NORMAL', // 计划类型 CAMPAIGN_TYPE_NORMAL CAMPAIGN_TYPE_SEARCH
- promotedObjectType: 'PROMOTED_OBJECT_TYPE_WECHAT_OFFICIAL_ACCOUNT', // 推广目标类型
- speedMode: 'SPEED_MODE_STANDARD', // 投放速度模式
- sysAdgroupId: undefined, // 广告组内容
- sysTargetingId: undefined, // 定向包 id
- adgroupName: undefined, // 广告名称
- configuredStatus: 'AD_STATUS_SUSPEND', // 广告状态
- sysAdcreativeId: undefined, // 创意ID
- expandEnabled: false,
- expandTargeting: [],
- model: 'cross'
- })
- }
- /** 设置落地页 */
- const setPage = (e: any) => {
- let arr: any = queryForm.taskMediaMaps || []
- function setUrl(item: { sysAdcreative: { overrideCanvasHeadOption: string, adcreativeElements: any } }) {
- if (item?.sysAdcreative?.overrideCanvasHeadOption && item?.sysAdcreative?.overrideCanvasHeadOption === "OPTION_CANVAS_OVERRIDE_CREATIVE") {
- let adcreativeElementsNew = { ...item.sysAdcreative.adcreativeElements }
- let obj = e[0].pageSpecsList[0].pageElementsSpecList[0]
- let { topImageSpec, topVideoSpec, topSliderSpec } = obj
- Object.keys(adcreativeElementsNew).forEach(key => {
- switch (key) {
- case 'imageUrl'://图素材
- adcreativeElementsNew[key] = topImageSpec?.imageUrl
- break;
- case 'videoUrl'://视频素材
- adcreativeElementsNew[key] = topVideoSpec?.videoUrl
- break;
- case 'imageUrlList'://图素材
- adcreativeElementsNew[key] = topSliderSpec?.imageUrlList || [topImageSpec?.imageUrl]
- break;
- case 'shortVideoStruct'://视频素材
- adcreativeElementsNew[key] = { shortVideo1Url: topVideoSpec?.videoUrl }
- break;
- }
- })
- return { ...item, sysPageId: e[0]?.id, accountPageIdMap: null, sysAdcreative: { ...item.sysAdcreative, adcreativeElements: adcreativeElementsNew } }
- }
- return { ...item, sysPageId: e[0]?.id, accountPageIdMap: null, }
- }
- if (page_checked) {
- arr = queryForm.taskMediaMaps?.map(item => {
- return setUrl(item)
- })
- } else {
- arr[targetKey as string] = setUrl(arr[targetKey as string])
- }
- getPageInfo(arr)
- setSelectImgVisible(false)
- }
- /** 获取落地页详情 */
- const getPageInfo = useCallback((arrList) => {
- console.log('arrList====>', arrList)
- if (arrList && arrList[targetKey]?.sysPageId) {
- get.run({ mediaType: 'PAGE', sysMediaId: arrList[targetKey]?.sysPageId }).then(res => {
- if (!Object.keys(res)?.includes('fail')) {
- let data = res
- let pageElementsSpecList = data?.pageSpecsList[0]?.pageElementsSpecList // 内容区
- let globalSpec = data?.globalSpec // 悬浮组件
- let arr: any = queryForm.pageList || []
- let adqPageArr: any = queryForm.adqPageList || []
- adqPageArr[targetKey] = null
- arr[targetKey] = data
- /** 处理客服 */
- let cropUserGroupMap: any[] = []
- 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'))) {
- let groupList: { type: number, name: string, cropList: any[], cropId?: number, groupId?: number }[] = [];
- (pageElementsSpecList as any[])?.forEach((item: { elementType: string, enterpriseWxSpec: { btnTitle: string } }) => {
- if (item?.elementType === 'ENTERPRISE_WX') {
- groupList.push({ type: 1, name: '联系商家', cropList: [] }) // item.enterpriseWxSpec.btnTitle
- }
- })
- if ((globalSpec?.globalElementsSpecList?.length > 0 && globalSpec?.globalElementsSpecList)) {
- groupList.push({ type: 2, name: '悬浮组件', cropList: [] })
- }
- cropUserGroupMap = accountCreateLogs?.map((item: any) => ({ adAccountId: item.adAccountId, id: item.id, data: groupList }))
- }
- arrList[targetKey].cropUserGroupMap = cropUserGroupMap
- setQueryForm({ ...queryForm, pageList: arr, taskMediaMaps: arrList, adqPageList: adqPageArr })//设置落地页详情数组
- } else {
- //清空对应创意中的落地页ID
- let arr = queryForm.taskMediaMaps || []
- arr[targetKey].sysPageId = ''
- setQueryForm({ ...queryForm, taskMediaMaps: arr })
- }
- })
- }
- }, [queryForm, targetKey, accountCreateLogs])
- // 设置云端落地页
- const setAdqPage = useCallback((data) => {
- if (Array.isArray(data) && data.length > 0) {
- let objMap = {}
- data?.forEach(item => {
- objMap[item.adAccountId] = item.pageList[0].pageId
- })
- let arr: any = queryForm.taskMediaMaps || []
- let adqPageArr: any = queryForm.adqPageList || []
- let pageArr: any = queryForm.pageList || []
- adqPageArr[targetKey as string] = data
- pageArr[targetKey as string] = null
- delete arr[targetKey as string]?.cropUserGroupMap
- arr[targetKey as string] = { ...arr[targetKey as string], sysPageId: '', accountPageIdMap: objMap }
- // 重新设置云端数据并清空本地数据
- setQueryForm({ ...queryForm, taskMediaMaps: arr, adqPageList: adqPageArr, pageList: pageArr })
- }
- }, [queryForm, targetKey])
- // tabs新增和删除
- const onEdit = useCallback((targetKey: string | React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<Element>, action: 'add' | 'remove') => {
- if (queryForm.taskMediaMaps) {
- if (action === 'remove') {
- let arr = queryForm.taskMediaMaps
- let adqPageArr: any = queryForm.adqPageList || []
- let pageArr: any = queryForm.pageList || []
- adqPageArr[targetKey as string] = null
- pageArr[targetKey as string] = null
- arr[targetKey as string] = { ...arr[targetKey as string], sysPageId: '', accountPageIdMap: null }
- setQueryForm({ ...queryForm, taskMediaMaps: arr, pageList: pageArr, adqPageList: adqPageArr })
- }
- }
- }, [queryForm, targetKey])
- // 媒体组更新通知
- const usersChange = useCallback(() => {
- let data = JSON.parse(localStorage.getItem('ADQUSERS' + userId) as any)
- setUsersArr(data)
- }, [])
- // 切换投放模式
- const switchLaunchMode = () => {
- if (launchMode === 1) {
- setLaunchMode(2)
- localStorage.setItem('LAUNCHMODE', '2')
- } else {
- setLaunchMode(1)
- localStorage.setItem('LAUNCHMODE', '1')
- }
- delBdPlan()
- set_targetKey('0')
- }
- /** 获取分组里账号 */
- 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?.map((item) => ({ adAccountId: item?.accountId, id: item.accountId })))
- clearData()
- setQueryForm({ ...queryForm, adqPageList: [], pageList: [], taskMediaMaps: queryForm?.taskMediaMaps?.map((item: { sysPageId: number }) => ({ ...item, sysPageId: '', accountPageIdMap: {}, cropUserGroupMap: [] })) })
- } else {
- message.error('操作异常')
- }
- })
- } else {
- setAccountCreateLogs([])
- }
- }
- return <Space direction="vertical" style={{ width: '100%' }}>
- <Card
- title={<Space>
- <div className={style.cardTitle}>配置区</div>
- <Popconfirm
- title="数据部分不会保存,是否切换?"
- onConfirm={switchLaunchMode}
- okText="是"
- cancelText="否"
- >
- <Button type="link" style={{ padding: 0 }}>切换投放模式</Button>
- </Popconfirm>
- </Space>}
- className={style.createAd}
- hoverable
- // extra={<AddGroup onChange={usersChange} pitcherData={getAdAccount?.data?.data} />}
- >
- <Space wrap>
- <Selector label="媒体账户组">
- <Select
- mode="multiple"
- style={{ minWidth: 200 }}
- placeholder="快捷选择媒体账户组"
- maxTagCount={1}
- allowClear
- bordered={false}
- filterOption={(input: any, option: any) => {
- return option!.children?.toString().toLowerCase().includes(input.toLowerCase())
- }}
- onChange={(e, option) => { getGroupAccountList(e) }}
- >
- {getGroupList?.data?.map((item: any) => <Select.Option value={item.groupId} key={item.groupId}>{item.groupName}</Select.Option>)}
- </Select>
- </Selector>
- <Selector label="媒体账户">
- <Select
- mode="multiple"
- style={{ minWidth: 200, maxWidth: 500 }}
- placeholder="媒体账户(多个,,空格换行)"
- maxTagCount={1}
- allowClear
- bordered={false}
- maxTagPlaceholder={<Tooltip color="#FFF" title={<span style={{ color: '#000' }}>{accountCreateLogs?.filter((item, index) => index !== 0)?.map(item => item.adAccountId).toString()}</span>}>
- <span>+{accountCreateLogs?.length > 1 ? accountCreateLogs.length - 1 : 0}</span>
- </Tooltip>}
- dropdownMatchSelectWidth={false}
- autoClearSearchValue={false}
- filterOption={(input: any, option: any) => {
- let newInput: string[] = input ? input?.split(/[,,\n\s]+/ig).filter((item: any) => item) : []
- return newInput?.some(val => option!.children?.toString().toLowerCase()?.includes(val))
- }}
- value={accountCreateLogs?.map((item: { id: number }) => item?.id)}
- onChange={(e, option) => {
- setQueryForm({ ...queryForm, adqPageList: [], pageList: [], taskMediaMaps: queryForm?.taskMediaMaps?.map((item: { sysPageId: number }) => ({ ...item, sysPageId: '', accountPageIdMap: {}, cropUserGroupMap: [] })) })
- setAccountCreateLogs(option?.map((item: any) => ({ adAccountId: item?.children?.toString()?.split('_')[0], id: item?.value })))
- clearData()
- }}
- searchValue={accSearch}
- onSearch={(val) => {
- setAccSearch(val)
- }}
- dropdownRender={menu => (
- <>
- {menu}
- <Divider style={{ margin: '8px 0' }} />
- <Space style={{ padding: '0 8px 4px' }}>
- <Checkbox onChange={(e) => {
- let data = []
- if (e.target.checked) {
- data = JSON.parse(JSON.stringify(getAllUserAccount?.data?.data))
- if (accSearch) {
- let newAccSearch = accSearch?.split(/[,,\n\s]+/ig).filter((item: any) => item)
- data = data?.filter((item: any) => newAccSearch?.some(val => item!.accountId?.toString().toLowerCase()?.includes(val)))
- }
- }
- setQueryForm({ ...queryForm, adqPageList: [], pageList: [], taskMediaMaps: queryForm?.taskMediaMaps?.map((item: { sysPageId: number }) => ({ ...item, sysPageId: '', accountPageIdMap: {}, cropUserGroupMap: [] })) })
- setAccountCreateLogs(data?.map((item: any) => ({ adAccountId: item?.accountId, id: item?.adAccountId })))
- clearData()
- }}>全选</Checkbox>
- </Space>
- </>
- )}
- >
- {getAllUserAccount?.data?.data?.map((item: any) => <Select.Option value={item.accountId} key={item.id}>{item.remark ? item.accountId + '_' + item.remark : item.accountId}</Select.Option>)}
- </Select>
- </Selector>
- <Selector label="推广目标">
- <Select style={{ width: 200 }} value={queryForm?.promotedObjectType} placeholder="请选择推广目标" bordered={false} showSearch filterOption={(input: any, option: any) =>
- (option!.children as unknown as string).toLowerCase().includes(input.toLowerCase())
- } onChange={(e) => { setQueryForm({ ...queryForm, promotedObjectType: e, sysAdgroup: null, sysAdgroupId: undefined, taskMediaMaps: [], sysAdcreativeId: undefined, materials: [], textData: [], texts: [] }); clearData() }}>
- {Object.keys(PromotedObjectType).map(key => {
- return <Select.Option value={key} key={key}>{PromotedObjectType[key]}</Select.Option>
- })}
- </Select>
- </Selector>
- {launchMode === 2 && accountCreateLogs?.length > 0 && <>
- <Button onClick={() => { setGoodsVisible(true) }}>商品广告(选填){accountCreateLogs?.some(item => item?.productList?.length) && <CheckOutlined style={{ color: '#1890ff' }} />}</Button>
- <Button onClick={() => { setSourceVisible(true) }}>精准匹配归因(选填){accountCreateLogs?.some(item => item?.userActionSetsList?.length) && <CheckOutlined style={{ color: '#1890ff' }} />}</Button>
- </>}
- </Space>
- <div className={style.cardBody}>
- <Row className={style.content}>
- <Col span={launchMode === 1 ? 12 : 8} xl={launchMode === 1 ? 12 : 8} lg={24} md={24} sm={24} xs={24} className={style.conLeft}>
- <Row className={`${style.conTitle} ${style.conRightBorder}`}><Col span={24}>广告</Col></Row>
- <Row className={style.items}>
- {/* =============广告基本信息=========== */}
- <Ad queryForm={queryForm} setQueryForm={setQueryForm} getSysAdgroups={getSysAdgroups} clearData={clearData} />
- {/* =============定向包=========== */}
- <TargetIng
- queryForm={queryForm}
- setQueryForm={setQueryForm}
- getSysAdgroups={getSysAdgroups}
- clearData={clearData}
- setAccountCreateLogs={setAccountCreateLogs}
- getsysTargeting={getsysTargeting}
- geoLocationList={geoLocationList}
- modelList={modelList}
- cpDel={cpDel}
- accountCreateLogs={accountCreateLogs}
- />
- {launchMode === 1 && <>
- {/* =============商品=========== */}
- <Col className={style.conRightBorder} span={5}>
- <div className={style.top}>
- 商品
- </div>
- <div className={style.center}>
- <div className={style.centerContent}>
- {accountCreateLogs?.map((item: any, index: number) => {
- if (item?.productList) {
- return <div className={style.acc} key={index}>
- <div className={style.accName} style={{ fontWeight: 800 }}>{item.adAccountId}</div>
- {
- item?.productList?.map((pack: { productName: string, author: string, id: number }, index: number) => {
- return <div className={style.accCon} key={pack.id}>{pack.productName}<CloseOutlined className={style.close} onClick={() => {
- goodsDel(index)
- }} /></div>
- })
- }
- </div>
- } else {
- return null
- }
- })}
- </div>
- </div>
- <div className={style.bottom}>
- {accountCreateLogs?.length > 0 ? <span onClick={() => { setGoodsVisible(true) }}>编辑</span> : <Tooltip title="请先选择媒体账户">
- <span>编辑</span>
- </Tooltip>}
- </div>
- </Col>
- {/* 数据源 */}
- <Col className={style.conRightBorder} span={5}>
- <div className={style.top}>
- 数据源
- </div>
- <div className={style.center}>
- <div className={style.centerContent}>
- {accountCreateLogs?.map((item: any, index: number) => {
- if (item?.userActionSetsList && item?.userActionSetsList?.length > 0) {
- return <div className={style.acc} key={index}>
- <div className={style.accName} style={{ fontWeight: 800 }}>{item.adAccountId}</div>
- {
- item?.userActionSetsList?.map((pack: { name: string, type: string, id: number }, index1: number) => {
- 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={() => {
- sourceDel(index, index1)
- }} /></div>
- })
- }
- </div>
- } else {
- return null
- }
- })}
- </div>
- </div>
- <div className={style.bottom}>
- {accountCreateLogs?.length > 0 ? <span onClick={() => { setSourceVisible(true) }}>编辑</span> : <Tooltip title="请先选择媒体账户">
- <span>编辑</span>
- </Tooltip>}
- </div>
- </Col>
- </>}
- </Row>
- </Col>
- {/* =============广告创意=========== */}
- {launchMode === 1 ? <Col span={12} xl={12} lg={24} md={24} sm={24} xs={24} className={style.conRight}>
- <Row className={style.conTitle}><Col span={24}>广告创意</Col></Row>
- <Row className={style.items}>
- {/* 创意 */}
- <Creative queryForm={queryForm} setQueryForm={setQueryForm} getSysAdgroups={getSysAdgroups} clearData={clearData} getSysAdcreative={getSysAdcreative} set_targetKey={set_targetKey} targetKey={targetKey} page_checked={page_checked} />
- {/* 落地页 */}
- <Col span={12} >
- <div className={style.top}>
- 落地页
- {(queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.cropUserGroupMap?.length > 0) && <CustomerServiceModal data={queryForm?.taskMediaMaps[targetKey]?.cropUserGroupMap} onChange={(data) => {
- let newQueryForm = JSON.parse(JSON.stringify(queryForm))
- newQueryForm.taskMediaMaps[targetKey].cropUserGroupMap = data
- setQueryForm(newQueryForm)
- }} />}
- </div>
- <div className={style.center}>
- <Tabs size={'small'} onEdit={onEdit} type="editable-card" activeKey={targetKey} onChange={(key) => { set_targetKey(key) }} hideAdd >
- {
- queryForm?.taskMediaMaps?.map((item, index) => {
- return <Tabs.TabPane tab={'创意' + (index + 1)} key={index} >
- <Spin spinning={get.loading}>
- <div className={style.centerContent}>
- {
- item?.sysPageId || item?.accountPageIdMap ? <>
- {
- (item?.sysPageId && queryForm?.pageList) && <>
- <div>落地页名称:{queryForm?.pageList[targetKey]?.pageName || ''}</div>
- <div>分享名称:{queryForm?.pageList[targetKey]?.shareContentSpec?.shareTitle || ''}</div>
- <div>分享描述:{queryForm?.pageList[targetKey]?.shareContentSpec?.shareDescription || ''}</div>
- <div style={{ marginBottom: 10 }}>原生推广页顶部素材预览:
- <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) => {
- switch (item?.elementType) {
- case 'TOP_IMAGE':
- return <Image width={80} src={item?.topImageSpec?.imageUrl} style={{ borderRadius: 8, overflow: 'hidden' }} key={index} />
- case 'TOP_SLIDER':
- return <Space wrap key={index}>
- {item?.topSliderSpec?.imageUrlList?.map((url: string, index: number) => <Image width={70} src={url} style={{ borderRadius: 8 }} key={'TOP_SLIDER' + index} />)}
- </Space>
- case 'TOP_VIDEO':
- return <video src={item?.topVideoSpec?.videoUrl} width={150} controls key={index}></video>
- }
- })}</div>
- </div>
- </>
- }
- {
- queryForm?.adqPageList && queryForm?.adqPageList[targetKey]?.map((adq: any) => {
- return <div className={style.acc} key={adq.adAccountId}>
- <div className={style.accName} style={{ fontWeight: 800 }}>{adq.adAccountId}</div>
- <div className={style.accCon}>
- <span className={style.title}>{adq.pageList[0].pageName}</span>
- </div>
- </div>
- })
- }
- </> : <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
- </div>
- </Spin>
- </Tabs.TabPane>
- })
- }
- </Tabs>
- </div>
- <div className={style.bottom}>{
- (queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysAdcreative) ? <>
- {queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysPageId && <Button type="link" onClick={() => { setLookVisible(true) }}>查看</Button>}
- <Button type="link" onClick={() => {
- setSelectImgVisible(true)
- // 判定是否用原生页顶部替换外部素材
- if (queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.overrideCanvasHeadOption === 'OPTION_CANVAS_OVERRIDE_CREATIVE') {
- init({ mediaType: 'PAGE', cloudSize: undefined, adcreativeTemplateId: queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.adcreativeTemplateId })
- } else {
- init({ mediaType: 'PAGE', cloudSize: undefined })
- }
- }}>{queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysPageId ? '修改' : '选择落地页'}</Button>
- {accountCreateLogs?.length > 0 ? <Button type="link" onClick={() => {
- setPageVisible(true)
- if (queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.overrideCanvasHeadOption === 'OPTION_CANVAS_OVERRIDE_CREATIVE') {
- setCloudParams({ adcreativeTemplateId: queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.adcreativeTemplateId })
- } else {
- setCloudParams({})
- }
- }}>云端落地页</Button> : <Tooltip title="请先选择媒体账户">
- <Button type="link">云端落地页</Button>
- </Tooltip>}
- </> : <Tooltip title="请先设置创意">
- <Button type="link"><span>选择落地页</span></Button>
- </Tooltip>}
- </div>
- </Col>
- </Row>
- </Col> : <Col span={16} xl={16} lg={24} md={24} sm={24} xs={24} className={style.conRight}>
- <Row className={style.conTitle}><Col span={24}>广告创意</Col></Row>
- <Row className={style.items}>
- {/* 创意 */}
- <CreativeCL queryForm={queryForm} setQueryForm={setQueryForm} clearData={clearData} getSysAdcreative={getSysAdcreative} targetKey={targetKey} />
- {/* 落地页 */}
- <Col className={style.conRightBorder} style={{ maxWidth: '25%', border: 'none' }}>
- <div className={style.top}>
- 落地页
- {(queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.cropUserGroupMap?.length > 0) && <CustomerServiceModal data={queryForm?.taskMediaMaps[targetKey]?.cropUserGroupMap} onChange={(data) => {
- let newQueryForm = JSON.parse(JSON.stringify(queryForm))
- newQueryForm.taskMediaMaps[targetKey].cropUserGroupMap = data
- setQueryForm(newQueryForm)
- }} />}
- </div>
- <div className={style.center}>
- {queryForm?.taskMediaMaps?.filter((item, index) => index === 0)?.map((item, index) => {
- return <Spin spinning={get.loading} key={index}>
- <div className={style.centerContent}>
- {item?.sysPageId || item?.accountPageIdMap ? <>
- {(item?.sysPageId && queryForm?.pageList) && <>
- <div>落地页名称:{queryForm?.pageList[targetKey]?.pageName || ''}</div>
- <div>分享名称:{queryForm?.pageList[targetKey]?.shareContentSpec?.shareTitle || ''}</div>
- <div>分享描述:{queryForm?.pageList[targetKey]?.shareContentSpec?.shareDescription || ''}</div>
- <div style={{ marginBottom: 10 }}>原生推广页顶部素材预览:
- <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) => {
- switch (item?.elementType) {
- case 'TOP_IMAGE':
- return <Image width={80} src={item?.topImageSpec?.imageUrl} style={{ borderRadius: 8, overflow: 'hidden' }} key={index} />
- case 'TOP_SLIDER':
- return <Space wrap key={index}>
- {item?.topSliderSpec?.imageUrlList?.map((url: string, index: number) => <Image width={70} src={url} style={{ borderRadius: 8 }} key={'TOP_SLIDER' + index} />)}
- </Space>
- case 'TOP_VIDEO':
- return <video src={item?.topVideoSpec?.videoUrl} width={150} controls key={index}></video>
- }
- })}</div>
- </div>
- </>}
- {queryForm?.adqPageList && queryForm?.adqPageList[targetKey]?.map((adq: any) => {
- return <div className={style.acc} key={adq.adAccountId}>
- <div className={style.accName} style={{ fontWeight: 800 }}>{adq.adAccountId}</div>
- <div className={style.accCon}>
- <span className={style.title}>{adq.pageList[0].pageName}</span>
- </div>
- </div>
- })}
- </> : <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
- </div>
- </Spin>
- })}
- </div>
- <div className={style.bottom}>{
- (queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysAdcreative) ? <>
- {queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysPageId && <Button type="link" onClick={() => { setLookVisible(true) }}>查看</Button>}
- <Button type="link" onClick={() => {
- setSelectImgVisible(true)
- // 判定是否用原生页顶部替换外部素材
- if (queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.overrideCanvasHeadOption === 'OPTION_CANVAS_OVERRIDE_CREATIVE') {
- init({ mediaType: 'PAGE', cloudSize: undefined, adcreativeTemplateId: queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.adcreativeTemplateId })
- } else {
- init({ mediaType: 'PAGE', cloudSize: undefined })
- }
- }}>{queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysPageId ? '修改' : '选择落地页'}</Button>
- {accountCreateLogs?.length > 0 ? <Button type="link" onClick={() => {
- setPageVisible(true)
- if (queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.overrideCanvasHeadOption === 'OPTION_CANVAS_OVERRIDE_CREATIVE') {
- setCloudParams({ adcreativeTemplateId: queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.adcreativeTemplateId })
- } else {
- setCloudParams({})
- }
- }}>云端落地页</Button> : <Tooltip title="请先选择媒体账户">
- <Button type="link">云端落地页</Button>
- </Tooltip>}
- </> : <Tooltip title="请先设置创意">
- <Button type="link"><span>选择落地页</span></Button>
- </Tooltip>}
- </div>
- </Col>
- </Row>
- </Col>}
- </Row>
- {/* =============广告底部按钮=========== */}
- <Space className={style.bts}>
- <Button type='primary' onClick={severBd}>存为预设</Button>
- <Button type='primary' onClick={preview}><SearchOutlined /> 批量预览广告</Button>
- <Button onClick={delBdPlan}>清空配置/预设</Button>
- </Space>
- </div>
- </Card>
- <Card
- className={style.createAd}
- hoverable
- extra={tableData?.length > 0 ? <Space>
- <span>推广计划总数:{tableData?.length}</span>
- <span>广告总数:{tableData?.length}</span>
- {/* {tableSelect?.length > 0 && <span> 已选:<span style={{ color: '#1890FF' }}>{tableSelect?.length}</span> 条</span>} */}
- {
- <Button type='primary' onClick={() => {
- // if (tableSelect.length === 0) {
- // message.error('请选择要提交的计划!')
- // return
- // };
- setSubVisible(true)
- }}>批量提交审核</Button>
- }
- </Space> : false
- }
- >
- {tableData?.length > 0 ? <div className={style.cardBody}>
- <div className={style.content} style={{ marginTop: 20 }}>
- <Tables
- columns={columns()}
- dataSource={tableData}
- total={0}
- size="small"
- bordered
- scroll={{ x: 2000 }}
- myKey={'myId'}
- // rowSelection={{
- // selectedRowKeys: tableSelect?.map((item: any) => item?.myId.toString()),
- // onChange: (selectedRowKeys: React.Key[], selectedRows: any) => {
- // setTableSelect(selectedRows)
- // }
- // }}
- />
- </div>
- </div> : <div style={{ minHeight: 400, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
- <Empty description="请先完成模块配置后,再预览广告计划" />
- </div>}
- </Card>
- {/* 选择商品 */}
- {goodsVisible && <GoodsModal visible={goodsVisible} data={accountCreateLogs} onClose={() => setGoodsVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setGoodsVisible(false); clearData() }} />}
- {/* 选择数据源 */}
- {sourceVisible && <DataSourceModal visible={sourceVisible} promotedObjectType={queryForm.promotedObjectType} data={accountCreateLogs} onClose={() => setSourceVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setSourceVisible(false); clearData() }} />}
- {/* 选择转化ID */}
- {idVisible && <IdModal visible={idVisible} data={accountCreateLogs} onClose={() => setIdVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setSourceVisible(false); clearData() }} />}
- {/* 选择ADQ落地页 */}
- {pageVisible && <PageModal cloudParams={cloudParams} visible={pageVisible} data={queryForm?.adqPageList?.[targetKey] || accountCreateLogs} onClose={() => setPageVisible(false)} onChange={(e) => { setAdqPage(e); setPageVisible(false); clearData() }} />}
- {/* 选择素材 */}
- {selectImgVisible && <SelectCloud visible={selectImgVisible} onClose={() => setSelectImgVisible(false)} onChange={setPage} isBack={false} />}
- {/* 查看落地页 */}
- {lookVisible && <LookLanding visible={lookVisible} onClose={() => setLookVisible(false)} id={queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey].sysPageId} />}
- {/* 设置名称 */}
- {subVisible && <SubmitModal data={getSysAdgroups?.data} visible={subVisible} onClose={() => setSubVisible(false)} onChange={submit} ajax={createAdBatch} />}
- </Space>
- }
- export default CreateAd
|