Procházet zdrojové kódy

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

wjx před 9 měsíci
rodič
revize
85ee4ac972

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

@@ -40,7 +40,7 @@ const MaterialText: React.FC = () => {
         <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>
-                {dynamicCreativesTextDTOS?.dynamicCreativesTextDetailDTOList?.map((item: { [x: string]: boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | null | undefined; }, index: number) => {
+                {dynamicCreativesTextDTOS?.dynamicCreativesTextDetailDTOList?.map((item: { [x: string]: (boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | null | undefined)[]; }, index: number) => {
                     if (item) {
                         let keys = Object.keys(item)
                         return <div key={index}>
@@ -70,6 +70,7 @@ const MaterialText: React.FC = () => {
             mediaType={mediaType}
             textData={textData}
             visible={addVisible}
+            deliveryMode={dynamic?.deliveryMode}
             onClose={() => {
                 setAddVisible(false)
             }}

+ 65 - 3
src/pages/launchSystemV3/tencentAdPutIn/create/MaterialText/newText.tsx

@@ -5,12 +5,15 @@ import React, { useEffect, useState } from "react"
 import { TextTypeList } from "../../const"
 import { DeleteOutlined, 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"
 
 interface Props {
     textData: any,
     dynamicMaterialDTos: any,
     mediaType: 0 | 1 | 2,
+    deliveryMode?: string,
     value?: any,
     visible?: boolean
     onClose?: () => void
@@ -22,7 +25,7 @@ interface Props {
  * @param param0 
  * @returns 
  */
-const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData, dynamicMaterialDTos, mediaType }) => {
+const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData, dynamicMaterialDTos, mediaType, deliveryMode }) => {
 
     /*************************************/
     const [form] = Form.useForm();
@@ -74,6 +77,62 @@ const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData,
         }
     }, [textData])
 
+    // 一一对应显示素材
+    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") {
+                console.log('--->', keys)
+                return <>
+                    <div className={style.detail_body_m}>
+                        {(keys.includes('video_id') || keys.includes('short_video1')) ? <>
+                            <div className={style.video}>
+                                <VideoNews src={dynamic?.video_id?.url || dynamic?.short_video1?.url} style={{ width: 40, height: 30 }} />
+                                {dynamic?.cover_id && <div className={style.cover_image} style={{ marginLeft: 4, width: 40, height: 30, minWidth: 42 }}>
+                                    <img src={dynamic?.cover_id?.url} style={{ maxWidth: '96%', maxHeight: '96%' }}/>
+                                </div>}
+                            </div>
+                        </> : keys.includes('image_id') ? <>
+                            <div className={style.cover_image} style={{ width: 40, height: 30, minWidth: 42 }}>
+                                <img src={dynamic?.image_id?.url} />
+                            </div>
+                        </> : (keys.includes('image_list') || keys.includes('element_story')) ? <>
+                            {dynamic?.[keys.includes('image_list') ? 'image_list' : 'element_story']?.map((item: { url: string | undefined; }, index: undefined) => <div className={style.cover_image} key={index} style={{ width: 30, height: 24, minWidth: 32 }}>
+                                <img src={item?.url} />
+                            </div>)}
+                        </> : null}
+                    </div>
+                </>
+            } else {
+                return <div style={{ display: 'flex', gap: 5, flexWrap: 'wrap' }}>
+                    {dynamic?.list?.map((item: any, index: number) => {
+                        if (Array.isArray(item)) {
+                            let length = item.length
+                            return <div className={styles.boxList_body_item} key={index} style={{ width: 30, height: 30 }}>
+                                <div className={styles.content} style={{ width: 30, height: 30 }}>
+                                    {item.map((l, i) => <img src={l?.url} key={i} style={{ width: length === 6 ? 9.999 : 14.999 }} />)}
+                                </div>
+                            </div>
+                        } else if (item?.url?.includes('mp4')) {
+                            return <div className={styles.boxList_body_item} key={index} style={{ width: 30, height: 30 }}>
+                                <div className={styles.content} style={{ width: 30, height: 30 }}>
+                                    <VideoNews src={item?.url} style={{ width: 30, height: 30 }} maskBodyStyle={{ backgroundColor: "rgba(242, 246, 254, 0.1)" }} />
+                                </div>
+                            </div>
+                        } else {
+                            return <div className={styles.boxList_body_item} key={index} style={{ width: 30, height: 30 }}>
+                                <div className={styles.content} style={{ width: 30, height: 30 }}><img src={item?.url} /></div>
+                            </div>
+                        }
+                    })}
+                </div>
+            }
+        }
+        return null
+    }
+
     return <Modal
         title={<Space>
             <strong style={{ fontSize: 20 }}>创意文案</strong>
@@ -141,7 +200,10 @@ const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData,
                 {(fields, { add, remove }) => (<>
                     {fields.map(({ key, name, ...restField }, num) => (
                         <Card
-                            title={type === 1 ? <strong style={{ fontSize: 14 }}>创意组{num + 1}</strong> : type === 0 ? null : <strong style={{ fontSize: 14 }}>文案组{num + 1}</strong>}
+                            title={<div style={{ display: 'flex', gap: 5, alignItems: 'center' }}>
+                                {type === 1 ? <strong style={{ fontSize: 14 }}>创意组{num + 1}</strong> : type === 0 ? null : <strong style={{ fontSize: 14 }}>文案组{num + 1}</strong>}
+                                {type === 1 && showMaterial(num)}
+                            </div>}
                             className="cardResetCss"
                             style={{ marginTop: 10, width: '100%' }}
                             key={key}

+ 2 - 2
src/pages/launchSystemV3/tencentAdPutIn/create/tableConfig.tsx

@@ -1,10 +1,10 @@
 import { Space, TableProps, Typography } from "antd"
 import React from "react"
-import { OPTIMIZATIONGOAL_ENUM } from "../const";
 const { Text, Title } = Typography;
 import style from './index.less'
 import VideoNews from "@/pages/launchSystemNew/components/newsModal/videoNews";
 import styles from './Material/index.less'
+import { OPTIMIZATIONGOAL_ENUM } from "../const";
 
 const columns = (): TableProps<any>['columns'] => {
 
@@ -74,7 +74,7 @@ const columns = (): TableProps<any>['columns'] => {
                         let { optimizationGoal, dailyBudget, bidAmount, bidMode } = b?.adgroupsDto
                         return <Space size={0} direction="vertical">
                             <Text style={{ fontSize: 12 }}>广告日预算:{dailyBudget ? dailyBudget + '元/天' : '不限'}</Text>
-                            <Text style={{ fontSize: 12 }}>出价:{bidAmount}元/{optimizationGoal ? OPTIMIZATIONGOAL_ENUM[optimizationGoal] : ['BID_MODE_OCPM', 'BID_MODE_OCPC'].includes(bidMode) ? '千次曝光' : '点击'}</Text>
+                            <Text style={{ fontSize: 12 }}>出价:{bidAmount}元/{optimizationGoal ? (OPTIMIZATIONGOAL_ENUM as any)[optimizationGoal] : ['BID_MODE_OCPM', 'BID_MODE_OCPC'].includes(bidMode) ? '千次曝光' : '点击'}</Text>
                         </Space>
                     },
                     onCell: (record, index = 0) => ({

+ 27 - 6
src/utils/utils.ts

@@ -70,8 +70,29 @@ export const getChannelName = (name: string) => {
   return newName
 }
 
+
+/**
+ * 转正则
+ * @param arr 
+ * @returns 
+ */
+function arrayToRegex(arr: string[]) {
+  // 转义正则表达式中的特殊字符
+  function escapeRegExp(str: string) {
+    return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+  }
+
+  // 将数组中的每个元素用括号包裹,并用 | 连接
+  const regexString = arr.map(item => `(${escapeRegExp(item)})`).join('|');
+
+  // 创建正则表达式
+  const regex = new RegExp(regexString, 'g');
+  return regex;
+}
+
 function extractAndFilterBracketsContent(input: string): { extracted: string[], filteredString: string } {
-  const regex = /\[([^\]]+)\]/g;
+  const arr = ['[微笑]', '[撇嘴]', '[色]', '[发呆]', '[流泪]', '[害羞]', '[睡]', '[大哭]', '[尴尬]', '[发怒]', '[调皮]', '[呲牙]', '[惊讶]', '[难过]', '[冷汗]', '[抓狂]', '[偷笑]', '[愉快]', '[白眼]', '[傲慢]', '[惊恐]', '[流汗]', '[憨笑]', '[奋斗]', '[疑问]', '[晕]', '[衰]', '[敲打]', '[再见]', '[擦汗]', '[鼓掌]', '[坏笑]', '[左哼哼]', '[右哼哼]', '[哈欠]', '[委屈]', '[快哭了]', '[阴险]', '[亲亲]', '[可怜]', '[西瓜]', '[咖啡]', '[猪头]', '[玫瑰]', '[嘴唇]', '[爱心]', '[蛋糕]', '[月亮]', '[太阳]', '[拥抱]', '[强]', '[胜利]', '[握手]', '[抱拳]', '[勾引]', '[拳头]', '[OK]', '[跳跳]', '[发抖]', '[怄火]', '[转圈]', '[嘿哈]', '[捂脸]', '[奸笑]', '[机智]', '[皱眉]', '[耶]', '[加油]', '[汗]', '[天啊]', '[社会社会]', '[旺柴]', '[好的]', '[加油加油]', '[哇]', '[红包]', '[發]', '[福]'];
+  const regex = arrayToRegex(arr);
   const matches: string[] = [];
   let match;
 
@@ -81,7 +102,7 @@ function extractAndFilterBracketsContent(input: string): { extracted: string[],
   }
 
   // 过滤掉原字符串中方括号及其包裹的内容
-  const filteredString = input.replace(/\[([^\]]+)\]/g, '');
+  const filteredString = input.replace(regex, '');
 
   return { extracted: matches, filteredString: filteredString };
 }
@@ -155,7 +176,7 @@ export const copy = (str: string) => {
 
 // 数组分组
 export const groupBy = (array: any[], f: (item: any) => any[]) => {
-  const groups = {};
+  const groups: any = {};
   array.forEach(function (o) { //注意这里必须是forEach 大写
     const group = JSON.stringify(f(o));
     groups[group] = groups[group] || [];
@@ -323,7 +344,7 @@ export const processData = (data: string | any[]) => {
   if (list?.length > 0 && Object.keys(parentData).includes('label')) {
     let l = parentData?.label?.children?.list
     if (l) {
-      let lChildren = {}
+      let lChildren: any = {}
       list.forEach(item => {
         lChildren[item.name] = item
       })
@@ -334,7 +355,7 @@ export const processData = (data: string | any[]) => {
   if (list?.length > 0 && Object.keys(parentData).includes('element_story')) {
     let l = parentData?.element_story?.children?.list
     if (l) {
-      let lChildren = {}
+      let lChildren: any = {}
       list.forEach(item => {
         lChildren[item.name] = item
       })
@@ -346,7 +367,7 @@ export const processData = (data: string | any[]) => {
   if (list?.length > 0 && Object.keys(parentData).includes('image_list')) {
     let l = parentData?.image_list?.children?.list
     if (l) {
-      let lChildren = {}
+      let lChildren: any = {}
       list.forEach(item => {
         lChildren[item.name] = item
       })