wjx 5 月之前
父節點
當前提交
e0d54819fd

+ 23 - 5
src/pages/launchSystemV3/adMonitorListV3/FilterDynamicQuery.tsx

@@ -1,6 +1,6 @@
 import { CloseOutlined, DownOutlined, FilterOutlined, SearchOutlined, UpOutlined } from "@ant-design/icons"
 import { Button, DatePicker, Form, Input, InputNumber, Popover, Select, Space } from "antd"
-import React, { useEffect, useState } from "react"
+import React, { forwardRef, useEffect, useImperativeHandle, useState } from "react"
 import '../../launchSystemNew/adq/ad/index.less'
 import moment from "moment"
 import { useLocalStorageState, useTimeout } from "ahooks"
@@ -29,7 +29,7 @@ interface Props {
  * 请求体 AD 合集
  * @returns 
  */
-const FilterDynamicQuery: React.FC<Props> = ({ onChange, initialValues, queryForm, setQueryForm }) => {
+const FilterDynamicQuery = forwardRef(({ onChange, initialValues, queryForm, setQueryForm }: Props, ref) => {
 
     /********************************/
     const [form] = Form.useForm();
@@ -40,6 +40,20 @@ const FilterDynamicQuery: React.FC<Props> = ({ onChange, initialValues, queryFor
     const { getPicherList } = useModel('useOperating.useWxGroupList')
     /********************************/
 
+    useImperativeHandle(ref, () => ({
+        onOpen(data: any) {
+            setVisible(true)
+            let { createdTimeMin, createdTimeMax, adgroupIds, ...params } = data
+            if (createdTimeMin && createdTimeMax) {
+                params.createdTime = [moment(createdTimeMin), moment(createdTimeMax)]
+            }
+            if (adgroupIds?.length) {
+                params.adgroupIds.toSting()
+            }
+            form.setFieldsValue(params)
+        },
+    }));
+
     useTimeout(() => {
         setVisible(false);
     }, 1000);
@@ -278,7 +292,12 @@ const FilterDynamicQuery: React.FC<Props> = ({ onChange, initialValues, queryFor
                 open={visible}
                 trigger={'click'}
                 placement="bottomLeft"
-                onOpenChange={(e) => setVisible(e)}
+                onOpenChange={(e) => {
+                    setVisible(e)
+                    if (e) {
+                        form.setFieldsValue(initialValues)
+                    }
+                }}
                 getPopupContainer={() => document.getElementById('filterQueryContentDynamic') as any}
                 content={<div style={{ width: 500, height: 400, overflowY: 'auto', padding: '10px 16px' }}>
                     <Form
@@ -286,7 +305,6 @@ const FilterDynamicQuery: React.FC<Props> = ({ onChange, initialValues, queryFor
                         form={form}
                         colon={false}
                         layout="vertical"
-                        initialValues={initialValues}
                         onValuesChange={(changedValues) => {
                             console.log(changedValues)
                             let messageArr = message ? message?.split(',') : []
@@ -368,7 +386,7 @@ const FilterDynamicQuery: React.FC<Props> = ({ onChange, initialValues, queryFor
             })}
         </div>
     </div>
-}
+})
 
 export default React.memo(FilterDynamicQuery)
 

+ 113 - 5
src/pages/launchSystemV3/adMonitorListV3/FilterQuery.tsx

@@ -1,6 +1,6 @@
 import { CloseOutlined, DownOutlined, FilterOutlined, SearchOutlined, UpOutlined } from "@ant-design/icons"
 import { Button, DatePicker, Form, Input, InputNumber, Popover, Select, Space } from "antd"
-import React, { useEffect, useState } from "react"
+import React, { forwardRef, useEffect, useImperativeHandle, useState } from "react"
 import '../../launchSystemNew/adq/ad/index.less'
 import moment from "moment"
 import { useLocalStorageState, useTimeout } from "ahooks"
@@ -9,6 +9,7 @@ import { AdListProps } from "@/services/adMonitor/adMonitor"
 import { useModel } from "umi"
 import { ADGROUP_STATUS } from "../adqv3/const"
 import { AdUnitType_Enum } from "@/pages/launchSystemNew/account/const"
+import { MARKETING_GOAL_ENUM, MARKETING_TARGET_TYPE_ENUM } from "../tencentAdPutIn/const"
 const { RangePicker } = DatePicker;
 
 type TypeProps = 'DatePicker' | 'Input' | 'InputNumber' | 'Select'
@@ -30,7 +31,7 @@ interface Props {
  * 请求体 AD 合集
  * @returns 
  */
-const FilterQuery: React.FC<Props> = ({ onChange, initialValues, queryForm, setQueryForm }) => {
+const FilterQuery = forwardRef(({ onChange, initialValues, queryForm, setQueryForm }: Props, ref) => {
 
     /********************************/
     const [form] = Form.useForm();
@@ -41,6 +42,21 @@ const FilterQuery: React.FC<Props> = ({ onChange, initialValues, queryForm, setQ
     const { getPicherList } = useModel('useOperating.useWxGroupList')
     /********************************/
 
+    useImperativeHandle(ref, () => ({
+        onOpen(data: any) {
+            setVisible(true)
+            let { adCreateTimeMin, adCreateTimeMax, putDateBegin, putDateEnd, ...params } = data
+            if (adCreateTimeMin && adCreateTimeMax) {
+                params.adCreateTime = [moment(adCreateTimeMin), moment(adCreateTimeMax)]
+            }
+            if (putDateBegin && putDateEnd) {
+                params.putDate = [moment(putDateBegin), moment(putDateEnd)]
+            }
+            console.log('params', params)
+            form.setFieldsValue(params)
+        },
+    }));
+
     useTimeout(() => {
         setVisible(false);
     }, 1000);
@@ -50,6 +66,40 @@ const FilterQuery: React.FC<Props> = ({ onChange, initialValues, queryForm, setQ
     }, [])
 
     const queryList: QueryProps[] = [
+        {
+            lable: '营销目的',
+            name: 'marketingGoal',
+            type: 'Select',
+            value: (params) => <Select
+                placeholder='营销目的'
+                style={{ width: '100%', minWidth: 130 }}
+                showSearch
+                allowClear
+                filterOption={(input: any, option: any) =>
+                    (option!.children as unknown as string).toLowerCase().includes(input.toLowerCase())
+                }
+                {...params}
+            >
+                {Object.keys(MARKETING_GOAL_ENUM).map(key => <Select.Option value={key} key={key}>{MARKETING_GOAL_ENUM[key as keyof typeof MARKETING_GOAL_ENUM]}</Select.Option>)}
+            </Select>
+        },
+        {
+            lable: '推广内容资产类型',
+            name: 'marketingTargetType',
+            type: 'Select',
+            value: (params) => <Select
+                placeholder='推广内容资产类型'
+                style={{ width: '100%', minWidth: 130 }}
+                showSearch
+                allowClear
+                filterOption={(input: any, option: any) =>
+                    (option!.children as unknown as string).toLowerCase().includes(input.toLowerCase())
+                }
+                {...params}
+            >
+                {Object.keys(MARKETING_TARGET_TYPE_ENUM).map(key => <Select.Option value={key} key={key}>{MARKETING_TARGET_TYPE_ENUM[key as keyof typeof MARKETING_TARGET_TYPE_ENUM]}</Select.Option>)}
+            </Select>
+        },
         {
             lable: '广告创建时间',
             name: 'adCreateTime',
@@ -204,6 +254,54 @@ const FilterQuery: React.FC<Props> = ({ onChange, initialValues, queryForm, setQ
             type: 'InputNumber',
             value: (params) => <InputNumber placeholder="请输入最低总千次曝光成本" style={{ width: '100%' }} {...params} />
         },
+        {
+            lable: '激活首日广告变现ROI区间最小值',
+            name: 'incomeRoi1Min',
+            type: 'InputNumber',
+            value: (params) => <InputNumber placeholder="激活首日广告变现ROI区间最小值" style={{ width: '100%' }} {...params} />
+        },
+        {
+            lable: '激活首日广告变现ROI区间最大值',
+            name: 'incomeRoi1Max',
+            type: 'InputNumber',
+            value: (params) => <InputNumber placeholder="激活首日广告变现ROI区间最大值" style={{ width: '100%' }} {...params} />
+        },
+        {
+            lable: '注册成本区间最小值',
+            name: 'regCostMin',
+            type: 'InputNumber',
+            value: (params) => <InputNumber placeholder="注册成本区间最小值" style={{ width: '100%' }} {...params} />
+        },
+        {
+            lable: '注册成本区间最大值',
+            name: 'regCostMax',
+            type: 'InputNumber',
+            value: (params) => <InputNumber placeholder="注册成本区间最大值" style={{ width: '100%' }} {...params} />
+        },
+        {
+            lable: '注册成本(平台上报+广告主上报)区间最小值',
+            name: 'regCostPlaMin',
+            type: 'InputNumber',
+            value: (params) => <InputNumber placeholder="注册成本(平台上报+广告主上报)区间最小值" style={{ width: '100%' }} {...params} />
+        },
+        {
+            lable: '注册成本(平台上报+广告主上报)区间最大值',
+            name: 'regCostPlaMax',
+            type: 'InputNumber',
+            value: (params) => <InputNumber placeholder="注册成本(平台上报+广告主上报)区间最大值" style={{ width: '100%' }} {...params} />
+        },
+        {
+            lable: '点击均价最小值',
+            name: 'cpcMin',
+            type: 'InputNumber',
+            value: (params) => <InputNumber placeholder="点击均价最小值" style={{ width: '100%' }} {...params} />
+        },
+        {
+            lable: '点击均价最大值',
+            name: 'cpcMax',
+            type: 'InputNumber',
+            value: (params) => <InputNumber placeholder="点击均价最大值" style={{ width: '100%' }} {...params} />
+        },
     ]
 
     useEffect(() => {
@@ -362,7 +460,12 @@ const FilterQuery: React.FC<Props> = ({ onChange, initialValues, queryForm, setQ
                 open={visible}
                 trigger={'click'}
                 placement="bottomLeft"
-                onOpenChange={(e) => setVisible(e)}
+                onOpenChange={(e) => {
+                    setVisible(e)
+                    if (e && initialValues) {
+                        form.setFieldsValue(initialValues)
+                    }
+                }}
                 getPopupContainer={() => document.getElementById('filterQueryContentAd') as any}
                 content={<div style={{ width: 500, height: 400, overflowY: 'auto', padding: '10px 16px' }}>
                     <Form
@@ -370,7 +473,6 @@ const FilterQuery: React.FC<Props> = ({ onChange, initialValues, queryForm, setQ
                         form={form}
                         colon={false}
                         layout="vertical"
-                        initialValues={initialValues}
                         onValuesChange={(changedValues) => {
                             console.log(changedValues)
                             let messageArr = message ? message?.split(',') : []
@@ -421,6 +523,12 @@ const FilterQuery: React.FC<Props> = ({ onChange, initialValues, queryForm, setQ
                     case 'optimizationGoal':
                         value = OptimizationGoalEnum[value as keyof typeof OptimizationGoalEnum] || '请选择'
                         break
+                    case 'marketingGoal':
+                        value = MARKETING_GOAL_ENUM[value as keyof typeof MARKETING_GOAL_ENUM] || '请选择'
+                        break
+                    case 'marketingTargetType':
+                        value = MARKETING_TARGET_TYPE_ENUM[value as keyof typeof MARKETING_TARGET_TYPE_ENUM] || '请选择'
+                        break
                     case 'promotedObjectType':
                         value = PromotedObjectType[value as keyof typeof PromotedObjectType] || '请选择'
                         break
@@ -467,7 +575,7 @@ const FilterQuery: React.FC<Props> = ({ onChange, initialValues, queryForm, setQ
             })}
         </div>
     </div>
-}
+})
 
 export default React.memo(FilterQuery)
 

+ 93 - 0
src/pages/launchSystemV3/adMonitorListV3/SaveSearch/index.tsx

@@ -0,0 +1,93 @@
+import { useAjax } from "@/Hook/useAjax";
+import { addV3StrategyApi, getV3StrategyListApi } from "@/services/adqV3";
+import { Button, Form, Input, message, Modal, Select, Space } from "antd"
+import React, { useEffect, useState } from "react"
+
+interface Props {
+    type: string
+    strategyValue: string
+    onChange?: (value: string) => void
+}
+/**
+ * 保存搜索条件
+ * @returns 
+ */
+const SaveSearch: React.FC<Props> = ({ type, strategyValue, onChange }) => {
+
+    /****************************************/
+    const [form] = Form.useForm();
+    const [visible, setVisible] = useState<boolean>(false)
+    const [queryFormNew] = useState<PULLIN.GetV3StrategyListProps>({ pageNum: 1, pageSize: 100, type })
+
+
+    const addV3Strategy = useAjax((params) => addV3StrategyApi(params))
+    const getStrategy = useAjax((params) => getV3StrategyListApi(params))
+    /****************************************/
+
+    useEffect(() => {
+        getStrategy.run({ ...queryFormNew, type })
+    }, [queryFormNew, type])
+
+    const seve = () => {
+        setVisible(true)
+    }
+
+    const handleOk = () => {
+        form.validateFields().then(values => {
+            addV3Strategy.run({ ...values, strategyValue: strategyValue, type: type }).then(res => {
+                if (res) {
+                    getStrategy.refresh()
+                    message.success('保存成功')
+                    form.resetFields()
+                    setVisible(false)
+                }
+            })
+        })
+    }
+
+    return <>
+        <Space>
+            <Select
+                showSearch
+                placeholder="选择预设"
+                optionFilterProp="children"
+                onChange={(_, option) => {
+                    if (option?.strategyValue) {
+                        onChange?.(option?.strategyValue)
+                    }
+                }}
+                allowClear
+                loading={getStrategy.loading}
+                filterOption={(input: any, option: any) =>
+                    (option!.children as unknown as string).toLowerCase().includes(input.toLowerCase())
+                }
+                style={{ width: 150 }}
+            >
+                {getStrategy?.data?.records?.map((item: { strategyKey: string; strategyValue: string; id: any }) => <Select.Option value={item.id} strategyValue={item.strategyValue} key={item.id}>{item.strategyKey}</Select.Option>)}
+            </Select>
+            <Button onClick={seve}>搜索条件存为预设</Button>
+        </Space>
+        {visible && <Modal
+            title={<strong>搜索条件存为预设</strong>}
+            open={visible}
+            onCancel={() => { form.resetFields(); setVisible(false) }}
+            onOk={handleOk}
+            confirmLoading={addV3Strategy.loading}
+            className="modalResetCss"
+        >
+            <Form
+                form={form}
+                layout='vertical'
+                name="saveUpdateAd"
+                colon={false}
+                initialValues={{}}
+            >
+                <Form.Item label={<strong>预设名称</strong>} name='strategyKey' rules={[{ required: true, message: '请输入预设名称' }]}>
+                    <Input placeholder="请输入预设名称" showCount maxLength={30} />
+                </Form.Item>
+            </Form>
+        </Modal>}
+    </>
+}
+
+export default React.memo(SaveSearch)

+ 16 - 0
src/pages/launchSystemV3/adMonitorListV3/TabDynamic.tsx

@@ -9,6 +9,7 @@ import TableData from "@/pages/launchSystemNew/components/TableData"
 import tableDynamicConfig from "./tableDynamicConfig"
 import { PauseCircleOutlined, PlayCircleOutlined } from "@ant-design/icons"
 import { updateBatchDynamicCreativesInfoApi } from "@/services/launchAdq/adqv3"
+import SaveSearch from "./SaveSearch"
 
 const configName = '创意列表3.0'
 
@@ -19,6 +20,7 @@ const configName = '创意列表3.0'
 const TabDynamic: React.FC = () => {
 
     /***********************************/
+    const ref = useRef(null)
     const [queryForm, setQueryForm] = useState<GetDynamicCreativeMonitorProps>({ pageNum: 1, pageSize: 20, columns: [], isDeleted: false, dataTimeMin: moment().subtract(7, 'days').format('YYYY-MM-DD'), dataTimeMax: moment().format('YYYY-MM-DD') })
     const [filterForm, setFilterForm] = useState<GetDynamicCreativeMonitorProps>()
     const [selectedRows, setSelectedRows] = useState<any[]>([])
@@ -95,6 +97,7 @@ const TabDynamic: React.FC = () => {
                 onChange={(value) => {
                     setFilterForm({ ...value })
                 }}
+                ref={ref}
             />
         </Row>
         <div className='expandClassname'>
@@ -128,6 +131,19 @@ const TabDynamic: React.FC = () => {
                     <Row gutter={[10, 10]} align='middle'>
                         <Col><Button type='primary' style={{ background: '#67c23a', borderColor: '#67c23a' }} loading={updateBatchDynamicCreativesInfo.loading} icon={<PlayCircleOutlined />} disabled={selectedRows.length === 0} onClick={() => dynamicHandle('启动')}>启动</Button></Col>
                         <Col><Button type='primary' style={{ background: '#e6a23c', borderColor: '#e6a23c' }} loading={updateBatchDynamicCreativesInfo.loading} icon={<PauseCircleOutlined />} disabled={selectedRows.length === 0} onClick={() => dynamicHandle('暂停')}>暂停</Button></Col>
+                        <Col><SaveSearch
+                            type='DYNAMIC_SEARCH'
+                            strategyValue={JSON.stringify({
+                                queryForm,
+                                filterForm
+                            })}
+                            onChange={(value) => {
+                                let { queryForm, filterForm } = JSON.parse(value)
+                                setQueryForm(data => ({ ...queryForm, pageNum: data.pageNum, pageSize: data.pageSize }))
+                                setFilterForm(filterForm);
+                                (ref.current as any)?.onOpen(filterForm)
+                            }}
+                        /></Col>
                     </Row>
                 </Space>}
                 rowSelection={{

+ 18 - 0
src/pages/launchSystemV3/adMonitorListV3/adPlanList.tsx

@@ -19,10 +19,12 @@ import RuleAccountLog from '@/components/EarlyWarning/ruleAccountLog'
 import Details from './Details'
 import { modifyStatusBatchApi, syncBatchApi } from '@/services/launchAdq/adqv3'
 import UpdateAd from '../adqv3/ad/updateAd'
+import SaveSearch from './SaveSearch'
 
 const AdPlanList: React.FC<{ userId: string }> = (props) => {
 
     /***********************/
+    const refF = useRef(null)
     const { userId } = props
     const [selectedRows, setSelectedRows] = useState<any[]>([])
     const [detailShow, setDetailShow] = useState<boolean>(false)
@@ -48,6 +50,7 @@ const AdPlanList: React.FC<{ userId: string }> = (props) => {
     const [scrollLeft, setScrollLeft] = useState<number>(0)
     const [totalData, setTotalData] = useState<any>({})
     const [tableField, setTableField] = useState<{ title: string, dataIndex: string }[]>([])
+    const [initialValues, setInitialValues] = useState<any>()
 
     const [trendVisible, setTrendVisible] = useState<boolean>(false)
     const [trendData, setTrendData] = useState<any>({})
@@ -248,6 +251,8 @@ const AdPlanList: React.FC<{ userId: string }> = (props) => {
                 onChange={(value) => {
                     setFilterForm({ ...value })
                 }}
+                initialValues={filterForm}
+                ref={refF}
             />
         </Row>
         <div ref={ref} className='expandClassname'>
@@ -283,6 +288,19 @@ const AdPlanList: React.FC<{ userId: string }> = (props) => {
                         <Col><Button type='primary' style={{ background: '#67c23a', borderColor: '#67c23a' }} loading={modifyStatusBatch.loading} icon={<PlayCircleOutlined />} disabled={selectedRows.length === 0} onClick={() => adStatus(true)}>启动</Button></Col>
                         <Col><Button type='primary' style={{ background: '#e6a23c', borderColor: '#e6a23c' }} loading={modifyStatusBatch.loading} icon={<PauseCircleOutlined />} disabled={selectedRows.length === 0} onClick={() => adStatus(false)}>暂停</Button></Col>
                         <Col><Button type='primary' icon={<TransactionOutlined />} disabled={selectedRows.length === 0} onClick={() => setUpdate({ visible: true })}>修改出价</Button></Col>
+                        <Col><SaveSearch
+                            type='ADPLAN_SEARCH'
+                            strategyValue={JSON.stringify({
+                                queryForm,
+                                filterForm
+                            })}
+                            onChange={(value) => {
+                                let { queryForm, filterForm } = JSON.parse(value)
+                                setQueryForm(data => ({ ...queryForm, pageNum: data.pageNum, pageSize: data.pageSize }))
+                                setFilterForm(filterForm);
+                                (refF.current as any)?.onOpen(filterForm)
+                            }}
+                        /></Col>
                     </Row>
                 </Space>}
                 rowSelection={{

+ 2 - 0
src/pages/launchSystemV3/adMonitorListV3/config.ts

@@ -25,6 +25,8 @@ const planAdConfig = [
             { title: '是否已删除', dataIndex: 'is_deleted', serverIndex: 'adgroup.is_deleted', label: '广告详情', default: 19, width: 60 },
             { title: '广告状态', dataIndex: 'system_status', serverIndex: 'adgroup.system_status', label: '广告详情', default: 20, width: 100 },
             { title: '广告详情', dataIndex: 'cost_speed', label: '广告详情', default: 21, width: 80 },
+            { title: '营销目的', dataIndex: 'marketing_goal', label: '广告详情', width: 85, serverIndex: 'adgroup.marketing_goal' },
+            { title: '推广内容资产类型', dataIndex: 'marketing_target_type', label: '广告详情', width: 85, serverIndex: 'adgroup.marketing_target_type' },
             { title: '标记备注', dataIndex: 'tag_remark', label: '广告详情', width: 80, serverIndex: 'adgroup_user_tag.tag_remark' },
             { title: '业务单元类型', dataIndex: 'ad_unit_type', label: '广告详情', width: 75, serverIndex: 'ad_account.ad_unit_type' },
             { title: '创意预览', dataIndex: 'creative_ids', serverIndex: 'adgroup_data.creative_ids', label: '广告详情', width: 130 },

+ 23 - 0
src/pages/launchSystemV3/adMonitorListV3/tablePlanListConfig.tsx

@@ -12,6 +12,7 @@ import SwitchStatus from '../adqv3/ad/switchStatus'
 import CreativePreview from './CreativePreview'
 import { ADGROUP_STATUS } from '@/pages/adMonitor/adMonitorList/data'
 import { AdUnitType_Enum } from '@/pages/launchSystemNew/account/const'
+import { MARKETING_GOAL_ENUM, MARKETING_TARGET_TYPE_ENUM } from '../tencentAdPutIn/const'
 function tablePlanConfig(
     onChange: () => void,
     details: (data: any) => void,
@@ -305,6 +306,28 @@ function tablePlanConfig(
                 </div>
             }
         },
+        {
+            title: '营销目的',
+            dataIndex: 'marketing_goal',
+            key: 'marketing_goal',
+            align: 'center',
+            width: 80,
+            className: 'padding2',
+            render: (a: any, b: any) => {
+                return MARKETING_GOAL_ENUM[a as keyof typeof MARKETING_GOAL_ENUM]
+            }
+        },
+        {
+            title: '推广内容资产类型',
+            dataIndex: 'marketing_target_type',
+            key: 'marketing_target_type',
+            align: 'center',
+            width: 80,
+            className: 'padding2',
+            render: (a: any, b: any) => {
+                return MARKETING_TARGET_TYPE_ENUM[a as keyof typeof MARKETING_TARGET_TYPE_ENUM]
+            }
+        },
         {
             title: '创意预览',
             dataIndex: 'creative_ids',

+ 1 - 1
src/pages/launchSystemV3/adqv3/ad/autoAcquisitionSet.tsx

@@ -143,7 +143,7 @@ const AutoAcquisitionSet: React.FC<Props> = ({ selectAdList, visible, onChange,
                         {autoAcquisitionData?.autoAcquisitionEnabled && <>
                             <Radio.Group buttonStyle="solid" value={addType} onChange={(e) => setAddType(e.target.value)}>
                                 <Radio.Button value="fixed">固定值</Radio.Button>
-                                <Radio.Button value="percent" disabled={!isPercent}>百分比添加</Radio.Button>
+                                <Radio.Button value="percent" disabled={!isPercent}>百分比上下浮动修改</Radio.Button>
                             </Radio.Group>
                             {addType === 'fixed' ?
                                 <InputNumber placeholder="起量预算,建议设置为出价的10倍" min={200} max={100000} style={{ width: '100%' }} value={autoAcquisitionData?.autoAcquisitionBudget} onChange={(e) => setAutoAcquisitionData({ autoAcquisitionEnabled: true, autoAcquisitionBudget: e || 0 })} />

+ 34 - 6
src/pages/launchSystemV3/adqv3/ad/updateAd.tsx

@@ -1,4 +1,4 @@
-import { Form, Input, message, Modal } from "antd"
+import { Form, Input, InputNumber, message, Modal, Radio } from "antd"
 import React from "react"
 import { useAjax } from "@/Hook/useAjax";
 import { modifyAmountBatchApi } from "@/services/launchAdq/adqv3";
@@ -17,6 +17,7 @@ const UpdateAd: React.FC<Props> = ({ visible, onChange, onClose, selectedRows })
 
     /***************************/
     const [form] = Form.useForm();
+    const updateType = Form.useWatch('updateType', form)
 
     const modifyAmountBatch = useAjax((params) => modifyAmountBatchApi(params))
     /***************************/
@@ -24,7 +25,13 @@ const UpdateAd: React.FC<Props> = ({ visible, onChange, onClose, selectedRows })
     const handleOk = () => {
         form.validateFields().then(values => {
             let accountAdgroupMaps = [...new Set(selectedRows?.map(item => item.accountId + ',' + item.adgroupId))]
-            modifyAmountBatch.run({ accountAdgroupMaps, ...values }).then(res => {
+            let paramsCj: any = {}
+            if (values?.updateType === 'percent') {
+                paramsCj.bidAmountPercent = values?.bidAmountPercent / 100
+            } else {
+                paramsCj.bidAmount = values?.bidAmount
+            }
+            modifyAmountBatch.run({ accountAdgroupMaps, ...paramsCj }).then(res => {
                 if (res) {
                     message.success(`修改操作完成!`)
                     onChange?.()
@@ -42,15 +49,36 @@ const UpdateAd: React.FC<Props> = ({ visible, onChange, onClose, selectedRows })
     >
         <Form
             form={form}
-            labelCol={{ span: 4 }}
+            labelCol={{ span: 6 }}
             className='ad_form_style'
             colon={false}
             labelAlign="left"
-            initialValues={{}}
+            initialValues={{ updateType: 'fixed' }}
         >
-            <Form.Item label={<strong>出价</strong>} name='bidAmount' rules={[{ required: true, message: '请输入价格' }]}>
-                <Input placeholder={`输入价格 元`} style={{ width: 300 }} />
+            <Form.Item
+                label={<strong>出价修改方式</strong>}
+                name='updateType'
+                rules={[
+                    { required: true, message: '请选择出价修改方式' }
+                ]}
+            >
+                <Radio.Group buttonStyle="solid">
+                    <Radio.Button value="fixed">固定值</Radio.Button>
+                    <Radio.Button value="percent">百分比上下浮动修改</Radio.Button>
+                </Radio.Group>
             </Form.Item>
+
+            {updateType === 'fixed' ? <Form.Item label={<strong>出价</strong>} name='bidAmount' rules={[{ required: true, message: '请输入价格' }]}>
+                <Input placeholder={`输入价格 元`} style={{ width: 300 }} />
+            </Form.Item> : <Form.Item
+                label={<strong>浮动比</strong>}
+                name='bidAmountPercent'
+                rules={[
+                    { required: true, message: '请输入' }
+                ]}
+            >
+                <InputNumber placeholder="出价,原有基础上下调百分比" style={{ width: '100%' }} addonAfter="%" />
+            </Form.Item>}
         </Form>
     </Modal>
 }

+ 76 - 14
src/pages/launchSystemV3/adqv3/ad/updateAd3.tsx

@@ -26,6 +26,7 @@ const UpdateAd3: React.FC<Props> = ({ visible, type, onClose, onChange, updateDa
     /****************************************/
     const [form] = Form.useForm();
     const timeSeriesType = Form.useWatch('timeSeriesType', form)
+    const updateType = Form.useWatch('updateType', form)
 
     const [failIdList, setFailIdList] = useState<{ adgroupId: number, code: number, message: string, messageCn: string }[]>([])
     const [failVisible, setFailVisible] = useState<boolean>(false)
@@ -50,7 +51,13 @@ const UpdateAd3: React.FC<Props> = ({ visible, type, onClose, onChange, updateDa
         let accountAdgroupMaps = [...new Set(updateData?.map(item => item.accountId + ',' + item.adgroupId))]
         switch (type) {
             case '修改出价':
-                modifyAmountBatch.run({ accountAdgroupMaps, ...values }).then(res => {
+                let paramsCj: any = {}
+                if (values?.updateType === 'percent') {
+                    paramsCj.bidAmountPercent = values?.bidAmountPercent / 100
+                } else {
+                    paramsCj.bidAmount = values?.bidAmount
+                }
+                modifyAmountBatch.run({ accountAdgroupMaps, ...paramsCj }).then(res => {
                     if (res?.failIdList?.length === 0) {
                         message.success(`修改操作完成!`)
                         onChange?.()
@@ -63,7 +70,20 @@ const UpdateAd3: React.FC<Props> = ({ visible, type, onClose, onChange, updateDa
             case '修改名称':
             case '深度优化ROI':
             case '修改投放首日开始时间':
-                updateBatchAdgroupInfo.run({ accountAdgroupMaps, ...values }).then(res => {
+                let params2: any = {}
+                if (type === '深度优化ROI') {
+                    params2 = JSON.parse(JSON.stringify(values))
+                    if (params2.updateType === 'percent') {
+                        delete params2?.deepConversionSpec?.deepConversionWorthSpec?.expectedRoi
+                        params2.deepConversionSpec.deepConversionWorthSpec.expectedRoiPercent = params2?.deepConversionSpec?.deepConversionWorthSpec?.expectedRoiPercent / 100
+                    } else {
+                        delete params2?.deepConversionSpec?.deepConversionWorthSpec?.expectedRoiPercent
+                    }
+                    delete params2.updateType
+                } else {
+                    params2 = values
+                }
+                updateBatchAdgroupInfo.run({ accountAdgroupMaps, ...params2 }).then(res => {
                     if (res?.failIdList?.length === 0) {
                         message.success(`修改操作完成!`)
                         onChange?.()
@@ -140,7 +160,7 @@ const UpdateAd3: React.FC<Props> = ({ visible, type, onClose, onChange, updateDa
                 form={form}
                 name="updateAd3.0"
                 labelAlign='left'
-                labelCol={{ span: type === '修改投放首日开始时间' ? 6 : 4 }}
+                labelCol={{ span: ['修改投放首日开始时间', '修改出价'].includes(type) ? 6 : 4 }}
                 colon={false}
                 style={{ backgroundColor: '#f1f4fc', maxHeight: 600, overflow: 'hidden', overflowY: 'auto', padding: '10px 10px 10px', borderRadius: '0 0 8px 8px' }}
                 scrollToFirstError
@@ -148,21 +168,44 @@ const UpdateAd3: React.FC<Props> = ({ visible, type, onClose, onChange, updateDa
                     message.error(errorFields?.[0]?.errors?.[0])
                 }}
                 onFinish={handleOk}
-                initialValues={{ timeSeriesType: '0', timeSeries: getTimeSeriesList() }}
+                initialValues={{ timeSeriesType: '0', timeSeries: getTimeSeriesList(), updateType: 'fixed' }}
             >
                 <Card
                     title={<strong style={{ fontSize: 14 }}>{type === '删除' ? '确认删除?' : '修改设置'}</strong>}
                     className="cardResetCss"
                 >
-                    {type === '修改出价' ? <Form.Item
-                        label={<strong>出价</strong>}
-                        name='bidAmount'
-                        rules={[
-                            { required: true, message: '请输入' }
-                        ]}
-                    >
-                        <InputNumber min={0} style={{ width: '100%' }} placeholder="请输入价格 元" />
-                    </Form.Item> : type === '修改名称' ? <Form.Item
+                    {type === '修改出价' ? <>
+                        <Form.Item
+                            label={<strong>出价修改方式</strong>}
+                            name='updateType'
+                            rules={[
+                                { required: true, message: '请选择出价修改方式' }
+                            ]}
+                        >
+                            <Radio.Group buttonStyle="solid">
+                                <Radio.Button value="fixed">固定值</Radio.Button>
+                                <Radio.Button value="percent">百分比上下浮动修改</Radio.Button>
+                            </Radio.Group>
+                        </Form.Item>
+                        {updateType === 'fixed' ? <Form.Item
+                            label={<strong>出价</strong>}
+                            name='bidAmount'
+                            rules={[
+                                { required: true, message: '请输入' }
+                            ]}
+                        >
+                            <InputNumber min={0} style={{ width: '100%' }} placeholder="请输入价格 元" />
+                        </Form.Item> : <Form.Item
+                            label={<strong>浮动比</strong>}
+                            name='bidAmountPercent'
+                            rules={[
+                                { required: true, message: '请输入' }
+                            ]}
+                        >
+                            <InputNumber placeholder="出价,原有基础上下调百分比" style={{ width: '100%' }} addonAfter="%" />
+                        </Form.Item>}
+
+                    </> : type === '修改名称' ? <Form.Item
                         label={<strong>广告名称</strong>}
                         name='adgroupName'
                         // tooltip="下标、日期时分秒、广告账户创建时默认自带"
@@ -232,6 +275,18 @@ const UpdateAd3: React.FC<Props> = ({ visible, type, onClose, onChange, updateDa
                             </Select>
                         </Form.Item>
                         <Form.Item
+                            label={<strong>期望ROI修改方式</strong>}
+                            name='updateType'
+                            rules={[
+                                { required: true, message: '请选择期望ROI修改方式' }
+                            ]}
+                        >
+                            <Radio.Group buttonStyle="solid">
+                                <Radio.Button value="fixed">固定值</Radio.Button>
+                                <Radio.Button value="percent">百分比上下浮动修改</Radio.Button>
+                            </Radio.Group>
+                        </Form.Item>
+                        {updateType === 'fixed' ? <Form.Item
                             label={<strong>期望ROI</strong>}
                             name={['deepConversionSpec', 'deepConversionWorthSpec', 'expectedRoi']}
                             rules={[
@@ -248,7 +303,14 @@ const UpdateAd3: React.FC<Props> = ({ visible, type, onClose, onChange, updateDa
                             ]}
                         >
                             <InputNumber style={{ width: 480 }} placeholder={`期望ROI目标范围0.001~1000,输入0.05,表示ROI目标为5%`} />
-                        </Form.Item>
+                        </Form.Item> : <Form.Item
+                            label={<strong>期望ROI浮动比</strong>}
+                            name={['deepConversionSpec', 'deepConversionWorthSpec', 'expectedRoiPercent']}
+                            rules={[{ required: true, message: '请输入期望ROI浮动比' }]}
+                        >
+                            <InputNumber style={{ width: 480 }} placeholder="期望ROI,原有基础上下调百分比" addonAfter="%" />
+                        </Form.Item>}
+
                     </> : type === '修改投放首日开始时间' ? <Form.Item name='firstDayBeginTime' label={<strong>首日开始时间</strong>} rules={[{ required: true, message: '请选择首日开始时间' }]}>
                         <Select
                             style={{ width: 180 }}

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

@@ -29,7 +29,8 @@ declare namespace ADQV3 {
         suspend: boolean
     };
     interface ModifyAmountBatchProps extends AccountAdgroupMapsProps {
-        bidAmount: number
+        bidAmount?: number
+        bidAmountPercent?: number
     };
     interface GetDynamicCreativeProps {
         pageNum: number;

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

@@ -422,7 +422,7 @@ const AddMaterial: React.FC<Props> = ({ creativeTemplateId, materialData, delive
                                                         num: 1,
                                                         defaultParams: {
                                                             materialType: 'video',
-                                                            sizeQueries: creativeTemplateId === 1708 ? [{ relation: '>=', width: 1280, height: 720 }] : [{ relation: '>=', width: item.restriction.videoRestriction.minWidth, height: item.restriction.videoRestriction.minHeight }],
+                                                            sizeQueries: creativeTemplateId === 1708 ? [{ relation: '=', width: 1280, height: 720 }] : [{ relation: item.restriction.videoRestriction.minWidth > item.restriction.videoRestriction.minHeight ? '=' : '>=', width: item.restriction.videoRestriction.minWidth, height: item.restriction.videoRestriction.minHeight }],
                                                             fileSize: item.restriction.videoRestriction.fileSize * 1024
                                                         }
                                                     })
@@ -483,7 +483,7 @@ const AddMaterial: React.FC<Props> = ({ creativeTemplateId, materialData, delive
                                                         </p>
                                                     </div>
                                                     {videoUploads && Object.keys(videoUploads)?.length > 0 && <div style={{ width: 32 }}>
-                                                        {dynamicGroup?.length > 0 && dynamicGroup[num] && (Object.keys(dynamicGroup[num])?.includes('video_id') || Object.keys(dynamicGroup[num])?.includes('short_video1')) && <VideoFrameSelect onChange={(e) => setFrame(e, num, item.name)} url={dynamicGroup[num]?.['video_id']?.['url'] || dynamicGroup[num]?.['short_video1']?.['url']} />}
+                                                        {dynamicGroup?.length > 0 && dynamicGroup[num] && ((Object.keys(dynamicGroup[num])?.includes('video_id') && dynamicGroup[num]['video_id']['materialType'] === 0) || (Object.keys(dynamicGroup[num])?.includes('short_video1') && dynamicGroup[num]['short_video1']['materialType'] === 0)) && <VideoFrameSelect onChange={(e) => setFrame(e, num, item.name)} url={dynamicGroup[num]?.['video_id']?.['url'] || dynamicGroup[num]?.['short_video1']?.['url']} />}
                                                     </div>}
                                                 </Space>
                                             </Form.Item>

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

@@ -83,7 +83,7 @@ const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData,
                 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 }} />
+                            <VideoNews src={dynamic?.video_id?.url || dynamic?.short_video1?.url} keyFrameImageUrl={dynamic?.video_id?.keyFrameImageUrl || dynamic?.short_video1?.keyFrameImageUrl} 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>}
@@ -108,10 +108,10 @@ const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData,
                                     {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')) {
+                        } else if (item?.url?.includes('mp4') || item?.keyFrameImageUrl) {
                             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)" }} />
+                                    <VideoNews src={item?.url} style={{ width: 30, height: 30 }} keyFrameImageUrl={item?.keyFrameImageUrl} maskBodyStyle={{ backgroundColor: "rgba(242, 246, 254, 0.1)" }} />
                                 </div>
                             </div>
                         } else {

+ 22 - 17
src/pages/launchSystemV3/tencentAdPutIn/create/SelectAccount/index.tsx

@@ -7,7 +7,7 @@ import { getGroupListApi, getAccountListApi } from "@/services/launchAdq/subgrou
 import { useAjax } from "@/Hook/useAjax";
 import { getAccountAssetsGroupListAllApi } from "@/services/adqV3/global";
 import { getAllUserAccountApi } from "@/services/launchAdq/adAuthorize";
-import { groupBy } from "@/utils/utils";
+import { arraysHaveSameValues, groupBy } from "@/utils/utils";
 import { DELIVERY_MODE_ENUM } from "../../const";
 import '../../index.less'
 const { Text } = Typography;
@@ -145,6 +145,15 @@ const SelectAccount: React.FC<Props> = ({ putInType, accountCreateLogs, setAccou
         setTipsVisible(false)
     }
 
+    const handleCancel = () => {
+        document.body.style.overflow = 'auto';
+        setSelectedRows([])
+        setInputAccountList([])
+        setMediaTypeGroupIds([])
+        setAssetSharingDeta(undefined)
+        setVisible(false)
+    }
+
     return <div className={style.selectAccount}>
         <div className={style.selectAccount_row} style={{ zIndex: visible ? 1000 : 1 }}>
             <Selector
@@ -164,6 +173,7 @@ const SelectAccount: React.FC<Props> = ({ putInType, accountCreateLogs, setAccou
                             <Tag
                                 closable
                                 color="#F5F5F5"
+                                key={selectedRows[0].accountId}
                                 className={style.content_tag}
                                 onClose={() => {
                                     setSelectedRows(selectedRows.slice(1))
@@ -172,10 +182,10 @@ const SelectAccount: React.FC<Props> = ({ putInType, accountCreateLogs, setAccou
                             {selectedRows?.length > 1 && <Tooltip
                                 color="#FFF"
                                 title={<span style={{ color: '#000' }}>
-                                    {selectedRows?.filter((item, index) => index !== 0)?.map((item, index) => <Tag
+                                    {selectedRows?.filter((_, index) => index !== 0)?.map((item) => <Tag
                                         color="#F5F5F5"
                                         className={style.content_tag}
-                                        key={index}
+                                        key={item.accountId}
                                         closable
                                         onClose={() => {
                                             setSelectedRows(selectedRows?.filter(item1 => item1.accountId !== item.accountId))
@@ -190,6 +200,7 @@ const SelectAccount: React.FC<Props> = ({ putInType, accountCreateLogs, setAccou
                                 closable
                                 color="#F5F5F5"
                                 className={style.content_tag}
+                                key={accountCreateLogs[0].accountId}
                                 onClose={() => {
                                     setAccountCreateLogs(accountCreateLogs.slice(1))
                                 }}
@@ -197,10 +208,10 @@ const SelectAccount: React.FC<Props> = ({ putInType, accountCreateLogs, setAccou
                             {accountCreateLogs?.length > 1 && <Tooltip
                                 color="#FFF"
                                 title={<span style={{ color: '#000' }}>
-                                    {accountCreateLogs?.filter((item, index) => index !== 0)?.map((item, index) => <Tag
+                                    {accountCreateLogs?.filter((_, index) => index !== 0)?.map((item) => <Tag
                                         className={style.content_tag}
                                         color="#F5F5F5"
-                                        key={index}
+                                        key={item.accountId}
                                         closable
                                         onClose={() => {
                                             setAccountCreateLogs(accountCreateLogs?.filter(item1 => item1.accountId !== item.accountId))
@@ -366,22 +377,16 @@ const SelectAccount: React.FC<Props> = ({ putInType, accountCreateLogs, setAccou
                     />
                 </div>
                 <div className={style.selectAccount_list_footer}>
-                    <Button
-                        className={style.resetCss}
-                        onClick={() => {
-                            document.body.style.overflow = 'auto';
-                            setSelectedRows([])
-                            setInputAccountList([])
-                            setMediaTypeGroupIds([])
-                            setAssetSharingDeta(undefined)
-                            setVisible(false)
-                        }}
-                    >取消</Button>
+                    <Button className={style.resetCss} onClick={handleCancel}>取消</Button>
                     <Button
                         className={style.resetCss}
                         type="primary"
                         style={{ marginLeft: 8 }}
                         onClick={() => {
+                            if (accountCreateLogs?.length && arraysHaveSameValues(accountCreateLogs.map(item => item.accountId), selectedRows.map(item => item.accountId))) {
+                                handleCancel()
+                                return
+                            }
                             let authMainAccountId: any
                             let isY = false
                             // 1.判断是否有账户组素材 有的话 获取账户组ID
@@ -446,7 +451,7 @@ const SelectAccount: React.FC<Props> = ({ putInType, accountCreateLogs, setAccou
                                     message.error('请联系管理员')
                                 }
                             }
-                            
+
                             if (isY && authMainAccountId) {
                                 // 2.有的话判断 判断账户是否为一组
                                 console.log('authMainAccountId---->', authMainAccountId, getauthMainAccountData(selectedRows))

+ 16 - 7
src/pages/launchSystemV3/tencentAdPutIn/create/addDynamic.tsx

@@ -440,7 +440,8 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
                                 value: {
                                     imageUrl: item?.image_id?.url,
                                     imageId: item?.image_id?.id,
-                                    materialType: item?.image_id?.materialType
+                                    materialType: item?.image_id?.materialType,
+                                    accountId: item?.image_id?.accountId
                                 }
                             })
                         }]
@@ -453,7 +454,8 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
                             return {
                                 imageUrl: l?.url,
                                 imageId: l?.id,
-                                materialType: l?.materialType
+                                materialType: l?.materialType,
+                                accountId: l?.accountId
                             }
                         })
                         return [{
@@ -468,12 +470,15 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
                         let value: any = {
                             materialType: item?.video_id?.materialType || item?.short_video1?.materialType || 0,
                             videoUrl: item?.video_id?.url || item?.short_video1?.url,
-                            videoId: item?.video_id?.id || item?.short_video1?.id
+                            videoId: item?.video_id?.id || item?.short_video1?.id,
+                            keyFrameImageUrl: item?.video_id?.keyFrameImageUrl || item?.short_video1?.keyFrameImageUrl,
+                            accountId: item?.video_id?.accountId || item?.short_video1?.accountId,
                         }
                         if (item?.cover_id?.url) {
                             value.imageUrl = item?.cover_id?.url
                             value.imageId = item?.cover_id?.id
                             value.materialCoverType = item?.cover_id?.materialType
+                            value.accountId = item?.cover_id?.accountId
                         }
                         return [{
                             type: mType,
@@ -501,20 +506,23 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
                                             return {
                                                 imageUrl: i?.url,
                                                 imageId: i?.id,
-                                                materialType: i?.materialType
+                                                materialType: i?.materialType,
+                                                accountId: i?.accountId
                                             }
                                         })
                                     }
                                 })
                             }
-                        } else if (l?.url?.includes('mp4')) {
+                        } else if (l?.url?.includes('mp4') || l?.keyFrameImageUrl) {
                             return {
                                 type: 'video',
                                 valueJson: JSON.stringify({
                                     value: {
                                         materialType: l?.materialType,
                                         videoUrl: l?.url,
-                                        videoId: l?.id
+                                        videoId: l?.id,
+                                        keyFrameImageUrl: l?.keyFrameImageUrl,
+                                        accountId: l?.accountId
                                     }
                                 })
                             }
@@ -525,7 +533,8 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
                                     value: {
                                         imageUrl: l?.url,
                                         imageId: l?.id,
-                                        materialType: l?.materialType
+                                        materialType: l?.materialType,
+                                        accountId: l?.accountId
                                     }
                                 })
                             }

+ 7 - 8
src/pages/launchSystemV3/tencentAdPutIn/create/index.tsx

@@ -202,15 +202,15 @@ const Create: React.FC = () => {
                                     let { type, valueJson } = item[0]
                                     let value = JSON.parse(valueJson).value
                                     if (type === 'image') {
-                                        return { image_id: { id: value.imageId, url: value.imageUrl, materialType: value.materialType } }
+                                        return { image_id: { id: value.imageId, url: value.imageUrl, materialType: value.materialType, accountId: value?.accountId } }
                                     } else if (type === 'image_list' || type === 'element_story') {
-                                        return { [type]: value.list.map((l: { imageUrl: any; imageId: any; materialType: any }) => ({ url: l.imageUrl, id: l.imageId, materialType: l.materialType })) }
+                                        return { [type]: value.list.map((l: { imageUrl: any; imageId: any; materialType: any, accountId: any }) => ({ url: l.imageUrl, id: l.imageId, materialType: l.materialType, accountId: l?.accountId })) }
                                     } else if (type === 'short_video' || type === 'video') {
                                         let field = type === 'video' ? 'video_id' : 'short_video1'
                                         let videoData: any = {}
-                                        videoData[field] = { materialType: value.materialType, url: value.videoUrl, id: value.videoId }
+                                        videoData[field] = { materialType: value.materialType, url: value.videoUrl, id: value.videoId, keyFrameImageUrl: value?.keyFrameImageUrl, accountId: value?.accountId }
                                         if (value.imageUrl) {
-                                            videoData['cover_id'] = { materialType: value.materialCoverType, url: value.imageUrl, id: value.iamgeId }
+                                            videoData['cover_id'] = { materialType: value.materialCoverType, url: value.imageUrl, id: value.iamgeId, accountId: value?.accountId }
                                         }
                                         return videoData
                                     } else {
@@ -224,11 +224,11 @@ const Create: React.FC = () => {
                                             let { type, valueJson } = i
                                             let value = JSON.parse(valueJson).value
                                             if (type === 'image') {
-                                                return { id: value.imageId, url: value.imageUrl, materialType: value.materialType }
+                                                return { id: value.imageId, url: value.imageUrl, materialType: value.materialType, accountId: value?.accountId }
                                             } else if (type === 'image_list') {
-                                                return value.list.map((l: { imageUrl: any; imageId: any; materialType: any }) => ({ url: l.imageUrl, id: l.imageId, materialType: l.materialType }))
+                                                return value.list.map((l: { imageUrl: any; imageId: any; materialType: any, accountId: any }) => ({ url: l.imageUrl, id: l.imageId, materialType: l.materialType, accountId: l?.accountId }))
                                             } else if (type === 'video') {
-                                                return { materialType: value.materialType, url: value.videoUrl, id: value.videoId }
+                                                return { materialType: value.materialType, url: value.videoUrl, id: value.videoId, keyFrameImageUrl: value?.keyFrameImageUrl, accountId: value?.accountId }
                                             } else {
                                                 return {}
                                             }
@@ -838,7 +838,6 @@ const Create: React.FC = () => {
     const clearData = () => {
         setTableData({})
     }
-    console.log('addelivery---->', addelivery)
 
     return <Space direction="vertical" style={{ width: '100%' }}>
         <Spin spinning={createAdgroupTask.loading || getSelectTaskDetail.loading || getCreativeDetails.loading}>

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

@@ -298,7 +298,7 @@ export const columnsAddDynamic = (): TableProps<any>['columns'] => {
                                         {(keys.includes('video_id') || keys.includes('short_video1')) ? <>
                                             <Title style={{ fontSize: 12, color: '#1890ff', marginBottom: 0, width: '100%' }}>已选1个视频,0张图片</Title>
                                             <div className={style.video}>
-                                                <VideoNews src={dynamicGroup?.video_id?.url || dynamicGroup?.short_video1?.url} />
+                                                <VideoNews src={dynamicGroup?.video_id?.url || dynamicGroup?.short_video1?.url} keyFrameImageUrl={dynamicGroup?.video_id?.keyFrameImageUrl || dynamicGroup?.short_video1?.keyFrameImageUrl}/>
                                                 {dynamicGroup?.cover_id && <div className={style.cover_image} style={{ marginLeft: 4 }}>
                                                     <img src={dynamicGroup?.cover_id?.url} />
                                                 </div>}
@@ -326,10 +326,10 @@ export const columnsAddDynamic = (): TableProps<any>['columns'] => {
                                                     {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')) {
+                                        } else if (item?.url?.includes('mp4') || item?.keyFrameImageUrl) {
                                             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)" }} />
+                                                    <VideoNews src={item?.url} style={{ width: 30, height: 30 }} keyFrameImageUrl={item?.keyFrameImageUrl} maskBodyStyle={{ backgroundColor: "rgba(242, 246, 254, 0.1)" }} />
                                                 </div>
                                             </div>
                                         } else {