Przeglądaj źródła

Merge branch 'develop' of http://git.zanxiangnet.com/wjx/ad-manage

wjx 4 miesięcy temu
rodzic
commit
30c39d7e69

+ 1 - 0
src/pages/launchSystemV3/adqv3/ad/index.tsx

@@ -336,6 +336,7 @@ const Ad: React.FC<ADQV3.AdProps> = ({ userId, creativeHandle }) => {
                                 setTactics(value)
                                 addDynamic()
                             }}
+                            adUnitType={useType}
                             userId={userId}
                             putInType={['GAME', 'GAME_IAA'].includes(useType) ? 'GAME' : 'NOVEL'}
                         /></Col>

+ 2 - 1
src/pages/launchSystemV3/tencentAdPutIn/const.ts

@@ -708,7 +708,8 @@ export const TextTypeList = [
 	{ label: '按创意组一一对应', value: 1 },
 	{ label: '文案顺序分配', value: 2 },
 	{ label: '先分配,文案后叉乘', value: 3 },
-	{ label: '文案叉乘打乱后分配', value: 4 }
+	{ label: '文案叉乘打乱后分配', value: 4 },
+	{ label: '先分配,文案后一一对应', value: 5 }
 ]
 
 /** 创意素材替换原生页顶部素材 */

+ 19 - 17
src/pages/launchSystemV3/tencentAdPutIn/create/Material/addMaterial.tsx

@@ -219,6 +219,7 @@ const AddMaterial: React.FC<Props> = ({ creativeTemplateId, materialData, delive
                                     { relation: '=', width: 720, height: 1280 },
                                     { relation: '=', width: 960, height: 334 },
                                     { relation: '=', width: 480, height: 320 },
+                                    { relation: '=', width: 1080, height: 1920 }
                                 ],
                                 fileSize: 400 * 1024
                             }
@@ -360,6 +361,7 @@ const AddMaterial: React.FC<Props> = ({ creativeTemplateId, materialData, delive
                                                                     { relation: '=', width: 720, height: 1280 },
                                                                     { relation: '=', width: 960, height: 334 },
                                                                     { relation: '=', width: 480, height: 320 },
+                                                                    { relation: '=', width: 1080, height: 1920 }
                                                                 ],
                                                                 fileSize: 400 * 1024
                                                             }
@@ -622,9 +624,9 @@ const AddMaterial: React.FC<Props> = ({ creativeTemplateId, materialData, delive
             visible={selectVideoVisible}
             isGroup={materialConfig?.isGroup}
             sliderImgContent={materialConfig.index === 99999 ? undefined :
-                materialConfig.type === 'element_story' ? (dynamicGroup[materialConfig.index] && Object.keys(dynamicGroup[materialConfig.index])?.includes('element_story')) ? dynamicGroup[materialConfig.index]['element_story']?.map((item: any) => ({ oss_url: item.url, id: item.id, materialType: item?.materialType, material_type: selectCloudData.defaultParams.materialType, })) : undefined :
-                    materialConfig.type === 'image_list' ? (dynamicGroup[materialConfig.index] && Object.keys(dynamicGroup[materialConfig.index])?.includes('image_list')) ? dynamicGroup[materialConfig.index]['image_list']?.map((item: any) => ({ oss_url: item.url, id: item.id, materialType: item?.materialType, material_type: selectCloudData.defaultParams.materialType, })) : undefined :
-                        (dynamicGroup[materialConfig.index] && Object.keys(dynamicGroup[materialConfig.index])?.includes(materialConfig.type)) ? [{ oss_url: dynamicGroup[materialConfig.index][materialConfig.type]['url'], id: dynamicGroup[materialConfig.index][materialConfig.type]['id'], material_type: selectCloudData.defaultParams.materialType, materialType: dynamicGroup[materialConfig.index][materialConfig.type]?.['materialType'], key_frame_image_url: dynamicGroup[materialConfig.index][materialConfig.type]?.['keyFrameImageUrl'] }] : undefined
+                materialConfig.type === 'element_story' ? (dynamicGroup[materialConfig.index] && Object.keys(dynamicGroup[materialConfig.index])?.includes('element_story')) ? dynamicGroup[materialConfig.index]['element_story']?.map((item: any) => ({ oss_url: item.url, id: item.id, materialType: item?.materialType, material_type: selectCloudData.defaultParams.materialType, owner_account_id: item?.accountId })) : undefined :
+                    materialConfig.type === 'image_list' ? (dynamicGroup[materialConfig.index] && Object.keys(dynamicGroup[materialConfig.index])?.includes('image_list')) ? dynamicGroup[materialConfig.index]['image_list']?.map((item: any) => ({ oss_url: item.url, id: item.id, materialType: item?.materialType, material_type: selectCloudData.defaultParams.materialType, owner_account_id: item?.accountId })) : undefined :
+                        (dynamicGroup[materialConfig.index] && Object.keys(dynamicGroup[materialConfig.index])?.includes(materialConfig.type)) ? [{ oss_url: dynamicGroup[materialConfig.index][materialConfig.type]['url'], id: dynamicGroup[materialConfig.index][materialConfig.type]['id'], material_type: selectCloudData.defaultParams.materialType, materialType: dynamicGroup[materialConfig.index][materialConfig.type]?.['materialType'], key_frame_image_url: dynamicGroup[materialConfig.index][materialConfig.type]?.['keyFrameImageUrl'], owner_account_id: dynamicGroup[materialConfig.index][materialConfig.type]?.['accountId'] }] : undefined
             }
             onClose={() => {
                 setSelectVideoVisible(false)
@@ -640,9 +642,9 @@ const AddMaterial: React.FC<Props> = ({ creativeTemplateId, materialData, delive
                             } else {
                                 const aContent = content.map((m: any) => {
                                     if (selectCloudData?.defaultParams?.materialType === 'video' && m?.materialType === 1) {
-                                        return { id: m?.id, url: m?.oss_url, materialType: m?.materialType || 0, keyFrameImageUrl: m?.key_frame_image_url, accountId: m?.account_id }
+                                        return { id: m?.id, url: m?.oss_url, materialType: m?.materialType || 0, keyFrameImageUrl: m?.key_frame_image_url, accountId: m?.owner_account_id }
                                     }
-                                    return { id: m?.id, url: m?.oss_url, materialType: m?.materialType || 0, accountId: m?.account_id }
+                                    return { id: m?.id, url: m?.oss_url, materialType: m?.materialType || 0, accountId: m?.owner_account_id }
                                 })
                                 let newDynamicGroup = dynamicGroup?.map((item: any) => {
                                     let oldList = item?.list || []
@@ -669,17 +671,17 @@ const AddMaterial: React.FC<Props> = ({ creativeTemplateId, materialData, delive
                                     if (materialConfig.isGroup) {
                                         oldList = oldList.concat([content.map((m: any) => {
                                             if (selectCloudData?.defaultParams?.materialType === 'video' && m?.materialType === 1) {
-                                                return { id: m?.id, url: m?.oss_url, materialType: m?.materialType || 0, keyFrameImageUrl: m?.key_frame_image_url, accountId: m?.account_id }
+                                                return { id: m?.id, url: m?.oss_url, materialType: m?.materialType || 0, keyFrameImageUrl: m?.key_frame_image_url, accountId: m?.owner_account_id }
                                             }
-                                            return { id: m?.id, url: m?.oss_url, materialType: m?.materialType || 0, accountId: m?.account_id }
+                                            return { id: m?.id, url: m?.oss_url, materialType: m?.materialType || 0, accountId: m?.owner_account_id }
                                         })])
                                         return { list: oldList }
                                     } else {
                                         oldList = oldList.concat(content.map((m: any) => {
                                             if (selectCloudData?.defaultParams?.materialType === 'video' && m?.materialType === 1) {
-                                                return { id: m?.id, url: m?.oss_url, materialType: m?.materialType || 0, keyFrameImageUrl: m?.key_frame_image_url, accountId: m?.account_id }
+                                                return { id: m?.id, url: m?.oss_url, materialType: m?.materialType || 0, keyFrameImageUrl: m?.key_frame_image_url, accountId: m?.owner_account_id }
                                             }
-                                            return { id: m?.id, url: m?.oss_url, materialType: m?.materialType || 0, accountId: m?.account_id }
+                                            return { id: m?.id, url: m?.oss_url, materialType: m?.materialType || 0, accountId: m?.owner_account_id }
                                         }))
                                         return { list: oldList }
                                     }
@@ -691,7 +693,7 @@ const AddMaterial: React.FC<Props> = ({ creativeTemplateId, materialData, delive
                     } else { // 自定义创意
                         if (materialConfig.index === 99999) {
                             if (materialConfig.type === 'image_list' || materialConfig.type === 'element_story') {
-                                let urls = content?.map((item: any) => ({ id: item?.id, url: item?.oss_url, materialType: item?.materialType || 0, accountId: item?.account_id }))
+                                let urls = content?.map((item: any) => ({ id: item?.id, url: item?.oss_url, materialType: item?.materialType || 0, accountId: item?.owner_account_id }))
                                 let max = materialConfig.max
                                 let materialsNew = dynamicGroup.map((item: any) => {
                                     let newItem = item || {}
@@ -739,9 +741,9 @@ const AddMaterial: React.FC<Props> = ({ creativeTemplateId, materialData, delive
                             } else {
                                 let newMaterials = content?.map((item: any) => {
                                     if (["short_video1", 'video_id'].includes(materialConfig.type) && mLength === 2) {
-                                        return { [materialConfig.type]: { url: item?.oss_url, keyFrameImageUrl: item.key_frame_image_url, id: item?.id, materialType: item?.materialType || 0, accountId: item?.account_id }, cover_id: { url: item?.materialType === 1 ? item?.key_frame_image_url : getVideoImgUrl(item?.oss_url), id: null, materialType: item?.materialType || 0, accountId: item?.account_id } }
+                                        return { [materialConfig.type]: { url: item?.oss_url, keyFrameImageUrl: item.key_frame_image_url, id: item?.id, materialType: item?.materialType || 0, accountId: item?.owner_account_id }, cover_id: { url: item?.materialType === 1 ? item?.key_frame_image_url : getVideoImgUrl(item?.oss_url), id: null, materialType: item?.materialType || 0, accountId: item?.owner_account_id } }
                                     }
-                                    return { [materialConfig.type]: { url: item?.oss_url, id: item?.id, materialType: item?.materialType || 0, accountId: item?.account_id } }
+                                    return { [materialConfig.type]: { url: item?.oss_url, id: item?.id, materialType: item?.materialType || 0, accountId: item?.owner_account_id } }
                                 })
                                 if (newMaterials.length > 0) {
                                     if (dynamicGroup?.every((item: any) => !item)) { // 没设置过
@@ -772,14 +774,14 @@ const AddMaterial: React.FC<Props> = ({ creativeTemplateId, materialData, delive
                                 if (materialConfig.index === index) {
                                     if (materialConfig.type === 'image_list' || materialConfig.type === 'element_story') {
                                         if (item) {
-                                            item[materialConfig.type] = content?.map((item: any) => ({ id: item?.id, url: item?.oss_url, materialType: item?.materialType || 0, accountId: item?.account_id }))
+                                            item[materialConfig.type] = content?.map((item: any) => ({ id: item?.id, url: item?.oss_url, materialType: item?.materialType || 0, accountId: item?.owner_account_id }))
                                             return { ...item }
                                         } else {
-                                            return { [materialConfig.type]: content?.map((item: any) => ({ id: item?.id, url: item?.oss_url, materialType: item?.materialType || 0, accountId: item?.account_id })) }
+                                            return { [materialConfig.type]: content?.map((item: any) => ({ id: item?.id, url: item?.oss_url, materialType: item?.materialType || 0, accountId: item?.owner_account_id })) }
                                         }
                                     } else {
                                         if (item) {
-                                            let d: any = { id: content[0]?.id, url: content[0]?.oss_url, materialType: content[0]?.materialType || 0, accountId: content[0]?.account_id }
+                                            let d: any = { id: content[0]?.id, url: content[0]?.oss_url, materialType: content[0]?.materialType || 0, accountId: content[0]?.owner_account_id }
                                             if (["short_video1", 'video_id'].includes(materialConfig.type) && content[0]?.materialType === 1) {
                                                 d.keyFrameImageUrl = content[0]?.key_frame_image_url
                                             }
@@ -787,9 +789,9 @@ const AddMaterial: React.FC<Props> = ({ creativeTemplateId, materialData, delive
                                             return { ...item }
                                         } else {
                                             if (["short_video1", 'video_id'].includes(materialConfig.type) && mLength === 2) {
-                                                return { [materialConfig.type]: { id: content[0]?.id, url: content[0]?.oss_url, keyFrameImageUrl: content[0]?.key_frame_image_url, materialType: content[0]?.materialType || 0, accountId: content[0]?.account_id }, cover_id: { id: null, url: content[0]?.materialType === 1 ? content[0]?.key_frame_image_url : getVideoImgUrl(content[0]?.oss_url), materialType: content[0]?.materialType || 0, accountId: content[0]?.account_id } }
+                                                return { [materialConfig.type]: { id: content[0]?.id, url: content[0]?.oss_url, keyFrameImageUrl: content[0]?.key_frame_image_url, materialType: content[0]?.materialType || 0, accountId: content[0]?.owner_account_id }, cover_id: { id: null, url: content[0]?.materialType === 1 ? content[0]?.key_frame_image_url : getVideoImgUrl(content[0]?.oss_url), materialType: content[0]?.materialType || 0, accountId: content[0]?.owner_account_id } }
                                             }
-                                            return { [materialConfig.type]: { id: content[0]?.id, url: content[0]?.oss_url, materialType: content[0]?.materialType || 0, accountId: content[0]?.account_id } }
+                                            return { [materialConfig.type]: { id: content[0]?.id, url: content[0]?.oss_url, materialType: content[0]?.materialType || 0, accountId: content[0]?.owner_account_id } }
                                         }
                                     }
                                 }

+ 18 - 33
src/pages/launchSystemV3/tencentAdPutIn/create/Material/index.tsx

@@ -13,10 +13,9 @@ const { Title } = Typography;
 const Material: React.FC<{ adData?: any[] }> = ({ adData }) => {
 
     /***************************************/
-    const { materialData, addelivery, setAddelivery, clearData, accountCreateLogs, putInType } = useContext(DispatchAddelivery)!;
-    const { dynamic, dynamicMaterialDTos, mediaType, targeting, adgroups: { marketingAssetOuterSpec, marketingCarrierType }, dynamicCreativesTextDTOS } = addelivery
+    const { materialData, addelivery, setAddelivery, clearData, accountCreateLogs, putInType, adLength } = useContext(DispatchAddelivery)!;
+    const { dynamic, dynamicMaterialDTos, mediaType, adgroups: { marketingAssetOuterSpec, marketingCarrierType }, dynamicCreativesTextDTOS } = addelivery
     const { creativeTemplateId, deliveryMode, dynamicCreativeSwitch } = dynamic
-    const [adLength, setAdLength] = useState<number>(0)
 
     const [newVisible, setNewVisible] = useState<boolean>(false)
     const [mType, setMtype] = useState<string>()
@@ -29,25 +28,6 @@ const Material: React.FC<{ adData?: any[] }> = ({ adData }) => {
         }
     }, [materialData])
 
-    // 获取广告总数
-    useEffect(() => {
-        if (adData && adData?.length > 0) {
-            setAdLength(adData.length)
-        } else if (accountCreateLogs?.length > 0 && marketingAssetOuterSpec?.marketingTargetType) {
-            let adLength = 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 || []
-                }
-                adLength += productList.length * targeting.length
-            })
-            setAdLength(adLength)
-        }
-    }, [accountCreateLogs, marketingAssetOuterSpec, adData])
-
     const handleDisruption = () => {
         let count = dynamicMaterialDTos?.dynamicGroup?.length
         if (count) {
@@ -85,7 +65,7 @@ const Material: React.FC<{ adData?: any[] }> = ({ adData }) => {
             }, []))
             const newDynamicGroup = JSON.parse(JSON.stringify(dynamicMaterialDTos.dynamicGroup)).map((item: { list: any[] }) => {
                 const length = item.list.length
-                return { list: dynamicGroupList.splice(0, length)}
+                return { list: dynamicGroupList.splice(0, length) }
             })
             setAddelivery({
                 ...addelivery,
@@ -224,20 +204,25 @@ const Material: React.FC<{ adData?: any[] }> = ({ adData }) => {
             putInType={putInType}
             accountCreateLogs={accountCreateLogs}
             onChange={({ dynamicMaterialDTos, mediaType }) => {
-                let newAddelivery = { ...addelivery, dynamicMaterialDTos, mediaType }
+                const newAddelivery = { ...addelivery, dynamicMaterialDTos, mediaType }
                 if (addelivery.mediaType !== mediaType && mediaType !== 1 && addelivery.dynamicCreativesTextDTOS?.type === 4) {
                     newAddelivery.dynamicCreativesTextDTOS = {}
                 }
-                if (newAddelivery.dynamicCreativesTextDTOS && Object.keys(newAddelivery.dynamicCreativesTextDTOS).length && dynamicMaterialDTos.dynamicGroup.length !== addelivery?.dynamicMaterialDTos?.dynamicGroup?.length && addelivery.dynamicCreativesTextDTOS?.type === 1) {
-                    let lengthN = dynamicMaterialDTos.dynamicGroup.length
-                    let lengthO = addelivery.dynamicMaterialDTos.dynamicGroup.length
-                    let diff = lengthN - lengthO
-                    let lengthL = addelivery.dynamicCreativesTextDTOS.dynamicCreativesTextDetailDTOList.length
-                    if (diff > 0) {
-                        newAddelivery.dynamicCreativesTextDTOS.dynamicCreativesTextDetailDTOList = [...newAddelivery.dynamicCreativesTextDTOS.dynamicCreativesTextDetailDTOList, ...Array(diff).fill({})]
-                    } else {
-                        newAddelivery.dynamicCreativesTextDTOS.dynamicCreativesTextDetailDTOList = newAddelivery.dynamicCreativesTextDTOS.dynamicCreativesTextDetailDTOList.splice(0, lengthL + diff)
+                if (newAddelivery.dynamicCreativesTextDTOS && Object.keys(newAddelivery.dynamicCreativesTextDTOS).length && dynamicMaterialDTos.dynamicGroup.length !== addelivery?.dynamicMaterialDTos?.dynamicGroup?.length) {
+                    if (addelivery.dynamicCreativesTextDTOS?.type === 1) {
+                        const lengthN = dynamicMaterialDTos.dynamicGroup.length
+                        const lengthO = addelivery.dynamicMaterialDTos.dynamicGroup.length
+                        const diff = lengthN - lengthO
+                        const lengthL = addelivery.dynamicCreativesTextDTOS.dynamicCreativesTextDetailDTOList.length
+                        if (diff > 0) {
+                            newAddelivery.dynamicCreativesTextDTOS.dynamicCreativesTextDetailDTOList = [...newAddelivery.dynamicCreativesTextDTOS.dynamicCreativesTextDetailDTOList, ...Array(diff).fill({})]
+                        } else {
+                            newAddelivery.dynamicCreativesTextDTOS.dynamicCreativesTextDetailDTOList = newAddelivery.dynamicCreativesTextDTOS.dynamicCreativesTextDetailDTOList.splice(0, lengthL + diff)
+                        }
+                    } else if (addelivery.dynamicCreativesTextDTOS?.type === 5) {
+                        newAddelivery.dynamicCreativesTextDTOS = {}
                     }
+
                 }
                 setAddelivery(newAddelivery)
                 setNewVisible(false)

+ 1 - 1
src/pages/launchSystemV3/tencentAdPutIn/create/MaterialText/addTextS.tsx

@@ -26,7 +26,7 @@ const AddTextS: React.FC<Props> = ({ title, visible, onClose, onChange }) => {
 
     return <Modal
         title={<strong>批量添加{title || '文案'}</strong>}
-        visible={visible}
+        open={visible}
         onCancel={onClose}
         onOk={handleOk}
         className={`modalResetCss`}

+ 6 - 3
src/pages/launchSystemV3/tencentAdPutIn/create/MaterialText/index.tsx

@@ -7,10 +7,10 @@ import NewText from "./newText";
 const { Title, Text } = Typography;
 
 
-const MaterialText: React.FC = () => {
+const MaterialText: React.FC<{ adDataGroup?: { [x: number]: any[] } }> = ({ adDataGroup }) => {
 
     /*************************************/
-    const { textData, addelivery, setAddelivery, clearData, putInType } = useContext(DispatchAddelivery)!;
+    const { textData, addelivery, setAddelivery, clearData, putInType, accountCreateLogs } = useContext(DispatchAddelivery)!;
     const { dynamic, dynamicCreativesTextDTOS, dynamicMaterialDTos, mediaType } = addelivery
 
     const [addVisible, setAddVisible] = useState<boolean>(false)
@@ -39,7 +39,7 @@ const MaterialText: React.FC = () => {
         </div>
         <div className={style.detail}>
             <div className={style.detail_body}>
-                <Title level={5} style={{ fontSize: 12 }} ellipsis>{dynamicCreativesTextDTOS?.type === 0 ? '全部相同' : dynamicCreativesTextDTOS?.type === 1 ? '按创意组一一对应' : dynamicCreativesTextDTOS?.type === 2 ? '按文案顺序分配' : dynamicCreativesTextDTOS?.type === 3 ? '先分配创意组,文案后叉乘': dynamicCreativesTextDTOS?.type === 4 ? '创意组和文案叉乘打乱后分配' : null}</Title>
+                <Title level={5} style={{ fontSize: 12 }} ellipsis>{dynamicCreativesTextDTOS?.type === 0 ? '全部相同' : dynamicCreativesTextDTOS?.type === 1 ? '按创意组一一对应' : dynamicCreativesTextDTOS?.type === 2 ? '按文案顺序分配' : dynamicCreativesTextDTOS?.type === 3 ? '先分配创意组,文案后叉乘' : dynamicCreativesTextDTOS?.type === 4 ? '创意组和文案叉乘打乱后分配' : dynamicCreativesTextDTOS?.type === 5 ? '创意组和广告分配后与文案一一对应' : null}</Title>
                 {dynamicCreativesTextDTOS?.dynamicCreativesTextDetailDTOList?.map((item: { [x: string]: (boolean | React.ReactPortal | null | undefined)[]; }, index: number) => {
                     if (item) {
                         let keys = Object.keys(item)
@@ -68,10 +68,13 @@ const MaterialText: React.FC = () => {
             value={dynamicCreativesTextDTOS}
             dynamicMaterialDTos={dynamicMaterialDTos}
             mediaType={mediaType}
+            accountCreateLogs={accountCreateLogs}
+            targetingLength={addelivery?.targeting?.length}
             textData={textData}
             visible={addVisible}
             putInType={putInType}
             deliveryMode={dynamic?.deliveryMode}
+            adDataGroup={adDataGroup}
             onClose={() => {
                 setAddVisible(false)
             }}

+ 96 - 59
src/pages/launchSystemV3/tencentAdPutIn/create/MaterialText/newText.tsx

@@ -1,6 +1,6 @@
 import TextAideInput from "@/pages/launchSystemV3/components/TextAideInput"
 import { extractAndFilterBracketsContent, txtLength } from "@/utils/utils"
-import { Button, Card, Form, InputNumber, Modal, Popconfirm, Radio, Space, message } from "antd"
+import { Button, Card, Form, InputNumber, Modal, Popconfirm, Radio, Space, Tooltip, message } from "antd"
 import React, { useEffect, useState } from "react"
 import { TextTypeList } from "../../const"
 import { DeleteOutlined, MinusCircleOutlined, PlusOutlined } from "@ant-design/icons"
@@ -14,12 +14,15 @@ interface Props {
     textData: any,
     dynamicMaterialDTos: any,
     mediaType: 0 | 1 | 2 | 3,
+    accountCreateLogs: PULLIN.AccountCreateLogsProps[]
+    targetingLength?: number
     deliveryMode?: string,
     value?: any,
     visible?: boolean
     onClose?: () => void
     onChange?: (value: any) => void
     putInType?: 'NOVEL' | 'GAME'
+    adDataGroup?: { [x: number]: any[] }
 }
 
 /**
@@ -27,7 +30,7 @@ interface Props {
  * @param param0 
  * @returns 
  */
-const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData, dynamicMaterialDTos, mediaType, deliveryMode, putInType }) => {
+const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData, accountCreateLogs, targetingLength = 1, dynamicMaterialDTos, mediaType, deliveryMode, putInType, adDataGroup }) => {
 
     /*************************************/
     const [form] = Form.useForm();
@@ -131,49 +134,53 @@ const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData,
     }
 
     const setText = (valList: string[]) => {
-        let fieldData = textList.find(item => item.label === addSTitle)
-        let count = dynamicMaterialDTos.dynamicGroup.length
-        if (type === 1 || type === 0) {
-            let len = 0
-            const newTextDto = textDto.map((item: { [x: string]: any }) => {
-                if (fieldData?.value && (item?.[fieldData?.value]?.length === 0 || !item?.[fieldData?.value]?.every((t: string) => t)) && valList.length >= len + 1) {
-                    return {
-                        ...item,
-                        [fieldData.value]: (item?.[fieldData?.value]?.length === 0 ? [''] : item?.[fieldData?.value]).map((t: string) => {
-                            if (t) {
-                                return t
-                            } else {
-                                return valList[len++]
+        const fieldData = textList.find(item => item.label === addSTitle)
+        const count = dynamicMaterialDTos.dynamicGroup.length
+        const valListLength = valList.length
+        let len = 0;
+
+        // 定义一个更新 textDto 的通用函数  
+        const updateTextDto = (textDto: any[]) => {
+            return textDto.map((item: { [key: string]: any }) => {
+                if (fieldData?.value && (item?.[fieldData.value]?.length === 0 || item?.[fieldData.value]?.length < groupNumber || !item?.[fieldData.value]?.every((t: string) => t)) && valListLength >= len + 1) {
+                    const textDto: string[] = (item?.[fieldData.value]?.length === 0 ? [''] : item?.[fieldData.value]).map((t: string) => {
+                        if (t) {
+                            return t;
+                        } else if (valListLength >= len + 1) {
+                            return valList[len++];
+                        }
+                        return t;
+                    });
+                    if (textDto.length < groupNumber && valListLength >= len + 1) {
+                        const diff = groupNumber - textDto.length;
+                        Array(diff).fill('').some(() => {
+                            if (valListLength >= len + 1) {
+                                textDto.push(valList[len++]);
+                                return false;
                             }
-                        })
+                            return true;
+                        });
                     }
+                    return {
+                        ...item,
+                        [fieldData.value]: textDto,
+                    };
                 }
-                return item
-            })
+                return item;
+            });
+        };
+
+        const newTextDto = updateTextDto(textDto);  
+
+        if ([1, 0, 5].includes(type)) {
             form.setFieldsValue({
                 textDto: newTextDto
             })
         } else if (type === 2) {
-            let len = 0
-            const newTextDto = textDto.map((item: { [x: string]: any }) => {
-                if (fieldData?.value && (item?.[fieldData?.value]?.length === 0 || !item?.[fieldData?.value]?.every((t: string) => t)) && valList.length >= len + 1) {
-                    return {
-                        ...item,
-                        [fieldData.value]: (item?.[fieldData?.value]?.length === 0 ? [''] : item?.[fieldData?.value]).map((t: string) => {
-                            if (t) {
-                                return t
-                            } else {
-                                return valList[len++]
-                            }
-                        })
-                    }
-                }
-                return item
-            })
             let diffTextDto: any[] = []
-            if (newTextDto.length < count && len < valList.length) {
-                let diffCount = count - newTextDto.length
-                let diffTextCount = valList.length - len
+            if (newTextDto.length < count && len < valListLength) {
+                const diffCount = count - newTextDto.length
+                const diffTextCount = Math.ceil((valListLength - len) / groupNumber)
                 let diff = 0
                 if (diffCount >= diffTextCount) {
                     diff = diffTextCount
@@ -182,7 +189,16 @@ const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData,
                 }
                 diffTextDto = Array(diff).fill('').map((item: { [x: string]: any }) => {
                     if (fieldData?.value) {
-                        return { ...item, [fieldData.value]: [valList[len++]] }
+                        const textDto: string[] = []
+                        Array(groupNumber).fill('').some(() => {
+                            if (valListLength >= len + 1) {
+                                textDto.push(valList[len++])
+                                return false
+                            } else {
+                                return true
+                            }
+                        })
+                        return { ...item, [fieldData.value]: textDto }
                     }
                     return item
                 })
@@ -191,27 +207,21 @@ const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData,
                 textDto: [...newTextDto, ...diffTextDto]
             })
         } else if ([3, 4].includes(type)) {
-            let len = 0
-            const newTextDto = textDto.map((item: { [x: string]: any }) => {
-                if (fieldData?.value && (item?.[fieldData?.value]?.length === 0 || !item?.[fieldData?.value]?.every((t: string) => t)) && valList.length >= len + 1) {
-                    return {
-                        ...item, [fieldData.value]: (item?.[fieldData?.value]?.length === 0 ? [''] : item?.[fieldData?.value]).map((t: string) => {
-                            if (t) {
-                                return t
-                            } else {
-                                return valList[len++]
-                            }
-                        })
-                    }
-                }
-                return item
-            })
             let diffTextDto: any[] = []
-            if (len < valList.length) {
-                let diff = valList.length - len
+            if (len < valListLength) {
+                const diff = Math.ceil((valListLength - len) / groupNumber)
                 diffTextDto = Array(diff).fill('').map((item: { [x: string]: any }) => {
                     if (fieldData?.value) {
-                        return { ...item, [fieldData.value]: [valList[len++]] }
+                        const textDto: string[] = []
+                        Array(groupNumber).fill('').some(() => {
+                            if (valListLength >= len + 1) {
+                                textDto.push(valList[len++])
+                                return false
+                            } else {
+                                return true
+                            }
+                        })
+                        return { ...item, [fieldData.value]: textDto }
                     }
                     return item
                 })
@@ -238,7 +248,7 @@ const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData,
                         setText(valList)
                     }}
                 />
-                {/* <Space><span style={{ fontSize: 12 }}>每组数量:</span><InputNumber max={maxNumber} size="small" value={groupNumber} onChange={(e) => setGroupNumber(e || 1)} /></Space> */}
+                <Space><span style={{ fontSize: 12 }}>每组数量:</span><InputNumber max={maxNumber} size="small" value={groupNumber} onChange={(e) => setGroupNumber(e || 1)} /></Space>
             </>}
         </Space>}
         open={visible}
@@ -270,7 +280,15 @@ const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData,
             onFinish={handleOk}
         >
             <Card className="cardResetCss" style={{ marginTop: 10 }}>
-                <Form.Item name="type" label={<strong>文案分配规则</strong>} style={{ marginBottom: 0 }} rules={[{ required: true, message: '请选择文案分配规则!' }]}>
+                <Form.Item
+                    name="type"
+                    label={<Space>
+                        <strong>文案分配规则</strong>
+                        {type == 5 && <span style={{ fontSize: 12 }}>共<span style={{ color: 'red' }}>{dynamicMaterialDTos.dynamicGroup.length * accountCreateLogs.length}</span>个文案组</span>}
+                    </Space>}
+                    style={{ marginBottom: 0 }}
+                    rules={[{ required: true, message: '请选择文案分配规则!' }]}
+                >
                     <Radio.Group onChange={(e) => {
                         let value = e.target.value
                         let count = dynamicMaterialDTos.dynamicGroup.length
@@ -288,10 +306,29 @@ const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData,
                             if (count < length) {
                                 oldtextDto = oldtextDto.slice(0, count)
                             }
+                        } else if (value === 5) {
+                            // 创意组数量 count 广告账号数量 adLength / targetingLength 所有创意数量  count * (adLength / targetingLength)
+                            const allDynCount = count * accountCreateLogs.length
+                            if (allDynCount > length) {
+                                oldtextDto = oldtextDto.concat(Array(allDynCount - length).fill(newText || { description: [''] }))
+                            } else {
+                                oldtextDto = oldtextDto.slice(0, allDynCount)
+                            }
                         }
                         form.setFieldsValue({ textDto: oldtextDto })
                     }}>
-                        {TextTypeList.filter(item => (mediaType !== 1 && mediaType !== 3) ? item.value !== 4 : true).map(item => <Radio value={item.value} key={item.value}>{item.label}</Radio>)}
+                        {TextTypeList
+                            .filter(item => (mediaType !== 1 && mediaType !== 3) ? ![4, 5].includes(item.value) : mediaType === 3 ? true : item.value !== 5)
+                            .map(item => {
+                                if (item.value === 5 && adDataGroup ? Object.keys(adDataGroup).some((key: any) => adDataGroup[key].length > dynamicMaterialDTos.dynamicGroup.length) : accountCreateLogs.some((pre) => ((pre?.productList || [{}]).length * targetingLength) > dynamicMaterialDTos.dynamicGroup.length)) {
+                                    return <Radio value={item.value} key={item.value} disabled><Tooltip title={'账号下平均分配到广告下的创意组数量不够,不能选择此项'}>
+                                        {item.label}
+                                    </Tooltip></Radio>
+                                } else {
+                                    return <Radio value={item.value} key={item.value}>{item.label}</Radio>
+                                }
+                            })
+                        }
                     </Radio.Group>
                 </Form.Item>
             </Card>

+ 3 - 2
src/pages/launchSystemV3/tencentAdPutIn/create/TacticsS/userTactics.tsx

@@ -9,6 +9,7 @@ import '../../index.less'
 interface Props {
     userId: number
     type: string,
+    adUnitType?: string
     putInType?: 'NOVEL' | 'GAME'
     onChange?: (value: any) => void
 }
@@ -16,7 +17,7 @@ interface Props {
  * 使用策略组
  * @returns 
  */
-const UserTactics: React.FC<Props> = ({ onChange, type, userId, putInType }) => {
+const UserTactics: React.FC<Props> = ({ onChange, type, userId, putInType, adUnitType }) => {
 
     /***********************/
     const [visible, setVisible] = useState<boolean>(false)
@@ -47,7 +48,7 @@ const UserTactics: React.FC<Props> = ({ onChange, type, userId, putInType }) =>
             const hide = message.loading('正在检测广告是否被删除...', 0)
             let { strategyValue } = selectedRowKeys[0]
             let { adData } = JSON.parse(strategyValue)
-            getAdqV3AdList.run({ pageNum: 1, pageSize: 100, useType: 1, userId, adgroupIdList: adData.map((item: { adgroupId: any; }) => item.adgroupId) }).then(res => {
+            getAdqV3AdList.run({ pageNum: 1, pageSize: 100, useType: 1, userId, adgroupIdList: adData.map((item: { adgroupId: any; }) => item.adgroupId), adUnitType }).then(res => {
                 if (res?.data) {
                     if (res.data?.records?.every((item: { isDeleted: boolean }) => !item.isDeleted)) {
                         onChange?.(selectedRowKeys[0])

+ 1 - 0
src/pages/launchSystemV3/tencentAdPutIn/create/Target/index.tsx

@@ -96,6 +96,7 @@ const Target: React.FC = () => {
                 let currentTarget = targeting?.filter((item: { id: any }) => !item?.id) || []
                 setAddelivery({ ...addelivery, targeting: [...target, ...currentTarget] })
                 setAddVisible(false)
+                clearData()
             }}
         />}
 

+ 19 - 4
src/pages/launchSystemV3/tencentAdPutIn/create/addDynamic.tsx

@@ -38,6 +38,7 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
     const [activeKey, setActiveKey] = useState<string>()
     const [dynamicCount, setDynamicCount] = useState<number>(0)
     const [adData, setAdData] = useState<any[]>(selectData)
+    const [adLength, setAdLength] = useState<number>(0)
     const [adDataGroup, setAdDataGroup] = useState<{ [x: number]: any[] }>({})
     const [creativeTemplateAppellation, setCreativeTemplateAppellation] = useState<string>()
     const [creativeTemplateStyle, setCreativeTemplateStyle] = useState<string>()
@@ -46,6 +47,13 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
     const createDynamicTask = useAjax((params) => createDynamicTaskApi(params))
     /****************************************/
 
+    // 获取广告总数
+    useEffect(() => {
+        if (adData && adData?.length > 0) {
+            setAdLength(adData.length)
+        }
+    }, [adData])
+
     useEffect(() => {
         if (creativeTemplateId) {
             let params: any = {
@@ -250,6 +258,11 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
             })) {
                 return
             }
+        } else if (textType === 5) {
+            if (dynamicGroupLength * accountCreateLogs.length !== textDtoLenth) {
+                message.error(`创意文案配置错误,内容数量和所有创意数量对不上,所有创意数量:${dynamicGroupLength * accountCreateLogs.length},文案数量:${textDtoLenth}`)
+                return
+            }
         }
 
         if (textType === 1) {
@@ -263,7 +276,7 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
             }
         }
 
-        let accountIndex1 = 0
+        let accountIndex1 = 0, accountIndex2 = 0
         if (dynamic?.landingPageType === 1 && [910].includes(dynamic.creativeTemplateId)) {
             accountCreateLogs.forEach(item => {
                 let adData = adDataGroup[item.accountId]
@@ -354,8 +367,9 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
                                             ...ad,
                                             id: ad.id + '_' + index,
                                             dynamicGroup: aad,
-                                            textDto: textType === 2 ? textDto?.[index % textDtoLenth] : aad?.textDto
+                                            textDto: textType === 2 ? textDto?.[index % textDtoLenth] : textType === 5 ? textDto?.[accountIndex2] : aad?.textDto
                                         })
+                                        accountIndex2 += 1
                                     })
                                 }
                             })
@@ -627,7 +641,8 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
                                     textData,
                                     setTextData,
                                     clearData,
-                                    putInType
+                                    putInType,
+                                    adLength
                                 }}>
                                 <div className={style.settingsBody_content_right}>
                                     <div className={`${style.settingsBody_content_row} ${style.row1}`}>
@@ -660,7 +675,7 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
                                 </div>
                                 <div className={style.settingsBody_content_left}>
                                     {/* 创意文案 */}
-                                    <MaterialText />
+                                    <MaterialText adDataGroup={adDataGroup} />
                                     {/* 落地页 */}
                                     <PageList adDataGroup={adDataGroup} />
                                 </div>

+ 39 - 4
src/pages/launchSystemV3/tencentAdPutIn/create/index.tsx

@@ -55,6 +55,7 @@ const Create: React.FC = () => {
     const [activeKey, setActiveKey] = useState<string>()
     const [subVisible, setSubVisible] = useState<boolean>(false) // 选择设置名称弹窗控制
     const [adCount, setAdCount] = useState<number>(0)
+    const [adLength, setAdLength] = useState<number>(0)
     const [dynamicCount, setDynamicCount] = useState<number>(0)
     const [creativeTemplateAppellation, setCreativeTemplateAppellation] = useState<string>()
     const [creativeTemplateStyle, setCreativeTemplateStyle] = useState<string>()
@@ -130,6 +131,26 @@ const Create: React.FC = () => {
         }
     }, [creativeTemplateId, deliveryMode, dynamicCreativeSwitch, marketingGoal, marketingAssetOuterSpec, marketingCarrierType, siteSet, sceneSpec?.wechatPosition, automaticSiteEnabled, putInType])
 
+
+    // 获取广告总数
+    useEffect(() => {
+        if (accountCreateLogs?.length > 0 && marketingAssetOuterSpec?.marketingTargetType && addelivery?.targeting?.length) {
+            let adLength = 0
+            accountCreateLogs.forEach(item => {
+                let productList: any[] = []
+                if (['MARKETING_TARGET_TYPE_FICTION', 'MARKETING_TARGET_TYPE_SHORT_DRAMA'].includes(marketingAssetOuterSpec?.marketingTargetType)) { // 小说
+                    productList = item?.productList || []
+                } else if (['MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT'].includes(marketingAssetOuterSpec?.marketingTargetType)) { // 公众号
+                    productList = item?.wechatChannelList || []
+                } else {
+                    productList = [{}]
+                }
+                adLength += productList.length * addelivery.targeting.length
+            })
+            setAdLength(adLength)
+        }
+    }, [accountCreateLogs, marketingAssetOuterSpec, addelivery?.targeting])
+
     /** 存为预设 */
     const severBd = () => {
         if (putInType) {
@@ -477,6 +498,11 @@ const Create: React.FC = () => {
                 message.error('创意文案配置错误,内容空')
                 return
             }
+        } else if (textType === 5) {
+            if (dynamicGroupLength * accountCreateLogs.length !== textDtoLenth) {
+                message.error(`创意文案配置错误,内容数量和所有创意数量对不上,所有创意数量:${dynamicGroupLength * accountCreateLogs.length},文案数量:${textDtoLenth}`)
+                return
+            }
         }
         // 落地页平均分配判断数量
         if ([910].includes(dynamic.creativeTemplateId) && dynamic?.landingPageType === 1) {
@@ -494,7 +520,7 @@ const Create: React.FC = () => {
                 return
             }
         }
-        let accountIndex = 0, accountIndex1 = 0
+        let accountIndex = 0, accountIndex1 = 0, accountIndex2 = 0
         accountCreateLogs.forEach(item => {
             let productList: any[] = [{}]
             if (['MARKETING_TARGET_TYPE_FICTION', 'MARKETING_TARGET_TYPE_SHORT_DRAMA'].includes(marketingAssetOuterSpec?.marketingTargetType)) { // 小说
@@ -615,13 +641,14 @@ const Create: React.FC = () => {
                                     ...ad,
                                     id: ad.id + '_' + index,
                                     dynamicGroup: aad,
-                                    textDto: textType === 2 ? textDto?.[index % textDtoLenth] : aad?.textDto,
+                                    textDto: textType === 2 ? textDto?.[index % textDtoLenth] : textType === 5 ? textDto?.[accountIndex2] : aad?.textDto,
                                     adLength: data.length,
                                     ...(mediaType === 3 ? {
                                         rowSpan: index === 0 ? averageAdDynamic.length : 0,
                                         isRowSpan: true
                                     } : {})
                                 })
+                                accountIndex2 += 1
                             })
                         }
                     })
@@ -920,9 +947,16 @@ const Create: React.FC = () => {
                         putInType={putInType}
                         onChange={(e, isClear) => {
                             clearData()
-                            setAccountCreateLogs(e?.map((item: any) => ({ accountId: item.accountId })) || [])
+                            setAccountCreateLogs(e?.map((item: any) => ({ accountId: item.accountId })) || []);
                             if (isClear) {
-                                setAddelivery({ ...addelivery, dynamicMaterialDTos: {} })
+                                const newAddelivery = JSON.parse(JSON.stringify(addelivery))
+                                newAddelivery.dynamicMaterialDTos = {}
+                                newAddelivery.dynamicCreativesTextDTOS = {}
+                                setAddelivery(newAddelivery)
+                            } else if (addelivery?.dynamicCreativesTextDTOS?.type === 5) {
+                                const newAddelivery = JSON.parse(JSON.stringify(addelivery))
+                                newAddelivery.dynamicCreativesTextDTOS = {}
+                                setAddelivery(newAddelivery)
                             }
                         }}
                         dynamicGroup={addelivery?.dynamicMaterialDTos?.dynamicGroup}
@@ -957,6 +991,7 @@ const Create: React.FC = () => {
                                 setTextData,
                                 clearData,
                                 putInType,
+                                adLength
                             }}>
                             <div className={style.settingsBody_content_right}>
                                 {/* 广告信息 */}

+ 2 - 1
src/pages/launchSystemV3/tencentAdPutIn/typings.d.ts

@@ -34,7 +34,8 @@ declare namespace PULLIN {
         clearData: () => void,
         putInType?: 'NOVEL' | 'GAME',
         // 是否可以选择云端素材
-        isSelectRemote?: boolean
+        isSelectRemote?: boolean,
+        adLength: number
     }
     type DataType = { label: string | number, value: any, disabled?: boolean }
     interface FormItemDataProps {