wjx преди 2 години
родител
ревизия
e4e9d8368d

+ 12 - 0
src/pages/launchSystemNew/adq/ad/tableConfig.tsx

@@ -1,6 +1,7 @@
 import { AdStatusEnum, OptimizationGoalEnum, PromotedObjectType } from '@/services/launchAdq/enum'
 import React from 'react'
 import { Badge, Switch } from 'antd'
+import PreviewAd from '../../components/previewAd'
 function tableConfig(
     switchHandle: (data: any, Status: any) => void,
     tableIdClick: (props: {
@@ -174,6 +175,17 @@ function tableConfig(
                 return AdStatusEnum[a]
             }
         },
+        // {
+        //     title: '预览',
+        //     dataIndex: 'preview',
+        //     key: 'preview',
+        //     align: 'center',
+        //     width: 40,
+        //     fixed: 'right',
+        //     render: (a: string, b: any) => {
+        //         return <PreviewAd adgroupId={b?.adgroupId} accountId={b?.accountId}/>
+        //     }
+        // },
     ]
 }
 export default tableConfig

+ 51 - 0
src/pages/launchSystemNew/components/previewAd/index.tsx

@@ -0,0 +1,51 @@
+import { useAjax } from "@/Hook/useAjax";
+import { getAdcreativePreviewsQrcodeApi } from "@/services/launchAdq/global";
+import { EyeOutlined } from "@ant-design/icons";
+import { Button, Popover } from "antd";
+import React, { useState } from "react";
+
+
+interface Props {
+    accountId: number,
+    adgroupId: number
+}
+/**
+ * 广告预览二维码
+ * @returns 
+ */
+const PreviewAd: React.FC<Props> = (props) => {
+
+    /*******************/
+    const { accountId, adgroupId } = props
+    const [open, setOpen] = useState(false);
+
+    const getAdcreativePreviewsQrcode = useAjax((params) => getAdcreativePreviewsQrcodeApi(params))
+    /*******************/
+    console.log('adAccountId, adgroupId--->', accountId);
+
+    const handleVisibleChange = (newOpen: boolean) => {
+        setOpen(newOpen);
+        if (newOpen && accountId && adgroupId) {
+            getAdcreativePreviewsQrcode.run({ accountId, adgroupId }).then(res => {
+
+            })
+        }
+    }
+
+    return <>
+        <Popover
+            content={<>
+                12312
+            </>}
+            trigger="click"
+            placement="left"
+            visible={open}
+            onVisibleChange={handleVisibleChange}
+        >
+            <a style={{fontSize: 12, color: '#1890FF'}}><EyeOutlined />广告</a>
+        </Popover>
+    </>
+}
+
+
+export default React.memo(PreviewAd)

+ 32 - 0
src/pages/launchSystemNew/components/previewOrigin/index.tsx

@@ -0,0 +1,32 @@
+import { useAjax } from "@/Hook/useAjax";
+import { getAdcreativeTemplatePreviewsApi } from "@/services/launchAdq/global";
+import { Button } from "antd";
+import React from "react";
+
+
+interface Props {
+    accountId: number,
+    adgroupId: number
+}
+/**
+ * 广告预览二维码
+ * @returns 
+ */
+const PreviewOrigin: React.FC<Props> = (props) => {
+
+    /*******************/
+    const { accountId, adgroupId } = props
+
+    const getAdcreativeTemplatePreviews = useAjax((params) => getAdcreativeTemplatePreviewsApi(params))
+    /*******************/
+
+    const handleVisibleChange = () => {
+        getAdcreativeTemplatePreviews.run({ accountId, adgroupId }).then(res => {
+            window.open(res)
+        })
+    }
+    return <Button style={{ fontSize: 12, color: '#1890FF', padding: 0 }} loading={getAdcreativeTemplatePreviews.loading} type='link' onClick={() => handleVisibleChange()}>创意预览</Button>
+}
+
+
+export default React.memo(PreviewOrigin)

+ 7 - 5
src/pages/launchSystemNew/launchManage/createAd/adcreativeCol.tsx

@@ -1,4 +1,4 @@
-import { EndPageTypeEnum, LinkPageNameTypeEnum, LinkPageTypeEnum, PromotedObjectType, SiteSetEnum } from "@/services/launchAdq/enum"
+import { AdcreativeTemplateEnum, EndPageTypeEnum, LinkPageNameTypeEnum, LinkPageTypeEnum, PromotedObjectType, SiteSetEnum } from "@/services/launchAdq/enum"
 import React from "react"
 import { Image, Space } from "antd"
 import { overrideCanvasHeadOptionEnum } from "./creative/modal/config"
@@ -37,22 +37,24 @@ const AdcreativeCol: React.FC<Props> = (props) => {
 
     /***************************/
     const { data } = props
-    const { adcreativeName, promotedObjectType, siteSet, adcreativeTemplateId, adcreativeElements, overrideCanvasHeadOption, linkNameType, linkPageType,linkPageSpec} = data
+    const { adcreativeName, promotedObjectType, siteSet, adcreativeTemplateId, adcreativeElements, profile, overrideCanvasHeadOption, linkNameType, linkPageType, linkPageSpec } = data
     /***************************/
 
     return <>
         <div><strong>创意名称:</strong><span style={{ color: "#5a5a5a" }}>{adcreativeName}</span></div>
         <div><strong>推广目标:</strong> <span style={{ color: "#5a5a5a" }}>{PromotedObjectType[promotedObjectType]}</span></div>
         <div><strong>广告版位:</strong> <span style={{ color: "#5a5a5a" }}>{siteSet?.map((item: string) => SiteSetEnum[item]).toString()}</span></div>
-        <div><strong>创意形式: </strong><span style={{ color: "#5a5a5a" }}>{adcreativeTemplate?.find((item: any) => item?.adcreativeTemplateId === adcreativeTemplateId)?.adcreativeTemplateAppellation || ''}</span></div>
-        {adcreativeElements?.brand && <div><strong>品牌形象:</strong> <span style={{ color: "#5a5a5a" }}><img src={adcreativeElements?.brand?.brandImgUrl} style={{ width: 20,marginRight:5 }} />{adcreativeElements?.brand?.brandName}</span></div>}
+        <div><strong>创意形式: </strong><span style={{ color: "#5a5a5a" }}>{AdcreativeTemplateEnum[adcreativeTemplateId]}</span></div>
+        {(profile && Object.keys(profile)?.length > 0) ?
+            <div><strong>头像及昵称跳转页:</strong> <span style={{ color: "#5a5a5a" }}><img src={adcreativeElements?.brand?.brandImgUrl} style={{ width: 20, marginRight: 5 }} />{adcreativeElements?.brand?.brandName}</span></div> :
+            adcreativeElements?.brand ? <div><strong>品牌形象:</strong> <span style={{ color: "#5a5a5a" }}><img src={adcreativeElements?.brand?.brandImgUrl} style={{ width: 20, marginRight: 5 }} />{adcreativeElements?.brand?.brandName}</span></div> : null}
         {adcreativeElements?.description && <div><strong>创意文案:</strong> <span style={{ color: "#5a5a5a" }}>{adcreativeElements?.description}</span></div>}
         {adcreativeElements?.title && <div><strong>文案:</strong> <span style={{ color: "#5a5a5a" }}>{adcreativeElements?.title}</span></div>}
         {linkNameType && <div><strong>按钮文案:</strong> <span style={{ color: "#5a5a5a" }}>{LinkPageNameTypeEnum[linkNameType]}</span></div>}
         {linkPageType && <div><strong>跳转落地页:</strong> <span style={{ color: "#5a5a5a" }}>{LinkPageTypeEnum[linkPageType]}</span></div>}
         {linkPageSpec?.pageUrl && <div><strong>落地页地址:</strong> <span style={{ color: "#5a5a5a" }}>{linkPageSpec?.pageUrl}</span></div>}
         {linkPageSpec?.miniProgramSpec && linkPageSpec?.miniProgramSpec?.miniProgramId && <div><strong>小程序ID:</strong> <span style={{ color: "#5a5a5a" }}>{linkPageSpec?.miniProgramSpec?.miniProgramId}</span></div>}
-        {linkPageSpec?.miniProgramSpec && linkPageSpec?.miniProgramSpec?.miniProgramPath  && <div><strong>小程序地址:</strong> <span style={{ color: "#5a5a5a" }}>{linkPageSpec?.miniProgramSpec?.miniProgramPath}</span></div>}
+        {linkPageSpec?.miniProgramSpec && linkPageSpec?.miniProgramSpec?.miniProgramPath && <div><strong>小程序地址:</strong> <span style={{ color: "#5a5a5a" }}>{linkPageSpec?.miniProgramSpec?.miniProgramPath}</span></div>}
         {adcreativeElements?.endPage && <div><strong>视频结束页类型:</strong> <span style={{ color: "#5a5a5a" }}>{EndPageTypeEnum[adcreativeElements?.endPage?.endPageType]}</span></div>}
         {adcreativeElements?.endPage && <div><strong>视频结束页文案:</strong> <span style={{ color: "#5a5a5a" }}>{adcreativeElements?.endPage?.endPageDesc}</span></div>}
         {adcreativeElements?.imageUrl && <div style={{ display: 'flex', alignItems: 'flex-start', marginBottom: 4 }}><strong>创意素材:</strong> <Image width={80} src={adcreativeElements?.imageUrl} style={{ borderRadius: 8, overflow: 'hidden', marginLeft: 5 }} /></div>}

+ 26 - 16
src/pages/launchSystemNew/launchManage/createAd/creative/modal/index.tsx

@@ -134,6 +134,7 @@ function CreativePup(props: Props) {
                         break;
                     case 'image_list'://图素材
                         newValues.adcreativeElements = {
+                            ...newValues.adcreativeElements,
                             imageUrlList: imgMaterialConfig.list?.map(item => item.url),
                             description: newValues.description,
                         }
@@ -141,6 +142,7 @@ function CreativePup(props: Props) {
                         break;
                     case 'short_video1'://视频素材
                         newValues.adcreativeElements = {
+                            ...newValues.adcreativeElements,
                             shortVideoStruct: {
                                 shortVideo1Url: videoMaterialConfig?.list[0]?.url
                             },
@@ -173,12 +175,20 @@ function CreativePup(props: Props) {
                                 brandImgUrl: newValues.brand.split('_')[1]
                             }
                         }
-                        // newValues.headClickSpec = {
-                        //     headImageUrl: newValues.brand.split('_')[1],
-                        //     profileName: newValues.brand.split('_')[0],
-                        //     description: newValues.brand.split('_')[2]
-                        // }
                         break;
+                    case 'profile':
+                        newValues.adcreativeElements = {
+                            ...newValues.adcreativeElements, brand: {
+                                brandName: newValues.profile.split('_')[0],
+                                brandImgUrl: newValues.profile.split('_')[1]
+                            }
+                        }
+                        newValues.profile = {
+                            headImageUrl: newValues.profile.split('_')[1],
+                            profileName: newValues.profile.split('_')[0],
+                            description: newValues.profile.split('_')[2]
+                        }
+                        break
                     case 'pageUrl'://跳转落地页
                         newValues.linkPageSpec = {
                             ...newValues.linkPageSpec,
@@ -381,7 +391,6 @@ function CreativePup(props: Props) {
                     newObj[item.name] = arr
                 })
                 setConversionList(newObj)
-
                 states = { ...states, sj_show: true }
                 if (newObj.conversion_data_type) {
                     values = { ...values, conversionDataType: newObj.conversion_data_type[0].value }
@@ -390,6 +399,7 @@ function CreativePup(props: Props) {
                     values = { ...values, conversionTargetType: newObj.conversion_target_type[0].value }
                 }
             }
+
             //行动按钮组件存在
             if (states.xd_show) {
                 let linkNameList = (pageList?.filter((item: { pageType: any; }) => item.pageType === pageType)[0] as any)?.supportLinkNameType?.list
@@ -460,8 +470,8 @@ function CreativePup(props: Props) {
     // 数据回填
     useEffect(() => {
         if (!infoSet && dataInfo && adcreative_template_list?.length > 0) {
-            let { adcreativeName, adcreativeTemplateId, conversionDataType, conversionTargetType, linkNameType, linkPageType, pageType, promotedObjectType, siteSet, headClickSpec, adcreativeElements, overrideCanvasHeadOption, linkPageSpec } = dataInfo
-            let { description, imageUrl, title, videoUrl, imageUrlList, endPage, shortVideoStruct, brand,buttonText } = adcreativeElements
+            let { adcreativeName, adcreativeTemplateId, conversionDataType, conversionTargetType, linkNameType, linkPageType, pageType, promotedObjectType, siteSet, profile, adcreativeElements, overrideCanvasHeadOption, linkPageSpec } = dataInfo
+            let { description, imageUrl, title, videoUrl, imageUrlList, endPage, shortVideoStruct, brand, buttonText } = adcreativeElements
             let obj: any = {
                 adcreativeName,
                 siteSet,
@@ -470,7 +480,7 @@ function CreativePup(props: Props) {
             }
             getTemplate(adcreativeTemplateId, true)
             console.log(2222,dataInfo)
-            if ([720, 721, 618, 1708].some(n => n === adcreativeTemplateId)) {
+            if ([720, 721, 618, 1708, 722, 1529].some(n => n === adcreativeTemplateId)) {
                 obj = { ...obj, adcreativeElementsType: '视频' }
             } else {
                 obj = { ...obj, adcreativeElementsType: '图片' }
@@ -511,6 +521,9 @@ function CreativePup(props: Props) {
             if (brand && brand.brandImgUrl && brand.brandName) {
                 obj = { ...obj, brand: brand.brandName + '_' + brand.brandImgUrl }
             }
+            if (profile && profile.headImageUrl && profile.profileName && profile.description) {
+                obj = { ...obj, profile: profile.profileName + '_' + profile.headImageUrl + '_' + profile.description}
+            }
             if(buttonText){
                 obj = {...obj,buttonText}
             }
@@ -656,13 +669,11 @@ function CreativePup(props: Props) {
                         {/* ============================================================创意内容============================================================= */}
                         <Divider orientation='center'>创意内容</Divider>
                         {/* =============================================================头像及昵称跳转页===================================================================== */}
-                        {queryForm.promotedObjectType === 'PROMOTED_OBJECT_TYPE_LEAD_AD' && <Form.Item label={<strong>头像及昵称跳转页</strong>} name='brand' rules={[{ required: true, message: '请选择一个头像及昵称跳转页,与广告创意一起展示' }]}>
+                        {queryForm.promotedObjectType === 'PROMOTED_OBJECT_TYPE_LEAD_AD' ? adcreative_template?.adcreativeAttributes?.find(item => item.name === 'profile_id') ? <Form.Item label={<strong>头像及昵称跳转页</strong>} name='profile' rules={[{ required: true, message: '请选择一个头像及昵称跳转页,与广告创意一起展示' }]}>
                             <HeadNickJump />
-                        </Form.Item>}
-                        {/* =============================================================品牌形象===================================================================== */}
-                        {queryForm.promotedObjectType === 'PROMOTED_OBJECT_TYPE_LEAD_AD' && <Form.Item label={<strong>品牌形象</strong>} name='brand' rules={[{ required: true, message: '请选择一个头像及昵称跳转页,与广告创意一起展示' }]}>
+                        </Form.Item> : <Form.Item label={<strong>品牌形象</strong>} name='brand' rules={[{ required: true, message: '请选择一个头像及昵称跳转页,与广告创意一起展示' }]}>
                             <BrandImage />
-                        </Form.Item>}
+                        </Form.Item> : null}
                         {/* ============================================================素材============================================================= */}
                         {/* 优先展示视频或图片,朋友圈常规不勾选使用外部素材替换内部,隐藏此选项,后期自动将落地页顶部素材添加进入 */}
                         {((overrideCanvasHeadOption !== 'OPTION_CANVAS_OVERRIDE_CREATIVE') || siteSet.every((name: string) => name !== 'SITE_SET_MOMENTS')) && <div style={{ display: 'flex', flexFlow: 'column' }}>
@@ -728,8 +739,7 @@ function CreativePup(props: Props) {
                                                         {imgMaterialConfig?.list[0] ? <img src={imgMaterialConfig?.list[0].url} /> : <>
                                                             <span>{`推荐尺寸(${item.restriction.imageRestriction.width} x ${item.restriction.imageRestriction.height})`}</span>
                                                             <span>{`${item.restriction.imageRestriction.fileFormat?.map(str => str?.replace('IMAGE_TYPE_', ''))};小于 ${item.restriction.imageRestriction.fileSize}KB`}</span>
-                                                        </>
-                                                        }
+                                                        </>}
                                                     </p>
                                                 </div>
                                             </Form.Item>

+ 3 - 2
src/pages/launchSystemNew/launchManage/createAd/index.tsx

@@ -653,7 +653,7 @@ const CreateAd: React.FC = () => {
                                 <div className={style.bottom}>{
                                     (queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysAdcreative) ? <>
                                         {queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysPageId && <Button type="link" onClick={() => { setLookVisible(true) }}>查看</Button>}
-                                        <Button type="link" onClick={() => {
+                                        {queryForm?.promotedObjectType !== 'PROMOTED_OBJECT_TYPE_LEAD_AD' && <Button type="link" onClick={() => {
                                             setSelectImgVisible(true)
                                             // 判定是否用原生页顶部替换外部素材
                                             if (queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.overrideCanvasHeadOption === 'OPTION_CANVAS_OVERRIDE_CREATIVE') {
@@ -661,7 +661,8 @@ const CreateAd: React.FC = () => {
                                             } else {
                                                 init({ mediaType: 'PAGE', cloudSize: undefined })
                                             }
-                                        }}>{queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysPageId ? '修改' : '选择落地页'}</Button>
+                                        }}>{queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysPageId ? '修改' : '选择落地页'}</Button>}
+                                        
                                         {accountCreateLogs?.length > 0 ? <Button type="link" onClick={() => {
                                             setPageVisible(true)
                                             if (queryForm?.taskMediaMaps && queryForm?.taskMediaMaps[targetKey]?.sysAdcreative?.overrideCanvasHeadOption === 'OPTION_CANVAS_OVERRIDE_CREATIVE') {

+ 18 - 0
src/pages/launchSystemNew/launchManage/taskList/logTableConfig.tsx

@@ -3,6 +3,8 @@ import { EyeOutlined } from "@ant-design/icons";
 import { Badge, Popover, Space } from "antd"
 import React, { useState } from "react"
 import AdcreativePopover from "../../components/adcreativePopover";
+import PreviewAd from "../../components/previewAd";
+import PreviewOrigin from "../../components/previewOrigin";
 type Props = {
     arr: any[],
     title: string,
@@ -40,6 +42,22 @@ function tableConfig(copyCreative: (data: any) => void, callback: (data: any) =>
         location.href = location.origin + '/#/launchSystemNew/adq'
     }
     return [
+        {
+            title: '预览',
+            dataIndex: 'preview',
+            key: 'preview',
+            align: 'center',
+            width: 90,
+            fixed: 'left',
+            render: (a: string, b: any) => {
+                if (b?.createStatus === 100) {
+                    return <PreviewOrigin adgroupId={b?.adgroupIds[0]} accountId={b?.accountId}/>
+                    // return <PreviewAd adgroupId={b?.adgroupIds[0]} accountId={b?.accountId}/>
+                } else {
+                    return '--'
+                }
+            }
+        },
         {
             title: 'ID',
             dataIndex: 'id',

+ 40 - 6
src/services/launchAdq/global.ts

@@ -135,7 +135,7 @@ export async function getSysProfileApi() {
  * @param data 
  * @returns 
  */
- export async function addSysProfileApi(data: { name: string, brandImgUrl: string }) {
+export async function addSysProfileApi(data: { name: string, brandImgUrl: string }) {
     return request(api + `/adq/sysProfile`, {
         method: 'POST',
         data
@@ -160,17 +160,51 @@ export async function editSysProfileApi(data: { name: string, brandImgUrl: strin
  * @param data 
  * @returns 
  */
- export async function delSysProfileApi(data: { sysProfileId: number }) {
+export async function delSysProfileApi(data: { sysProfileId: number }) {
     const { sysProfileId } = data
     return request(api + `/adq/sysProfile/${sysProfileId}`, {
         method: 'DELETE'
     })
 }
 
-/**查询优化目标权限*/ 
-export async function getOptimizationGoalPermissions(data:any) {
-    return request(api+`/adq/launch/tools/getOptimizationGoalPermissions`,{
-        method:'POST',
+/**查询优化目标权限*/
+export async function getOptimizationGoalPermissions(data: any) {
+    return request(api + `/adq/launch/tools/getOptimizationGoalPermissions`, {
+        method: 'POST',
         data
     })
+}
+
+/**
+ * 广告预览二维码
+ * @param param0 
+ * @returns 
+ */
+export async function getAdcreativePreviewsQrcodeApi({ accountId, adgroupId }: { accountId: number, adgroupId: number }) {
+    return request(api + `/adq/launch/tools/getAdcreativePreviewsQrcode/${accountId}/${adgroupId}`, {
+        method: 'GET'
+    })
+}
+
+/**
+ * 广告创意预览链接
+ * @param param0 
+ * @returns 
+ */
+export async function getAdcreativeTemplatePreviewsApi({ accountId, adgroupId }: { accountId: number, adgroupId: number }) {
+    return request(api + `/adq/launch/tools/adcreativeTemplatePreviews/${accountId}/${adgroupId}`, {
+        method: 'GET'
+    })
+}
+
+
+/**
+ * 广告创意预览链接
+ * @param param0 
+ * @returns 
+ */
+export async function getAdcreativeTemplatePreviews1Api({ adAccountId, adgroupId, adIdList }: { adAccountId: number, adgroupId: number, adIdList: any }) {
+    return request(api + `/adq/launch/tools/adcreativeTemplatePreviews/${adAccountId}/${adgroupId}/${adIdList}`, {
+        method: 'GET'
+    })
 }