|
@@ -7,11 +7,12 @@ import { getTagsList } from "@/services/launchAdq/global"
|
|
import { getSysAdgroupsInfo } from "@/services/launchAdq/localAd"
|
|
import { getSysAdgroupsInfo } from "@/services/launchAdq/localAd"
|
|
import { getsysTargetingInfo } from "@/services/launchAdq/targeting"
|
|
import { getsysTargetingInfo } from "@/services/launchAdq/targeting"
|
|
import { CloseOutlined, SearchOutlined } from "@ant-design/icons"
|
|
import { CloseOutlined, SearchOutlined } from "@ant-design/icons"
|
|
-import { Button, Card, Col, Empty, Row, Select, Space, Spin, Tooltip, Image, message } from "antd"
|
|
|
|
|
|
+import { Button, Card, Col, Empty, Row, Select, Space, Spin, Tooltip, Image, message, Popover } from "antd"
|
|
import React, { useEffect, useState } from "react"
|
|
import React, { useEffect, useState } from "react"
|
|
import { useModel } from "umi"
|
|
import { useModel } from "umi"
|
|
import AdModal from "../../components/adModal"
|
|
import AdModal from "../../components/adModal"
|
|
import CreativeModal from "../../components/creativeModal"
|
|
import CreativeModal from "../../components/creativeModal"
|
|
|
|
+import CrowdPackModal from "../../components/crowdPackModal"
|
|
import DataSourceModal from "../../components/dataSourceModal"
|
|
import DataSourceModal from "../../components/dataSourceModal"
|
|
import GoodsModal from "../../components/goodsModal"
|
|
import GoodsModal from "../../components/goodsModal"
|
|
import IdModal from "../../components/idModal"
|
|
import IdModal from "../../components/idModal"
|
|
@@ -35,14 +36,14 @@ const CreateAd: React.FC = () => {
|
|
campaignType: 'CAMPAIGN_TYPE_NORMAL', // 计划类型 CAMPAIGN_TYPE_NORMAL CAMPAIGN_TYPE_SEARCH
|
|
campaignType: 'CAMPAIGN_TYPE_NORMAL', // 计划类型 CAMPAIGN_TYPE_NORMAL CAMPAIGN_TYPE_SEARCH
|
|
promotedObjectType: 'PROMOTED_OBJECT_TYPE_WECHAT_OFFICIAL_ACCOUNT', // 推广目标类型
|
|
promotedObjectType: 'PROMOTED_OBJECT_TYPE_WECHAT_OFFICIAL_ACCOUNT', // 推广目标类型
|
|
speedMode: 'SPEED_MODE_STANDARD', // 投放速度模式
|
|
speedMode: 'SPEED_MODE_STANDARD', // 投放速度模式
|
|
- sysAdgroupsId: undefined, // 广告组内容
|
|
|
|
|
|
+ sysAdgroupId: undefined, // 广告组内容
|
|
sysTargetingId: undefined, // 定向包 id
|
|
sysTargetingId: undefined, // 定向包 id
|
|
adName: undefined, // 广告名称
|
|
adName: undefined, // 广告名称
|
|
configuredStatus: 'AD_STATUS_SUSPEND', // 广告状态
|
|
configuredStatus: 'AD_STATUS_SUSPEND', // 广告状态
|
|
sysAdcreativeId: undefined, // 创意ID
|
|
sysAdcreativeId: undefined, // 创意ID
|
|
sysPageId: undefined, // 落地页Id
|
|
sysPageId: undefined, // 落地页Id
|
|
})
|
|
})
|
|
- const [accountCreateLogs, setAccountCreateLogs] = useState<{ adAccountId: number, id: number, userActionSetsList?: number, productList?: any, conversionList?: any }[]>([]) // 账户
|
|
|
|
|
|
+ const [accountCreateLogs, setAccountCreateLogs] = useState<{ adAccountId: number, id: number, userActionSetsList?: number, productList?: any, conversionList?: any, customAudienceList?: any, excludedCustomAudienceList?: any }[]>([]) // 账户
|
|
|
|
|
|
const [adVisible, setAdVisible] = useState<boolean>(false) // 选择广告弹窗控制
|
|
const [adVisible, setAdVisible] = useState<boolean>(false) // 选择广告弹窗控制
|
|
const [dxVisible, setDxVisible] = useState<boolean>(false) // 选择定向弹窗控制
|
|
const [dxVisible, setDxVisible] = useState<boolean>(false) // 选择定向弹窗控制
|
|
@@ -53,6 +54,7 @@ const CreateAd: React.FC = () => {
|
|
const [selectImgVisible, setSelectImgVisible] = useState<boolean>(false) // 选择转化ID弹窗控制
|
|
const [selectImgVisible, setSelectImgVisible] = useState<boolean>(false) // 选择转化ID弹窗控制
|
|
const [lookVisible, setLookVisible] = useState<boolean>(false) // 选择转化ID弹窗控制
|
|
const [lookVisible, setLookVisible] = useState<boolean>(false) // 选择转化ID弹窗控制
|
|
const [subVisible, setSubVisible] = useState<boolean>(false) // 选择设置名称弹窗控制
|
|
const [subVisible, setSubVisible] = useState<boolean>(false) // 选择设置名称弹窗控制
|
|
|
|
+ const [cpVisible, setCpVisible] = useState<boolean>(false) // 选择设置名称弹窗控制
|
|
const [wxButtonList, setWxButtonList] = useState<WxAutoButton[]>([])
|
|
const [wxButtonList, setWxButtonList] = useState<WxAutoButton[]>([])
|
|
const [tableData, setTableData] = useState<any[]>([]) // 预览表格
|
|
const [tableData, setTableData] = useState<any[]>([]) // 预览表格
|
|
const [tableSelect, setTableSelect] = useState<any[]>([])
|
|
const [tableSelect, setTableSelect] = useState<any[]>([])
|
|
@@ -108,10 +110,10 @@ const CreateAd: React.FC = () => {
|
|
|
|
|
|
/** 获取广告详情 */
|
|
/** 获取广告详情 */
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
- if (queryForm?.sysAdgroupsId) {
|
|
|
|
- getSysAdgroups.run(queryForm?.sysAdgroupsId)
|
|
|
|
|
|
+ if (queryForm?.sysAdgroupId) {
|
|
|
|
+ getSysAdgroups.run(queryForm?.sysAdgroupId)
|
|
}
|
|
}
|
|
- }, [queryForm?.sysAdgroupsId])
|
|
|
|
|
|
+ }, [queryForm?.sysAdgroupId])
|
|
|
|
|
|
/** 获取创意详情 */
|
|
/** 获取创意详情 */
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
@@ -147,12 +149,18 @@ const CreateAd: React.FC = () => {
|
|
|
|
|
|
/** 删除数据源 */
|
|
/** 删除数据源 */
|
|
const sourceDel = (index: number, num: number) => {
|
|
const sourceDel = (index: number, num: number) => {
|
|
- console.log(index, num);
|
|
|
|
let newArr = JSON.parse(JSON.stringify(accountCreateLogs))
|
|
let newArr = JSON.parse(JSON.stringify(accountCreateLogs))
|
|
newArr[index].userActionSetsList?.splice(num, 1)
|
|
newArr[index].userActionSetsList?.splice(num, 1)
|
|
setAccountCreateLogs(newArr)
|
|
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 setPage = (e: any) => {
|
|
const setPage = (e: any) => {
|
|
setQueryForm({ ...queryForm, sysPageId: e[0]?.id || undefined })
|
|
setQueryForm({ ...queryForm, sysPageId: e[0]?.id || undefined })
|
|
@@ -169,7 +177,7 @@ const CreateAd: React.FC = () => {
|
|
message.error('请选择推广目标')
|
|
message.error('请选择推广目标')
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- if (!queryForm.sysAdgroupsId) {
|
|
|
|
|
|
+ if (!queryForm.sysAdgroupId) {
|
|
message.error('请先设置广告基本信息')
|
|
message.error('请先设置广告基本信息')
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -198,20 +206,27 @@ const CreateAd: React.FC = () => {
|
|
let accountLogs = tableSelect.map((item: any) => {
|
|
let accountLogs = tableSelect.map((item: any) => {
|
|
// userActionSetsList 数据源 productList 商品
|
|
// userActionSetsList 数据源 productList 商品
|
|
let data: any = { adAccountId: item.id }
|
|
let data: any = { adAccountId: item.id }
|
|
- if (item?.userActionSetsList?.length > 0) {
|
|
|
|
|
|
+ if (item?.userActionSetsList?.length > 0) { // 数据源
|
|
data.userActionSets = item?.userActionSetsList?.map((item: any) => ({ id: item?.id, type: item?.type }))
|
|
data.userActionSets = item?.userActionSetsList?.map((item: any) => ({ id: item?.id, type: item?.type }))
|
|
}
|
|
}
|
|
- if (item?.productList?.length) {
|
|
|
|
|
|
+ if (item?.productList?.length > 0) { // 商品
|
|
data.productId = item?.productList[0].productOuterId
|
|
data.productId = item?.productList[0].productOuterId
|
|
data.productCatalogId = item?.productList[0].productCatalogId
|
|
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)
|
|
|
|
+ }
|
|
return data
|
|
return data
|
|
})
|
|
})
|
|
params.accountCreateLogs = accountLogs
|
|
params.accountCreateLogs = accountLogs
|
|
createAdBatch.run(params).then(res => {
|
|
createAdBatch.run(params).then(res => {
|
|
if (res) {
|
|
if (res) {
|
|
|
|
+ sessionStorage.setItem('CAMP', data?.campaignName)
|
|
message.success('创建成功')
|
|
message.success('创建成功')
|
|
- window.location.href = '/#/launchSystemNew/launchManage/taskList'
|
|
|
|
|
|
+ // window.location.href = '/#/launchSystemNew/launchManage/taskList'
|
|
}
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
@@ -241,7 +256,7 @@ const CreateAd: React.FC = () => {
|
|
campaignType: 'CAMPAIGN_TYPE_NORMAL', // 计划类型 CAMPAIGN_TYPE_NORMAL CAMPAIGN_TYPE_SEARCH
|
|
campaignType: 'CAMPAIGN_TYPE_NORMAL', // 计划类型 CAMPAIGN_TYPE_NORMAL CAMPAIGN_TYPE_SEARCH
|
|
promotedObjectType: 'PROMOTED_OBJECT_TYPE_WECHAT_OFFICIAL_ACCOUNT', // 推广目标类型
|
|
promotedObjectType: 'PROMOTED_OBJECT_TYPE_WECHAT_OFFICIAL_ACCOUNT', // 推广目标类型
|
|
speedMode: 'SPEED_MODE_STANDARD', // 投放速度模式
|
|
speedMode: 'SPEED_MODE_STANDARD', // 投放速度模式
|
|
- sysAdgroupsId: undefined, // 广告组内容
|
|
|
|
|
|
+ sysAdgroupId: undefined, // 广告组内容
|
|
sysTargetingId: undefined, // 定向包 id
|
|
sysTargetingId: undefined, // 定向包 id
|
|
adName: undefined, // 广告名称
|
|
adName: undefined, // 广告名称
|
|
configuredStatus: 'AD_STATUS_SUSPEND', // 广告状态
|
|
configuredStatus: 'AD_STATUS_SUSPEND', // 广告状态
|
|
@@ -323,15 +338,58 @@ const CreateAd: React.FC = () => {
|
|
{/* =============定向包=========== */}
|
|
{/* =============定向包=========== */}
|
|
<Col className={style.conRightBorder}>
|
|
<Col className={style.conRightBorder}>
|
|
<div className={style.top}>
|
|
<div className={style.top}>
|
|
- 定向{/* <span>已选:{1}</span> */}
|
|
|
|
|
|
+ 定向
|
|
|
|
+ {accountCreateLogs?.length > 0 && queryForm?.sysTargetingId ? <Button type="link" style={{ fontSize: 12, padding: 0 }} onClick={() => setCpVisible(true)}>选择定向包</Button> : <Tooltip title={accountCreateLogs?.length > 0 ? `请先添加定向` : `请先选择媒体账户`}>
|
|
|
|
+ <Button type="link" style={{ fontSize: 12, padding: 0 }}>选择定向包</Button>
|
|
|
|
+ </Tooltip>}
|
|
</div>
|
|
</div>
|
|
<div className={style.center}>
|
|
<div className={style.center}>
|
|
<Spin spinning={getsysTargeting.loading}>
|
|
<Spin spinning={getsysTargeting.loading}>
|
|
<div className={style.centerContent}>
|
|
<div className={style.centerContent}>
|
|
- {getsysTargeting?.data ? <>
|
|
|
|
- <div>定向名称: <span>{getsysTargeting?.data?.targetingName}</span></div>
|
|
|
|
- <div>定向描述: <span>{getsysTargeting?.data?.description}</span></div>
|
|
|
|
- <TargetingTooltip data={getsysTargeting?.data} geoLocationList={geoLocationList} modelList={modelList} />
|
|
|
|
|
|
+ {queryForm?.sysTargetingId ? <>
|
|
|
|
+ {getsysTargeting?.data && <Popover
|
|
|
|
+ content={<div className={style.popover}>
|
|
|
|
+ <TargetingTooltip data={getsysTargeting?.data} geoLocationList={geoLocationList} modelList={modelList} />
|
|
|
|
+ </div>}
|
|
|
|
+ trigger="hover"
|
|
|
|
+ placement="right"
|
|
|
|
+ >
|
|
|
|
+ <div className={style.popoverContent}>
|
|
|
|
+ <div>定向名称: <span>{getsysTargeting?.data?.targetingName}</span></div>
|
|
|
|
+ <div>定向描述: <span>{getsysTargeting?.data?.description || '<空>'}</span></div>
|
|
|
|
+ </div>
|
|
|
|
+ </Popover>}
|
|
|
|
+
|
|
|
|
+ {accountCreateLogs?.map((item: any, index: number) => {
|
|
|
|
+ if (item?.customAudienceList) {
|
|
|
|
+ return <div className={style.acc} key={index}>
|
|
|
|
+ <div className={style.accName} style={{ fontWeight: 800 }}>{item.adAccountId}</div>
|
|
|
|
+ {item?.customAudienceList?.length > 0 && <>
|
|
|
|
+ <div className={style.accName}>定向用户群</div>
|
|
|
|
+ {
|
|
|
|
+ item?.customAudienceList?.map((pack: { name: string, id: number }, index1: number) => {
|
|
|
|
+ return <div className={style.accCon} key={pack.id}>{pack.name}<CloseOutlined className={style.close} onClick={() => {
|
|
|
|
+ cpDel(index, index1, 'customAudienceList')
|
|
|
|
+ }} /></div>
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ </>}
|
|
|
|
+ {item?.excludedCustomAudienceList?.length > 0 && <>
|
|
|
|
+ <div className={style.accName} style={{ marginTop: 5 }}>排除用户群</div>
|
|
|
|
+ {
|
|
|
|
+ item?.excludedCustomAudienceList?.map((pack: { name: string, id: number }, index1: number) => {
|
|
|
|
+ return <div className={style.accCon} key={pack.id}>{pack.name}<CloseOutlined className={style.close} onClick={() => {
|
|
|
|
+ cpDel(index, index1, 'excludedCustomAudienceList')
|
|
|
|
+ }} /></div>
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ </>}
|
|
|
|
+ </div>
|
|
|
|
+ } else {
|
|
|
|
+ return null
|
|
|
|
+ }
|
|
|
|
+ })}
|
|
|
|
+
|
|
</> : <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
|
|
</> : <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
|
|
</div>
|
|
</div>
|
|
</Spin>
|
|
</Spin>
|
|
@@ -348,7 +406,7 @@ const CreateAd: React.FC = () => {
|
|
{accountCreateLogs?.map((item: any, index: number) => {
|
|
{accountCreateLogs?.map((item: any, index: number) => {
|
|
if (item?.productList) {
|
|
if (item?.productList) {
|
|
return <div className={style.acc} key={index}>
|
|
return <div className={style.acc} key={index}>
|
|
- <div className={style.accName}>{item.adAccountId}</div>
|
|
|
|
|
|
+ <div className={style.accName} style={{ fontWeight: 800 }}>{item.adAccountId}</div>
|
|
{
|
|
{
|
|
item?.productList?.map((pack: { productName: string, author: string, id: number }, index: number) => {
|
|
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={() => {
|
|
return <div className={style.accCon} key={pack.id}>{pack.productName}<CloseOutlined className={style.close} onClick={() => {
|
|
@@ -380,7 +438,7 @@ const CreateAd: React.FC = () => {
|
|
{accountCreateLogs?.map((item: any, index: number) => {
|
|
{accountCreateLogs?.map((item: any, index: number) => {
|
|
if (item?.userActionSetsList && item?.userActionSetsList?.length > 0) {
|
|
if (item?.userActionSetsList && item?.userActionSetsList?.length > 0) {
|
|
return <div className={style.acc} key={index}>
|
|
return <div className={style.acc} key={index}>
|
|
- <div className={style.accName}>{item.adAccountId}</div>
|
|
|
|
|
|
+ <div className={style.accName} style={{ fontWeight: 800 }}>{item.adAccountId}</div>
|
|
{
|
|
{
|
|
item?.userActionSetsList?.map((pack: { name: string, type: string, id: number }, index1: number) => {
|
|
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}</span> <CloseOutlined className={style.close} onClick={() => {
|
|
return <div className={style.accCon} key={pack.id}> <span className={style.title}>{pack.name}{' > '}{pack.type}</span> <CloseOutlined className={style.close} onClick={() => {
|
|
@@ -417,7 +475,7 @@ const CreateAd: React.FC = () => {
|
|
</div>
|
|
</div>
|
|
</Spin>
|
|
</Spin>
|
|
</div>
|
|
</div>
|
|
- <div className={style.bottom}>{queryForm?.sysAdgroupsId ? <>
|
|
|
|
|
|
+ <div className={style.bottom}>{queryForm?.sysAdgroupId ? <>
|
|
<Button type="link" onClick={() => { setCreativeVisible(true) }}>{queryForm?.sysAdcreativeId ? '修改' : '添加'}</Button>
|
|
<Button type="link" onClick={() => { setCreativeVisible(true) }}>{queryForm?.sysAdcreativeId ? '修改' : '添加'}</Button>
|
|
</> : <Tooltip title="请先设置广告">
|
|
</> : <Tooltip title="请先设置广告">
|
|
<Button type="link"><span>添加</span></Button>
|
|
<Button type="link"><span>添加</span></Button>
|
|
@@ -518,7 +576,7 @@ const CreateAd: React.FC = () => {
|
|
|
|
|
|
|
|
|
|
{/* 选择广告 */}
|
|
{/* 选择广告 */}
|
|
- {adVisible && <AdModal visible={adVisible} onClose={() => setAdVisible(false)} promotedObjectType={queryForm.promotedObjectType as string} onChange={(e) => { setQueryForm({ ...queryForm, sysAdgroupsId: e, sysAdcreativeId: undefined }); setAdVisible(false); clearData() }} sysAdgroupsId={queryForm?.sysAdgroupsId} />}
|
|
|
|
|
|
+ {adVisible && <AdModal visible={adVisible} onClose={() => setAdVisible(false)} promotedObjectType={queryForm.promotedObjectType as string} onChange={(e) => { setQueryForm({ ...queryForm, sysAdgroupId: e, sysAdcreativeId: undefined }); setAdVisible(false); clearData() }} sysAdgroupId={queryForm?.sysAdgroupId} />}
|
|
{/* 选择定向 */}
|
|
{/* 选择定向 */}
|
|
{dxVisible && <TargetingModal visible={dxVisible} onClose={() => setDxVisible(false)} onChange={(e) => { setQueryForm({ ...queryForm, sysTargetingId: e }); setDxVisible(false); clearData() }} sysTargetingId={queryForm?.sysTargetingId} />}
|
|
{dxVisible && <TargetingModal visible={dxVisible} onClose={() => setDxVisible(false)} onChange={(e) => { setQueryForm({ ...queryForm, sysTargetingId: e }); setDxVisible(false); clearData() }} sysTargetingId={queryForm?.sysTargetingId} />}
|
|
{/* 选择创意 */}
|
|
{/* 选择创意 */}
|
|
@@ -529,6 +587,8 @@ const CreateAd: React.FC = () => {
|
|
{sourceVisible && <DataSourceModal visible={sourceVisible} data={accountCreateLogs} onClose={() => setSourceVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setSourceVisible(false); clearData() }} />}
|
|
{sourceVisible && <DataSourceModal visible={sourceVisible} data={accountCreateLogs} onClose={() => setSourceVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setSourceVisible(false); clearData() }} />}
|
|
{/* 选择转化ID */}
|
|
{/* 选择转化ID */}
|
|
{idVisible && <IdModal visible={idVisible} data={accountCreateLogs} onClose={() => setIdVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setSourceVisible(false); clearData() }} />}
|
|
{idVisible && <IdModal visible={idVisible} data={accountCreateLogs} onClose={() => setIdVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setSourceVisible(false); clearData() }} />}
|
|
|
|
+ {/* 选择定向包 */}
|
|
|
|
+ {cpVisible && <CrowdPackModal visible={cpVisible} data={accountCreateLogs} onClose={() => setCpVisible(false)} onChange={(e) => { setAccountCreateLogs(e); setCpVisible(false); clearData() }} />}
|
|
{/* 选择素材 */}
|
|
{/* 选择素材 */}
|
|
{selectImgVisible && <SelectCloud visible={selectImgVisible} onClose={() => setSelectImgVisible(false)} onChange={setPage} isBack={false} />}
|
|
{selectImgVisible && <SelectCloud visible={selectImgVisible} onClose={() => setSelectImgVisible(false)} onChange={setPage} isBack={false} />}
|
|
{/* 查看落地页 */}
|
|
{/* 查看落地页 */}
|