import TextAideInput from "@/pages/launchSystemV3/components/TextAideInput" import { extractAndFilterBracketsContent, txtLength } from "@/utils/utils" 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" import AddTextS from "./addTextS" import style from '../index.less' import styles from '../Material/index.less' import VideoNews from "@/pages/launchSystemNew/components/newsModal/videoNews" import SelectCopyWriting from "@/pages/launchSystemV3/tencenTasset/copyWriting/selectCopyWriting" 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[] } } /** * 创意文案 * @param param0 * @returns */ const NewText: React.FC = ({ visible, onClose, onChange, value, textData, accountCreateLogs, targetingLength = 1, dynamicMaterialDTos, mediaType, deliveryMode, putInType, adDataGroup }) => { /*************************************/ const [form] = Form.useForm(); const type = Form.useWatch('type', form) const textDto = Form.useWatch('textDto', form) const [textList, setTextList] = useState([]) const [desVisible, setDesVisible] = useState(false) const [addSTitle, setAddStitle] = useState() const [newText, setNewText] = useState<{ description?: string[], title?: string[] }>({}) const [maxNumber, setMaxNumber] = useState(1) const [groupNumber, setGroupNumber] = useState(1) /*************************************/ const handleOk = (values: any) => { console.log(values) const { type, textDto } = values onChange?.({ type, dynamicCreativesTextDetailDTOList: textDto }) } useEffect(() => { if (value && Object.keys(value).length) { const { type, dynamicCreativesTextDetailDTOList } = value form.setFieldsValue({ type, textDto: dynamicCreativesTextDetailDTOList }) } }, [value]) useEffect(() => { if (textData && Object.keys(textData)) { let newText: { description?: string[], title?: string[] } = {} let data = Object.values(textData).map((item: any) => { let content = item.children.content if (item.name === 'description') { newText.description = [''] } else if (item.name === 'title') { newText.title = [''] } return { label: content.description, restriction: content.restriction, value: item.name, required: item.required, arrayProperty: item?.arrayProperty } }) setMaxNumber(data?.[0]?.arrayProperty?.maxNumber) setNewText(newText) if (!(value && Object.keys(value).length)) { form.setFieldsValue({ textDto: [newText] }) } setTextList(data) } }, [textData, value]) // 一一对应显示素材 const showMaterial = (index: number) => { const dynamicGroup = dynamicMaterialDTos?.dynamicGroup if (dynamicGroup && Object.keys(dynamicGroup).length) { let dynamic = dynamicGroup[index] const keys = Object.keys(dynamic) if (deliveryMode === "DELIVERY_MODE_CUSTOMIZE") { return
{(keys.includes('video_id') || keys.includes('short_video1')) ? <>
{dynamic?.cover_id &&
}
: keys.includes('image_id') ? <>
: (keys.includes('image_list') || keys.includes('element_story')) ? <> {dynamic?.[keys.includes('image_list') ? 'image_list' : 'element_story']?.map((item: { url: string | undefined; }, index: undefined) =>
)} : null}
} else { return
{dynamic?.list?.map((item: any, index: number) => { if (Array.isArray(item)) { let length = item.length return
{item.map((l, i) => )}
} else if (item?.url?.includes('mp4') || item?.keyFrameImageUrl) { return
} else { return
} })}
} } return null } const setText = (valList: string[]) => { 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; }); }; const newTextDto = updateTextDto(textDto); if ([1, 0, 5].includes(type)) { form.setFieldsValue({ textDto: newTextDto }) } else if (type === 2) { let diffTextDto: any[] = [] 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 } else { diff = diffCount } diffTextDto = Array(diff).fill('').map((item: { [x: string]: any }) => { if (fieldData?.value) { 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 }) } form.setFieldsValue({ textDto: [...newTextDto, ...diffTextDto] }) } else if ([3, 4].includes(type)) { let diffTextDto: any[] = [] if (len < valListLength) { const diff = Math.ceil((valListLength - len) / groupNumber) diffTextDto = Array(diff).fill('').map((item: { [x: string]: any }) => { if (fieldData?.value) { 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 }) } form.setFieldsValue({ textDto: [...newTextDto, ...diffTextDto] }) } } return 创意文案 {type !== 0 && <> {textList.some(item => item.value === "description") && { setDesVisible(true); setAddStitle(textList.find(item => item.value === "description")?.label) }}>批量添加{textList.find(item => item.value === "description")?.label}} {textList.some(item => item.value === "title") && { setDesVisible(true); setAddStitle(textList.find(item => item.value === "description")?.label) }}>批量添加{textList.find(item => item.value === "description")?.label}} } {textList.some(item => item.value === "description") && <> { setAddStitle(textList.find(item => item.value === "description")?.label) }} onChange={(valList) => { setText(valList) }} /> 每组数量: setGroupNumber(e || 1)} /> } } open={visible} onCancel={onClose} footer={null} width={800} className={`modalResetCss`} bodyStyle={{ padding: '0 0 40px', position: 'relative', borderRadius: '0 0 8px 8px' }} maskClosable={false} >
{ message.error(errorFields?.[0]?.errors?.[0]) }} initialValues={{ type: 0, textDto: [{ description: [''], title: [''] }] }} onFinish={handleOk} > 文案分配规则 {type == 5 && {dynamicMaterialDTos.dynamicGroup.length * accountCreateLogs.length}个文案组} } style={{ marginBottom: 0 }} rules={[{ required: true, message: '请选择文案分配规则!' }]} > { let value = e.target.value let count = dynamicMaterialDTos.dynamicGroup.length let oldtextDto: PULLIN.TextDtoProps[] = JSON.parse(JSON.stringify(textDto)) let length = oldtextDto.length if (value === 0 || (mediaType === 2 && value === 2)) { oldtextDto = [textDto[0] || {}] } else if (value === 1) { if (count > length) { oldtextDto = oldtextDto.concat(Array(count - length).fill(newText || { description: [''] })) } else { oldtextDto = oldtextDto.slice(0, count) } } else if (value === 2) { 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) ? ![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 {item.label} } else { return {item.label} } }) } {(fields, { add, remove }) => (<> {fields.map(({ key, name, ...restField }, num) => ( {type === 1 ? 创意组{num + 1} : type === 0 ? null : 文案组{num + 1}} {type === 1 && showMaterial(num)} } className="cardResetCss" style={{ marginTop: 10, width: '100%' }} key={key} extra={([3, 2, 4].includes(type) && textDto?.length > 1) && remove(name)} > } >
{textList.map(item => { return {(fields, { add, remove }) => <> {fields.map((field, tIndex) => ( {item.label} {textDto?.[num]?.[item.value]?.length > 1 && remove(field.name)}>} } style={{ marginBottom: 0, width: '100%' }} rules={[{ required: item.required, validator: (rule, value) => { if (!value) { return Promise.reject('请输入正确的' + item.label) } else if (!value.match(RegExp(item.restriction.textRestriction.textPattern))) { return Promise.reject('请输入正确的' + item.label) } else if (txtLength(value) > item.restriction.textRestriction.maxLength) { return Promise.reject('请输入正确的' + item.label) } const result = extractAndFilterBracketsContent(value); if (result.extracted.length > 4) { return Promise.reject('表情数量不得超出: 4 个') } return Promise.resolve() } }]} > ))} {deliveryMode === 'DELIVERY_MODE_COMPONENT' && item.arrayProperty?.maxNumber > 1 && textDto?.[num]?.[item.value]?.length < item.arrayProperty?.maxNumber && } } })}
))} {[3, 2, 4].includes(type) && !(mediaType === 2 && type === 2) && !(type === 2 && textDto.length >= dynamicMaterialDTos.dynamicGroup.length) && } )}
{/* 批量添加 */} {desVisible && { setDesVisible(false) setAddStitle(undefined) }} onChange={(value) => { if (value) { let valList = value .split(/\r?\n/) // 按换行符分割字符串 .map(line => line.trim()) // 去除每行的首尾空白 .filter(line => line !== ''); // 过滤掉空行 setText(valList) } setDesVisible(false) setAddStitle(undefined) }} />}
} export default React.memo(NewText)