import { Button, Card, Checkbox, Divider, Empty, Modal, Popconfirm, Select, Space, Spin, Table, Tabs, Tag, Tooltip, message } 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, randomString } from "@/utils/utils" import columns from "./tableConfig" import SubmitModal from "./submitModal" import { createAdgroupTaskApi, getSelectTaskDetailApi } from "@/services/adqV3" import WechatAccount from "../../components/WechatAccount" export const DispatchAddelivery = React.createContext(null); /** * 创建广告 * @returns */ const Create: React.FC = () => { /*******************************************/ const { getAllUserAccount } = useModel('useLaunchAdq.useAdAuthorize') const { initTargeting } = useModel('useLaunchV3.useTargeting') const [addelivery, setAddelivery] = useState({ adgroups: {}, targeting: [], dynamic: {}, dynamicMaterialDTos: {}, dynamicCreativesTextDTOS: {}, mediaType: 0 }) const { marketingAssetOuterSpec, marketingCarrierType } = addelivery.adgroups const [accSearch, setAccSearch] = useState() const [accountCreateLogs, setAccountCreateLogs] = useState([]) // 账户 const [goodsVisible, setGoodsVisible] = useState(false) // 选择小说弹窗控制 const [wechatVisible, setWechatVisible] = useState(false) // 选择微信公众号弹窗控制 const [sourceVisible, setSourceVisible] = 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 getGroupList = useAjax(() => getGroupListApi()) const createAdgroupTask = useAjax((params) => createAdgroupTaskApi(params)) const getSelectTaskDetail = useAjax((params) => getSelectTaskDetailApi(params)) /*******************************************/ useEffect(() => { console.log('addelivery---->', addelivery) // 获取账户组 getGroupList.run() // 获取账户列表 getAllUserAccount.run() initTargeting() }, []) /** 获取分组里账号 */ 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) => ({ accountId: item?.accountId }))) clearData() setAddelivery({ adgroups: {}, targeting: [], dynamic: {}, dynamicMaterialDTos: {}, dynamicCreativesTextDTOS: {}, mediaType: 0 }) } else { message.error('操作异常') } }) } else { setAccountCreateLogs([]) } } /** 存为预设 */ const severBd = () => { // queryForm accountCreateLogs localStorage.setItem('ADQADV3', JSON.stringify({ addelivery, accountCreateLogs, materialData, textData })) message.success('存储成功') } /** 清除 */ const delBdPlan = () => { localStorage.removeItem('ADQADV3') setAccountCreateLogs([]) setMaterialData({}) setTextData({}) setAddelivery({ adgroups: {}, targeting: [], dynamic: {}, dynamicMaterialDTos: {}, dynamicCreativesTextDTOS: {}, mediaType: 0 }) setTableData({}) } /**数据回填 */ useEffect(() => { let taskId = sessionStorage.getItem('TASKID3.0') let adqAdData = localStorage.getItem('ADQADV3') if (taskId) { getSelectTaskDetail.run(taskId).then(res => { console.log(res) if (res) { const { adgroupDTO, accountIdParamVOMap, targetings, dynamicCreativesDTO: { mediaType, ...dynamic }, dynamicCreativesTextDTO, dynamicMaterialDTOS } = res let beginDate = adgroupDTO.beginDate let endDate = adgroupDTO.endDate 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'] = { materialCoverType: value.materialType, url: value.imageUrl, id: value.iamgeId } } return videoData } else { return {} } }) } setAddelivery({ adgroups: { ...adgroupDTO, 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 }) setAccountCreateLogs(Object.keys(accountIdParamVOMap || {}).map(accountId => { const { productDTOS, wechatOfficialAccountsVO, pageList, userActionSetsList } = accountIdParamVOMap[accountId] let data: PULLIN.AccountCreateLogsProps = { accountId: Number(accountId), productList: productDTOS } if (wechatOfficialAccountsVO) { data.wechatChannelList = [wechatOfficialAccountsVO] } if (pageList) { data.pageList = pageList } if (userActionSetsList) { data.userActionSetsList = userActionSetsList } return data })) 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) } }, []) const preview = () => { console.log('addelivery------>', addelivery) console.log('accountCreateLogs------>', accountCreateLogs) if (accountCreateLogs?.length === 0) { message.error('请先选择媒体账户') return } const { adgroups, targeting, dynamic, dynamicMaterialDTos, dynamicCreativesTextDTOS, mediaType } = addelivery if (!(adgroups && Object.keys(adgroups).length)) { message.error('请先配置广告信息') return } if (['MARKETING_TARGET_TYPE_FICTION'].includes(marketingAssetOuterSpec?.marketingTargetType) && !accountCreateLogs?.some(item => item?.productList?.length)) { message.error('请先选择小说') return } if ((['MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT'].includes(marketingAssetOuterSpec?.marketingTargetType) || marketingCarrierType === 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT') && !accountCreateLogs?.some(item => item?.wechatChannelList?.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 (!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].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) { if (mediaType === 0) { newDynamicGroup = cartesianProduct(newDynamicGroup, textDto || [{}]).map((item) => { let [dynamicGroup, textDtoData] = item return { ...dynamicGroup as any, textDto: textDtoData } }) } } } } // 创意组平均分配到广告逻辑 let averageAdDynamicList: any[] = [] if (mediaType === 1 && newDynamicGroup.length) { let adLength = 0 let isReturn = false accountCreateLogs.forEach(item => { let productList: any[] = [] if (['MARKETING_TARGET_TYPE_FICTION'].includes(marketingAssetOuterSpec?.marketingTargetType)) { // 小说 productList = item?.productList || [] } else if (['MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT'].includes(marketingAssetOuterSpec?.marketingTargetType)) { // 公众号 productList = item?.wechatChannelList || [] } adLength += productList.length * targeting.length if (adLength > dynamicGroupLength) { isReturn = true } averageAdDynamicList = distributeArray(newDynamicGroup, adLength) }) if (isReturn) { message.error(`创意组分配规则选择创意组平均分配到广告时,创意组总数必须大于等于广告总数。当前创意组数量:${dynamicGroupLength},广告数量:${adLength}`) return } } let accountIndex = 0 accountCreateLogs.forEach(item => { let productList: any[] = [] if (['MARKETING_TARGET_TYPE_FICTION'].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, // 数据源 pageListDto: item.pageList, // 落地页 productDto, // 商品 targetDto: { // 定向 ...targetDto, targetingName: targetDto.targetingName + suffix }, adgroupsDto: { // 广告信息 ...adgroups, adgroupName: adgroups.adgroupName + suffix }, dynamicDto: dynamic, // 创意信息 averageAdDynamic, rowSpan: mediaType === 1 ? 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)) { 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 }) }) } else { averageAdDynamic.forEach((aad: any, index: number) => { newData.push({ ...ad, id: ad.id + '_' + index, dynamicGroup: aad, textDto: aad?.textDto }) }) } }) } 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 } }) } } 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 } = addelivery let dynamicMaterialDTOS = [] 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: '' }] }) } let accountIdParamDTOMap: any = {} accountCreateLogs.forEach(item => { let { pageList, productList, userActionSetsList, accountId, wechatChannelList } = 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) { map.productDTOS = productList?.map(item => { return { productId: item.marketingAssetId } }) } if (wechatChannelList) { map.wechatChannelId = wechatChannelList?.[0]?.wechatOfficialAccountId } accountIdParamDTOMap[accountId] = map }) let params = { ...values, adgroupDTO: adgroups, targetings: targeting.map(item => ({ targetingName: item.targetingName, ...item?.targeting || {} })), dynamicCreativesDTO: { ...dynamic, mediaType }, dynamicCreativesTextDTOS, dynamicMaterialDTOS, accountIdParamDTOMap } // setSubVisible(false) 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
配置区
} className={style.createAd} > {accountCreateLogs?.length > 0 && <> {marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_FICTION' && } {(marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT' || marketingCarrierType === 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT') && } }
{/* 广告信息 */} {/* 定向 */} {/* 创意 */} {/* 创意素材 */}
{/* 创意文案 */} {/* 落地页 */}
{/* 选择小说 */} {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() }} />}
{activeKey && tableData && Object.keys(tableData)?.length > 0 ?
{ setActiveKey(e) }} type="card" activeKey={activeKey} tabBarExtraContent={ 广告总数:{adCount} 创意总数:{dynamicCount} } > {accountCreateLogs.map(item => )}
当前共{total}个创意,{tableData[activeKey]?.length / (tableData[activeKey]?.[0]?.rowSpan)}个广告, }} /> :
} {/* 提交任务 */} {subVisible && { onSubmit(e) }} onClose={() => { setSubVisible(false) }} />} } export default Create