index.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import React, { useContext, useState } from "react"
  2. import style from '../index.less'
  3. import NewCreateAd from "./newCreateAd"
  4. import { DispatchAddelivery } from "..";
  5. import { Button, Modal, Typography } from "antd";
  6. import { EditOutlined } from "@ant-design/icons";
  7. import { AD_STATUS_ENUM, BID_MODE_ENUM, DEEP_CONVERSION_ENUM, GOAL_ROAS_ENUM, MARKETING_CARRIER_TYPE_ENUM, MARKETING_GOAL_ENUM, MARKETING_SUB_GOAL_ENUM, MARKETING_TARGET_TYPE_ENUM, MARKETING_TARGET_TYPE_GAME_ENUM, OPTIMIZATIONGOAL_ENUM, SITE_SET_ENUM, SMART_BID_TYPE_ENUM } from "../../const";
  8. import TimeSeriesLook from "@/pages/launchSystemNew/adq/ad/timeSeriesLook";
  9. import { arraysHaveSameValues } from "@/utils/utils";
  10. import '../../index.less'
  11. import { ShowMiniProgramWechatDetail } from "@/pages/launchSystemV3/tencenTasset/miniProgramWechat";
  12. import { ShowGameDetail } from "@/pages/launchSystemV3/tencenTasset/game";
  13. /**
  14. * 广告信息
  15. * @returns
  16. */
  17. const Ad: React.FC = () => {
  18. /*****************************/
  19. const { addelivery, setAddelivery, accountCreateLogs, clearData, setAccountCreateLogs, putInType } = useContext(DispatchAddelivery)!;
  20. const { adgroups } = addelivery
  21. const {
  22. marketingGoal, marketingSubGoal, marketingAssetOuterSpec, marketingCarrierType, automaticSiteEnabled, siteSet, searchExpandTargetingSwitch, bidMode, smartBidType, bidAmount, optimizationGoal, isConversion, depthConversionEnabled,
  23. deepConversionSpec, autoAcquisitionEnabled, autoAcquisitionBudget, dailyBudget, endDate, beginDate, timeSeries, firstDayBeginTime, configuredStatus, adgroupName, sceneSpec, autoDerivedCreativeEnabled, sysWechatAppId, sysWxGameId
  24. } = adgroups
  25. const [newVisible, setNewVisible] = useState<boolean>(false)
  26. /*****************************/
  27. return <>
  28. <div className={`${style.settingsBody_content_row} ${style.row1}`}>
  29. <div className={style.title}>
  30. <span>广告信息</span>
  31. </div>
  32. <div className={style.detail}>
  33. <div className={style.detail_body}>
  34. {(adgroups && Object.keys(adgroups).length > 0) ? <>
  35. <p style={{ fontWeight: 'bold', color: configuredStatus === 'AD_STATUS_NORMAL' ? '#52c41a' : '#FF4D4F' }}>广告状态:{AD_STATUS_ENUM[configuredStatus as keyof typeof AD_STATUS_ENUM]}</p>
  36. {putInType === 'NOVEL' ? <>
  37. <p>营销目的:{MARKETING_GOAL_ENUM[marketingGoal as keyof typeof MARKETING_GOAL_ENUM]}</p>
  38. <p style={{ fontWeight: 'bold', color: '#000' }}>推广产品类型:{MARKETING_TARGET_TYPE_ENUM[marketingAssetOuterSpec?.marketingTargetType as keyof typeof MARKETING_TARGET_TYPE_ENUM]}</p>
  39. </> : <>
  40. <p>营销目的:{MARKETING_SUB_GOAL_ENUM[marketingSubGoal as keyof typeof MARKETING_SUB_GOAL_ENUM]}</p>
  41. <p style={{ fontWeight: 'bold', color: '#000' }}>推广产品类型:{MARKETING_TARGET_TYPE_GAME_ENUM[marketingAssetOuterSpec?.marketingTargetType as keyof typeof MARKETING_TARGET_TYPE_GAME_ENUM]}</p>
  42. </>}
  43. {marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_MINI_PROGRAM_WECHAT' ?
  44. <ShowMiniProgramWechatDetail id={sysWechatAppId} /> :
  45. marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' ?
  46. <ShowGameDetail id={sysWxGameId}/> :
  47. null
  48. }
  49. <p>营销载体类型:{MARKETING_CARRIER_TYPE_ENUM[marketingCarrierType as keyof typeof MARKETING_CARRIER_TYPE_ENUM]}</p>
  50. <p>版位选择:{automaticSiteEnabled ? '自动版位' : '选择特定版位'}</p>
  51. {!automaticSiteEnabled && <Typography.Paragraph className={style.tpP} style={{ marginBottom: 0 }} ellipsis={{ tooltip: true, rows: 2 }}>广告版位:{siteSet.map((item: string | number) => SITE_SET_ENUM[item as keyof typeof SITE_SET_ENUM]).toString()}</Typography.Paragraph>}
  52. <p>搜索场景扩量:{searchExpandTargetingSwitch === 'SEARCH_EXPAND_TARGETING_SWITCH_OPEN' ? '开启' : '关闭'}</p>
  53. <p>计费方式:{BID_MODE_ENUM[bidMode as keyof typeof BID_MODE_ENUM]}</p>
  54. <p>出价类型:{SMART_BID_TYPE_ENUM[smartBidType as keyof typeof SMART_BID_TYPE_ENUM]}</p>
  55. <p>出价:{bidAmount}元/{optimizationGoal ? OPTIMIZATIONGOAL_ENUM[optimizationGoal as keyof typeof OPTIMIZATIONGOAL_ENUM] : ['BID_MODE_OCPM', 'BID_MODE_OCPC'].includes(bidMode) ? '千次曝光' : '点击'}</p>
  56. {isConversion && <p style={{ fontWeight: 'bold', color: '#000' }}>转化:新链路转化</p>}
  57. {optimizationGoal && <p style={{ fontWeight: 'bold', color: '#000' }}>优化目标:{OPTIMIZATIONGOAL_ENUM[optimizationGoal as keyof typeof OPTIMIZATIONGOAL_ENUM]}</p>}
  58. {deepConversionSpec && <>
  59. <p style={{ fontWeight: 'bold', color: '#000' }}>深度转化优化:开启</p>
  60. <p style={{ fontWeight: 'bold', color: '#000' }}>深度优化类型:{DEEP_CONVERSION_ENUM[deepConversionSpec?.deepConversionType as keyof typeof DEEP_CONVERSION_ENUM]}</p>
  61. {deepConversionSpec.deepConversionType === 'DEEP_CONVERSION_BEHAVIOR' ? <>
  62. <p style={{ fontWeight: 'bold', color: '#000' }}>深度优化目标:{OPTIMIZATIONGOAL_ENUM[deepConversionSpec.deepConversionBehaviorSpec.goal as keyof typeof OPTIMIZATIONGOAL_ENUM]}</p>
  63. <p style={{ fontWeight: 'bold', color: '#000' }}>深度目标出价:{deepConversionSpec.deepConversionBehaviorSpec.bidAmount}元/{OPTIMIZATIONGOAL_ENUM[deepConversionSpec.deepConversionBehaviorSpec.goal as keyof typeof OPTIMIZATIONGOAL_ENUM] || '优化目标'}</p>
  64. </> : <>
  65. <p style={{ fontWeight: 'bold', color: '#000' }}>深度优化目标:{GOAL_ROAS_ENUM[deepConversionSpec.deepConversionWorthSpec.goal as keyof typeof GOAL_ROAS_ENUM]}</p>
  66. <p style={{ fontWeight: 'bold', color: '#000' }}>期望ROI:{deepConversionSpec.deepConversionWorthSpec.expectedRoi}</p>
  67. </>}
  68. </>}
  69. <p>一键起量:{autoAcquisitionEnabled ? '开启' : '关闭'}</p>
  70. {autoAcquisitionEnabled && <p>起量预算:{autoAcquisitionBudget}元/天</p>}
  71. <p>广告日预算:{dailyBudget ? dailyBudget + '元/天' : '不限'}</p>
  72. <p style={{ fontWeight: 'bold', color: '#000' }}>投放日期:{beginDate} 至 {endDate}</p>
  73. <p>投放时段:{timeSeries.includes('0') ? <TimeSeriesLook timeSeries={timeSeries} /> : '全天'}</p>
  74. <p>首日开始时间:{firstDayBeginTime ? firstDayBeginTime : '关闭'}</p>
  75. <p>自动衍生创意:{autoDerivedCreativeEnabled ? '系统衍生' : '关闭衍生'}</p>
  76. <p>广告名称:{adgroupName}</p>
  77. </> : <div className={style.ad_config}>
  78. {accountCreateLogs?.length > 0 ?
  79. <div className={style.ad_config_item} onClick={() => setNewVisible(true)}>新建广告</div>
  80. :
  81. <div className={style.ad_config_item} style={{ backgroundColor: '#FFF' }}>请完善媒体账户信息</div>
  82. }
  83. </div>}
  84. </div>
  85. <div className={style.detail_footer}>
  86. {(adgroups && Object.keys(adgroups).length > 0) ? <>
  87. <Button type="link" icon={<EditOutlined />} style={{ padding: 0, fontSize: 12 }} onClick={() => setNewVisible(true)}>编辑</Button>
  88. </> : <></>}
  89. </div>
  90. </div>
  91. </div>
  92. {/* 新建广告 */}
  93. {newVisible && <NewCreateAd
  94. putInType={putInType}
  95. value={addelivery.adgroups}
  96. visible={newVisible}
  97. onClose={() => {
  98. setNewVisible(false)
  99. }}
  100. onChange={(adgroups) => {
  101. if (
  102. adgroups.marketingGoal === marketingGoal && // 营销内容
  103. adgroups.marketingCarrierType === marketingCarrierType && // 营销载体
  104. adgroups.marketingAssetOuterSpec.marketingTargetType === marketingAssetOuterSpec.marketingTargetType && // 推广产品
  105. adgroups.automaticSiteEnabled === automaticSiteEnabled && // 版位选择
  106. arraysHaveSameValues(adgroups?.siteSet || [], siteSet || []) && // 版位
  107. arraysHaveSameValues(adgroups?.sceneSpec?.wechatPosition || [], sceneSpec?.wechatPosition || []) // 微信公众号与小程序定投
  108. ) {
  109. if (adgroups?.isConversion !== isConversion || ((isConversion || adgroups?.isConversion) && adgroups?.depthConversionEnabled !== depthConversionEnabled)) {
  110. setAccountCreateLogs(accountCreateLogs.map(item => {
  111. delete item?.newConversionList
  112. delete item?.userActionSetsList
  113. return item
  114. }))
  115. }
  116. setNewVisible(false)
  117. setAddelivery({ ...addelivery, adgroups })
  118. clearData()
  119. } else {
  120. setAccountCreateLogs(accountCreateLogs.map(item => ({ accountId: item.accountId })))
  121. if (
  122. addelivery?.adgroups && Object.keys(addelivery?.adgroups).length &&
  123. ((addelivery?.dynamic && Object.keys(addelivery?.dynamic).length)
  124. || addelivery?.targeting?.length
  125. || (addelivery?.dynamicMaterialDTos && Object.keys(addelivery?.dynamicMaterialDTos).length)
  126. || (addelivery?.dynamicCreativesTextDTOS && Object.keys(addelivery?.dynamicCreativesTextDTOS).length)
  127. )
  128. ) {
  129. Modal.confirm({
  130. title: <strong style={{ color: '#FAAD14' }}>注意</strong>,
  131. content: <span>当前改变了“营销内容”、“营销载体”、“推广产品”、“版位选择”、“版位”、“微信公众号与小程序定投”中的某些内容,不清空后面内容可能会导致当前“定向”、“创意”、“素材”等一些内容不匹配,<span style={{ color: 'red' }}>是否清空内容</span></span>,
  132. okText: '清空',
  133. cancelText: '不清空',
  134. keyboard: false,
  135. onOk() { // 清空
  136. setNewVisible(false)
  137. setAddelivery({ adgroups, targeting: [], dynamic: {}, dynamicMaterialDTos: {}, dynamicCreativesTextDTOS: {}, mediaType: 0 })
  138. clearData()
  139. },
  140. onCancel() { // 不清空
  141. setNewVisible(false)
  142. setAddelivery({ ...addelivery, adgroups })
  143. clearData()
  144. },
  145. className: 'modalResetCss'
  146. })
  147. } else {
  148. setNewVisible(false)
  149. setAddelivery({ adgroups, targeting: [], dynamic: {}, dynamicMaterialDTos: {}, dynamicCreativesTextDTOS: {}, mediaType: 0 })
  150. clearData()
  151. }
  152. }
  153. }}
  154. />}
  155. </>
  156. }
  157. export default React.memo(Ad)