wjx 10 maanden geleden
bovenliggende
commit
d5062784fd

+ 87 - 67
src/pages/launchSystemV3/adqv3/creative/index.tsx

@@ -1,19 +1,28 @@
 import { useAjax } from "@/Hook/useAjax"
 import { getDynamicCreativeV3ListApi } from "@/services/launchAdq/adqv3"
-import { Button, Col, Form, Input, Row, Select, Space } from "antd"
-import React, { useEffect } from "react"
+import { Badge, Button, Col, Form, Input, Row, Select, Space } from "antd"
+import React, { useEffect, useState } from "react"
 import { txDynamicConfig } from "../config"
 import tableConfig from "./tableConfig"
 import TableData from "@/pages/launchSystemNew/components/TableData"
-import { getCreativeReviewDetailApi } from "@/services/adqV3/global"
+import ReviewDetails from "./reviewDetails"
 
+/** 审核结果 */
+export const AD_STATUS = {
+	NORMAL: <Badge status="success" text="审核通过" />,
+	PENDING: <Badge status="default" text="审核中" />,
+	DENIED: <Badge status="error" text="有违规" />,
+	PARTIALLY_NORMAL: <Badge status="warning" text="部分审核通过" />,
+}
 
 const Creative: React.FC<ADQV3.CreativeProps> = ({ queryForm, setQueryForm, userId }) => {
 
     /*********************************/
     const [form] = Form.useForm();
+    const [dynimicData, setDynamicData] = useState<any>({})
+    const [dynimicVisible, setDynamicVisible] = useState<boolean>(false)
+
     const getDynamicCreativeV3List = useAjax((params) => getDynamicCreativeV3ListApi(params), { formatResult: true })
-    const getCreativeReviewDetail = useAjax((params) => getCreativeReviewDetailApi(params))
     /*********************************/
 
     useEffect(() => {
@@ -30,71 +39,82 @@ const Creative: React.FC<ADQV3.CreativeProps> = ({ queryForm, setQueryForm, user
     }
 
     const reviewStatusDetails = (value: any) => {
-        
+        setDynamicData(value)
+        setDynamicVisible(true)
     }
 
-    return <TableData
-        isCard={false}
-        columns={() => tableConfig(reviewStatusDetails)}
-        ajax={getDynamicCreativeV3List}
-        fixed={{ left: 2, right: 4 }}
-        dataSource={getDynamicCreativeV3List?.data?.data?.records}
-        loading={getDynamicCreativeV3List?.loading}
-        scroll={{ y: 560 }}
-        total={getDynamicCreativeV3List?.data?.data?.total}
-        page={getDynamicCreativeV3List?.data?.data?.current}
-        pageSize={getDynamicCreativeV3List?.data?.data?.size}
-        myKey={'dynamicCreativeId'}
-        gutter={[0, 10]}
-        config={txDynamicConfig}
-        configName="创意3.0"
-        leftChild={<Form
-            layout="inline"
-            form={form}
-            name="basignCreative"
-            initialValues={queryForm}
-            onFinish={onFinish}
-        >
-            <Row gutter={[10, 10]}>
-                <Col><Form.Item name='accountId' style={{ marginRight: 0 }}>
-                    <Input placeholder="广告账号" style={{ width: 120 }} allowClear />
-                </Form.Item></Col>
-                <Col><Form.Item name='adgroupId' style={{ marginRight: 0 }}>
-                    <Input placeholder="广告ID" style={{ width: 120 }} allowClear />
-                </Form.Item></Col>
-                <Col><Form.Item name='creativeName' style={{ marginRight: 0 }}>
-                    <Input placeholder="创意名称" style={{ width: 150 }} allowClear />
-                </Form.Item></Col>
-                <Col><Form.Item name='creativeId' style={{ marginRight: 0 }}>
-                    <Input placeholder="创意ID" style={{ width: 120 }} allowClear />
-                </Form.Item></Col>
-                <Col><Form.Item name='isDeleted'>
-                    <Select
-                        placeholder='是否删除?'
-                        style={{ width: 100 }}
-                        showSearch
-                        filterOption={(input: any, option: any) =>
-                            (option!.children as unknown as string).toLowerCase().includes(input.toLowerCase())
-                        }
-                    >
-                        <Select.Option value={true}>是</Select.Option>
-                        <Select.Option value={false}>否</Select.Option>
-                    </Select>
-                </Form.Item></Col>
-                <Col><Form.Item style={{ marginRight: 0 }}>
-                    <Space>
-                        <Button type="primary" htmlType="submit">搜索</Button>
-                        <Button onClick={() => form.resetFields()}>重置</Button>
-                    </Space>
-                </Form.Item></Col>
-            </Row>
-        </Form>}
-        onChange={(props: any) => {
-            let { pagination } = props
-            let { current, pageSize } = pagination
-            setQueryForm({ ...queryForm, pageNum: current, pageSize })
-        }}
-    />
+    return <>
+        <TableData
+            isCard={false}
+            columns={() => tableConfig(reviewStatusDetails)}
+            ajax={getDynamicCreativeV3List}
+            fixed={{ left: 2, right: 4 }}
+            dataSource={getDynamicCreativeV3List?.data?.data?.records}
+            loading={getDynamicCreativeV3List?.loading}
+            scroll={{ y: 560 }}
+            total={getDynamicCreativeV3List?.data?.data?.total}
+            page={getDynamicCreativeV3List?.data?.data?.current}
+            pageSize={getDynamicCreativeV3List?.data?.data?.size}
+            myKey={'dynamicCreativeId'}
+            gutter={[0, 10]}
+            config={txDynamicConfig}
+            configName="创意3.0"
+            leftChild={<Form
+                layout="inline"
+                form={form}
+                name="basignCreative"
+                initialValues={queryForm}
+                onFinish={onFinish}
+            >
+                <Row gutter={[10, 10]}>
+                    <Col><Form.Item name='accountId' style={{ marginRight: 0 }}>
+                        <Input placeholder="广告账号" style={{ width: 120 }} allowClear />
+                    </Form.Item></Col>
+                    <Col><Form.Item name='adgroupId' style={{ marginRight: 0 }}>
+                        <Input placeholder="广告ID" style={{ width: 120 }} allowClear />
+                    </Form.Item></Col>
+                    <Col><Form.Item name='creativeName' style={{ marginRight: 0 }}>
+                        <Input placeholder="创意名称" style={{ width: 150 }} allowClear />
+                    </Form.Item></Col>
+                    <Col><Form.Item name='creativeId' style={{ marginRight: 0 }}>
+                        <Input placeholder="创意ID" style={{ width: 120 }} allowClear />
+                    </Form.Item></Col>
+                    <Col><Form.Item name='isDeleted'>
+                        <Select
+                            placeholder='是否删除?'
+                            style={{ width: 100 }}
+                            showSearch
+                            filterOption={(input: any, option: any) =>
+                                (option!.children as unknown as string).toLowerCase().includes(input.toLowerCase())
+                            }
+                        >
+                            <Select.Option value={true}>是</Select.Option>
+                            <Select.Option value={false}>否</Select.Option>
+                        </Select>
+                    </Form.Item></Col>
+                    <Col><Form.Item style={{ marginRight: 0 }}>
+                        <Space>
+                            <Button type="primary" htmlType="submit">搜索</Button>
+                            <Button onClick={() => form.resetFields()}>重置</Button>
+                        </Space>
+                    </Form.Item></Col>
+                </Row>
+            </Form>}
+            onChange={(props: any) => {
+                let { pagination } = props
+                let { current, pageSize } = pagination
+                setQueryForm({ ...queryForm, pageNum: current, pageSize })
+            }}
+        />
+        {dynimicVisible && <ReviewDetails
+            visible={dynimicVisible}
+            dynamic={dynimicData}
+            onClose={() => {
+                setDynamicData({})
+                setDynamicVisible(false)
+            }}
+        />}
+    </>
 }
 
 export default React.memo(Creative)

+ 66 - 8
src/pages/launchSystemV3/adqv3/creative/reviewDetails.tsx

@@ -1,7 +1,12 @@
-import { Drawer } from "antd"
-import React from "react"
+import { useAjax } from "@/Hook/useAjax"
+import { getCreativeReviewDetailApi } from "@/services/adqV3/global"
+import { Card, Drawer, Table } from "antd"
+import React, { useEffect, useState } from "react"
+import { tableConfigDetail } from "./tableConfig"
+import '../../tencentAdPutIn/index.less'
 
 interface Props {
+    dynamic: any
     visible?: boolean,
     onClose?: () => void
 }
@@ -9,20 +14,73 @@ interface Props {
  * 审核详情
  * @returns 
  */
-const ReviewDetails: React.FC<Props> = ({ visible, onClose }) => {
+const ReviewDetails: React.FC<Props> = ({ dynamic, visible, onClose }) => {
 
     /****************************/
-
+    const [tableData, setTableData] = useState<any[]>([])
+    const getCreativeReviewDetail = useAjax((params) => getCreativeReviewDetailApi(params))
     /****************************/
 
+    useEffect(() => {
+        if (dynamic && Object.keys(dynamic).length) {
+            const { accountId, dynamicCreativeId } = dynamic
+            getCreativeReviewDetail.run({ accountId, dynamicCreativeIds: [dynamicCreativeId] }).then(res => {
+                console.log('------------->', res)
+                if (res) {
+                    let { elementResultList } = res[0]
+                    let cover: any, count = 0
+                    elementResultList.forEach((item: any) => {
+                        if (item?.elementName === '图片' && item?.componentInfo?.componentType === "VIDEO") {
+                            cover = item
+                        }
+                        if (item?.componentInfo) {
+                            count += 1
+                        }
+                    })
+
+                    setTableData(elementResultList?.map((item: any, index: number) => {
+                        let params = { ...item, id: index, rowSpan: 1 }
+                        if (item?.componentInfo?.componentType === 'VIDEO' && cover) {
+                            if (item?.elementType === "VIDEO") {
+                                params.rowSpan = 2
+                            } else {
+                                params.rowSpan = 0
+                            }
+                        }
+                        if (index === count) {
+                            params.rowSpan = elementResultList.length - count
+                        } else if (index > count) {
+                            params.rowSpan = 0
+                        }
+                        return params
+                    }))
+                }
+            })
+        }
+    }, [dynamic])
+
     return <Drawer
-        title={<strong>添加创意</strong>}
+        title={<strong>创意审核详情</strong>}
         visible={visible}
-        width={1500}
+        width={'70%'}
         onClose={onClose}
-        bodyStyle={{ backgroundColor: '#f1f4fc', padding: '0 10px 10px' }}
+        bodyStyle={{ backgroundColor: '#f1f4fc', padding: 10 }}
     >
-
+        <Card
+            title={<strong>{dynamic?.dynamicCreativeName}</strong>}
+            bodyStyle={{ padding: 0 }}
+            className="cardResetCss"
+        >
+            <Table
+                columns={tableConfigDetail()}
+                dataSource={tableData}
+                size="small"
+                loading={getCreativeReviewDetail?.loading}
+                scroll={{ x: 1100 }}
+                bordered
+                rowKey={'id'}
+            />
+        </Card>
     </Drawer>
 }
 

+ 89 - 4
src/pages/launchSystemV3/adqv3/creative/tableConfig.tsx

@@ -1,9 +1,11 @@
 import React from 'react'
-import { Space, Switch, Image, Popover } from 'antd'
+import { Space, Switch, Image, Popover, TableProps, Typography } from 'antd'
 import '../index.less'
 import { copy } from '@/utils/utils'
 import { DELIVERY_MODE, DYNAMIC_CREATIVE_TYPE } from '../const'
-import { creativeTemplate } from '../../tencentAdPutIn/const'
+import { ELEMENT_ENUM, SITE_SET_ENUM, creativeTemplate } from '../../tencentAdPutIn/const'
+import { AD_STATUS } from '.'
+const { Text } = Typography;
 
 function tableConfig(reviewStatusDetails: (value: any) => void): any {
     return [
@@ -94,7 +96,7 @@ function tableConfig(reviewStatusDetails: (value: any) => void): any {
             ellipsis: true,
             render: (_: any[], b: any) => {
                 let video = b?.creativeComponents?.video
-                return video?.length > 0 ? < Popover
+                return video?.length > 0 ? <Popover
                     placement='right'
                     content={< div >
                         <Space style={{ maxWidth: 300, display: 'flex', flexFlow: 'row wrap', margin: '10px 0' }}>
@@ -216,10 +218,93 @@ function tableConfig(reviewStatusDetails: (value: any) => void): any {
             render: (a: string, b: any) => {
                 return <Space direction="vertical" size={0}>
                     <span style={{ fontSize: 12 }}>{a}</span>
-                    {/* <a style={{ fontSize: 12 }} onClick={() => { reviewStatusDetails(b) }}>详情</a> */}
+                    <a style={{ fontSize: 12 }} onClick={() => { reviewStatusDetails(b) }}>详情</a>
                 </Space>
             }
         }
     ]
 }
+
+export const tableConfigDetail = (): TableProps<any>['columns'] => {
+
+
+    return [
+        {
+            title: '创意组件',
+            dataIndex: 'componentInfo',
+            key: 'componentInfo',
+            width: 180,
+            render: (value) => {
+                if (value) {
+                    let { componentId, componentType } = value
+                    return <Space direction="vertical" size={0}>
+                        <Text style={{ fontSize: 12 }}>{ELEMENT_ENUM[componentType]}</Text>
+                        <Text type="secondary" style={{ fontSize: 12 }}>{componentId}</Text>
+                    </Space>
+                }
+                return null
+            },
+            onCell: (record) => ({
+                rowSpan: record.rowSpan
+            })
+        },
+        {
+            title: '组件审核结果',
+            dataIndex: 'reviewStatus',
+            key: 'reviewStatus',
+            width: 120,
+            render: (value, records) => {
+                if (!records?.componentInfo) {
+                    return null
+                }
+                return <span style={{ fontSize: 12 }}>{AD_STATUS[value]}</span>
+            }
+        },
+        {
+            title: '组件元素',
+            dataIndex: 'elementName',
+            key: 'elementName',
+            width: 155,
+            render: (value, records) => {
+                return <>
+                    <Text type="secondary" style={{ fontSize: 12 }}>{value}</Text>
+                    <div style={{ maxWidth: 178 }}>
+                        {records.elementType === 'VIDEO' ? <Popover
+                            placement='right'
+                            content={< div >
+                                <Space style={{ maxWidth: 300, display: 'flex', flexFlow: 'row wrap', margin: '10px 0' }}>
+                                    <video src={records.elementValue} style={{ width: 250 }} controls />
+                                </Space>
+                            </div >}
+                            destroyTooltipOnHide
+                            mouseEnterDelay={0.5}
+                        >
+                            <video src={records.elementValue} style={{ maxHeight: 40, maxWidth: 60 }} />
+                        </Popover> : records.elementType === 'IMAGE' ? <img src={records.elementValue} style={{ maxHeight: 40, maxWidth: 60 }} />
+                            : <Text style={{ fontSize: 12 }} ellipsis strong>{records.elementValue}</Text>}
+                    </div>
+                </>
+            }
+        },
+        {
+            title: '驳回原因',
+            dataIndex: 'elementRejectDetailInfo',
+            key: 'elementRejectDetailInfo',
+            width: 560,
+            render: (value) => {
+                return value ? <Text style={{ fontSize: 12 }}>{value?.map((item: { reason: any }) => item.reason)?.join(',')}</Text> : null
+            }
+        },
+        {
+            title: '影响版位',
+            dataIndex: 'siteSetList',
+            key: 'siteSetList',
+            width: 125,
+            render: (_, records) => {
+                let siteSetList = records?.elementRejectDetailInfo?.siteSetList
+                return siteSetList ? <Text style={{ fontSize: 12 }}>{siteSetList?.map((item: { siteSet: any }) => SITE_SET_ENUM[item?.siteSet])?.join(',')}</Text> : null
+            }
+        },
+    ]
+}
 export default tableConfig

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

@@ -15,7 +15,7 @@ const AdqV3: React.FC = () => {
     const userInfo = useModel('@@initialState', model => model.initialState?.currentUser)
     const allOfMember = useAjax(() => getPicherListApi(), { formatResult: true })
     const [userAll, setUserAll] = useState([])
-    const [activeKey, setActiveKey] = useState('1')
+    const [activeKey, setActiveKey] = useState('2')
     const [userId, setUserId] = useState<any>(userInfo?.userId?.toString())
     const [hide, setHide] = useState<boolean>(false)
     const [queryForm, setQueryForm] = useState<ADQV3.GetDynamicCreativeProps>({ pageNum: 1, pageSize: 20, userId, isDeleted: false })

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

@@ -534,4 +534,71 @@ export enum OPTION_ENUM {
 }
 
 /** 创意ID对应名称 */
-export const creativeTemplate = { "311": "常规大图 1:1", "618": "常规视频  4:3", "641": "常规多图 1:1 三图", "642": "常规多图 1:1 四图", "643": "常规多图 1:1 六图", "711": "横版大图 16:9", "712": "竖版大图 9:16", "713": "通栏大图 7:2", "714": "横版小图 3:2", "720": "横版视频 16:9", "721": "竖版视频 9:16", "722": "贴片视频 16:9", "910": "激励浏览广告", "925": "Banner图片 20:7", "1529": "闪屏视频  9:16", "1707": "卡片广告 横版大图 16:9", "1708": "卡片广告 横版视频 16:9", "2106": "常规图片", "2107": "橱窗广告 - 图片", "2109": "橱窗广告 - 视频" }
+export const creativeTemplate = { "311": "常规大图 1:1", "618": "常规视频  4:3", "641": "常规多图 1:1 三图", "642": "常规多图 1:1 四图", "643": "常规多图 1:1 六图", "711": "横版大图 16:9", "712": "竖版大图 9:16", "713": "通栏大图 7:2", "714": "横版小图 3:2", "720": "横版视频 16:9", "721": "竖版视频 9:16", "722": "贴片视频 16:9", "910": "激励浏览广告", "925": "Banner图片 20:7", "1529": "闪屏视频  9:16", "1707": "卡片广告 横版大图 16:9", "1708": "卡片广告 横版视频 16:9", "2106": "常规图片", "2107": "橱窗广告 - 图片", "2109": "橱窗广告 - 视频" }
+
+/** 创意组件 */
+export enum ELEMENT_ENUM {
+	"UNKNOWN"= "未知",
+	"TITLE"= "标题组件",
+	"DESCRIPTION"= "描述组件",
+	"IMAGE"= "图片组件",
+	"IMAGE_LIST"= "图片列表组件",
+	"JUMP_INFO"= "落地页组件",
+	"VIDEO"= "视频组件",
+	"BRAND"= "品牌组件",
+	"CONSULT"= "咨询组件",
+	"PHONE"= "电话组件",
+	"FORM"= "表单组件",
+	"ACTION_BUTTON"= "行动按钮组件",
+	"CHOSEN_BUTTON"= "选择按钮组件",
+	"LABEL"= "标签组件",
+	"SHOW_DATA"= "数据外显组件",
+	"MARKETING_PENDANT"= "挂件组件",
+	"APP_GIFT_PACK_CODE"= "礼包码组件",
+	"SHOP_IMAGE"= "卖点图组件",
+	"COUNT_DOWN"= "倒计时组件",
+	"BARRAGE"= "弹幕组件",
+	"FLOATING_ZONE"= "轮播组件",
+	"TEXT_LINK"= "文字链组件",
+	"END_PAGE"= "视频结束页组件",
+	"LIVING_DESC"= "轮播文案组件",
+	"WECHAT_CHANNELS"= "视频号组件",
+	"SHORT_VIDEO"= "短视频组件",
+	"ELEMENT_STORY"= "集装箱创意组合组件",
+	"WXGAME_PLAYABLE_PAGE"= "小游戏试玩页组件",
+	"APP_PROMOTION_VIDEO"= "ott 视频组件",
+	"VIDEO_SHOWCASE"= "橱窗视频组件",
+	"IMAGE_SHOWCASE"= "橱窗图片组件",
+	"MINI_CARD_LINK"= "图文链接组件",
+	"V2_TITLE"= "标题",
+	"V2_DESCRIPTION"= "描述",
+	"V2_LONG_SUBLINK"= "长子链单条",
+	"V2_SHORT_SUBLINK"= "短子链单条",
+	"V2_LONG_SUBLINK_LIST"= "长子链组",
+	"V2_SHORT_SUBLINK_LIST"= "短子链组",
+	"V2_APP_DOWNLOAD"= "app 下载",
+	"V2_IMAGE_1X1"= "单图 1=1",
+	"V2_IMAGE_LIST_1X1"= "图集 1=1",
+	"V2_IMAGE_TEXT_1X1"= "图文 1=1",
+	"V2_IMAGE_BIG_20X7"= "大图 20=7",
+	"V2_VIDEO_16X9_IMAGE_16X9"= "视频 16=9,封面图 16=9",
+	"V2_VIDEO_16X9_IMAGE_4X3"= "视频 16=9,封面图 4=3",
+	"V2_VIDEO_16X9_IMAGE_1X1"= "视频 16=9,封面图 1=1",
+	"V2_QUICK_CONSULT"= "快咨询",
+	"V2_PHONE"= "电话组件",
+	"V2_FORM"= "线索营销",
+	"V2_BRAND"= "品牌形象",
+	"V2_LANDING_PAGE"= "跳转组件",
+	"V2_HOLIDAY_LOGO"= "节日 logo",
+	"V2_ACTION_BUTTON"= "跳转组件",
+	"V2_CHOSEN_BUTTON"= "跳转组件",
+	"V2_VIDEO_9X16_IMAGE_9X16"= "跳转组件",
+	"V2_IMAGE_16X9"= "16=9 单图",
+	"V2_LABEL"= "标签组件",
+	"V2_PROMOTION_SUBLINK"= "活动促销组件",
+	"V2_IMAGE_LIST_3X2"= "图集 3=2",
+	"V2_IMAGE_LIST_9X16"= "9=16 图集",
+	"V2_LIST_SUBLINK"= "列表子链组件",
+	"V2_MDPA_TITLE"= "动态商品标题",
+	"V2_MDPA_DESCRIPTION"= "动态商品描述"
+}

+ 3 - 2
src/services/adqV3/global.ts

@@ -306,9 +306,10 @@ export async function delProfilesApi(params: { id: number }) {
  * @param data 
  * @returns 
  */
-export async function getCreativeReviewDetailApi(data: { accountId: number, dynamicCreativeIds: number[] }) {
+export async function getCreativeReviewDetailApi({ accountId, dynamicCreativeIds }: { accountId: number, dynamicCreativeIds: number[] }) {
     return request(api + `/adq/adgroup/creativeReviewDetail`, {
         method: 'POST',
-        data
+        data: dynamicCreativeIds,
+        params: { accountId }
     })
 }