newDynamic.tsx 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. import { Button, Card, Form, Modal, Radio, Space, Spin, message } from "antd"
  2. import React, { useContext, useEffect, useState } from "react"
  3. import '../../index.less'
  4. import { getCreativeDetailsApi, getCreativeTemplateListApi } from "@/services/adqV3/global";
  5. import { useAjax } from "@/Hook/useAjax";
  6. import { DELIVERY_MODE_ENUM, pageSpecFieldConVert } from "../../const";
  7. import New2Radio from "@/pages/launchSystemV3/components/New2Radio";
  8. import New1Radio from "@/pages/launchSystemV3/components/New1Radio";
  9. import { outAdcreativeTemplateIdFun } from "@/pages/launchSystemNew/launchManage/localAd/adenum";
  10. import { DispatchAddelivery } from "..";
  11. import { processData, randomString } from "@/utils/utils";
  12. import CreativeTemplateContent from "./creativeTemplateContent";
  13. import CreativeConversionAssistant from "./creativeConversionAssistant";
  14. import CreativeTemplateSetup from "./creativeTemplateSetup";
  15. export const DispatchDynamic = React.createContext<PULLIN.DynamicReactContent | null>(null);
  16. interface Props {
  17. putInType?: 'NOVEL' | 'GAME'
  18. value?: any,
  19. visible?: boolean
  20. creativeTemplateStyle?: string,
  21. onClose?: () => void
  22. onChange?: (value: any) => void
  23. }
  24. /**
  25. * 创意新建
  26. * @param param0
  27. * @returns
  28. */
  29. const NewDynamic: React.FC<Props> = ({ putInType, value: newValue, visible, onClose, onChange, creativeTemplateStyle: oldCreativeTemplateStyle }) => {
  30. /**********************************/
  31. const { addelivery, setMaterialData, setTextData } = useContext(DispatchAddelivery)!;
  32. const { adgroups } = addelivery
  33. const [form] = Form.useForm();
  34. const creativeTemplateStyle = Form.useWatch('creativeTemplateStyle', form);
  35. const deliveryMode = Form.useWatch('deliveryMode', form);
  36. const [marketingGoalTypeList, setMarketingGoalTypeList] = useState<PULLIN.DataType[]>([])
  37. const [adcreativeTemplateList, setAdcreativeTemplateList] = useState<PULLIN.AdcreativeTemplateList[]>([])
  38. const [creativeComponents, setCreativeComponents] = useState<any>({})
  39. const [isUpdate, setIsUpdate] = useState<boolean>(false)
  40. const { marketingGoal, marketingAssetOuterSpec, marketingCarrierType, siteSet, sceneSpec, automaticSiteEnabled, marketingSubGoal } = adgroups
  41. const [newMaterialData, setNewMaterialData] = useState<any>({}) // 素材数据
  42. const [newTextData, setNewTextData] = useState<any>({})
  43. const [value, setValue] = useState<any>(newValue)
  44. const [isJustEntered, setIsJustEntered] = useState<boolean>(true)
  45. const getCreativeTemplateList = useAjax((params) => getCreativeTemplateListApi(params))
  46. const getCreativeDetails = useAjax((params) => getCreativeDetailsApi(params))
  47. /**********************************/
  48. useEffect(() => {
  49. if (deliveryMode === 'DELIVERY_MODE_CUSTOMIZE') { // 自定义创意
  50. let params: any = {
  51. marketingGoal,
  52. marketingTargetType: marketingAssetOuterSpec.marketingTargetType,
  53. marketingCarrierType,
  54. siteSet,
  55. wechatSceneSpecPosition: sceneSpec?.wechatPosition || [],
  56. taskType: putInType
  57. }
  58. if (putInType === 'GAME') {
  59. params.marketingSubGoal = marketingSubGoal
  60. }
  61. getCreativeTemplateList.run(params).then((res: any) => {
  62. let newArr: any = []
  63. let newData: any[] = []
  64. // 过滤掉相同的和即将下线的
  65. if (!res) {
  66. return
  67. }
  68. if (automaticSiteEnabled) {
  69. delete res?.SITE_SET_WECHAT
  70. }
  71. let creativeTemplateStyle = ''
  72. Object.values(res)?.forEach(arr => {
  73. newData.push(arr)
  74. if (Array.isArray(arr)) {
  75. arr?.forEach((item: any) => {
  76. let adcreativeTemplateListStructAdpermit = item?.adcreativeTemplateListStructAdpermit
  77. if (adcreativeTemplateListStructAdpermit) {
  78. creativeTemplateStyle += adcreativeTemplateListStructAdpermit?.creativeTemplateStyle
  79. let creativeTemplateId = adcreativeTemplateListStructAdpermit.creativeTemplateId
  80. if (newArr.length > 0) {//假如已存在ID,需要过滤相同
  81. if (outAdcreativeTemplateIdFun(creativeTemplateId) && newArr.every((i: { creativeTemplateId: any }) => i.creativeTemplateId !== creativeTemplateId)) {//不重复的添加
  82. newArr.push(adcreativeTemplateListStructAdpermit)
  83. }
  84. } else {//不存在ID直接过滤掉即将下线的
  85. if (outAdcreativeTemplateIdFun(creativeTemplateId)) {
  86. newArr.push(adcreativeTemplateListStructAdpermit)
  87. }
  88. }
  89. }
  90. })
  91. }
  92. })
  93. /*****暂时排除激励和banner有问题******/
  94. if (!siteSet || siteSet.some((i: string) => i === 'SITE_SET_MOMENTS')) {
  95. newArr = newArr.filter((item: { creativeTemplateId: number }) => ![2107, 2109].includes(item.creativeTemplateId))
  96. }
  97. /*****暂时排除出框形态 视频合约广告******/
  98. if (!siteSet || siteSet.some((i: string) => i === 'SITE_SET_WECHAT')) {
  99. newArr = newArr.filter((item: { creativeTemplateId: number }) => item.creativeTemplateId !== 1945)
  100. }
  101. newArr = newArr.filter((item: { creativeTemplateId: number }) => ![713, 727, 951, 965].includes(item.creativeTemplateId))
  102. let newArr1: any[] = []
  103. let newArr2: any[] = []
  104. newArr?.forEach((arr: { creativeTemplateId: any, creativeTemplateAppellation: string, creativeSampleImage: string, isGeneral?: boolean }) => {
  105. let arr2 = { label: arr.creativeTemplateAppellation, value: arr.creativeTemplateId, img: arr.creativeSampleImage, ...arr }
  106. if (newData.every((item: any[]) => item.find(i => i?.adcreativeTemplateListStructAdpermit?.creativeTemplateId === arr.creativeTemplateId))) {
  107. newArr1.push({ ...arr2, isGeneral: true })
  108. } else {
  109. newArr2.push(arr2)
  110. }
  111. })
  112. setAdcreativeTemplateList([...newArr1, ...newArr2])
  113. let goalTypeData: PULLIN.DataType[] = []
  114. if (creativeTemplateStyle.includes('视频')) {
  115. goalTypeData.push({ label: '视频', value: 'video' })
  116. }
  117. if (creativeTemplateStyle.includes('图片')) {
  118. goalTypeData.push({ label: '图片', value: 'image' })
  119. }
  120. setMarketingGoalTypeList(goalTypeData)
  121. if (value && Object.keys(value).length > 0) {
  122. getTemplate(value.creativeTemplateId)
  123. form.setFieldsValue({ creativeTemplateStyle: oldCreativeTemplateStyle === '视频' ? 'video' : 'image' })
  124. } else {
  125. form.setFieldsValue({ creativeTemplateStyle: creativeTemplateStyle.includes('视频') ? 'video' : 'image' })
  126. }
  127. })
  128. } else if (deliveryMode === 'DELIVERY_MODE_COMPONENT') { // 组件化创意
  129. getTemplate()
  130. }
  131. }, [deliveryMode, marketingGoal, marketingAssetOuterSpec, marketingCarrierType, siteSet, sceneSpec?.wechatPosition, value, automaticSiteEnabled, putInType])
  132. useEffect(() => {
  133. if (!(value && Object.keys(value).length > 0) && adcreativeTemplateList?.length > 0 && marketingGoalTypeList?.length > 0) {
  134. typeChange(marketingGoalTypeList.some(item => item.value === 'video') ? '视频' : '图片')
  135. }
  136. }, [value, adcreativeTemplateList, marketingGoalTypeList])
  137. const typeChange = (creativeTemplateStyle: string, isAntTemplateId?: boolean) => {
  138. if (creativeTemplateStyle && adcreativeTemplateList?.length > 0) {
  139. let adcreativeTemplateIdArr = adcreativeTemplateList?.filter(item => item.creativeTemplateStyle === creativeTemplateStyle)
  140. if (adcreativeTemplateIdArr?.length > 0) {
  141. let creativeTemplateId = adcreativeTemplateIdArr[0].creativeTemplateId
  142. getTemplate(creativeTemplateId, isAntTemplateId)
  143. form.setFieldsValue({ creativeTemplateId })
  144. }
  145. }
  146. }
  147. // 获取创意形式详情
  148. const getTemplate = (id?: any, isAntTemplateId?: boolean) => {
  149. // CAMPAIGN_TYPE_NORMAL
  150. if (marketingAssetOuterSpec?.marketingTargetType && deliveryMode) {
  151. let params: any = {
  152. marketingGoal,
  153. marketingTargetType: marketingAssetOuterSpec.marketingTargetType,
  154. marketingCarrierType,
  155. deliveryMode,
  156. creativeTemplateId: id,
  157. wechatSceneSpecPosition: sceneSpec?.wechatPosition,
  158. dynamicCreativeType: deliveryMode === 'DELIVERY_MODE_COMPONENT' ? 'DYNAMIC_CREATIVE_TYPE_PROGRAM' : 'DYNAMIC_CREATIVE_TYPE_COMMON'
  159. }
  160. if (automaticSiteEnabled) {
  161. params.automaticSiteEnabled = automaticSiteEnabled
  162. } else {
  163. params.siteSet = siteSet
  164. }
  165. params.taskType = putInType
  166. if (putInType === 'GAME') {
  167. params.marketingSubGoal = marketingSubGoal
  168. }
  169. getCreativeDetails.run(params).then(res => {
  170. if (res?.adcreativeTemplateStructAdpermits?.length > 0) {
  171. let adcreativeTemplateStructAdpermits = res?.adcreativeTemplateStructAdpermits[0]
  172. templateChange(adcreativeTemplateStructAdpermits, isAntTemplateId)
  173. } else {
  174. message.error({
  175. content: '当前所选营销目的,广告版位下不支持该创意形式。或者无此创意形式权限,请联系相关人员开通白名单',
  176. duration: 10
  177. })
  178. setCreativeComponents({})
  179. }
  180. })
  181. }
  182. }
  183. //每次选中创意设置该展示的界面
  184. const templateChange = (adcreativeTemplateStructAdpermits: any, isAntTemplateId?: boolean) => {
  185. let creativeComponents = adcreativeTemplateStructAdpermits?.creativeComponents || []
  186. let creativeTemplateId = adcreativeTemplateStructAdpermits?.creativeTemplateId
  187. let creativeTemplateAppellation = adcreativeTemplateStructAdpermits?.creativeTemplateAppellation
  188. let result = processData(creativeComponents);
  189. console.log('result-->', result);
  190. if (!result.barrage && true) {
  191. result.barrage = { required: false }
  192. }
  193. setCreativeComponents(result)
  194. let newMaterialData: { [x: string]: any } = {};
  195. let newTextData: { [x: string]: any } = {};
  196. Object.keys(result).forEach(key => {
  197. let data = result[key]
  198. if ((key === 'image_list' || key === 'short_video' || key === 'video' || key === 'image' || key === 'element_story') && data.required) {
  199. newMaterialData[key] = data
  200. } else if (key === 'title' || (data.required && key === 'description')) {
  201. newTextData[key] = data
  202. }
  203. })
  204. setNewMaterialData(newMaterialData)
  205. setNewTextData(newTextData)
  206. if (!(value && Object.keys(value).length > 0) || isAntTemplateId) {
  207. let values: any = {
  208. dynamicCreativeName: creativeTemplateAppellation ? '自定义创意' + '_' + creativeTemplateAppellation + '_' + localStorage.getItem('userId') + '_' + randomString(true, 3, 5) : '动态创意' + '_' + localStorage.getItem('userId') + '_' + randomString(true, 3, 5),
  209. pageSpec: marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' ? [{
  210. pageType: "PAGE_TYPE_WECHAT_MINI_GAME"
  211. }] : [{
  212. pageType: 'PAGE_TYPE_WECHAT_CANVAS',
  213. overrideCanvasHeadOption: 'OPTION_CREATIVE_OVERRIDE_CANVAS'
  214. }],
  215. brand: undefined
  216. }
  217. Object.keys(result).forEach(key => {
  218. switch (key) {
  219. case 'brand':
  220. let brand = result[key]
  221. let page_type = brand.children.page_type
  222. let typeList = ["PAGE_TYPE_WECHAT_OFFICIAL_ACCOUNT_DETAIL", "PAGE_TYPE_H5_PROFILE", "PAGE_TYPE_NOT_USED", "PAGE_TYPE_WECHAT_CHANNELS_PROFILE"]
  223. let enumeration = (page_type.enumProperty.enumeration as { value: string, description: string }[]).filter((item: { value: string; }) => typeList.includes(item.value))
  224. values.jumpInfo = {
  225. pageType: enumeration[0]?.value
  226. }
  227. break
  228. case 'text_link':// 朋友圈文字链
  229. let textLink = result[key]
  230. let linkNameType = textLink?.children?.link_name_type
  231. let linkNameEnumeration = (linkNameType?.enumProperty?.enumeration as { value: string, description: string }[]).map(item => ({ label: item.description, value: item.value }))
  232. values.textLink = {
  233. value: {
  234. linkNameType: linkNameEnumeration?.[0]?.value,
  235. jumpInfo: {
  236. pageType: marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' ? "PAGE_TYPE_WECHAT_MINI_GAME" : 'PAGE_TYPE_WECHAT_CANVAS'
  237. }
  238. }
  239. }
  240. values.textLinkShow = true
  241. break
  242. case 'action_button':
  243. let actionButton = result[key]
  244. let buttonText = actionButton.children.button_text
  245. let butttonTextEnumeration = (buttonText.enumProperty.enumeration as { value: string }[]).map(item => ({ label: item.value, value: item.value }))
  246. values.actionButton = {
  247. value: {
  248. buttonText: butttonTextEnumeration?.[0]?.value,
  249. jumpInfo: {
  250. pageType: marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' ? "PAGE_TYPE_WECHAT_MINI_GAME" : 'PAGE_TYPE_WECHAT_CANVAS'
  251. }
  252. }
  253. }
  254. values.actionButtonShow = true
  255. break
  256. case 'floating_zone':
  257. let floatingZone = result[key]
  258. if (floatingZone?.required) {
  259. let floatingZoneData: any = {
  260. value: {
  261. floatingZoneSwitch: false,
  262. floatingZoneType: 'FLOATING_ZONE_TYPE_IMAGE_TEXT',
  263. floatingZoneButtonText: '了解更多'
  264. }
  265. }
  266. if (floatingZone?.children?.floating_zone_image_id && floatingZone?.children?.floating_zone_button_text) {
  267. floatingZoneData.value.floatingZoneButtonText = floatingZone.children.floating_zone_button_text?.enumProperty?.enumeration[0]?.value
  268. }
  269. floatingZoneData.value.floatingZoneSwitch = true
  270. values.floatingZone = floatingZoneData
  271. }
  272. break
  273. }
  274. })
  275. if ([1707, 1708].includes(creativeTemplateId)) {
  276. delete values?.actionButtonShow
  277. values.cardType = ['not']
  278. }
  279. form.setFieldsValue(values)
  280. setTimeout(() => { setIsUpdate(true) }, 50)
  281. }
  282. }
  283. const handleOk = (values: any) => {
  284. const {
  285. creativeTemplateStyle,
  286. brand,
  287. jumpInfo,
  288. pageSpec,
  289. textLinkShow,
  290. textLink,
  291. actionButtonShow,
  292. cardType,
  293. actionButton,
  294. showDataShow,
  295. showData,
  296. floatingZone,
  297. creativeLabelDTOS,
  298. ...surplusValues
  299. } = values
  300. let dynamicValues: any = {
  301. ...surplusValues,
  302. }
  303. let creativeComponents: any = {}
  304. let actionButtonJumpInfo = {
  305. pageType: undefined
  306. }
  307. if (pageSpec?.length > 0) {
  308. let { pageType } = pageSpec?.[0]
  309. actionButtonJumpInfo.pageType = pageType
  310. creativeComponents.mainJumpInfo = pageSpec.map((item: { pageType: string, overrideCanvasHeadOption: string, }) => {
  311. let pageSpec: { [x: string]: any } = {}
  312. if (item.pageType === "PAGE_TYPE_WECHAT_CANVAS") { // 原生推广页
  313. pageSpec = {
  314. [pageSpecFieldConVert[item.pageType as keyof typeof pageSpecFieldConVert]]: {
  315. pageId: null,
  316. overrideCanvasHeadOption: item.overrideCanvasHeadOption
  317. }
  318. }
  319. } else if (item.pageType === "PAGE_TYPE_OFFICIAL") { // 官方落地页
  320. pageSpec = {
  321. [pageSpecFieldConVert[item.pageType as keyof typeof pageSpecFieldConVert]]: {
  322. pageId: null
  323. }
  324. }
  325. } else if (item.pageType === "PAGE_TYPE_WECHAT_MINI_PROGRAM") { // 微信小程序
  326. pageSpec = {
  327. [pageSpecFieldConVert[item.pageType as keyof typeof pageSpecFieldConVert]]: {
  328. miniProgramId: null,
  329. miniProgramPath: null
  330. }
  331. }
  332. }
  333. return {
  334. value: {
  335. pageType: item.pageType,
  336. pageSpec
  337. }
  338. }
  339. })
  340. }
  341. // 品牌形象
  342. if (jumpInfo) {
  343. let pageType = jumpInfo.pageType
  344. let value: { [x: string]: any } = {
  345. jumpInfo
  346. }
  347. if (['PAGE_TYPE_H5_PROFILE'].includes(pageType)) {
  348. value['profileId'] = brand
  349. } else if (["PAGE_TYPE_NOT_USED"].includes(pageType)) {
  350. let [brandName, brandImageId] = brand.split('_')
  351. value['brandName'] = brandName
  352. value['brandImageId'] = brandImageId
  353. } else {
  354. value['brandName'] = null
  355. value['brandImageId'] = null
  356. }
  357. let pageSpecData: any = {}
  358. if (pageType === 'PAGE_TYPE_H5_PROFILE') {
  359. pageSpecData[pageSpecFieldConVert[pageType as keyof typeof pageSpecFieldConVert]] = {
  360. pageId: null
  361. }
  362. } else if (pageType === 'PAGE_TYPE_H5') {
  363. pageSpecData[pageSpecFieldConVert[pageType as keyof typeof pageSpecFieldConVert]] = {
  364. pageUrl: null,
  365. mpaH5WildcardUrl: null
  366. }
  367. } else if (pageType === 'PAGE_TYPE_WECHAT_OFFICIAL_ACCOUNT_DETAIL') {
  368. pageSpecData[pageSpecFieldConVert[pageType as keyof typeof pageSpecFieldConVert]] = {
  369. appId: null
  370. }
  371. }
  372. value.jumpInfo = {
  373. ...value.jumpInfo,
  374. pageSpec: pageSpecData
  375. }
  376. let length = pageSpec.length
  377. creativeComponents.brand = Array(length).fill('').map(() => ({ value }))
  378. }
  379. // 朋友圈文字链
  380. if (textLinkShow) {
  381. creativeComponents.textLink = [textLink]
  382. }
  383. // 行动按钮
  384. if (actionButton && Object.keys(actionButton).length > 0) {
  385. let newActionButton = [actionButton]
  386. if (!actionButton.value?.jumpInfo) {
  387. newActionButton = [{
  388. ...actionButton,
  389. value: {
  390. ...actionButton.value,
  391. jumpInfo: actionButtonJumpInfo
  392. }
  393. }]
  394. }
  395. creativeComponents.actionButton = newActionButton
  396. }
  397. // 标签
  398. if (creativeLabelDTOS?.length) {
  399. creativeComponents.creativeLabelDTOS = creativeLabelDTOS
  400. }
  401. // 数据外显
  402. if (showDataShow) {
  403. creativeComponents.showData = [showData]
  404. }
  405. if (floatingZone?.value?.floatingZoneSwitch) {
  406. let value = floatingZone.value
  407. let { image, ...val } = value
  408. if (val.floatingZoneType === "FLOATING_ZONE_TYPE_SINGLE_IMAGE") {
  409. delete image?.floatingZoneImageId
  410. delete image?.floatingZoneImageUrl
  411. delete image?.floatingZoneImageMaterialType
  412. } else {
  413. delete image?.floatingZoneSingleImageId
  414. delete image?.floatingZoneSingleImageUrl
  415. delete image?.floatingZoneSingleImageMaterialType
  416. }
  417. creativeComponents.floatingZoneComponent = {
  418. ...val,
  419. ...image
  420. }
  421. }
  422. dynamicValues.creativeComponents = creativeComponents
  423. setMaterialData(newMaterialData)
  424. setTextData(newTextData)
  425. onChange?.(dynamicValues)
  426. }
  427. useEffect(() => {
  428. // 只允许进入一次 锁住
  429. if (!isJustEntered) {
  430. return
  431. }
  432. setIsJustEntered(() => false)
  433. // if (value && Object.keys(value).length > 0 && adcreativeTemplateList?.length > 0 && ((value.deliveryMode === 'DELIVERY_MODE_CUSTOMIZE' && oldCreativeTemplateStyle) || value.deliveryMode === 'DELIVERY_MODE_COMPONENT')) {
  434. if (value && Object.keys(value).length > 0 && ((value.deliveryMode === 'DELIVERY_MODE_CUSTOMIZE' && oldCreativeTemplateStyle) || value.deliveryMode === 'DELIVERY_MODE_COMPONENT')) {
  435. const {
  436. creativeComponents: {
  437. brand,
  438. textLink,
  439. actionButton,
  440. showData,
  441. mainJumpInfo,
  442. floatingZoneComponent,
  443. creativeLabelDTOS
  444. },
  445. ...surplusValues
  446. } = JSON.parse(JSON.stringify(value))
  447. let dynamicValues: any = {
  448. ...surplusValues,
  449. creativeLabelDTOS
  450. }
  451. // if (value.deliveryMode === 'DELIVERY_MODE_CUSTOMIZE') {
  452. // getTemplate(value.creativeTemplateId)
  453. // dynamicValues.creativeTemplateStyle = oldCreativeTemplateStyle === '视频' ? 'video' : 'image'
  454. // }
  455. // else getTemplate()
  456. // 卡片广告
  457. let isCardDynamic = dynamicValues?.creativeTemplateId && [1707, 1708].includes(dynamicValues.creativeTemplateId)
  458. let cardType: string[] = []
  459. // 529 闪屏视频 没有品牌 要单独处理
  460. if (brand && brand?.length > 0) {
  461. let { jumpInfo, brandName, brandImageId, profileId } = brand[0].value
  462. if (jumpInfo) {
  463. let { pageType } = jumpInfo
  464. dynamicValues.jumpInfo = { pageType }
  465. }
  466. if (brandName && brandImageId) {
  467. dynamicValues.brand = brandName + '_' + brandImageId
  468. } else if (profileId) {
  469. dynamicValues.brand = profileId
  470. }
  471. }
  472. if (mainJumpInfo && mainJumpInfo?.length > 0) {
  473. dynamicValues.pageSpec = mainJumpInfo.map((item: any) => {
  474. let { pageSpec, pageType } = item.value
  475. let key = Object.keys(pageSpec)[0]
  476. let pageSpecValue = pageSpec[key]
  477. return { ...pageSpecValue, pageType }
  478. })
  479. }
  480. // 文字链
  481. if (textLink && textLink?.length > 0) {
  482. dynamicValues = {
  483. ...dynamicValues,
  484. textLinkShow: true,
  485. textLink: textLink[0]
  486. }
  487. }
  488. // 行动按钮
  489. if (actionButton && actionButton?.length > 0) {
  490. dynamicValues = {
  491. ...dynamicValues,
  492. actionButtonShow: true,
  493. actionButton: actionButton[0]
  494. }
  495. if (isCardDynamic) {
  496. cardType.push('action_button')
  497. delete dynamicValues.actionButtonShow
  498. }
  499. }
  500. // 数据外显
  501. if (showData && showData?.length > 0) {
  502. dynamicValues = {
  503. ...dynamicValues,
  504. showDataShow: true,
  505. showData: showData[0]
  506. }
  507. }
  508. if (floatingZoneComponent && Object.keys(floatingZoneComponent).length) {
  509. const {
  510. floatingZoneImageId,
  511. floatingZoneImageUrl,
  512. floatingZoneImageMaterialType,
  513. floatingZoneSingleImageId,
  514. floatingZoneSingleImageUrl,
  515. floatingZoneSingleImageMaterialType,
  516. ...val
  517. } = floatingZoneComponent
  518. dynamicValues = {
  519. ...dynamicValues,
  520. floatingZone: {
  521. value: {
  522. image: {
  523. floatingZoneImageId,
  524. floatingZoneImageUrl,
  525. floatingZoneImageMaterialType,
  526. floatingZoneSingleImageId,
  527. floatingZoneSingleImageUrl,
  528. floatingZoneSingleImageMaterialType,
  529. },
  530. ...val
  531. }
  532. }
  533. }
  534. }
  535. if (cardType.length === 0 && isCardDynamic) {
  536. cardType = ['not']
  537. }
  538. dynamicValues.cardType = cardType
  539. form.setFieldsValue({ ...dynamicValues })
  540. } else {
  541. form.setFieldsValue({
  542. deliveryMode: 'DELIVERY_MODE_COMPONENT',
  543. configuredStatus: 'AD_STATUS_NORMAL'
  544. })
  545. }
  546. }, [value, oldCreativeTemplateStyle])
  547. return <Modal
  548. title={<strong style={{ fontSize: 20 }}>创意基本信息</strong>}
  549. open={visible}
  550. onCancel={onClose}
  551. footer={null}
  552. width={900}
  553. className={`modalResetCss`}
  554. bodyStyle={{ padding: '0 0 40px', position: 'relative', borderRadius: '0 0 8px 8px' }}
  555. maskClosable={false}
  556. >
  557. <Form
  558. form={form}
  559. name="newDynamic"
  560. labelAlign='left'
  561. layout="vertical"
  562. colon={false}
  563. style={{ backgroundColor: '#f1f4fc', maxHeight: 650, overflow: 'hidden', overflowY: 'auto', padding: '0 10px 10px', borderRadius: '0 0 8px 8px' }}
  564. scrollToFirstError={{
  565. behavior: 'smooth',
  566. block: 'center'
  567. }}
  568. onFinishFailed={({ errorFields }) => {
  569. message.error(errorFields?.[0]?.errors?.[0])
  570. }}
  571. onFinish={handleOk}
  572. initialValues={{
  573. // deliveryMode: 'DELIVERY_MODE_CUSTOMIZE',
  574. // configuredStatus: 'AD_STATUS_NORMAL'
  575. }}
  576. >
  577. <Spin spinning={getCreativeTemplateList.loading || getCreativeDetails.loading}>
  578. <DispatchDynamic.Provider value={{ form, adgroups, value, creativeComponents, setCreativeComponents, isUpdate, setIsUpdate }}>
  579. <Space direction="vertical" style={{ width: '100%' }}>
  580. {/* 创意形式 */}
  581. <Card
  582. title={<strong style={{ fontSize: 18 }}>创意形式</strong>}
  583. className="cardResetCss"
  584. >
  585. <Form.Item name="deliveryMode" label={<strong>投放模式</strong>} rules={[{ required: true, message: '请选择投放模式!' }]}>
  586. <Radio.Group onChange={() => {
  587. setTimeout(() => { setIsUpdate(true) }, 50)
  588. setValue(undefined)
  589. }}>
  590. {Object.keys(DELIVERY_MODE_ENUM).map(key => <Radio value={key} key={key}>{DELIVERY_MODE_ENUM[key as keyof typeof DELIVERY_MODE_ENUM]}</Radio>)}
  591. </Radio.Group>
  592. </Form.Item>
  593. {deliveryMode === 'DELIVERY_MODE_CUSTOMIZE' && <>
  594. <Form.Item name="creativeTemplateStyle" label={<strong>创意形式类型</strong>} rules={[{ required: true, message: '请选择营销目的!' }]}>
  595. <New1Radio data={marketingGoalTypeList} onChange={(e) => { typeChange(e === 'video' ? '视频' : '图片', true); }} />
  596. </Form.Item>
  597. <Form.Item name="creativeTemplateId" label={<strong>创意形式</strong>} rules={[{ required: true, message: '请选择营销目的!' }]}>
  598. <New2Radio
  599. data={adcreativeTemplateList.filter(item => creativeTemplateStyle === 'video' ? item.creativeTemplateStyle === '视频' : item.creativeTemplateStyle === '图片')}
  600. onChange={(id) => { getTemplate(id, true); }}
  601. />
  602. </Form.Item>
  603. </>}
  604. </Card>
  605. {Object.keys(creativeComponents).length > 0 && <>
  606. {/* 创意内容 */}
  607. <CreativeTemplateContent automaticSiteEnabled={automaticSiteEnabled} putInType={putInType} />
  608. {/* 营销组件 */}
  609. <CreativeConversionAssistant automaticSiteEnabled={automaticSiteEnabled} putInType={putInType} />
  610. {/* 创意设置 */}
  611. <CreativeTemplateSetup />
  612. </>}
  613. </Space>
  614. </DispatchDynamic.Provider>
  615. </Spin>
  616. <Form.Item className="submit_pull">
  617. <Space>
  618. <Button onClick={onClose}>取消</Button>
  619. <Button type="primary" htmlType="submit" className="modalResetCss">
  620. 确定
  621. </Button>
  622. </Space>
  623. </Form.Item>
  624. </Form>
  625. </Modal>
  626. }
  627. export default React.memo(NewDynamic)