123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- import { Card, Form, Select, Space, Switch, Tooltip } from "antd"
- import React, { useContext, useEffect, useState } from "react"
- import MarketingGoal from "./marketingGoal"
- import NewRadio from "@/pages/launchSystemV3/components/NewRadio"
- import { DispatchAd } from "./newCreateAd"
- import { GOAL_ROAS_ENUM, MARKETING_CARRIER_TYPE_ENUM, MARKETING_TARGET_TYPE_ENUM, MARKETING_TARGET_TYPE_GAME_ENUM, OPTIMIZATIONGOAL_ENUM, defaultSiteSet, marketingGoalGameList, marketingGoalList, marketingSubGoalGameList } from "../../const"
- import New1Radio from "@/pages/launchSystemV3/components/New1Radio"
- import { getOptimizationGoalPermissionsV3Api } from "@/services/adqV3/global"
- import { adRules } from "../../rules"
- import { QuestionCircleFilled } from "@ant-design/icons"
- import { SelectMiniProgramWechat } from "@/pages/launchSystemV3/tencenTasset/miniProgramWechat"
- import { SelectCorpWechat } from "@/pages/launchSystemV3/tencenTasset/corpWechat"
- import { SelectGameAppId } from "@/pages/launchSystemV3/tencenTasset/game"
- import { useRequest } from "ahooks"
- import { SelectApplication } from "@/pages/launchSystemV3/tencenTasset/application"
- /**
- * 营销内容
- * @param value 回填
- * @returns
- */
- const AdgroupsMarketingContent: React.FC<{ accountIdList: number[], value?: any }> = ({ accountIdList, value }) => {
- /****************************************/
- const { form, OGPParams, setOGPparams, putInType } = useContext(DispatchAd)!;
- const marketingGoal = Form.useWatch('marketingGoal', form);
- const marketingSubGoal = Form.useWatch<string>('marketingSubGoal', form);
- const marketingTargetType = Form.useWatch('marketingTargetType', form);
- const marketingCarrierType = Form.useWatch('marketingCarrierType', form);
- const bidMode = Form.useWatch('bidMode', form);
- const optimizationGoal = Form.useWatch('optimizationGoal', form);
- const smartBidType = Form.useWatch('smartBidType', form);
- const bidScene = Form.useWatch('bidScene', form);
- const wxGameAppId = Form.useWatch('wxGameAppId', form);
- const depthConversionEnabled = Form.useWatch('depthConversionEnabled', form);
- const deepConversionType = Form.useWatch(['deepConversionSpec', 'deepConversionType'], form);
- const goal = Form.useWatch(['deepConversionSpec', deepConversionType === 'DEEP_CONVERSION_BEHAVIOR' ? 'deepConversionBehaviorSpec' : 'deepConversionWorthSpec', 'goal'], form);
- // 推广产品
- const [marketingTargetTypeList, setMarketingTargetTypeList] = useState<PULLIN.DataType[]>([])
- const [marketingCarrierTypeList, setMarketingCarrierTypeList] = useState<PULLIN.DataType[]>([])
- const [rules, setRules] = useState<any>({})
- const [behaviorList, setBehaviorList] = useState<string[]>([])
- const [worthList, setWorthList] = useState<string[]>([])
- const [deepConversionData, setDeepConversionData] = useState<PULLIN.DataType[]>([])
- const [isUpdateOptimizationGoal, setIsUpdateOptimizationGoal] = useState<boolean>(false)
- const queryOptimizationGoalPermissions = useRequest((params) => getOptimizationGoalPermissionsV3Api(params), { manual: true, debounceInterval: 100 })
- /****************************************/
- /** 获取深度优化 出价和版位改变时查询 */
- const getOptimizationGoalPermissions = () => {
- let marketingCarrierType = OGPParams?.marketingCarrierType
- let bidMode = OGPParams.bidMode
- let siteSet = OGPParams.siteSet
- let automaticSiteEnabled = OGPParams.automaticSiteEnabled
- let marketingGoal = OGPParams.marketingGoal
- let marketingTargetType = OGPParams?.marketingTargetType
- if (marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT') {
- marketingCarrierType = 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT'
- }
- if ((bidMode && siteSet && siteSet?.length > 0 && marketingGoal && marketingCarrierType && marketingTargetType) || automaticSiteEnabled) {
- let obj: any = { siteSet: automaticSiteEnabled ? defaultSiteSet : siteSet, marketingGoal, marketingCarrierType: marketingCarrierType, marketingTargetType, marketingSubGoal: OGPParams?.marketingSubGoal || 'MARKETING_SUB_GOAL_UNKNOWN' }
- if (bidMode === 'BID_MODE_OCPC' || bidMode === 'BID_MODE_OCPM') {
- obj.bidMode = bidMode
- }
- if (putInType === 'GAME' && marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' && wxGameAppId) {
- obj.marketingCarrierDetail = {
- marketingCarrierId: wxGameAppId
- }
- }
- queryOptimizationGoalPermissions.run({ ...obj, taskType: putInType, accountIdList })
- }
- }
- useEffect(() => {
- if (OGPParams.marketingCarrierType && OGPParams.marketingTargetType) {
- getOptimizationGoalPermissions()
- }
- }, [OGPParams, putInType, wxGameAppId, accountIdList])
- // 处理深度转化优化
- useEffect(() => {
- if (optimizationGoal && queryOptimizationGoalPermissions?.data?.data) {
- let { deepBehaviorOptimizationGoalPermissionList, deepWorthOptimizationGoalPermissionList } = queryOptimizationGoalPermissions?.data?.data
- let behavior = deepBehaviorOptimizationGoalPermissionList?.find((item: { optimizationGoal: string }) => item.optimizationGoal === optimizationGoal)
- let worth = deepWorthOptimizationGoalPermissionList?.find((item: { optimizationGoal: string }) => item.optimizationGoal === optimizationGoal)
- let newBehaviorList = behavior?.deepBehaviorOptimizationGoalList || []
- setBehaviorList(newBehaviorList)
- let newWorthList = worth?.deepWorthOptimizationGoalList || []
- setWorthList(newWorthList)
- let newDeepConversionData: PULLIN.DataType[] = [];
- (newBehaviorList?.length > 0 && newDeepConversionData.push({ label: '优化转化行为', value: 'DEEP_CONVERSION_BEHAVIOR' }))
- { newWorthList?.length > 0 && newDeepConversionData.push({ label: '优化ROI', value: 'DEEP_CONVERSION_WORTH' }) }
- setDeepConversionData(newDeepConversionData)
- const inputInstance = form.getFieldValue('deepConversionSpec');
- let deepConversionType = newBehaviorList?.length > 0 ? 'DEEP_CONVERSION_BEHAVIOR' : newWorthList?.length > 0 ? "DEEP_CONVERSION_WORTH" : ''
- if (inputInstance?.deepConversionType ? inputInstance?.deepConversionType === 'DEEP_CONVERSION_BEHAVIOR' ? !newBehaviorList?.length : !newWorthList?.length : true) {
- form.setFieldsValue({
- deepConversionSpec: {
- deepConversionType
- }
- })
- }
- }
- }, [optimizationGoal, queryOptimizationGoalPermissions?.data?.data])
- // 选择营销目的触发
- useEffect(() => {
- let newRule: any = {}
- let newMarketingTargetTypeList: PULLIN.DataType[] = []
- if (marketingGoal) {
- // 根据const里数据对比选出可展示数据
- if (putInType === 'NOVEL') {
- newRule = adRules[marketingGoal]
- newMarketingTargetTypeList = Object.keys(MARKETING_TARGET_TYPE_ENUM).filter(key => newRule?.[key]).map(key => ({ label: MARKETING_TARGET_TYPE_ENUM[key as keyof typeof MARKETING_TARGET_TYPE_ENUM], value: key }))
- } else if (putInType === 'GAME') {
- newRule = adRules[marketingGoal][marketingSubGoal]
- newMarketingTargetTypeList = Object.keys(MARKETING_TARGET_TYPE_GAME_ENUM).filter(key => newRule?.[key]).map(key => ({ label: MARKETING_TARGET_TYPE_GAME_ENUM[key as keyof typeof MARKETING_TARGET_TYPE_GAME_ENUM], value: key }))
- }
- }
- setMarketingTargetTypeList(newMarketingTargetTypeList)
- setRules(newRule)
- }, [marketingGoal, marketingSubGoal, putInType])
- // 推广产品设置默认值
- useEffect(() => {
- if (!(value && Object.keys(value).length > 0) && marketingTargetTypeList && (!marketingTargetType || (marketingTargetType && !marketingTargetTypeList.some(item => item.value === marketingTargetType)))) {
- form.setFieldsValue({ marketingTargetType: marketingTargetTypeList?.[0]?.value })
- }
- }, [marketingTargetType, marketingTargetTypeList, OGPParams, value])
- // 营销载体类型
- useEffect(() => {
- let newMarketingTargetTypeListList: PULLIN.DataType[] = []
- // 推广产品是公众号不展示 营销载体类型
- if (marketingTargetType) {
- let marketingTargetTypeRules: string[] = rules?.[marketingTargetType]?.MARKETING_SUB_GOAL_UNKNOWN
- newMarketingTargetTypeListList = Object.keys(MARKETING_CARRIER_TYPE_ENUM).filter(key => marketingTargetTypeRules?.[key as keyof typeof marketingTargetTypeRules]).map(key => ({ label: MARKETING_CARRIER_TYPE_ENUM[key as keyof typeof MARKETING_CARRIER_TYPE_ENUM], value: key }))
- }
- setMarketingCarrierTypeList(newMarketingTargetTypeListList)
- }, [marketingTargetType, rules])
- // 设置营销载体默认值
- useEffect(() => {
- if (!(value && Object.keys(value).length > 0) && !marketingCarrierType || (marketingCarrierType && !marketingCarrierTypeList.some(item => item.value === marketingCarrierType))) {
- let newMarketingCarrierType = marketingCarrierTypeList?.[0]?.value
- form.setFieldsValue({ marketingCarrierType: newMarketingCarrierType })
- setOGPparams({ ...OGPParams, marketingTargetType, marketingCarrierType: newMarketingCarrierType })
- }
- }, [marketingCarrierType, marketingCarrierTypeList, OGPParams, value, marketingTargetType])
- // 切换 其他 优化目标更新
- useEffect(() => {
- let optimizationGoalPermissionList: string[] = queryOptimizationGoalPermissions?.data?.data?.optimizationGoalPermissionList
- if (isUpdateOptimizationGoal && optimizationGoalPermissionList?.length > 0 && !optimizationGoalPermissionList?.includes(optimizationGoal)) {
- if (putInType === 'NOVEL') {
- form.setFieldsValue({ optimizationGoal: optimizationGoalPermissionList?.includes('OPTIMIZATIONGOAL_ECOMMERCE_ORDER') ? 'OPTIMIZATIONGOAL_ECOMMERCE_ORDER' : optimizationGoalPermissionList?.includes('OPTIMIZATIONGOAL_PAGE_SCAN_CODE') ? 'OPTIMIZATIONGOAL_PAGE_SCAN_CODE' : undefined })
- } else if (putInType === 'GAME') {
- form.setFieldsValue({ optimizationGoal: (optimizationGoalPermissionList?.includes('OPTIMIZATIONGOAL_ECOMMERCE_ORDER') ? 'OPTIMIZATIONGOAL_ECOMMERCE_ORDER' : optimizationGoalPermissionList?.[0]) || undefined })
- }
- setIsUpdateOptimizationGoal(false)
- }
- }, [queryOptimizationGoalPermissions?.data?.data?.optimizationGoalPermissionList, marketingGoal, marketingTargetType, marketingCarrierType, optimizationGoal, value, isUpdateOptimizationGoal, putInType])
- const setIsUpdate = () => {
- if (bidMode === 'BID_MODE_OCPM' || bidMode === 'BID_MODE_OCPC') {
- setIsUpdateOptimizationGoal(true)
- }
- form.setFieldsValue({
- deepConversionSpec: {
- deepConversionType,
- ...(deepConversionType === 'DEEP_CONVERSION_BEHAVIOR' ? {
- deepConversionBehaviorSpec: {
- goal: undefined
- }
- } : {
- deepConversionWorthSpec: {
- goal: undefined
- }
- })
- }
- })
- }
- return <Card
- title={<strong style={{ fontSize: 18 }}>营销内容</strong>}
- className="cardResetCss"
- >
- <Form.Item name="marketingGoal" label={<strong>营销目的</strong>} rules={[{ required: true, message: '请选择营销目的!' }]} hidden={putInType === 'GAME'}>
- <MarketingGoal data={putInType === 'GAME' ? marketingGoalGameList : marketingGoalList} onChange={(e) => {
- if (e === 'MARKETING_GOAL_LEAD_RETENTION' && ['MARKETING_TARGET_TYPE_APP_ANDROID', 'MARKETING_TARGET_TYPE_APP_IOS'].includes(marketingTargetType)) {
- form.setFieldsValue({
- marketingTargetType: 'MARKETING_TARGET_TYPE_FICTION',
- })
- }
- setOGPparams({ ...OGPParams, marketingGoal: e as string });
- setIsUpdate()
- }} />
- </Form.Item>
- {putInType === 'GAME' && <Form.Item name="marketingSubGoal" label={<strong>营销目的</strong>} rules={[{ required: true, message: '请选择营销目的!' }]}>
- <MarketingGoal data={marketingSubGoalGameList} onChange={(e) => { setOGPparams({ ...OGPParams, marketingSubGoal: e as string }); setIsUpdate() }} />
- </Form.Item>}
- {marketingTargetTypeList?.length > 0 && <Form.Item name="marketingTargetType" label={<strong>推广产品</strong>} rules={[{ required: true, message: '请选择推广产品!' }]}>
- <NewRadio data={marketingTargetTypeList} onChange={(e) => {
- if (e === 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT') { // 公众号
- setOGPparams({ ...OGPParams, marketingTargetType: e, marketingCarrierType: 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT' })
- form.setFieldsValue({ marketingCarrierType: 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT' })
- } else {
- setOGPparams({ ...OGPParams, marketingTargetType: e })
- }
- setIsUpdate()
- }} />
- </Form.Item>}
- {marketingCarrierTypeList?.length > 0 && <Form.Item name="marketingCarrierType" label={<strong>营销载体类型</strong>} rules={[{ required: true, message: '请选择营销载体类型!' }]}>
- <New1Radio data={marketingCarrierTypeList} onChange={(e) => { setOGPparams({ ...OGPParams, marketingCarrierType: e }); setIsUpdate() }} />
- </Form.Item>}
- {marketingTargetType === 'MARKETING_TARGET_TYPE_MINI_PROGRAM_WECHAT' ? <Form.Item name='sysWechatAppId' rules={[{ required: true, message: '请选择微信小程序' }]}>
- <SelectMiniProgramWechat />
- </Form.Item> : marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_WORK' ? <Form.Item name='sysCorpWechatId' rules={[{ required: true, message: '请选择企业微信' }]}>
- <SelectCorpWechat />
- </Form.Item> : marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' ? <Form.Item name='wxGameAppId' rules={[{ required: true, message: '请选择微信小游戏' }]}>
- <SelectGameAppId gameType="WXGAME" />
- </Form.Item> : null}
- {['MARKETING_CARRIER_TYPE_APP_ANDROID', 'MARKETING_CARRIER_TYPE_APP_IOS'].includes(marketingCarrierType) && <Form.Item name='promoteApplicationId' rules={[{ required: true, message: '请选择推广应用' }]}>
- <SelectApplication type={marketingCarrierType === 'MARKETING_CARRIER_TYPE_APP_ANDROID' ? 'ANDROID' : marketingCarrierType === 'MARKETING_CARRIER_TYPE_APP_IOS' ? 'IOS' : undefined} />
- </Form.Item>}
- {(bidMode === 'BID_MODE_OCPM' || bidMode === 'BID_MODE_OCPC') && <>
- {['MARKETING_CARRIER_TYPE_JUMP_PAGE', 'MARKETING_CARRIER_TYPE_APP_IOS', 'MARKETING_CARRIER_TYPE_APP_ANDROID', 'MARKETING_CARRIER_TYPE_APP_QUICK_APP', 'MARKETING_CARRIER_TYPE_WECHAT_MINI_GAME', 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT'].includes(marketingCarrierType) && <Form.Item
- label={<Space>
- <strong>转化归因新链路</strong>
- <Tooltip title={<>
- <h5 style={{ color: '#FFF' }}>注意账号需要开通权限,该功能与“精准匹配归因”互斥;</h5>
- <p>
- 转化中包含你希望高效获取的行为作为优化目标,深度优化目标,以及转化数据上报和归因的方式。
- 我们将按照你设置的优化目标,为你尽可能找到实现转化的用户。
- 你可以在工具箱-转化归因模块进行转化配置。
- <a href="https://e.qq.com/ads/helpcenter/detail/?cid=3529&pid=3179" target="__blank">了解更多</a>
- </p>
- </>}>
- <QuestionCircleFilled />
- </Tooltip>
- </Space>}
- name='isConversion'
- help="注意账号需要开通权限"
- >
- <New1Radio data={[{ label: '开启', value: true }, { label: '关闭', value: false }]} />
- </Form.Item>}
- <Form.Item
- label={<strong>优化目标</strong>}
- name='optimizationGoal'
- rules={[{ required: true, message: '请选择优化目标' }]}
- help={(marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' && !wxGameAppId) ? '请先选择微信小游戏' : undefined}
- validateStatus={(marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' && !wxGameAppId) ? 'error' : undefined}
- >
- <Select
- style={{ width: 480 }}
- showSearch
- filterOption={(input, option) =>
- (option!.children as unknown as string)?.toLowerCase()?.includes(input?.toLowerCase())
- }
- disabled={(marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' && !wxGameAppId)}
- allowClear
- placeholder='请选择'
- loading={queryOptimizationGoalPermissions.loading}
- >
- {queryOptimizationGoalPermissions?.data?.data?.optimizationGoalPermissionList.filter((key: string) => key !== 'UNKNOWN').map((key: string) => {
- return <Select.Option value={key} key={key}>{OPTIMIZATIONGOAL_ENUM[key as keyof typeof OPTIMIZATIONGOAL_ENUM]}</Select.Option>
- })}
- </Select>
- </Form.Item>
- {/* 深度优化 */}
- {((behaviorList?.length > 0 || worthList?.length > 0) && (marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' ? !!wxGameAppId : true) && (putInType === 'GAME' ? bidScene !== 'BID_SCENE_NORMAL_MAX' : smartBidType !== 'SMART_BID_TYPE_SYSTEMATIC')) && <>
- <Form.Item label={<strong>深度转化优化</strong>} name='depthConversionEnabled' valuePropName="checked">
- <Switch
- disabled={(marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' && !wxGameAppId)}
- checkedChildren="开启"
- unCheckedChildren="关闭"
- onChange={(e) => {
- if (e) {
- if (behaviorList?.length > 0) {
- form.setFieldsValue({
- deepConversionSpec: {
- deepConversionType: 'DEEP_CONVERSION_BEHAVIOR',
- }
- })
- } else if (worthList?.length > 0) {
- form.setFieldsValue({
- deepConversionSpec: {
- deepConversionType: 'DEEP_CONVERSION_WORTH',
- deepConversionWorthSpec: { roiAllocationMode: 1 }
- }
- })
- } else {
- form.setFieldsValue({
- deepConversionSpec: {
- deepConversionType: undefined,
- }
- })
- }
- }
- }}
- />
- </Form.Item>
- {depthConversionEnabled && <>
- <Form.Item label={<strong>深度优化类型</strong>} name={['deepConversionSpec', 'deepConversionType']} rules={[{ required: true, message: '请选择深度优化类型' }]}>
- <New1Radio
- data={deepConversionData}
- onChange={(e) => {
- form.setFieldsValue({
- deepConversionSpec: {
- deepConversionType: e,
- ...(e === 'DEEP_CONVERSION_WORTH' ? { deepConversionWorthSpec: { roiAllocationMode: 1 } } : {})
- }
- })
- }}
- />
- </Form.Item>
- <Form.Item label={<strong>深度优化目标</strong>} name={['deepConversionSpec', deepConversionType === 'DEEP_CONVERSION_BEHAVIOR' ? 'deepConversionBehaviorSpec' : 'deepConversionWorthSpec', 'goal']} rules={[{ required: true, message: '请选择深度优化目标' }]}>
- <Select style={{ width: 480 }} placeholder='请选择'>
- {deepConversionType === 'DEEP_CONVERSION_BEHAVIOR' ? Object.keys(OPTIMIZATIONGOAL_ENUM).filter(key => behaviorList?.includes(key)).map(key => <Select.Option value={key} key={key}>{OPTIMIZATIONGOAL_ENUM[key as keyof typeof OPTIMIZATIONGOAL_ENUM]}</Select.Option>) : deepConversionType === 'DEEP_CONVERSION_WORTH' ?
- Object.keys(GOAL_ROAS_ENUM).filter(key => worthList?.includes(key)).map(key => <Select.Option value={key} key={key}>{GOAL_ROAS_ENUM[key as keyof typeof GOAL_ROAS_ENUM]}</Select.Option>) : null}
- </Select>
- </Form.Item>
- </>}
- </>}
- </>}
- </Card>
- }
- export default React.memo(AdgroupsMarketingContent)
|