wjx 8 maanden geleden
bovenliggende
commit
934126fd7a
35 gewijzigde bestanden met toevoegingen van 558 en 277 verwijderingen
  1. 4 4
      src/pages/launchSystemV3/adMonitorListV3/TabAd.tsx
  2. 51 26
      src/pages/launchSystemV3/adqv3/ad/index.tsx
  3. 10 4
      src/pages/launchSystemV3/adqv3/ad/tableConfig.tsx
  4. 1 1
      src/pages/launchSystemV3/adqv3/ad/updateAd3.tsx
  5. 2 2
      src/pages/launchSystemV3/adqv3/creative/tableConfig.tsx
  6. 24 16
      src/pages/launchSystemV3/components/AdgroupTooltip/index.tsx
  7. 13 11
      src/pages/launchSystemV3/components/DynamicTooltip/index.tsx
  8. 4 3
      src/pages/launchSystemV3/components/TextAideInput/index.tsx
  9. 27 6
      src/pages/launchSystemV3/tencenTasset/game/index.tsx
  10. 8 1
      src/pages/launchSystemV3/tencentAdPutIn/const.ts
  11. 43 21
      src/pages/launchSystemV3/tencentAdPutIn/create/Ad/adgroupsMarketingContent.tsx
  12. 13 8
      src/pages/launchSystemV3/tencentAdPutIn/create/Ad/adgroupsPrice.tsx
  13. 8 6
      src/pages/launchSystemV3/tencentAdPutIn/create/Ad/index.tsx
  14. 1 2
      src/pages/launchSystemV3/tencentAdPutIn/create/Ad/newCreateAd.tsx
  15. 80 0
      src/pages/launchSystemV3/tencentAdPutIn/create/Dynamic/SelectBarrage.tsx
  16. 84 82
      src/pages/launchSystemV3/tencentAdPutIn/create/Dynamic/SelectLable.tsx
  17. 24 5
      src/pages/launchSystemV3/tencentAdPutIn/create/Dynamic/creativeConversionAssistant.tsx
  18. 13 10
      src/pages/launchSystemV3/tencentAdPutIn/create/Dynamic/creativeTemplateContent.tsx
  19. 19 9
      src/pages/launchSystemV3/tencentAdPutIn/create/Dynamic/newDynamic.tsx
  20. 2 1
      src/pages/launchSystemV3/tencentAdPutIn/create/Material/index.tsx
  21. 2 1
      src/pages/launchSystemV3/tencentAdPutIn/create/MaterialText/index.tsx
  22. 3 2
      src/pages/launchSystemV3/tencentAdPutIn/create/MaterialText/newText.tsx
  23. 4 1
      src/pages/launchSystemV3/tencentAdPutIn/create/PageList/index.tsx
  24. 4 3
      src/pages/launchSystemV3/tencentAdPutIn/create/Save/index.tsx
  25. 4 3
      src/pages/launchSystemV3/tencentAdPutIn/create/Save/saveUseImg.tsx
  26. 3 2
      src/pages/launchSystemV3/tencentAdPutIn/create/TacticsS/index.tsx
  27. 3 3
      src/pages/launchSystemV3/tencentAdPutIn/create/TacticsS/tableConfig.tsx
  28. 5 4
      src/pages/launchSystemV3/tencentAdPutIn/create/TacticsS/userTactics.tsx
  29. 1 1
      src/pages/launchSystemV3/tencentAdPutIn/create/Target/index.tsx
  30. 33 24
      src/pages/launchSystemV3/tencentAdPutIn/create/addDynamic.tsx
  31. 12 5
      src/pages/launchSystemV3/tencentAdPutIn/create/index.tsx
  32. 11 0
      src/pages/launchSystemV3/tencentAdPutIn/create/tableConfig.tsx
  33. 14 9
      src/pages/launchSystemV3/tencentAdPutIn/taskList/tableConfig.tsx
  34. 4 1
      src/pages/launchSystemV3/tencentAdPutIn/typings.d.ts
  35. 24 0
      src/services/adqV3/global.ts

+ 4 - 4
src/pages/launchSystemV3/adMonitorListV3/TabAd.tsx

@@ -89,10 +89,10 @@ const TabAd: React.FC<Props> = ({ accountId, adgroupId }) => {
                             <Typography.Text ellipsis={{ tooltip: true }}>{adgroupName}</Typography.Text>
                         </div>
                     </Descriptions.Item>
-                    <Descriptions.Item labelStyle={{ width: 100 }} label="出价">{`${BidModeEnum[bidMode]} ${bidAmount}元/${bidMode === 'BID_MODE_CPM' ? '千次曝光' : bidMode === 'BID_MODE_CPC' ? '点击' : OptimizationGoalEnum[optimizationGoal]}`}</Descriptions.Item>
+                    <Descriptions.Item labelStyle={{ width: 100 }} label="出价">{`${BidModeEnum[bidMode as keyof typeof BidModeEnum]} ${bidAmount}元/${bidMode === 'BID_MODE_CPM' ? '千次曝光' : bidMode === 'BID_MODE_CPC' ? '点击' : OptimizationGoalEnum[optimizationGoal as keyof typeof OptimizationGoalEnum]}`}</Descriptions.Item>
                     <Descriptions.Item labelStyle={{ width: 100 }} label="广告ID">{adgroupId}</Descriptions.Item>
                     <Descriptions.Item labelStyle={{ width: 100 }} label="状态">
-                        {ADGROUP_STATUS[systemStatus] || '--'}
+                        {ADGROUP_STATUS[systemStatus as keyof typeof ADGROUP_STATUS] || '--'}
                     </Descriptions.Item>
                     <Descriptions.Item label="广告账号" labelStyle={{ width: 100 }}>{accountId}</Descriptions.Item>
                     <Descriptions.Item label="出价类型" labelStyle={{ width: 100 }}>{smartBidType === 'SMART_BID_TYPE_CUSTOM' ? '手动出价' : '自动出价'}</Descriptions.Item>
@@ -102,7 +102,7 @@ const TabAd: React.FC<Props> = ({ accountId, adgroupId }) => {
                     <Descriptions.Item label="首日开始时间" labelStyle={{ width: 100 }}>{firstDayBeginTime}</Descriptions.Item>
                     <Descriptions.Item label="日预算" labelStyle={{ width: 100 }}>{dailyBudget}</Descriptions.Item>
                     <Descriptions.Item label="创意名称" labelStyle={{ width: 100 }}>{creativeName}</Descriptions.Item>
-                    <Descriptions.Item label="出价策略" labelStyle={{ width: 100 }}>{BidStrategyEnum[bidStrategy]}</Descriptions.Item>
+                    <Descriptions.Item label="出价策略" labelStyle={{ width: 100 }}>{BidStrategyEnum[bidStrategy as keyof typeof BidStrategyEnum]}</Descriptions.Item>
                 </Descriptions>
             </Spin>
         }
@@ -159,7 +159,7 @@ const TabAd: React.FC<Props> = ({ accountId, adgroupId }) => {
                     ajax={getAdgroupDetails}
                     dataSource={data[key]}
                     leftChild={<Space>
-                        <strong>{EWTypeEnum[key]}</strong>
+                        <strong>{EWTypeEnum[key as keyof typeof EWTypeEnum]}</strong>
                         {key === 'ADGROUP' && <SetEarlyWarnings accountId={accountId} adgroupId={adgroupId} onChange={() => getAdgroupDetails.refresh()} />}
                     </Space>}
                     loading={getAdgroupDetails?.loading}

+ 51 - 26
src/pages/launchSystemV3/adqv3/ad/index.tsx

@@ -10,17 +10,19 @@ import UpdateAd from "./updateAd";
 import TableData from "@/pages/launchSystemNew/components/TableData";
 import AddDynamic from "../../tencentAdPutIn/create/addDynamic";
 import { arraysHaveSameValues } from "@/utils/utils";
-import { MARKETING_CARRIER_TYPE_ENUM, MARKETING_GOAL_ENUM, MARKETING_TARGET_TYPE_ENUM, SITE_SET_ENUM } from "../../tencentAdPutIn/const";
+import { MARKETING_CARRIER_TYPE_ENUM, MARKETING_GOAL_ENUM, MARKETING_SUB_GOAL_ENUM, MARKETING_TARGET_TYPE_ENUM, MARKETING_TARGET_TYPE_GAME_ENUM, SITE_SET_ENUM } from "../../tencentAdPutIn/const";
 import Log from "../components/log";
 import '../../tencentAdPutIn/index.less'
 import UserTactics from "../../tencentAdPutIn/create/TacticsS/userTactics";
 import UpdateAd3 from "./updateAd3";
+import { useLocalStorageState } from "ahooks";
 const { Text } = Typography;
 
 const Ad: React.FC<ADQV3.AdProps> = ({ userId, creativeHandle }) => {
 
     /*****************************************/
-    const [queryFrom, set_queryFrom] = useState<ADQV3.GetAdListProps>({ pageNum: 1, pageSize: 20, useType: 1 })
+    const [useType, setUseType] = useLocalStorageState<1 | 2>('AD_USETYPE', 1);
+    const [queryFrom, set_queryFrom] = useState<ADQV3.GetAdListProps>({ pageNum: 1, pageSize: 20, useType: useType || 1 })
     const [isClearSelect, setIsClearSelect] = useState(true)
     const [selectedRows, setSelectedRows] = useState<any[]>([])
     const [tactics, setTactics] = useState<any>()
@@ -36,7 +38,7 @@ const Ad: React.FC<ADQV3.AdProps> = ({ userId, creativeHandle }) => {
     /*****************************************/
 
     useEffect(() => {
-        getList({ pageNum: 1, pageSize: 20, useType: 1 })
+        getList({ pageNum: 1, pageSize: 20, useType: useType || 1 })
     }, [userId])
 
     // 获取列表
@@ -93,9 +95,12 @@ const Ad: React.FC<ADQV3.AdProps> = ({ userId, creativeHandle }) => {
                     filterOption={(input: any, option: any) =>
                         (option!.children as unknown as string).toLowerCase().includes(input.toLowerCase())
                     }
-                    value={queryFrom.useType}
+                    value={useType}
                     onChange={(value: any) => {
-                        set_queryFrom({ ...queryFrom, useType: value })
+                        let params = { ...queryFrom, useType: value, pageNum: 1 }
+                        setUseType(value)
+                        set_queryFrom(params)
+                        getList(params)
                     }}
                 >
                     <Select.Option value={1}>小说</Select.Option>
@@ -232,7 +237,7 @@ const Ad: React.FC<ADQV3.AdProps> = ({ userId, creativeHandle }) => {
         </Row>
         <TableData
             isCard={false}
-            columns={() => tableConfig(() => getAdqV3AdList.refresh(), creativeHandle)}
+            columns={() => tableConfig(() => getAdqV3AdList.refresh(), creativeHandle, useType)}
             ajax={getAdqV3AdList}
             syncAjax={sync}
             fixed={{ left: 2, right: 5 }}
@@ -268,23 +273,40 @@ const Ad: React.FC<ADQV3.AdProps> = ({ userId, creativeHandle }) => {
                             setUpdateDate({ visible: true, type: '删除' })
                         }}>删除</Button></Col>
                         <Col><Dropdown
-                            overlay={<Menu>
-                                <Menu.Item disabled={selectedRows.length === 0} onClick={() => {
-                                    setUpdateDate({ visible: true, type: '修改出价' })
-                                }}><span style={{ display: 'inline-block', width: 120 }}>修改出价</span></Menu.Item>
-                                <Menu.Item disabled={selectedRows.length === 0} onClick={() => {
-                                    setUpdateDate({ visible: true, type: '修改名称' })
-                                }}>修改名称</Menu.Item>
-                                <Menu.Item disabled={selectedRows.length === 0} onClick={() => {
-                                    setUpdateDate({ visible: true, type: '修改日限额' })
-                                }}>修改日限额</Menu.Item>
-                                <Menu.Item disabled={selectedRows.length === 0} onClick={() => {
-                                    setUpdateDate({ visible: true, type: '修改投放时间' })
-                                }}>修改投放日期</Menu.Item>
-                                <Menu.Item disabled={selectedRows.length === 0} onClick={() => {
-                                    setUpdateDate({ visible: true, type: '修改投放首日开始时间' })
-                                }}>修改投放首日开始时间</Menu.Item>
-                            </Menu>}
+                            menu={{
+                                items: [
+                                    {
+                                        label: <span style={{ display: 'inline-block', width: 120 }}>修改出价</span>,
+                                        key: '1',
+                                        disabled: selectedRows.length === 0,
+                                        onClick: () => { setUpdateDate({ visible: true, type: '修改出价' }) }
+                                    },
+                                    {
+                                        label: '修改名称',
+                                        key: '2',
+                                        disabled: selectedRows.length === 0,
+                                        onClick: () => { setUpdateDate({ visible: true, type: '修改名称' }) }
+                                    },
+                                    {
+                                        label: '修改日限额',
+                                        key: '3',
+                                        disabled: selectedRows.length === 0,
+                                        onClick: () => { setUpdateDate({ visible: true, type: '修改日限额' }) }
+                                    },
+                                    {
+                                        label: '修改投放日期',
+                                        key: '4',
+                                        disabled: selectedRows.length === 0,
+                                        onClick: () => { setUpdateDate({ visible: true, type: '修改投放时间' }) }
+                                    },
+                                    {
+                                        label: '修改投放首日开始时间',
+                                        key: '5',
+                                        disabled: selectedRows.length === 0,
+                                        onClick: () => { setUpdateDate({ visible: true, type: '修改投放首日开始时间' }) }
+                                    }
+                                ]
+                            }}
                             placement="bottomLeft"
                             arrow
                         >
@@ -303,6 +325,7 @@ const Ad: React.FC<ADQV3.AdProps> = ({ userId, creativeHandle }) => {
                                 addDynamic()
                             }}
                             userId={userId}
+                            putInType={useType === 1 ? 'NOVEL' : 'GAME'}
                         /></Col>
                         <Col><Button type='primary' icon={<PlusOutlined />} disabled={selectedRows.length === 0} onClick={addDynamic}>添加创意</Button></Col>
                         <Col>
@@ -313,8 +336,8 @@ const Ad: React.FC<ADQV3.AdProps> = ({ userId, creativeHandle }) => {
                                 {selectedRows?.length > 0 && <div style={{ maxWidth: '380px' }}>
                                     <Text type="danger" ellipsis={{ tooltip: true }} strong style={{ fontSize: 12 }}>
                                         {`当前广告选择:
-                                        营销目的:${MARKETING_GOAL_ENUM[selectedRows?.[0]?.marketingGoal as keyof typeof MARKETING_GOAL_ENUM]},
-                                        推广产品类型:${MARKETING_TARGET_TYPE_ENUM[selectedRows?.[0]?.marketingTargetType as keyof typeof MARKETING_TARGET_TYPE_ENUM]},
+                                        营销目的:${useType === 2 ? MARKETING_SUB_GOAL_ENUM[selectedRows?.[0]?.marketingSubGoal as keyof typeof MARKETING_SUB_GOAL_ENUM] : MARKETING_GOAL_ENUM[selectedRows?.[0]?.marketingGoal as keyof typeof MARKETING_GOAL_ENUM]},
+                                        推广产品类型:${useType === 2 ? MARKETING_TARGET_TYPE_GAME_ENUM[selectedRows?.[0]?.marketingTargetType as keyof typeof MARKETING_TARGET_TYPE_GAME_ENUM] : MARKETING_TARGET_TYPE_ENUM[selectedRows?.[0]?.marketingTargetType as keyof typeof MARKETING_TARGET_TYPE_ENUM]},
                                         营销载体类型:${MARKETING_CARRIER_TYPE_ENUM[selectedRows?.[0]?.marketingCarrierType as keyof typeof MARKETING_CARRIER_TYPE_ENUM]},
                                         版位选择:${selectedRows?.[0]?.automaticSiteEnabled ? '自动版位' : '选择特定版位'},
                                         ${!selectedRows?.[0]?.automaticSiteEnabled && `广告版位:${selectedRows?.[0]?.siteSet.map((item: string | number) => SITE_SET_ENUM[item as keyof typeof SITE_SET_ENUM]).toString()}`}
@@ -335,10 +358,11 @@ const Ad: React.FC<ADQV3.AdProps> = ({ userId, creativeHandle }) => {
                 // hideSelectAll: handleType === 3,
                 getCheckboxProps: (record: any) => {
                     if (handleType === 2 && selectedRows?.length > 0) {
-                        const { siteSet, marketingCarrierType, marketingGoal, marketingTargetType, sceneSpec, automaticSiteEnabled } = selectedRows[0]
+                        const { siteSet, marketingCarrierType, marketingGoal, marketingSubGoal, marketingTargetType, sceneSpec, automaticSiteEnabled } = selectedRows[0]
                         return {
                             disabled: record.isDeleted || !(
                                 record?.marketingGoal === marketingGoal &&  // 营销内容
+                                record?.marketingSubGoal === marketingSubGoal &&  // 二级营销内容
                                 record?.marketingCarrierType === marketingCarrierType && // 营销载体
                                 record?.marketingTargetType === marketingTargetType && // 推广产品
                                 record?.automaticSiteEnabled === automaticSiteEnabled &&   // 自动版位
@@ -435,6 +459,7 @@ const Ad: React.FC<ADQV3.AdProps> = ({ userId, creativeHandle }) => {
         {/* 新增创意 */}
         {addDynamicVisible && <AddDynamic
             adData={selectedRows}
+            putInType={useType === 1 ? 'NOVEL' : 'GAME'}
             visible={addDynamicVisible}
             onClose={() => {
                 setAddDynamicVisible(false)

+ 10 - 4
src/pages/launchSystemV3/adqv3/ad/tableConfig.tsx

@@ -7,8 +7,8 @@ import { ADGROUP_STATUS } from '../const'
 import SwitchStatus from './switchStatus'
 import TimeSeriesLook from '@/pages/launchSystemNew/adq/ad/timeSeriesLook'
 import CreativePreview from '../../adMonitorListV3/CreativePreview'
-import { BID_MODE_ENUM, MARKETING_CARRIER_TYPE_ENUM, MARKETING_GOAL_ENUM, MARKETING_TARGET_TYPE_ENUM, OPTIMIZATIONGOAL_ENUM, SITE_SET_ENUM } from '../../tencentAdPutIn/const'
-function tableConfig(onChange: () => void, creativeHandle?: (id: number) => void): any {
+import { BID_MODE_ENUM, BID_SCENE_NORMAL_ENUM, MARKETING_CARRIER_TYPE_ENUM, MARKETING_GOAL_ENUM, MARKETING_TARGET_TYPE_ENUM, MARKETING_TARGET_TYPE_GAME_ENUM, OPTIMIZATIONGOAL_ENUM, SITE_SET_ENUM } from '../../tencentAdPutIn/const'
+function tableConfig(onChange: () => void, creativeHandle?: (id: number) => void, useType?: 1 | 2): any {
     return [
         {
             title: '启停',
@@ -150,13 +150,16 @@ function tableConfig(onChange: () => void, creativeHandle?: (id: number) => void
             }
         },
         {
-            title: '出价策略',
+            title: useType === 2 ? '出价场景' : '出价策略',
             dataIndex: 'bidStrategy',
             key: 'bidStrategy',
             align: 'center',
             width: 70,
             ellipsis: true,
-            render: (a: string, b: { endDate: string }) => {
+            render: (a: string, b: { bidScene: string }) => {
+                if (useType === 2) {
+                    return BID_SCENE_NORMAL_ENUM[b?.bidScene as keyof typeof BID_SCENE_NORMAL_ENUM] || '--'
+                }
                 return BidStrategyEnum[a as keyof typeof BidStrategyEnum]
             }
         },
@@ -186,6 +189,9 @@ function tableConfig(onChange: () => void, creativeHandle?: (id: number) => void
             width: 80,
             ellipsis: true,
             render: (a: any) => {
+                if (useType === 2) {
+                    return MARKETING_TARGET_TYPE_GAME_ENUM[a as keyof typeof MARKETING_TARGET_TYPE_GAME_ENUM] || '--'
+                }
                 return MARKETING_TARGET_TYPE_ENUM[a as keyof typeof MARKETING_TARGET_TYPE_ENUM]
             }
         },

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

@@ -129,7 +129,7 @@ const UpdateAd3: React.FC<Props> = ({ visible, type, onClose, onChange, updateDa
     return <>
         <Modal
             title={<strong>{type}</strong>}
-            visible={visible}
+            open={visible}
             footer={null}
             onCancel={onClose}
             bodyStyle={{ padding: '0 0 40px', position: 'relative', borderRadius: '0 0 8px 8px' }}

+ 2 - 2
src/pages/launchSystemV3/adqv3/creative/tableConfig.tsx

@@ -7,7 +7,7 @@ import { ELEMENT_ENUM, SITE_SET_ENUM, creativeTemplate } from '../../tencentAdPu
 import { AD_STATUS } from '.'
 const { Text } = Typography;
 
-function tableConfig(reviewStatusDetails: (value: any) => void, suspendHandle: (b: any, suspend: '启动' | '暂停') => void): any {
+function tableConfig(reviewStatusDetails: (value: any) => void, suspendHandle?: (b: any, suspend: '启动' | '暂停') => void): any {
     return [
         {
             title: '启停',
@@ -17,7 +17,7 @@ function tableConfig(reviewStatusDetails: (value: any) => void, suspendHandle: (
             width: 40,
             fixed: 'left',
             render: (a: string, b: any) => {
-                return <Switch size="small" checked={a === 'AD_STATUS_NORMAL'} onChange={(checked) => { suspendHandle(b, checked ? '启动' : '暂停') }} />
+                return <Switch size="small" checked={a === 'AD_STATUS_NORMAL'} onChange={(checked) => { suspendHandle?.(b, checked ? '启动' : '暂停') }} />
             }
         },
         {

+ 24 - 16
src/pages/launchSystemV3/components/AdgroupTooltip/index.tsx

@@ -1,12 +1,13 @@
 import React from "react"
 import style from '../../tencentAdPutIn/create/index.less'
-import { AD_STATUS_ENUM, BID_MODE_ENUM, DEEP_CONVERSION_ENUM, GOAL_ROAS_ENUM, MARKETING_CARRIER_TYPE_ENUM, MARKETING_GOAL_ENUM, MARKETING_TARGET_TYPE_ENUM, OPTIMIZATIONGOAL_ENUM, SITE_SET_ENUM, SMART_BID_TYPE_ENUM } from "../../tencentAdPutIn/const"
+import { AD_STATUS_ENUM, BID_MODE_ENUM, BID_SCENE_NORMAL_ENUM, DEEP_CONVERSION_ENUM, GOAL_ROAS_ENUM, MARKETING_CARRIER_TYPE_ENUM, MARKETING_GOAL_ENUM, MARKETING_SUB_GOAL_ENUM, MARKETING_TARGET_TYPE_ENUM, MARKETING_TARGET_TYPE_GAME_ENUM, OPTIMIZATIONGOAL_ENUM, SITE_SET_ENUM, SMART_BID_TYPE_ENUM } from "../../tencentAdPutIn/const"
 import { Typography } from "antd"
 import TimeSeriesLook from "@/pages/launchSystemNew/adq/ad/timeSeriesLook"
 
 
 interface Props {
     data: any
+    taskType?: 'GAME' | 'NOVEL'
 }
 
 /**
@@ -14,35 +15,42 @@ interface Props {
  * @param param0 
  * @returns 
  */
-const AdgroupTooltip: React.FC<Props> = ({ data: adgroups }) => {
+const AdgroupTooltip: React.FC<Props> = ({ data: adgroups, taskType }) => {
 
     /************************************/
     const {
-        marketingGoal, marketingAssetOuterSpec, marketingCarrierType, automaticSiteEnabled, siteSet, searchExpandTargetingSwitch, bidMode, smartBidType, bidAmount, optimizationGoal,
+        marketingGoal, marketingSubGoal, marketingAssetOuterSpec, marketingCarrierType, automaticSiteEnabled, siteSet, searchExpandTargetingSwitch, bidMode, smartBidType, bidScene, bidAmount, optimizationGoal,
         deepConversionSpec, autoAcquisitionEnabled, autoAcquisitionBudget, dailyBudget, endDate, beginDate, timeSeries, firstDayBeginTime, configuredStatus, adgroupName
     } = adgroups
     /************************************/
 
     return <div className={style.detail_body} style={{ height: 'auto' }}>
         {(adgroups && Object.keys(adgroups).length > 0) && <>
-            <p>营销目的:{MARKETING_GOAL_ENUM[marketingGoal]}</p>
-            <p style={{ fontWeight: 'bold', color: '#000' }}>推广产品类型:{MARKETING_TARGET_TYPE_ENUM[marketingAssetOuterSpec?.marketingTargetType]}</p>
-            <p>营销载体类型:{MARKETING_CARRIER_TYPE_ENUM[marketingCarrierType]}</p>
+            {taskType === 'NOVEL' ? <>
+                <p>营销目的:{MARKETING_GOAL_ENUM[marketingGoal as keyof typeof MARKETING_GOAL_ENUM]}</p>
+                <p style={{ fontWeight: 'bold', color: '#000' }}>推广产品类型:{MARKETING_TARGET_TYPE_ENUM[marketingAssetOuterSpec?.marketingTargetType as keyof typeof MARKETING_TARGET_TYPE_ENUM]}</p>
+            </> : <>
+                <p>营销目的:{MARKETING_SUB_GOAL_ENUM[marketingSubGoal as keyof typeof MARKETING_SUB_GOAL_ENUM]}</p>
+                <p style={{ fontWeight: 'bold', color: '#000' }}>推广产品类型:{MARKETING_TARGET_TYPE_GAME_ENUM[marketingAssetOuterSpec?.marketingTargetType as keyof typeof MARKETING_TARGET_TYPE_GAME_ENUM]}</p>
+            </>}
+            <p>营销载体类型:{MARKETING_CARRIER_TYPE_ENUM[marketingCarrierType as keyof typeof MARKETING_CARRIER_TYPE_ENUM]}</p>
             <p>版位选择:{automaticSiteEnabled ? '自动版位' : '选择特定版位'}</p>
-            {!automaticSiteEnabled && <Typography.Paragraph className={style.tpP} style={{ marginBottom: 0 }} ellipsis={{ tooltip: true, rows: 2 }}>广告版位:{siteSet.map((item: string | number) => SITE_SET_ENUM[item]).toString()}</Typography.Paragraph>}
+            {!automaticSiteEnabled && <Typography.Paragraph className={style.tpP} style={{ marginBottom: 0 }} ellipsis={{ tooltip: true, rows: 2 }}>广告版位:{siteSet.map((item: string | number) => SITE_SET_ENUM[item as keyof typeof SITE_SET_ENUM]).toString()}</Typography.Paragraph>}
             <p>搜索场景扩量:{searchExpandTargetingSwitch === 'SEARCH_EXPAND_TARGETING_SWITCH_OPEN' ? '开启' : '关闭'}</p>
-            <p>计费方式:{BID_MODE_ENUM[bidMode]}</p>
-            <p>出价类型:{SMART_BID_TYPE_ENUM[smartBidType]}</p>
-            <p>出价:{bidAmount}元/{optimizationGoal ? OPTIMIZATIONGOAL_ENUM[optimizationGoal] : ['BID_MODE_OCPM', 'BID_MODE_OCPC'].includes(bidMode) ? '千次曝光' : '点击'}</p>
-            {optimizationGoal && <p style={{ fontWeight: 'bold', color: '#000' }}>优化目标:{OPTIMIZATIONGOAL_ENUM[optimizationGoal]}</p>}
+            <p>计费方式:{BID_MODE_ENUM[bidMode as keyof typeof BID_MODE_ENUM]}</p>
+            {taskType === 'GAME' ? <>
+                <p>出价场景:{BID_SCENE_NORMAL_ENUM[bidScene as keyof typeof BID_SCENE_NORMAL_ENUM]}</p>
+            </> : <p>出价类型:{SMART_BID_TYPE_ENUM[smartBidType as keyof typeof SMART_BID_TYPE_ENUM]}</p>}
+            <p>出价:{bidAmount}元/{optimizationGoal ? OPTIMIZATIONGOAL_ENUM[optimizationGoal as keyof typeof OPTIMIZATIONGOAL_ENUM] : ['BID_MODE_OCPM', 'BID_MODE_OCPC'].includes(bidMode) ? '千次曝光' : '点击'}</p>
+            {optimizationGoal && <p style={{ fontWeight: 'bold', color: '#000' }}>优化目标:{OPTIMIZATIONGOAL_ENUM[optimizationGoal as keyof typeof OPTIMIZATIONGOAL_ENUM]}</p>}
             {deepConversionSpec && <>
                 <p style={{ fontWeight: 'bold', color: '#000' }}>深度转化优化:开启</p>
-                <p style={{ fontWeight: 'bold', color: '#000' }}>深度优化类型:{DEEP_CONVERSION_ENUM[deepConversionSpec?.deepConversionType]}</p>
+                <p style={{ fontWeight: 'bold', color: '#000' }}>深度优化类型:{DEEP_CONVERSION_ENUM[deepConversionSpec?.deepConversionType as keyof typeof DEEP_CONVERSION_ENUM]}</p>
                 {deepConversionSpec.deepConversionType === 'DEEP_CONVERSION_BEHAVIOR' ? <>
-                    <p style={{ fontWeight: 'bold', color: '#000' }}>深度优化目标:{OPTIMIZATIONGOAL_ENUM[deepConversionSpec.deepConversionBehaviorSpec.goal]}</p>
-                    <p style={{ fontWeight: 'bold', color: '#000' }}>深度目标出价:{deepConversionSpec.deepConversionBehaviorSpec.bidAmount}元/{OPTIMIZATIONGOAL_ENUM[deepConversionSpec.deepConversionBehaviorSpec.goal] || '优化目标'}</p>
+                    <p style={{ fontWeight: 'bold', color: '#000' }}>深度优化目标:{OPTIMIZATIONGOAL_ENUM[deepConversionSpec.deepConversionBehaviorSpec.goal as keyof typeof OPTIMIZATIONGOAL_ENUM]}</p>
+                    <p style={{ fontWeight: 'bold', color: '#000' }}>深度目标出价:{deepConversionSpec.deepConversionBehaviorSpec.bidAmount}元/{OPTIMIZATIONGOAL_ENUM[deepConversionSpec.deepConversionBehaviorSpec.goal as keyof typeof OPTIMIZATIONGOAL_ENUM] || '优化目标'}</p>
                 </> : <>
-                    <p style={{ fontWeight: 'bold', color: '#000' }}>深度优化目标:{GOAL_ROAS_ENUM[deepConversionSpec.deepConversionWorthSpec.goal]}</p>
+                    <p style={{ fontWeight: 'bold', color: '#000' }}>深度优化目标:{GOAL_ROAS_ENUM[deepConversionSpec.deepConversionWorthSpec.goal as keyof typeof GOAL_ROAS_ENUM]}</p>
                     <p style={{ fontWeight: 'bold', color: '#000' }}>期望ROI:{deepConversionSpec.deepConversionWorthSpec.expectedRoi}</p>
                 </>}
             </>}
@@ -52,7 +60,7 @@ const AdgroupTooltip: React.FC<Props> = ({ data: adgroups }) => {
             <p style={{ fontWeight: 'bold', color: '#000' }}>投放日期:{beginDate} 至 {endDate}</p>
             <p>投放时段:{timeSeries.includes('0') ? <TimeSeriesLook timeSeries={timeSeries} /> : '全天'}</p>
             <p>首日开始时间:{firstDayBeginTime ? firstDayBeginTime : '关闭'}</p>
-            <p>广告状态:{AD_STATUS_ENUM[configuredStatus]}</p>
+            <p>广告状态:{AD_STATUS_ENUM[configuredStatus as keyof typeof AD_STATUS_ENUM]}</p>
             <p>广告名称:{adgroupName}</p>
         </>}
     </div>

+ 13 - 11
src/pages/launchSystemV3/components/DynamicTooltip/index.tsx

@@ -34,15 +34,15 @@ const DynamicTooltip: React.FC<Props> = ({ data: dynamicData }) => {
             })
         }
     }, [brand])
-    
+
     return <div className={style.detail_body} style={{ height: 'auto' }}>
         {dynamicData && Object.keys(dynamicData).length > 0 && <>
             <p>创意名称:{dynamicCreativeName}</p>
-            <p style={{ fontWeight: 'bold', color: '#000' }}>创意状态:{AD_STATUS_ENUM[configuredStatus]}</p>
-            <p>投放模式:{DELIVERY_MODE_ENUM[deliveryMode]}</p>
+            <p style={{ fontWeight: 'bold', color: '#000' }}>创意状态:{AD_STATUS_ENUM[configuredStatus as keyof typeof AD_STATUS_ENUM]}</p>
+            <p>投放模式:{DELIVERY_MODE_ENUM[deliveryMode as keyof typeof DELIVERY_MODE_ENUM]}</p>
             <p>创意形式ID:{creativeTemplateId}</p>
             {brand?.length > 0 && <>
-                <p style={{ fontWeight: 'bold', color: '#000' }}>品牌形象跳转:{PAGE_TYPE_ENUM[brand?.[0]?.value?.jumpInfo?.pageType]}</p>
+                <p style={{ fontWeight: 'bold', color: '#000' }}>品牌形象跳转:{PAGE_TYPE_ENUM[brand?.[0]?.value?.jumpInfo?.pageType as keyof typeof PAGE_TYPE_ENUM]}</p>
                 {['PAGE_TYPE_H5_PROFILE'].includes(brand?.[0]?.value?.jumpInfo?.pageType) ? <>
                     {profileData ? <>
                         <Space>
@@ -57,23 +57,25 @@ const DynamicTooltip: React.FC<Props> = ({ data: dynamicData }) => {
                 </Space>}
             </>}
             <p style={{ fontWeight: 'bold', color: '#000' }}>跳转类型:{mainJumpInfo?.map((item: any) => {
-                let pageSpec = item.value.pageSpec
-                return PAGE_TYPE_ENUM[pageSpecFieldConVertUn[Object.keys(pageSpec)?.[0]]]
+                // let pageSpec = item.value.pageSpec
+                // return PAGE_TYPE_ENUM[pageSpecFieldConVertUn[Object.keys(pageSpec)?.[0] as keyof typeof pageSpecFieldConVertUn] as keyof typeof PAGE_TYPE_ENUM]
+                let pageType = item.value.pageType
+                return PAGE_TYPE_ENUM[pageType as keyof typeof PAGE_TYPE_ENUM]
             }).toString()}</p>
             {textLink?.length > 0 && <>
                 <p style={{ fontWeight: 'bold', color: '#000' }}>朋友圈文字链:开启</p>
-                <p>文字链文案:{TEXT_LINK_TYPE_ENUM[textLink?.[0]?.value?.linkNameType]}</p>
-                {textLink?.[0]?.value?.jumpInfo?.pageType && <p>跳转落地页:{PAGE_TYPE_ENUM[textLink?.[0]?.value?.jumpInfo?.pageType]}</p>}
+                <p>文字链文案:{TEXT_LINK_TYPE_ENUM[textLink?.[0]?.value?.linkNameType as keyof typeof TEXT_LINK_TYPE_ENUM]}</p>
+                {textLink?.[0]?.value?.jumpInfo?.pageType && <p>跳转落地页:{PAGE_TYPE_ENUM[textLink?.[0]?.value?.jumpInfo?.pageType as keyof typeof PAGE_TYPE_ENUM]}</p>}
             </>}
             {actionButton?.length > 0 && <>
                 <p style={{ fontWeight: 'bold', color: '#000' }}>行动按钮:开启</p>
                 <p>按钮文案:{actionButton?.[0]?.value?.buttonText}</p>
-                {actionButton?.[0]?.value?.jumpInfo?.pageType && <p>跳转落地页:{PAGE_TYPE_ENUM[actionButton?.[0]?.value?.jumpInfo?.pageType]}</p>}
+                {actionButton?.[0]?.value?.jumpInfo?.pageType && <p>跳转落地页:{PAGE_TYPE_ENUM[actionButton?.[0]?.value?.jumpInfo?.pageType as keyof typeof PAGE_TYPE_ENUM]}</p>}
             </>}
             {showData?.length > 0 && <>
                 <p style={{ fontWeight: 'bold', color: '#000' }}>数据外显:开启</p>
-                <p>数据类型:{CONVERSION_DATA_ENUM[showData?.[0]?.value?.conversionDataType]}</p>
-                <p>转化行为:{CONVERSION_TARGET_ENUM[showData?.[0]?.value?.conversionTargetType]}</p>
+                <p>数据类型:{CONVERSION_DATA_ENUM[showData?.[0]?.value?.conversionDataType as keyof typeof CONVERSION_DATA_ENUM]}</p>
+                <p>转化行为:{CONVERSION_TARGET_ENUM[showData?.[0]?.value?.conversionTargetType as keyof typeof CONVERSION_TARGET_ENUM]}</p>
             </>}
         </>}
     </div>

+ 4 - 3
src/pages/launchSystemV3/components/TextAideInput/index.tsx

@@ -17,6 +17,7 @@ interface Props {
     maxTextLength?: number;
     isShowAjax?: boolean
     isSelectEmoji?: boolean
+    putInType?: 'NOVEL' | 'GAME'
 }
 
 /**
@@ -27,7 +28,7 @@ interface Props {
 const TextAideInput: React.FC<Props> = (props) => {
 
     /************************/
-    const { value, onChange, style, placeholder, maxTextLength = 10, isShowAjax = true, isSelectEmoji = true } = props
+    const { value, onChange, style, placeholder, maxTextLength = 10, isShowAjax = true, isSelectEmoji = true, putInType } = props
     const [text, setText] = useState<any>(value)
     const [descriptionShow, setDescriptionshow] = useState(false)
     const [cursorPosition, setCursorPosition] = useState<number | null>(null);
@@ -43,7 +44,7 @@ const TextAideInput: React.FC<Props> = (props) => {
 
     // 文案助手
     const textList = (keyword?: any) => {
-        getTextLsit.run({ keyword, maxTextLength })
+        getTextLsit.run({ keyword, maxTextLength, taskType: putInType })
     }
 
     const insertTextAtCursor = (emoji: string) => {
@@ -102,7 +103,7 @@ const TextAideInput: React.FC<Props> = (props) => {
                     onBlur={(e) => {
                         setCursorPosition(e.target.selectionStart)
                         if (!emojiOpen) {
-                            setTimeout(() => { setDescriptionshow(false) }, 0)
+                            setTimeout(() => { setDescriptionshow(false) }, 500)
                         }
                     }}
                     onChange={(e) => {

+ 27 - 6
src/pages/launchSystemV3/tencenTasset/game/index.tsx

@@ -1,5 +1,5 @@
 import { useAjax } from "@/Hook/useAjax";
-import { delGameApi, getGameLibraryApi, getGameLibraryDetailApi, getGameLibraryListApi } from "@/services/adqV3/global";
+import { delGameApi, getGameLibraryApi, getGameLibraryAppIdDetailApi, getGameLibraryDetailApi, getGameLibraryListApi } from "@/services/adqV3/global";
 import { PlusOutlined, SearchOutlined } from "@ant-design/icons";
 import { Button, Card, Divider, Input, message, Select, Spin, Table, Typography } from "antd";
 import React, { useEffect, useState } from "react"
@@ -117,7 +117,7 @@ const Game: React.FC = () => {
  * @param param0 
  * @returns 
  */
-export const SelectGame: React.FC<{ gameType: 'WXGAME', value?: string, onChange?: (value?: string) => void }> = ({ gameType, value, onChange }) => {
+export const SelectGame: React.FC<{ gameType: 'WXGAME', value?: string, onChange?: (value?: string, appId?: string) => void }> = ({ gameType, value, onChange }) => {
 
     /*******************************/
     const [visible, setVisible] = useState<boolean>(false)
@@ -154,10 +154,10 @@ export const SelectGame: React.FC<{ gameType: 'WXGAME', value?: string, onChange
                 </div>
             </>}
             value={value}
-            onChange={(e) => onChange?.(e)}
+            onChange={(e, options) => onChange?.(e, options?.appId)}
         >
             {getGameLibrary?.data?.map((item: { id: number, appId: string, gameName: string }) => {
-                return <Select.Option value={item.id} key={item.id} name={item.gameName + `(${item.appId})`}><Text strong>{item.gameName}</Text><Text type="secondary">{`(${item.appId})`}</Text></Select.Option>
+                return <Select.Option value={item.id} key={item.id} appId={item.appId} name={item.gameName + `(${item.appId})`}><Text strong>{item.gameName}</Text><Text type="secondary">{`(${item.appId})`}</Text></Select.Option>
             })}
         </Select>
         {/* 新增修改 */}
@@ -199,7 +199,6 @@ export const SelectGameAppId: React.FC<{ gameType: 'WXGAME', value?: string[], o
             filterOption={(input: any, option: any) => {
                 return option!.name?.toString().toLowerCase().includes(input.toLowerCase())
             }}
-            mode="multiple"
             style={{ width: 480 }}
             dropdownRender={menu => <>
                 {menu}
@@ -220,7 +219,7 @@ export const SelectGameAppId: React.FC<{ gameType: 'WXGAME', value?: string[], o
             onChange={(e) => onChange?.(e)}
         >
             {getGameLibrary?.data?.map((item: { id: number, appId: string, gameName: string }) => {
-                return <Select.Option value={item.appId} disabled={value && value?.length > 0 && !value.includes(item.appId)} key={item.id} name={item.gameName + `(${item.appId})`}><Text strong>{item.gameName}</Text><Text type="secondary">{`(${item.appId})`}</Text></Select.Option>
+                return <Select.Option value={item.appId} key={item.id} name={item.gameName + `(${item.appId})`}><Text strong>{item.gameName}</Text><Text type="secondary">{`(${item.appId})`}</Text></Select.Option>
             })}
         </Select>
         {/* 新增修改 */}
@@ -265,4 +264,26 @@ export const ShowGameDetail: React.FC<{ id: number }> = ({ id }) => {
     </Spin>
 }
 
+export const ShowGameAppIdDetail: React.FC<{ appId: number }> = ({ appId }) => {
+
+    /*******************************/
+    const getGameLibraryAppIdDetail = useAjax((params) => getGameLibraryAppIdDetailApi(params))
+    /*******************************/
+
+    // 获取列表
+    useEffect(() => {
+        if (appId) {
+            getGameLibraryAppIdDetail.run(appId)
+        }
+    }, [appId])
+
+    return <Spin spinning={getGameLibraryAppIdDetail.loading}>
+        <Paragraph style={{ fontSize: 12, wordBreak: 'break-all', marginBottom: 0 }} ellipsis={{ rows: 2 }}>
+            {getGameLibraryAppIdDetail.data ? <>
+                <Text strong>游戏:{getGameLibraryAppIdDetail.data?.gameName}</Text><Text type="secondary">{`(${getGameLibraryAppIdDetail.data?.appId})`}</Text>
+            </> : appId}
+        </Paragraph>
+    </Spin>
+}
+
 export default Game

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

@@ -173,6 +173,12 @@ export enum SMART_BID_TYPE_ENUM {
 	SMART_BID_TYPE_SYSTEMATIC = '最大转化量投放'
 }
 
+/** 出价场景 */
+export enum BID_SCENE_NORMAL_ENUM {
+	BID_SCENE_NORMAL_AVERAGE = '常规投放',
+	BID_SCENE_NORMAL_MAX = '最大转化量投放'
+}
+
 /** 广告优化目标类型 */
 export enum OPTIMIZATIONGOAL_ENUM {
 	OPTIMIZATIONGOAL_NONE = "none",
@@ -592,7 +598,8 @@ export enum PAGE_TYPE_ENUM {
 	PAGE_TYPE_XJ_QUICK = "蹊径性能版落地页",
 	PAGE_TYPE_WECHAT_CANVAS = "原生推广页",
 	PAGE_TYPE_APP_DEEP_LINK = "应用直达",
-	PAGE_TYPE_OFFICIAL = "灵鹊落地页(官方落地页)"
+	PAGE_TYPE_OFFICIAL = "灵鹊落地页(官方落地页)",
+	PAGE_TYPE_WECHAT_MINI_GAME = '微信小游戏'
 }
 
 /** 外显数据类型 */

+ 43 - 21
src/pages/launchSystemV3/tencentAdPutIn/create/Ad/adgroupsMarketingContent.tsx

@@ -11,7 +11,7 @@ import { adRules } from "../../rules"
 import { QuestionCircleFilled } from "@ant-design/icons"
 import { SelectMiniProgramWechat } from "@/pages/launchSystemV3/tencenTasset/miniProgramWechat"
 import { SelectCorpWechat } from "@/pages/launchSystemV3/tencenTasset/corpWechat"
-import { SelectGame } from "@/pages/launchSystemV3/tencenTasset/game"
+import { SelectGame, SelectGameAppId } from "@/pages/launchSystemV3/tencenTasset/game"
 
 
 /**
@@ -31,6 +31,8 @@ const AdgroupsMarketingContent: React.FC<{ value?: any }> = ({ value }) => {
     const bidMode = Form.useWatch('bidMode', form);
     const optimizationGoal = Form.useWatch('optimizationGoal', form);
     const smartBidType = Form.useWatch('smartBidType', form);
+    const bidScene = Form.useWatch('bidScene', form);
+    const wxGameAppId = Form.useWatch('wxGameAppId', form);
     const depthConversionEnabled = Form.useWatch('depthConversionEnabled', form);
     const deepConversionType = Form.useWatch(['deepConversionSpec', 'deepConversionType'], form);
     const goal = Form.useWatch(['deepConversionSpec', deepConversionType === 'DEEP_CONVERSION_BEHAVIOR' ? 'deepConversionBehaviorSpec' : 'deepConversionWorthSpec', 'goal'], form);
@@ -62,6 +64,11 @@ const AdgroupsMarketingContent: React.FC<{ value?: any }> = ({ value }) => {
             if (bidMode === 'BID_MODE_OCPC' || bidMode === 'BID_MODE_OCPM') {
                 obj.bidMode = bidMode
             }
+            if (putInType === 'GAME' && marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' && wxGameAppId) {
+                obj.marketingCarrierDetail = {
+                    marketingCarrierId: wxGameAppId
+                }
+            }
             queryOptimizationGoalPermissions.run({ ...obj, taskType: putInType })
         }
     }
@@ -70,7 +77,7 @@ const AdgroupsMarketingContent: React.FC<{ value?: any }> = ({ value }) => {
         if (OGPParams.marketingCarrierType && OGPParams.marketingTargetType) {
             getOptimizationGoalPermissions()
         }
-    }, [OGPParams, putInType])
+    }, [OGPParams, putInType, wxGameAppId])
 
     // 处理深度转化优化
     useEffect(() => {
@@ -86,14 +93,17 @@ const AdgroupsMarketingContent: React.FC<{ value?: any }> = ({ value }) => {
             (newBehaviorList?.length > 0 && newDeepConversionData.push({ label: '优化转化行为', value: 'DEEP_CONVERSION_BEHAVIOR' }))
             { newWorthList?.length > 0 && newDeepConversionData.push({ label: '优化ROI', value: 'DEEP_CONVERSION_WORTH' }) }
             setDeepConversionData(newDeepConversionData)
+            const inputInstance = form.getFieldValue('deepConversionSpec');
             let deepConversionType = newBehaviorList?.length > 0 ? 'DEEP_CONVERSION_BEHAVIOR' : newWorthList?.length > 0 ? "DEEP_CONVERSION_WORTH" : ''
-            form.setFieldsValue({
-                deepConversionSpec: {
-                    deepConversionType
-                }
-            })
+            if (inputInstance?.deepConversionType ? inputInstance?.deepConversionType === 'DEEP_CONVERSION_BEHAVIOR' ? !newBehaviorList?.length : !newWorthList?.length : true) {
+                form.setFieldsValue({
+                    deepConversionSpec: {
+                        deepConversionType
+                    }
+                })
+            }
         }
-    }, [optimizationGoal, queryOptimizationGoalPermissions?.data, goal])
+    }, [optimizationGoal, queryOptimizationGoalPermissions?.data])
 
     // 选择营销目的触发
     useEffect(() => {
@@ -200,8 +210,8 @@ const AdgroupsMarketingContent: React.FC<{ value?: any }> = ({ value }) => {
             <SelectMiniProgramWechat />
         </Form.Item> : marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_WORK' ? <Form.Item label={<strong>企业微信</strong>} name='sysCorpWechatId' rules={[{ required: true, message: '请选择企业微信' }]}>
             <SelectCorpWechat />
-        </Form.Item> : marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' ? <Form.Item label={<strong>微信小游戏</strong>} name='sysWxGameId' rules={[{ required: true, message: '请选择微信小游戏' }]}>
-            <SelectGame gameType="WXGAME" />
+        </Form.Item> : marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' ? <Form.Item label={<strong>微信小游戏</strong>} name='wxGameAppId' rules={[{ required: true, message: '请选择微信小游戏' }]}>
+            <SelectGameAppId gameType="WXGAME" />
         </Form.Item> : null}
         {marketingCarrierTypeList?.length > 0 && <Form.Item name="marketingCarrierType" label={<strong>营销载体类型</strong>} rules={[{ required: true, message: '请选择营销载体类型!' }]}>
             <New1Radio data={marketingCarrierTypeList} onChange={(e) => { setOGPparams({ ...OGPParams, marketingCarrierType: e }); setIsUpdate() }} />
@@ -227,13 +237,20 @@ const AdgroupsMarketingContent: React.FC<{ value?: any }> = ({ value }) => {
             >
                 <New1Radio data={[{ label: '开启', value: true }, { label: '关闭', value: false }]} />
             </Form.Item>}
-            <Form.Item label={<strong>优化目标</strong>} name='optimizationGoal' rules={[{ required: true, message: '请选择优化目标' }]}>
+            <Form.Item
+                label={<strong>优化目标</strong>}
+                name='optimizationGoal'
+                rules={[{ required: true, message: '请选择优化目标' }]}
+                help={(marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' && !wxGameAppId) ? '请先选择微信小游戏' : undefined}
+                validateStatus={(marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' && !wxGameAppId) ? 'error' : undefined}
+            >
                 <Select
                     style={{ width: 480 }}
                     showSearch
                     filterOption={(input, option) =>
                         (option!.children as unknown as string)?.toLowerCase()?.includes(input?.toLowerCase())
                     }
+                    disabled={(marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' && !wxGameAppId)}
                     allowClear
                     placeholder='请选择'
                     loading={queryOptimizationGoalPermissions.loading}
@@ -244,17 +261,22 @@ const AdgroupsMarketingContent: React.FC<{ value?: any }> = ({ value }) => {
                 </Select>
             </Form.Item>
             {/* 深度优化 */}
-            {((behaviorList?.length > 0 || worthList?.length > 0) && smartBidType !== 'SMART_BID_TYPE_SYSTEMATIC') && <>
+            {((behaviorList?.length > 0 || worthList?.length > 0) && (marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' ? !!wxGameAppId : true) && (putInType === 'GAME' ? bidScene !== 'BID_SCENE_NORMAL_MAX' : smartBidType !== 'SMART_BID_TYPE_SYSTEMATIC')) && <>
                 <Form.Item label={<strong>深度转化优化</strong>} name='depthConversionEnabled' valuePropName="checked">
-                    <Switch checkedChildren="开启" unCheckedChildren="关闭" onChange={(e) => {
-                        if (e) {
-                            form.setFieldsValue({
-                                deepConversionSpec: {
-                                    deepConversionType: behaviorList?.length > 0 ? 'DEEP_CONVERSION_BEHAVIOR' : worthList?.length > 0 ? "DEEP_CONVERSION_WORTH" : ''
-                                }
-                            })
-                        }
-                    }} />
+                    <Switch
+                        disabled={(marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' && !wxGameAppId)}
+                        checkedChildren="开启"
+                        unCheckedChildren="关闭"
+                        onChange={(e) => {
+                            if (e) {
+                                form.setFieldsValue({
+                                    deepConversionSpec: {
+                                        deepConversionType: behaviorList?.length > 0 ? 'DEEP_CONVERSION_BEHAVIOR' : worthList?.length > 0 ? "DEEP_CONVERSION_WORTH" : ''
+                                    }
+                                })
+                            }
+                        }}
+                    />
                 </Form.Item>
                 {depthConversionEnabled && <>
                     <Form.Item label={<strong>深度优化类型</strong>} name={['deepConversionSpec', 'deepConversionType']} rules={[{ required: true, message: '请选择深度优化类型' }]}>

+ 13 - 8
src/pages/launchSystemV3/tencentAdPutIn/create/Ad/adgroupsPrice.tsx

@@ -2,7 +2,7 @@ import { Card, Form, Input, InputNumber, Space, Switch, Tooltip } from "antd"
 import React, { useContext } from "react"
 import { DispatchAd } from "./newCreateAd";
 import New1Radio from "@/pages/launchSystemV3/components/New1Radio";
-import { BID_MODE_ENUM, OPTIMIZATIONGOAL_ENUM, SMART_BID_TYPE_ENUM } from "../../const";
+import { BID_MODE_ENUM, BID_SCENE_NORMAL_ENUM, OPTIMIZATIONGOAL_ENUM, SMART_BID_TYPE_ENUM } from "../../const";
 import { QuestionCircleFilled } from "@ant-design/icons";
 
 
@@ -13,12 +13,13 @@ import { QuestionCircleFilled } from "@ant-design/icons";
 const AdgroupsPrice: React.FC = () => {
 
     /****************************************/
-    const { form, setOGPparams, OGPParams } = useContext(DispatchAd)!;
+    const { form, setOGPparams, OGPParams, putInType } = useContext(DispatchAd)!;
 
     const siteSet = Form.useWatch('siteSet', form)
     const bidMode = Form.useWatch('bidMode', form)
     const optimizationGoal = Form.useWatch('optimizationGoal', form)
     const smartBidType = Form.useWatch('smartBidType', form)
+    const bidScene = Form.useWatch('bidScene', form)
     const autoAcquisitionEnabled = Form.useWatch('autoAcquisitionEnabled', form)
     const automaticSiteEnabled = Form.useWatch('automaticSiteEnabled', form)
     const deepConversionType = Form.useWatch(['deepConversionSpec', 'deepConversionType'], form);
@@ -55,6 +56,7 @@ const AdgroupsPrice: React.FC = () => {
                         form.setFieldsValue({
                             optimizationGoal: null,
                             smartBidType: null,
+                            bidScene: null,
                             // bidAmount:null,
                             bidStrategy: null,
                             autoAcquisitionEnabled: false,
@@ -65,6 +67,7 @@ const AdgroupsPrice: React.FC = () => {
                         form.setFieldsValue({
                             optimizationGoal: "OPTIMIZATIONGOAL_ECOMMERCE_ORDER",
                             smartBidType: "SMART_BID_TYPE_CUSTOM",
+                            bidScene: "BID_SCENE_NORMAL_AVERAGE",
                             bidAmount: '1000',
                             bidStrategy: "BID_STRATEGY_TARGET_COST",
                             autoAcquisitionEnabled: false,
@@ -76,12 +79,14 @@ const AdgroupsPrice: React.FC = () => {
             />
         </Form.Item>
         {(bidMode === 'BID_MODE_OCPM' || bidMode === 'BID_MODE_OCPC') && <>
-            <Form.Item label={<strong>出价类型</strong>} name='smartBidType' rules={[{ required: true, message: '请选择出价类型' }]}>
+            {putInType === 'GAME' ? <Form.Item label={<strong>出价场景</strong>} name='bidScene' rules={[{ required: true, message: '请选择出价场景' }]}>
+                <New1Radio data={Object.keys(BID_SCENE_NORMAL_ENUM).map(key => ({ label: BID_SCENE_NORMAL_ENUM[key as keyof typeof BID_SCENE_NORMAL_ENUM], value: key }))} />
+            </Form.Item> : <Form.Item label={<strong>出价类型</strong>} name='smartBidType' rules={[{ required: true, message: '请选择出价类型' }]}>
                 <New1Radio data={Object.keys(SMART_BID_TYPE_ENUM).map(key => ({ label: SMART_BID_TYPE_ENUM[key as keyof typeof SMART_BID_TYPE_ENUM], value: key }))} />
-            </Form.Item>
+            </Form.Item>}
         </>}
 
-        {smartBidType !== 'SMART_BID_TYPE_SYSTEMATIC' && <>
+        {(putInType === 'GAME' ? bidScene !== 'BID_SCENE_NORMAL_MAX' : smartBidType !== 'SMART_BID_TYPE_SYSTEMATIC') && <>
             <Form.Item label={<strong>出价</strong>} name='bidAmount' rules={[{ required: true, message: '请输入价格' }]}>
                 <Input
                     placeholder={`请输入价格`}
@@ -116,7 +121,7 @@ const AdgroupsPrice: React.FC = () => {
                     </Form.Item>
                 </> : null}
 
-            {(bidMode === 'BID_MODE_OCPM' || bidMode === 'BID_MODE_OCPC') && <>
+            {((bidMode === 'BID_MODE_OCPM' || bidMode === 'BID_MODE_OCPC') && (putInType === 'GAME' ? bidScene !== 'BID_SCENE_NORMAL_MAX' : smartBidType !== 'SMART_BID_TYPE_SYSTEMATIC')) && <>
                 <Form.Item
                     style={{ marginBottom: 10 }}
                     label={<Space>
@@ -154,8 +159,8 @@ const AdgroupsPrice: React.FC = () => {
             </>}
         </>}
 
-        <Form.Item label={<strong>广告日预算</strong>} name='dailyBudget' rules={[{ required: smartBidType === 'SMART_BID_TYPE_SYSTEMATIC', message: '请输入广告日预算' }]}>
-            <Input placeholder={`广告日预算${smartBidType === 'SMART_BID_TYPE_SYSTEMATIC' ? '' : ', 不填默认为不限'}`} style={{ width: 480 }} suffix="元/天" />
+        <Form.Item label={<strong>广告日预算</strong>} name='dailyBudget' rules={[{ required: (smartBidType === 'SMART_BID_TYPE_SYSTEMATIC' || bidScene === 'BID_SCENE_NORMAL_MAX'), message: '请输入广告日预算' }]}>
+            <Input placeholder={`广告日预算${(smartBidType === 'SMART_BID_TYPE_SYSTEMATIC' || bidScene === 'BID_SCENE_NORMAL_MAX') ? '' : ', 不填默认为不限'}`} style={{ width: 480 }} suffix="元/天" />
         </Form.Item>
 
     </Card>

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

@@ -4,12 +4,12 @@ import NewCreateAd from "./newCreateAd"
 import { DispatchAddelivery } from "..";
 import { Button, Modal, Typography } from "antd";
 import { EditOutlined } from "@ant-design/icons";
-import { AD_STATUS_ENUM, BID_MODE_ENUM, DEEP_CONVERSION_ENUM, GOAL_ROAS_ENUM, MARKETING_CARRIER_TYPE_ENUM, MARKETING_GOAL_ENUM, MARKETING_SUB_GOAL_ENUM, MARKETING_TARGET_TYPE_ENUM, MARKETING_TARGET_TYPE_GAME_ENUM, OPTIMIZATIONGOAL_ENUM, SITE_SET_ENUM, SMART_BID_TYPE_ENUM } from "../../const";
+import { AD_STATUS_ENUM, BID_MODE_ENUM, BID_SCENE_NORMAL_ENUM, DEEP_CONVERSION_ENUM, GOAL_ROAS_ENUM, MARKETING_CARRIER_TYPE_ENUM, MARKETING_GOAL_ENUM, MARKETING_SUB_GOAL_ENUM, MARKETING_TARGET_TYPE_ENUM, MARKETING_TARGET_TYPE_GAME_ENUM, OPTIMIZATIONGOAL_ENUM, SITE_SET_ENUM, SMART_BID_TYPE_ENUM } from "../../const";
 import TimeSeriesLook from "@/pages/launchSystemNew/adq/ad/timeSeriesLook";
 import { arraysHaveSameValues } from "@/utils/utils";
 import '../../index.less'
 import { ShowMiniProgramWechatDetail } from "@/pages/launchSystemV3/tencenTasset/miniProgramWechat";
-import { ShowGameDetail } from "@/pages/launchSystemV3/tencenTasset/game";
+import { ShowGameAppIdDetail } from "@/pages/launchSystemV3/tencenTasset/game";
 
 /**
  * 广告信息
@@ -21,8 +21,8 @@ const Ad: React.FC = () => {
     const { addelivery, setAddelivery, accountCreateLogs, clearData, setAccountCreateLogs, putInType } = useContext(DispatchAddelivery)!;
     const { adgroups } = addelivery
     const {
-        marketingGoal, marketingSubGoal, marketingAssetOuterSpec, marketingCarrierType, automaticSiteEnabled, siteSet, searchExpandTargetingSwitch, bidMode, smartBidType, bidAmount, optimizationGoal, isConversion, depthConversionEnabled,
-        deepConversionSpec, autoAcquisitionEnabled, autoAcquisitionBudget, dailyBudget, endDate, beginDate, timeSeries, firstDayBeginTime, configuredStatus, adgroupName, sceneSpec, autoDerivedCreativeEnabled, sysWechatAppId, sysWxGameId
+        marketingGoal, marketingSubGoal, marketingAssetOuterSpec, marketingCarrierType, automaticSiteEnabled, siteSet, searchExpandTargetingSwitch, bidMode, smartBidType, bidScene, bidAmount, optimizationGoal, isConversion, depthConversionEnabled,
+        deepConversionSpec, autoAcquisitionEnabled, autoAcquisitionBudget, dailyBudget, endDate, beginDate, timeSeries, firstDayBeginTime, configuredStatus, adgroupName, sceneSpec, autoDerivedCreativeEnabled, sysWechatAppId, wxGameAppId
     } = adgroups
     const [newVisible, setNewVisible] = useState<boolean>(false)
     /*****************************/
@@ -46,7 +46,7 @@ const Ad: React.FC = () => {
                         {marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_MINI_PROGRAM_WECHAT' ?
                             <ShowMiniProgramWechatDetail id={sysWechatAppId} /> :
                             marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' ?
-                                <ShowGameDetail id={sysWxGameId}/> :
+                                <ShowGameAppIdDetail appId={wxGameAppId}/> :
                                 null
                         }
                         <p>营销载体类型:{MARKETING_CARRIER_TYPE_ENUM[marketingCarrierType as keyof typeof MARKETING_CARRIER_TYPE_ENUM]}</p>
@@ -54,7 +54,9 @@ const Ad: React.FC = () => {
                         {!automaticSiteEnabled && <Typography.Paragraph className={style.tpP} style={{ marginBottom: 0 }} ellipsis={{ tooltip: true, rows: 2 }}>广告版位:{siteSet.map((item: string | number) => SITE_SET_ENUM[item as keyof typeof SITE_SET_ENUM]).toString()}</Typography.Paragraph>}
                         <p>搜索场景扩量:{searchExpandTargetingSwitch === 'SEARCH_EXPAND_TARGETING_SWITCH_OPEN' ? '开启' : '关闭'}</p>
                         <p>计费方式:{BID_MODE_ENUM[bidMode as keyof typeof BID_MODE_ENUM]}</p>
-                        <p>出价类型:{SMART_BID_TYPE_ENUM[smartBidType as keyof typeof SMART_BID_TYPE_ENUM]}</p>
+                        {putInType === 'GAME' ? <>
+                            <p>出价场景:{BID_SCENE_NORMAL_ENUM[bidScene as keyof typeof BID_SCENE_NORMAL_ENUM]}</p>
+                        </> : <p>出价类型:{SMART_BID_TYPE_ENUM[smartBidType as keyof typeof SMART_BID_TYPE_ENUM]}</p>}
                         <p>出价:{bidAmount}元/{optimizationGoal ? OPTIMIZATIONGOAL_ENUM[optimizationGoal as keyof typeof OPTIMIZATIONGOAL_ENUM] : ['BID_MODE_OCPM', 'BID_MODE_OCPC'].includes(bidMode) ? '千次曝光' : '点击'}</p>
                         {isConversion && <p style={{ fontWeight: 'bold', color: '#000' }}>转化:新链路转化</p>}
                         {optimizationGoal && <p style={{ fontWeight: 'bold', color: '#000' }}>优化目标:{OPTIMIZATIONGOAL_ENUM[optimizationGoal as keyof typeof OPTIMIZATIONGOAL_ENUM]}</p>}

+ 1 - 2
src/pages/launchSystemV3/tencentAdPutIn/create/Ad/newCreateAd.tsx

@@ -147,7 +147,6 @@ const NewCreateAd: React.FC<Props> = ({ value, visible, onChange, onClose, putIn
             } else {
                 adgroupsValues.displaySceneType = '0'
             }
-            console.log('------------------------------------>', adgroupsValues)
             setOGPparams({
                 bidMode: adgroupsValues.bidMode,
                 siteSet: adgroupsValues.siteSet,
@@ -194,8 +193,8 @@ const NewCreateAd: React.FC<Props> = ({ value, visible, onChange, onClose, putIn
                 searchExpandTargetingSwitch: 'SEARCH_EXPAND_TARGETING_SWITCH_OPEN',
                 bidMode: 'BID_MODE_OCPM',
                 smartBidType: 'SMART_BID_TYPE_CUSTOM',
+                bidScene: 'BID_SCENE_NORMAL_AVERAGE',
                 optimizationGoal: putInType === 'NOVEL' ? 'OPTIMIZATIONGOAL_ECOMMERCE_ORDER' : 'OPTIMIZATIONGOAL_MOBILE_APP_AD_INCOME',
-                depthConversionEnabled: true,
                 deepConversionSpec: {
                     deepConversionType: 'DEEP_CONVERSION_WORTH'
                 },

+ 80 - 0
src/pages/launchSystemV3/tencentAdPutIn/create/Dynamic/SelectBarrage.tsx

@@ -0,0 +1,80 @@
+import { useAjax } from "@/Hook/useAjax"
+import { getBarrageRecommendListApi } from "@/services/adqV3/global"
+import { Select } from "antd"
+import React, { useEffect, useState } from "react"
+
+interface Props {
+    arrayProperty: { maxNumber: number, minNumber: number }
+    value?: { text: string }[]
+    onChange?: (value?: { text: string }[]) => void
+    putInType?: 'NOVEL' | 'GAME'
+}
+
+/**
+ * 选择弹幕
+ * @param param0 
+ * @returns 
+ */
+const SelectBarrage: React.FC<Props> = ({ arrayProperty, value = [], onChange, putInType }) => {
+
+    /****************************************/
+    const [barrageList, setBarrageList] = useState<string[]>([])
+
+    const getBarrageRecommendList = useAjax((params) => getBarrageRecommendListApi(params))
+    /****************************************/
+
+    useEffect(() => {
+        getBarrageRecommendList.run({ taskType: putInType }).then(res => {
+            if (res?.list?.length) {
+                const setBarrage = new Set(res?.list.map((item: { text: string }) => item.text))
+                const arrayBarrage = [...setBarrage]
+                setBarrageList(arrayBarrage as string[])
+            } else {
+                setBarrageList([])
+            }
+        })
+    }, [putInType])
+
+    let barrageValue = value?.map(item => item.text)
+    return <div
+        style={{
+            border: '1px solid #d9d9d9',
+            borderRadius: 6,
+            display: 'flex',
+            gap: 10,
+            borderColor: barrageValue?.length > arrayProperty.maxNumber ? 'red' : '#d9d9d9',
+            alignItems: 'center'
+        }}
+    >
+        <Select
+            showSearch
+            placeholder="请选择弹幕"
+            onChange={(e) => {
+                onChange?.(e?.length > 0 ? e.map(item => ({ text: item })) : [])
+            }}
+            value={barrageValue}
+            mode="multiple"
+            filterOption={(input, option) =>
+                ((option?.label ?? '') as any).toLowerCase().includes(input.toLowerCase())
+            }
+            loading={getBarrageRecommendList.loading}
+            bordered={false}
+        >
+            {barrageList.map((item: string, index: number) => <Select.Option key={index} value={item} disabled={barrageValue?.length > arrayProperty.maxNumber && !barrageValue.includes(item)}>{item}</Select.Option>)}
+        </Select>
+        <div
+            style={{
+                // borderLeft: '1px solid #d9d9d9',
+                display: 'flex',
+                alignContent: 'center',
+                justifyContent: 'center',
+                paddingLeft: 10,
+                paddingRight: 10
+            }}
+        >
+            <span>{value?.length || 0}/{arrayProperty.maxNumber}</span>
+        </div>
+    </div>
+}
+
+export default React.memo(SelectBarrage)

+ 84 - 82
src/pages/launchSystemV3/tencentAdPutIn/create/Dynamic/SelectLable.tsx

@@ -11,6 +11,7 @@ const { Text } = Typography;
 
 interface Props {
     arrayProperty: { maxNumber: number, minNumber: number }
+    putInType?: 'NOVEL' | 'GAME'
     value?: { content: string, type: LABEL_TYPE_ENUM }[]
     onChange?: (value?: { content: string, type: LABEL_TYPE_ENUM }[]) => void
 }
@@ -19,7 +20,7 @@ interface Props {
  * 选择标签
  * @returns 
  */
-const SelectLabel: React.FC<Props> = ({ value, onChange, arrayProperty }) => {
+const SelectLabel: React.FC<Props> = ({ value, onChange, arrayProperty, putInType }) => {
 
     /************************************/
     const [visible, setVisible] = useState<boolean>(false)
@@ -39,9 +40,9 @@ const SelectLabel: React.FC<Props> = ({ value, onChange, arrayProperty }) => {
 
     useEffect(() => {
         if (visible) {
-            getAdLabel.run({})
+            getAdLabel.run({ taskType: putInType })
         }
-    }, [visible])
+    }, [visible, putInType])
 
     const handleOk = () => {
         onChange?.(oldValue)
@@ -98,89 +99,90 @@ const SelectLabel: React.FC<Props> = ({ value, onChange, arrayProperty }) => {
                 accessKey={activeKey}
                 onChange={(e) => setActiveKey(e)}
                 tabBarExtraContent={<Text type="secondary" style={{ fontSize: 12 }}>最多可选 {arrayProperty.maxNumber} 个标签,且标签总字数上限不超过 16 个字,中英文均算 1 个字</Text>}
-            >
-                <Tabs.TabPane tab="选择已有" key="1" >
-                    <Spin spinning={getAdLabel.loading}>
-                        <div className={style.labelContent}>
-                            <div className={style.tips}>
-                                <strong>行业通用</strong>
+                items={[
+                    {
+                        label: '选择已有', key: '1', children: <Spin spinning={getAdLabel.loading}>
+                            <div className={style.labelContent}>
+                                <div className={style.tips}>
+                                    <strong>行业通用</strong>
+                                </div>
+                                <Form
+                                    name="basicSelectLabel"
+                                    labelCol={{ span: 3 }}
+                                    wrapperCol={{ span: 21 }}
+                                    labelAlign="left"
+                                    colon={false}
+                                >
+                                    {getAdLabel.data?.map((item: { labelCategory: string, label: string[], labelTypeName: string }, index: number) => <Form.Item className={style.toggleLabelForm} label={<strong>{item.labelCategory}</strong>} key={index}>
+                                        <div className={style.toggleLabels}>
+                                            {item.label.map((text, tIndex) => {
+                                                let activeIndex = oldValue?.findIndex(i => i.content === text)
+                                                return <div
+                                                    key={tIndex}
+                                                    className={`${style.toggleLabel} ${(activeIndex !== -1) ? style.active : ''}`}
+                                                    onClick={() => {
+                                                        let newValue: { content: string, type: LABEL_TYPE_ENUM }[] = JSON.parse(JSON.stringify(oldValue))
+                                                        if (activeIndex !== -1) {
+                                                            newValue = newValue.filter((_, index) => activeIndex !== index)
+                                                        } else {
+                                                            newValue.push({ content: text, type: (item.labelTypeName === '普通文本标签' ? 'LABEL_TYPE_COMMON' : 'LABEL_TYPE_UNKNOWN') as LABEL_TYPE_ENUM })
+                                                        }
+                                                        setOldValue(newValue)
+                                                    }}
+                                                >{text}</div>
+                                            })}
+                                        </div>
+                                    </Form.Item>)}
+                                </Form>
                             </div>
-                            <Form
-                                name="basicSelectLabel"
-                                labelCol={{ span: 3 }}
-                                wrapperCol={{ span: 21 }}
-                                labelAlign="left"
-                                colon={false}
+                        </Spin>
+                    },
+                    {
+                        label: '新建标签', key: '2', children: <div className={style.spauiInputGroup} style={{ borderColor: isFocus ? '#296bef' : '#dfe1e6' }}>
+                            {oldValue?.filter(item => item.type === 'LABEL_TYPE_CUSTOMIZETEXT' as LABEL_TYPE_ENUM)?.map((item, tIndex) => <div
+                                key={tIndex}
+                                className={`${style.toggleLabel} ${style.customizeLabel}`}
                             >
-                                {getAdLabel.data?.map((item: { labelCategory: string, label: string[], labelTypeName: string }, index: number) => <Form.Item className={style.toggleLabelForm} label={<strong>{item.labelCategory}</strong>} key={index}>
-                                    <div className={style.toggleLabels}>
-                                        {item.label.map((text, tIndex) => {
-                                            let activeIndex = oldValue?.findIndex(i => i.content === text)
-                                            return <div
-                                                key={tIndex}
-                                                className={`${style.toggleLabel} ${(activeIndex !== -1) ? style.active : ''}`}
-                                                onClick={() => {
-                                                    let newValue: { content: string, type: LABEL_TYPE_ENUM }[] = JSON.parse(JSON.stringify(oldValue))
-                                                    if (activeIndex !== -1) {
-                                                        newValue = newValue.filter((_, index) => activeIndex !== index)
-                                                    } else {
-                                                        newValue.push({ content: text, type: (item.labelTypeName === '普通文本标签' ? 'LABEL_TYPE_COMMON' : 'LABEL_TYPE_UNKNOWN') as LABEL_TYPE_ENUM })
-                                                    }
-                                                    setOldValue(newValue)
-                                                }}
-                                            >{text}</div>
-                                        })}
-                                    </div>
-                                </Form.Item>)}
-                            </Form>
-                        </div>
-                    </Spin>
-                </Tabs.TabPane>
-                <Tabs.TabPane tab="新建标签" key="2" >
-                    <div className={style.spauiInputGroup} style={{ borderColor: isFocus ? '#296bef' : '#dfe1e6' }}>
-                        {oldValue?.filter(item => item.type === 'LABEL_TYPE_CUSTOMIZETEXT' as LABEL_TYPE_ENUM)?.map((item, tIndex) => <div
-                            key={tIndex}
-                            className={`${style.toggleLabel} ${style.customizeLabel}`}
-                        >
-                            <Space>
-                                <span>{item.content}</span>
-                                <CloseOutlined className={style.clearLable} onClick={() => setOldValue(oldValue.filter((_, index) => tIndex !== index))} />
-                            </Space>
-                        </div>)}
-                        <div className={style.divInput}>
-                            <Input
-                                placeholder="请输入自定义标签文案,按回车键生成标签,单标签 2-7 字"
-                                bordered={false}
-                                onFocus={() => setIsFocus(true)}
-                                onBlur={() => setIsFocus(false)}
-                                value={customizetext}
-                                maxLength={7}
-                                minLength={2}
-                                onChange={(e) => setCustomizetext(e.target.value)}
-                                onPressEnter={() => {
-                                    if (customizetext) {
-                                        if (oldValue.some(item => item.content === customizetext)) {
-                                            message.error('存在相同名称标签')
-                                            return
+                                <Space>
+                                    <span>{item.content}</span>
+                                    <CloseOutlined className={style.clearLable} onClick={() => setOldValue(oldValue.filter((_, index) => tIndex !== index))} />
+                                </Space>
+                            </div>)}
+                            <div className={style.divInput}>
+                                <Input
+                                    placeholder="请输入自定义标签文案,按回车键生成标签,单标签 2-7 字"
+                                    bordered={false}
+                                    onFocus={() => setIsFocus(true)}
+                                    onBlur={() => setIsFocus(false)}
+                                    value={customizetext}
+                                    maxLength={7}
+                                    minLength={2}
+                                    onChange={(e) => setCustomizetext(e.target.value)}
+                                    onPressEnter={() => {
+                                        if (customizetext) {
+                                            if (oldValue.some(item => item.content === customizetext)) {
+                                                message.error('存在相同名称标签')
+                                                return
+                                            }
+                                            let yyLables = getAdLabel?.data?.reduce((pre: any, cur: { label: any }) => [...pre, ...(cur.label || [])], [])
+                                            if (yyLables.some((item: string) => item === customizetext)) {
+                                                message.warn(`标签【${customizetext}】为已有标签,已为您自动选择`)
+                                                return
+                                            }
+                                            let newValue: { content: string, type: LABEL_TYPE_ENUM }[] = JSON.parse(JSON.stringify(oldValue))
+                                            newValue.push({ content: customizetext, type: 'LABEL_TYPE_CUSTOMIZETEXT' as LABEL_TYPE_ENUM })
+                                            setOldValue(newValue)
+                                            setCustomizetext(undefined)
+                                        } else {
+                                            message.error('请填写内容')
                                         }
-                                        let yyLables = getAdLabel?.data?.reduce((pre: any, cur: { label: any }) => [...pre, ...(cur.label || [])], [])
-                                        if (yyLables.some((item: string) => item === customizetext)) {
-                                            message.warn(`标签【${customizetext}】为已有标签,已为您自动选择`)
-                                            return
-                                        }
-                                        let newValue: { content: string, type: LABEL_TYPE_ENUM }[] = JSON.parse(JSON.stringify(oldValue))
-                                        newValue.push({ content: customizetext, type: 'LABEL_TYPE_CUSTOMIZETEXT' as LABEL_TYPE_ENUM })
-                                        setOldValue(newValue)
-                                        setCustomizetext(undefined)
-                                    } else {
-                                        message.error('请填写内容')
-                                    }
-                                }}
-                            />
+                                    }}
+                                />
+                            </div>
                         </div>
-                    </div>
-                </Tabs.TabPane>
-            </Tabs>
+                    }
+                ]}
+            />
         </Modal>}
     </>
 }

+ 24 - 5
src/pages/launchSystemV3/tencentAdPutIn/create/Dynamic/creativeConversionAssistant.tsx

@@ -10,12 +10,13 @@ import TextAideInput from "@/pages/launchSystemV3/components/TextAideInput";
 import styles from '../Material/index.less'
 import SelectLabel from "./SelectLable"
 import SelectCloudNew from "@/pages/launchSystemV3/material/cloudNew/selectCloudNew";
+import SelectBarrage from "./SelectBarrage";
 
 /**
  * 营销组件
  * @returns 
  */
-const CreativeConversionAssistant: React.FC<{ automaticSiteEnabled?: boolean }> = ({ automaticSiteEnabled }) => {
+const CreativeConversionAssistant: React.FC<{ automaticSiteEnabled?: boolean, putInType?: 'NOVEL' | 'GAME' }> = ({ automaticSiteEnabled, putInType }) => {
 
     /**************************************/
     const { creativeComponents, form, isUpdate, setIsUpdate } = useContext(DispatchDynamic)!;
@@ -137,6 +138,12 @@ const CreativeConversionAssistant: React.FC<{ automaticSiteEnabled?: boolean }>
             if (linkNamePageType) {
                 linkNamePageTypeEnumeration = (linkNamePageType?.enumProperty?.enumeration as { value: string, description: string }[]).filter(item => item.value === pageSpecPageType).map(item => ({ label: item.description, value: item.value }))
             }
+            if (putInType === 'GAME') {
+                let jumpInfoPageType = creativeComponents?.jump_info?.children?.page_type?.enumProperty?.enumeration
+                if (jumpInfoPageType?.length && jumpInfoPageType?.length !== linkNamePageType?.enumProperty?.enumeration?.length) {
+                    return
+                }
+            }
 
             return <Form.Item style={{ marginBottom: 0 }}>
                 <div className={style.newSpace}>
@@ -186,7 +193,7 @@ const CreativeConversionAssistant: React.FC<{ automaticSiteEnabled?: boolean }>
             </Form.Item>
         }
         return null
-    }, [creativeComponents?.text_link, pageSpec, textLinkShow, creativeTemplateId, automaticSiteEnabled])
+    }, [creativeComponents?.text_link, pageSpec, textLinkShow, creativeTemplateId, automaticSiteEnabled, putInType])
 
     /** 行动按钮 */
     const actionButtonContent = useMemo(() => {
@@ -270,11 +277,22 @@ const CreativeConversionAssistant: React.FC<{ automaticSiteEnabled?: boolean }>
             const list = label.children.list
 
             return <Form.Item name={'creativeLabelDTOS'} style={{ marginTop: 16, marginBottom: 0 }} label={<strong>&nbsp;&nbsp;&nbsp;标签{label.required ? '' : '(选填)'}</strong>}>
-                <SelectLabel arrayProperty={list.arrayProperty} />
+                <SelectLabel arrayProperty={list.arrayProperty} putInType={putInType} />
+            </Form.Item>
+        }
+        return null
+    }, [creativeComponents?.label, cardType, putInType])
+
+    /** 弹幕 */
+    const barrageContent = useMemo(() => {
+        let barrage = creativeComponents?.barrage;
+        if (barrage) {
+            return <Form.Item name={'creativeBarrageDTOS'} style={{ marginTop: 16, marginBottom: 0 }} label={<strong>&nbsp;&nbsp;&nbsp;弹幕{barrage.required ? '' : '(选填)'}</strong>}>
+                <SelectBarrage arrayProperty={{ minNumber: 0, maxNumber: 20 }} putInType={putInType} />
             </Form.Item>
         }
         return null
-    }, [creativeComponents?.label, cardType])
+    }, [creativeComponents?.label, cardType, putInType])
 
     /** 数据外显 */
     const showDataContent = useMemo(() => {
@@ -562,7 +580,7 @@ const CreativeConversionAssistant: React.FC<{ automaticSiteEnabled?: boolean }>
         }
     }, [cardType])
 
-    if (Object.keys(creativeComponents).some(key => ['text_link', 'action_button', 'show_data', 'floating_zone', 'label'].includes(key))) {
+    if (Object.keys(creativeComponents).some(key => ['text_link', 'action_button', 'show_data', 'floating_zone', 'label', 'barrage'].includes(key))) {
         return <Card
             title={<strong style={{ fontSize: 18 }}>营销组件</strong>}
             className="cardResetCss"
@@ -610,6 +628,7 @@ const CreativeConversionAssistant: React.FC<{ automaticSiteEnabled?: boolean }>
             {textLinkContent}
             {actionButtonContent}
             {labelContent}
+            {barrageContent}
             {showDataContent}
             {floatingZoneContent}
 

+ 13 - 10
src/pages/launchSystemV3/tencentAdPutIn/create/Dynamic/creativeTemplateContent.tsx

@@ -1,17 +1,18 @@
-import { Button, Card, Form, Radio, Space } from "antd"
+import { Button, Card, Form, Radio, Space, Tooltip } from "antd"
 import React, { useContext, useMemo } from "react"
 import { DispatchDynamic } from "./newDynamic";
 import New1Radio from "@/pages/launchSystemV3/components/New1Radio";
 import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
 import BrandImage from "@/pages/launchSystemV3/components/BrandImage";
 import { SelectProfiles } from "@/pages/launchSystemV3/tencenTasset/profiles";
+import { PAGE_TYPE_ENUM } from "../../const";
 
 
 /**
  * 创意内容
  * @returns 
  */
-const CreativeTemplateContent: React.FC<{ automaticSiteEnabled: boolean }> = ({ automaticSiteEnabled }) => {
+const CreativeTemplateContent: React.FC<{ automaticSiteEnabled: boolean, putInType?: 'NOVEL' | 'GAME' }> = ({ automaticSiteEnabled, putInType }) => {
 
     /******************************************/
     const { creativeComponents, form, adgroups: { siteSet } } = useContext(DispatchDynamic)!;
@@ -40,12 +41,12 @@ const CreativeTemplateContent: React.FC<{ automaticSiteEnabled: boolean }> = ({
                     let jump_info = creativeComponents[key]
                     jumpInfoNumber = jump_info?.arrayProperty?.maxNumber || 1
                     let jumpInfoPageType = jump_info.children.page_type
-                    pageTypeList = (jumpInfoPageType.enumProperty.enumeration as { value: string, description: string }[]).filter(item => !["PAGE_TYPE_WECHAT_CANVAS_MINI_PROGRAM", "PAGE_TYPE_H5", "PAGE_TYPE_WECHAT_SIMPLE_CANVAS", "PAGE_TYPE_APP_DEEP_LINK"].includes(item.value)).map(item => ({ label: item.description, value: item.value, disabled: !["PAGE_TYPE_WECHAT_CANVAS", "PAGE_TYPE_OFFICIAL", "PAGE_TYPE_WECHAT_MINI_PROGRAM"].includes(item.value) }))
+                    pageTypeList = (jumpInfoPageType.enumProperty.enumeration as { value: string, description: string }[]).filter(item => !["PAGE_TYPE_WECHAT_CANVAS_MINI_PROGRAM", "PAGE_TYPE_H5", "PAGE_TYPE_WECHAT_SIMPLE_CANVAS", "PAGE_TYPE_APP_DEEP_LINK"].includes(item.value)).map(item => ({ label: item.description, value: item.value, disabled: !["PAGE_TYPE_WECHAT_CANVAS", "PAGE_TYPE_OFFICIAL", "PAGE_TYPE_WECHAT_MINI_PROGRAM", "PAGE_TYPE_WECHAT_MINI_GAME"].includes(item.value) }))
                     break
             }
         })
-        
-        if (!pageTypeList.some(item => item.value === "PAGE_TYPE_OFFICIAL") && creativeTemplateId !== 910) {
+
+        if (!pageTypeList.some(item => item.value === "PAGE_TYPE_OFFICIAL") && creativeTemplateId !== 910 && putInType !== 'GAME') {
             pageTypeList.push({ label: "灵鹊落地页", value: "PAGE_TYPE_OFFICIAL", disabled: false })
         }
 
@@ -154,18 +155,20 @@ const CreativeTemplateContent: React.FC<{ automaticSiteEnabled: boolean }> = ({
                                 </Space>
                             ))}
                             {pageSpec?.length < jumpInfoNumber && <Form.Item>
-                                <Button type="dashed" onClick={() => add({ pageId: null, pageType: pageSpec?.[0]?.pageType || 'PAGE_TYPE_WECHAT_CANVAS', overrideCanvasHeadOption: 'OPTION_CREATIVE_OVERRIDE_CANVAS' })} block icon={<PlusOutlined />}>
+                                {pageSpec?.[0]?.pageType === "PAGE_TYPE_WECHAT_MINI_GAME" ? <Tooltip placement="top" title={`「${PAGE_TYPE_ENUM[pageSpec?.[0]?.pageType as keyof typeof PAGE_TYPE_ENUM]}」仅支持单独使用,如需添加多组,请修改跳转类型。`}>
+                                    <Button type="dashed" disabled block icon={<PlusOutlined />}>
+                                        还可以添加 {jumpInfoNumber - pageSpec?.length} 组
+                                    </Button>
+                                </Tooltip> : <Button type="dashed" onClick={() => add({ pageId: null, pageType: pageSpec?.[0]?.pageType || 'PAGE_TYPE_WECHAT_CANVAS', overrideCanvasHeadOption: 'OPTION_CREATIVE_OVERRIDE_CANVAS' })} block icon={<PlusOutlined />}>
                                     还可以添加 {jumpInfoNumber - pageSpec?.length} 组
-                                </Button>
+                                </Button>}
                             </Form.Item>}
                         </>
                     )}
                 </Form.List>
             </Form.Item>
-
-
         </>
-    }, [creativeComponents, pageType, pageSpec, siteSet, creativeTemplateId])
+    }, [creativeComponents, pageType, pageSpec, siteSet, creativeTemplateId, putInType])
 
     return <Card
         title={<strong style={{ fontSize: 18 }}>创意内容</strong>}

+ 19 - 9
src/pages/launchSystemV3/tencentAdPutIn/create/Dynamic/newDynamic.tsx

@@ -56,13 +56,18 @@ const NewDynamic: React.FC<Props> = ({ putInType, value: newValue, visible, onCl
 
     useEffect(() => {
         if (deliveryMode === 'DELIVERY_MODE_CUSTOMIZE') { // 自定义创意
-            getCreativeTemplateList.run({
+            let params: any = {
                 marketingGoal,
                 marketingTargetType: marketingAssetOuterSpec.marketingTargetType,
                 marketingCarrierType,
                 siteSet,
-                wechatSceneSpecPosition: sceneSpec?.wechatPosition || []
-            }).then((res: any) => {
+                wechatSceneSpecPosition: sceneSpec?.wechatPosition || [],
+                taskType: putInType
+            }
+            if (putInType === 'GAME') {
+                params.marketingSubGoal = marketingSubGoal
+            }
+            getCreativeTemplateList.run(params).then((res: any) => {
                 let newArr: any = []
                 let newData: any[] = []
                 // 过滤掉相同的和即将下线的
@@ -136,7 +141,7 @@ const NewDynamic: React.FC<Props> = ({ putInType, value: newValue, visible, onCl
         } else if (deliveryMode === 'DELIVERY_MODE_COMPONENT') {  // 组件化创意
             getTemplate()
         }
-    }, [deliveryMode, marketingGoal, marketingAssetOuterSpec, marketingCarrierType, siteSet, sceneSpec?.wechatPosition, value, automaticSiteEnabled])
+    }, [deliveryMode, marketingGoal, marketingAssetOuterSpec, marketingCarrierType, siteSet, sceneSpec?.wechatPosition, value, automaticSiteEnabled, putInType])
 
     useEffect(() => {
         if (!(value && Object.keys(value).length > 0) && adcreativeTemplateList?.length > 0 && marketingGoalTypeList?.length > 0) {
@@ -199,6 +204,9 @@ const NewDynamic: React.FC<Props> = ({ putInType, value: newValue, visible, onCl
         let creativeTemplateAppellation = adcreativeTemplateStructAdpermits?.creativeTemplateAppellation
         let result = processData(creativeComponents);
         console.log('result-->', result);
+        if (!result.barrage && true) {
+            result.barrage = { required: false }
+        }
         setCreativeComponents(result)
 
         let newMaterialData: { [x: string]: any } = {};
@@ -218,7 +226,9 @@ const NewDynamic: React.FC<Props> = ({ putInType, value: newValue, visible, onCl
         if (!(value && Object.keys(value).length > 0) || isAntTemplateId) {
             let values: any = {
                 dynamicCreativeName: creativeTemplateAppellation ? '自定义创意' + '_' + creativeTemplateAppellation + '_' + localStorage.getItem('userId') + '_' + randomString(true, 3, 5) : '动态创意' + '_' + localStorage.getItem('userId') + '_' + randomString(true, 3, 5),
-                pageSpec: [{
+                pageSpec: marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' ? [{
+                    pageType: "PAGE_TYPE_WECHAT_MINI_GAME"
+                }] : [{
                     pageType: 'PAGE_TYPE_WECHAT_CANVAS',
                     overrideCanvasHeadOption: 'OPTION_CREATIVE_OVERRIDE_CANVAS'
                 }],
@@ -243,7 +253,7 @@ const NewDynamic: React.FC<Props> = ({ putInType, value: newValue, visible, onCl
                             value: {
                                 linkNameType: linkNameEnumeration?.[0]?.value,
                                 jumpInfo: {
-                                    pageType: 'PAGE_TYPE_WECHAT_CANVAS'
+                                    pageType: marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' ? "PAGE_TYPE_WECHAT_MINI_GAME" : 'PAGE_TYPE_WECHAT_CANVAS'
                                 }
                             }
                         }
@@ -257,7 +267,7 @@ const NewDynamic: React.FC<Props> = ({ putInType, value: newValue, visible, onCl
                             value: {
                                 buttonText: butttonTextEnumeration?.[0]?.value,
                                 jumpInfo: {
-                                    pageType: 'PAGE_TYPE_WECHAT_CANVAS'
+                                    pageType: marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_MINI_GAME' ? "PAGE_TYPE_WECHAT_MINI_GAME" : 'PAGE_TYPE_WECHAT_CANVAS'
                                 }
                             }
                         }
@@ -634,9 +644,9 @@ const NewDynamic: React.FC<Props> = ({ putInType, value: newValue, visible, onCl
 
                         {Object.keys(creativeComponents).length > 0 && <>
                             {/* 创意内容 */}
-                            <CreativeTemplateContent automaticSiteEnabled={automaticSiteEnabled} />
+                            <CreativeTemplateContent automaticSiteEnabled={automaticSiteEnabled} putInType={putInType} />
                             {/* 营销组件 */}
-                            <CreativeConversionAssistant automaticSiteEnabled={automaticSiteEnabled} />
+                            <CreativeConversionAssistant automaticSiteEnabled={automaticSiteEnabled} putInType={putInType} />
                             {/* 创意设置 */}
                             <CreativeTemplateSetup />
                         </>}

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

@@ -13,7 +13,7 @@ const { Title } = Typography;
 const Material: React.FC<{ adData?: any[] }> = ({ adData }) => {
 
     /***************************************/
-    const { materialData, addelivery, setAddelivery, clearData, accountCreateLogs } = useContext(DispatchAddelivery)!;
+    const { materialData, addelivery, setAddelivery, clearData, accountCreateLogs, putInType } = useContext(DispatchAddelivery)!;
     const { dynamic, dynamicMaterialDTos, mediaType, targeting, adgroups: { marketingAssetOuterSpec, marketingCarrierType }, dynamicCreativesTextDTOS } = addelivery
     const { creativeTemplateId, deliveryMode } = dynamic
     const [adLength, setAdLength] = useState<number>(0)
@@ -175,6 +175,7 @@ const Material: React.FC<{ adData?: any[] }> = ({ adData }) => {
                     选择素材
                 </Button>
                 {dynamic && deliveryMode && <SaveUseImg
+                    putInType={putInType}
                     type={deliveryMode === "DELIVERY_MODE_CUSTOMIZE" ? creativeTemplateId : deliveryMode}
                     onChange={({ dynamicMaterialDTos, mediaType, dynamicCreativesTextDTOS }) => {
                         setAddelivery({ ...addelivery, dynamicMaterialDTos, mediaType: mediaType as any, dynamicCreativesTextDTOS })

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

@@ -10,7 +10,7 @@ const { Title, Text } = Typography;
 const MaterialText: React.FC = () => {
 
     /*************************************/
-    const { textData, addelivery, setAddelivery, clearData } = useContext(DispatchAddelivery)!;
+    const { textData, addelivery, setAddelivery, clearData, putInType } = useContext(DispatchAddelivery)!;
     const { dynamic, dynamicCreativesTextDTOS, dynamicMaterialDTos, mediaType } = addelivery
 
     const [addVisible, setAddVisible] = useState<boolean>(false)
@@ -70,6 +70,7 @@ const MaterialText: React.FC = () => {
             mediaType={mediaType}
             textData={textData}
             visible={addVisible}
+            putInType={putInType}
             deliveryMode={dynamic?.deliveryMode}
             onClose={() => {
                 setAddVisible(false)

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

@@ -18,6 +18,7 @@ interface Props {
     visible?: boolean
     onClose?: () => void
     onChange?: (value: any) => void
+    putInType?: 'NOVEL' | 'GAME'
 }
 
 /**
@@ -25,7 +26,7 @@ interface Props {
  * @param param0 
  * @returns 
  */
-const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData, dynamicMaterialDTos, mediaType, deliveryMode }) => {
+const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData, dynamicMaterialDTos, mediaType, deliveryMode, putInType }) => {
 
     /*************************************/
     const [form] = Form.useForm();
@@ -239,7 +240,7 @@ const NewText: React.FC<Props> = ({ visible, onClose, onChange, value, textData,
                                                         }
                                                     }]}
                                                 >
-                                                    <TextAideInput placeholder={'请输入' + item.label} style={{ width: 580 }} maxTextLength={item.restriction.textRestriction.maxLength} />
+                                                    <TextAideInput placeholder={'请输入' + item.label} style={{ width: 580 }} maxTextLength={item.restriction.textRestriction.maxLength} putInType={putInType} />
                                                 </Form.Item>
                                             ))}
                                             {deliveryMode === 'DELIVERY_MODE_COMPONENT' && item.arrayProperty?.maxNumber > 1 && textDto?.[num]?.[item.value]?.length < item.arrayProperty?.maxNumber && <Form.Item style={{ marginTop: 6, marginBottom: 0 }}>

+ 4 - 1
src/pages/launchSystemV3/tencentAdPutIn/create/PageList/index.tsx

@@ -81,7 +81,7 @@ const PageList: React.FC<{ adDataGroup?: { [x: number]: any[] } }> = ({ adDataGr
 
     return <div className={`${style.settingsBody_content_row} ${style.row6}`}>
         <div className={style.title}>
-            <span>{pageType === 'PAGE_TYPE_OFFICIAL' ? '灵鹊落地页(官方落地页)' : pageType === "PAGE_TYPE_WECHAT_MINI_PROGRAM" ? '微信小程序' : '原生推广页'}</span>
+            <span>{PAGE_TYPE_ENUM[pageType as keyof typeof PAGE_TYPE_ENUM] || '原生推广页'}</span>
         </div>
         <div className={style.detail}>
             <div className={style.detail_body}>
@@ -94,6 +94,9 @@ const PageList: React.FC<{ adDataGroup?: { [x: number]: any[] } }> = ({ adDataGr
                             <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} style={{ margin: 0, fontSize: 12 }} imageStyle={{ height: 18 }} />}
                     </div>
                 })}
+                {pageType === "PAGE_TYPE_WECHAT_MINI_GAME" && <div className={style.ad_config}>
+                    <div className={style.ad_config_item}>无需设置落地页</div>
+                </div>}
             </div>
             <div className={style.detail_footer}>
                 <Button

+ 4 - 3
src/pages/launchSystemV3/tencentAdPutIn/create/Save/index.tsx

@@ -1,12 +1,13 @@
 import { useAjax } from "@/Hook/useAjax";
 import { addV3StrategyApi } from "@/services/adqV3";
-import { Button, Dropdown, Form, Input, Menu, message, Modal } from "antd";
+import { Button, Dropdown, Form, Input, message, Modal } from "antd";
 import React, { useState } from "react";
 
 
 
 interface Props {
     addelivery: PULLIN.AddeliveryProps
+    putInType?: 'NOVEL' | 'GAME'
 }
 
 /**
@@ -14,7 +15,7 @@ interface Props {
  * @param param0 
  * @returns 
  */
-const Save: React.FC<Props> = ({ addelivery: { dynamic: { deliveryMode, creativeTemplateId }, dynamicMaterialDTos, mediaType, dynamicCreativesTextDTOS } }) => {
+const Save: React.FC<Props> = ({ addelivery: { dynamic: { deliveryMode, creativeTemplateId }, dynamicMaterialDTos, mediaType, dynamicCreativesTextDTOS }, putInType }) => {
 
     /*********************************/
     const [form] = Form.useForm();
@@ -39,7 +40,7 @@ const Save: React.FC<Props> = ({ addelivery: { dynamic: { deliveryMode, creative
                 }
                 params.strategyValue = JSON.stringify({ mediaType, dynamicMaterialDTos, deliveryMode, creativeTemplateId, dynamicCreativesTextDTOS })
             }
-            addV3Strategy.run(params).then(res => {
+            addV3Strategy.run({ ...params, taskType: putInType }).then(res => {
                 if (res) {
                     message.success('保存成功')
                     form.resetFields()

+ 4 - 3
src/pages/launchSystemV3/tencentAdPutIn/create/Save/saveUseImg.tsx

@@ -10,12 +10,13 @@ import { DiffOutlined } from "@ant-design/icons"
 interface Props {
     type: string,
     onChange?: (value: { dynamicMaterialDTos: any, mediaType: number, deliveryMode: string, creativeTemplateId: number, dynamicCreativesTextDTOS: any }) => void
+    putInType?: 'NOVEL' | 'GAME'
 }
 /**
  * 使用素材
  * @returns 
  */
-const SaveUseImg: React.FC<Props> = ({ onChange, type }) => {
+const SaveUseImg: React.FC<Props> = ({ onChange, type, putInType }) => {
 
     /***********************/
     const [visible, setVisible] = useState<boolean>(false)
@@ -31,10 +32,10 @@ const SaveUseImg: React.FC<Props> = ({ onChange, type }) => {
         if (visible) {
             getList()
         }
-    }, [visible, queryFormNew])
+    }, [visible, queryFormNew, putInType])
 
     const getList = () => {
-        getStrategy.run(queryFormNew)
+        getStrategy.run({ ...queryFormNew, taskType: putInType })
     }
 
     const use = () => {

+ 3 - 2
src/pages/launchSystemV3/tencentAdPutIn/create/TacticsS/index.tsx

@@ -12,12 +12,13 @@ interface Props {
         materialData: any,
         textData: any
     }
+    putInType?: 'NOVEL' | 'GAME'
 }
 /**
  * 存为策略组
  * @returns 
  */
-const TacticsS: React.FC<Props> = ({ strategyValue }) => {
+const TacticsS: React.FC<Props> = ({ strategyValue, putInType }) => {
 
     /*********************************/
     const [form] = Form.useForm();
@@ -32,7 +33,7 @@ const TacticsS: React.FC<Props> = ({ strategyValue }) => {
 
     const handleOk = () => {
         form.validateFields().then(values => {
-            addV3Strategy.run({ ...values, strategyValue: JSON.stringify(strategyValue), type: 'updateAd' }).then(res => {
+            addV3Strategy.run({ ...values, strategyValue: JSON.stringify(strategyValue), type: 'updateAd', taskType: putInType }).then(res => {
                 if (res) {
                     message.success('保存成功')
                     form.resetFields()

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

@@ -1,6 +1,6 @@
 import { Popconfirm, TableProps, Typography } from "antd";
 import React from "react";
-import { MARKETING_CARRIER_TYPE_ENUM, MARKETING_GOAL_ENUM, MARKETING_TARGET_TYPE_ENUM, SITE_SET_ENUM } from "../../const";
+import { MARKETING_CARRIER_TYPE_ENUM, MARKETING_GOAL_ENUM, MARKETING_SUB_GOAL_ENUM, MARKETING_TARGET_TYPE_ENUM, MARKETING_TARGET_TYPE_GAME_ENUM, SITE_SET_ENUM } from "../../const";
 const { Paragraph } = Typography;
 
 export const Columns = (del: (id: number) => void): TableProps<any>['columns'] => {
@@ -71,8 +71,8 @@ export const Columns = (del: (id: number) => void): TableProps<any>['columns'] =
                 let strategyValue = b.strategyValue
                 let { adData } = JSON.parse(strategyValue)
                 return <span dangerouslySetInnerHTML={{
-                    __html: `营销目的:<span style="color: #52c41a">${MARKETING_GOAL_ENUM[adData?.[0]?.marketingGoal as keyof typeof MARKETING_GOAL_ENUM]}</span>,
-                    推广产品类型:<span style="color: #52c41a">${MARKETING_TARGET_TYPE_ENUM[adData?.[0]?.marketingTargetType as keyof typeof MARKETING_TARGET_TYPE_ENUM]}</span>,
+                    __html: `营销目的:<span style="color: #52c41a">${b?.taskType === 'GAME' ?  MARKETING_SUB_GOAL_ENUM[adData?.[0]?.marketingSubGoal as keyof typeof MARKETING_SUB_GOAL_ENUM] : MARKETING_GOAL_ENUM[adData?.[0]?.marketingGoal as keyof typeof MARKETING_GOAL_ENUM]}</span>,
+                    推广产品类型:<span style="color: #52c41a">${b?.taskType === 'GAME' ? MARKETING_TARGET_TYPE_GAME_ENUM[adData?.[0]?.marketingTargetType as keyof typeof MARKETING_TARGET_TYPE_GAME_ENUM] : MARKETING_TARGET_TYPE_ENUM[adData?.[0]?.marketingTargetType as keyof typeof MARKETING_TARGET_TYPE_ENUM]}</span>,
                     营销载体类型:<span style="color: #52c41a">${MARKETING_CARRIER_TYPE_ENUM[adData?.[0]?.marketingCarrierType as keyof typeof MARKETING_CARRIER_TYPE_ENUM]}</span>,
                     版位选择:<span style="color: #52c41a">${adData?.[0]?.automaticSiteEnabled ? '自动版位' : '选择特定版位'}</span>,
                     ${!adData?.[0]?.automaticSiteEnabled && `广告版位:<span style="color: #52c41a">${adData?.[0]?.siteSet.map((item: string | number) => SITE_SET_ENUM[item as keyof typeof SITE_SET_ENUM]).toString()}</span>`}

+ 5 - 4
src/pages/launchSystemV3/tencentAdPutIn/create/TacticsS/userTactics.tsx

@@ -9,13 +9,14 @@ import '../../index.less'
 interface Props {
     userId: number
     type: string,
+    putInType?: 'NOVEL' | 'GAME'
     onChange?: (value: any) => void
 }
 /**
  * 使用策略组
  * @returns 
  */
-const UserTactics: React.FC<Props> = ({ onChange, type, userId }) => {
+const UserTactics: React.FC<Props> = ({ onChange, type, userId, putInType }) => {
 
     /***********************/
     const [visible, setVisible] = useState<boolean>(false)
@@ -31,10 +32,10 @@ const UserTactics: React.FC<Props> = ({ onChange, type, userId }) => {
         if (visible) {
             getList()
         }
-    }, [visible, queryFormNew])
+    }, [visible, queryFormNew, putInType])
 
     const getList = () => {
-        getStrategy.run(queryFormNew)
+        getStrategy.run({ ...queryFormNew, taskType: putInType })
     }
 
     const use = () => {
@@ -44,7 +45,7 @@ const UserTactics: React.FC<Props> = ({ onChange, type, userId }) => {
     const handleOk = () => {
         if (selectedRowKeys.length > 0) {
             const hide = message.loading('正在检测广告是否被删除...', 0)
-            let {strategyValue} = selectedRowKeys[0]
+            let { strategyValue } = selectedRowKeys[0]
             let { adData } = JSON.parse(strategyValue)
             getAdqV3AdList.run({ pageNum: 1, pageSize: 100, useType: 1, userId, adgroupIdList: adData.map((item: { adgroupId: any; }) => item.adgroupId) }).then(res => {
                 if (res?.data) {

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

@@ -44,7 +44,7 @@ const Target: React.FC = () => {
                                 geoLocationList={geoLocationList}
                                 modelList={modelList}
                                 key={index}
-                                taksType={item.taskType}
+                                taksType={item.taskType || putInType}
                                 targeting={{ targetingName: item.targetingName, ...item.targeting }}
                                 onClear={() => {
                                     let newTargeting: any[] = JSON.parse(JSON.stringify(targeting))

+ 33 - 24
src/pages/launchSystemV3/tencentAdPutIn/create/addDynamic.tsx

@@ -22,12 +22,12 @@ const { Text, Title } = Typography;
  * 新增创意
  * @returns 
  */
-const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose, adData: selectData, tactics }) => {
+const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose, adData: selectData, tactics, putInType }) => {
 
     /****************************************/
     const [addelivery, setAddelivery] = useState<PULLIN.AddeliveryProps>({ adgroups: {}, targeting: [], dynamic: {}, dynamicMaterialDTos: {}, dynamicCreativesTextDTOS: {}, mediaType: 0 })
     const { adgroups, dynamic } = addelivery
-    const { marketingAssetOuterSpec, marketingCarrierType, marketingGoal, siteSet, automaticSiteEnabled, sceneSpec } = addelivery.adgroups
+    const { marketingAssetOuterSpec, marketingCarrierType, marketingGoal, marketingSubGoal, siteSet, automaticSiteEnabled, sceneSpec } = addelivery.adgroups
     const { deliveryMode, creativeTemplateId } = addelivery.dynamic
     const [wechatVisible, setWechatVisible] = useState<boolean>(false) // 选择微信公众号弹窗控制
     const [channelsProfileVisible, setChannelsProfileVisible] = useState<boolean>(false) // 选择微信公众号弹窗控制
@@ -45,7 +45,7 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
 
     const createDynamicTask = useAjax((params) => createDynamicTaskApi(params))
     /****************************************/
-    
+
     useEffect(() => {
         if (creativeTemplateId) {
             let params: any = {
@@ -62,6 +62,10 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
             } else {
                 params.siteSet = siteSet
             }
+            params.taskType = putInType
+            if (putInType === 'GAME') {
+                params.marketingSubGoal = marketingSubGoal
+            }
             getCreativeDetails.run(params).then(res => {
                 if (res?.adcreativeTemplateStructAdpermits?.length > 0) {
                     let adcreativeTemplateStructAdpermits = res?.adcreativeTemplateStructAdpermits[0]
@@ -88,7 +92,7 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
                 }
             })
         }
-    }, [creativeTemplateId, deliveryMode, marketingGoal, marketingAssetOuterSpec, marketingCarrierType, siteSet, sceneSpec?.wechatPosition, automaticSiteEnabled])
+    }, [creativeTemplateId, deliveryMode, marketingGoal, marketingAssetOuterSpec, marketingCarrierType, siteSet, sceneSpec?.wechatPosition, automaticSiteEnabled, putInType])
 
     useEffect(() => {
         if (adData && adData.length) {
@@ -120,8 +124,8 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
             setMaterialData(materialData)
             setTextData(textData)
         } else if (selectData?.length > 0) {
-            const { siteSet, marketingCarrierType, marketingGoal, marketingTargetType, sceneSpec, automaticSiteEnabled } = selectData[0]
-            setAddelivery({ ...addelivery, adgroups: { marketingGoal, marketingCarrierType, siteSet, automaticSiteEnabled, sceneSpec, marketingAssetOuterSpec: { marketingTargetType } } })
+            const { siteSet, marketingCarrierType, marketingGoal, marketingTargetType, sceneSpec, automaticSiteEnabled, marketingSubGoal } = selectData[0]
+            setAddelivery({ ...addelivery, adgroups: { marketingGoal, marketingSubGoal, marketingCarrierType, siteSet, automaticSiteEnabled, sceneSpec, marketingAssetOuterSpec: { marketingTargetType } } })
             let AccountSet = new Set(selectData.map(item => item.accountId))
             setAccountCreateLogs([...AccountSet].map(accountId => ({ accountId })))
         }
@@ -154,7 +158,8 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
             message.error('请先配置创意文案')
             return
         }
-        if (!accountCreateLogs?.some(item => item?.pageList?.length)) {
+
+        if (!accountCreateLogs?.some(item => item?.pageList?.length) && !['PAGE_TYPE_WECHAT_MINI_GAME'].includes(dynamic?.creativeComponents?.mainJumpInfo?.[0]?.value?.pageType)) {
             message.error('请先选择落地页')
             return
         }
@@ -579,7 +584,8 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
                                     setMaterialData,
                                     textData,
                                     setTextData,
-                                    clearData
+                                    clearData,
+                                    putInType
                                 }}>
                                 <div className={style.settingsBody_content_right}>
                                     <div className={`${style.settingsBody_content_row} ${style.row1}`}>
@@ -603,7 +609,7 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
                                         </div>
                                     </div>
                                     {/* 创意 */}
-                                    <Dynamic 
+                                    <Dynamic
                                         creativeTemplateAppellation={creativeTemplateAppellation}
                                         creativeTemplateStyle={creativeTemplateStyle}
                                     />
@@ -621,21 +627,24 @@ const AddDynamic: React.FC<PULLIN.NewAddDynamic> = ({ visible, onChange, onClose
                     </div>
 
                     <Space className={style.bts} wrap>
-                        <TacticsS strategyValue={{
-                            adData: adData.map(item => {
-                                const { accountId, adgroupName, adgroupId, siteSet, marketingCarrierType, marketingGoal, marketingTargetType, sceneSpec, automaticSiteEnabled } = item
-                                return {
-                                    siteSet, marketingCarrierType, marketingGoal, marketingTargetType, sceneSpec, automaticSiteEnabled,
-                                    accountId,
-                                    adgroupId,
-                                    adgroupName
-                                }
-                            }),
-                            addelivery,
-                            accountCreateLogs,
-                            materialData,
-                            textData
-                        }} />
+                        <TacticsS
+                            strategyValue={{
+                                adData: adData.map(item => {
+                                    const { accountId, adgroupName, adgroupId, siteSet, marketingCarrierType, marketingGoal, marketingTargetType, sceneSpec, automaticSiteEnabled, marketingSubGoal } = item
+                                    return {
+                                        siteSet, marketingCarrierType, marketingGoal, marketingSubGoal, marketingTargetType, sceneSpec, automaticSiteEnabled,
+                                        accountId,
+                                        adgroupId,
+                                        adgroupName
+                                    }
+                                }),
+                                addelivery,
+                                accountCreateLogs,
+                                materialData,
+                                textData
+                            }}
+                            putInType={putInType}
+                        />
                         <Button type='primary' onClick={preview}><SearchOutlined />预览广告</Button>
                     </Space>
 

+ 12 - 5
src/pages/launchSystemV3/tencentAdPutIn/create/index.tsx

@@ -41,7 +41,7 @@ const Create: React.FC = () => {
     const { getAllUserAccount } = useModel('useLaunchAdq.useAdAuthorize')
     const { initTargeting } = useModel('useLaunchV3.useTargeting')
     const [addelivery, setAddelivery] = useState<PULLIN.AddeliveryProps>({ adgroups: {}, targeting: [], dynamic: {}, dynamicMaterialDTos: {}, dynamicCreativesTextDTOS: {}, mediaType: 0 })
-    const { marketingAssetOuterSpec, marketingCarrierType, marketingGoal, siteSet, automaticSiteEnabled, sceneSpec, isConversion } = addelivery.adgroups
+    const { marketingAssetOuterSpec, marketingCarrierType, marketingGoal, marketingSubGoal, siteSet, automaticSiteEnabled, sceneSpec, isConversion } = addelivery.adgroups
     const { deliveryMode, creativeTemplateId, creativeComponents } = addelivery.dynamic
     const [accSearch, setAccSearch] = useState<string>()
     const [accountCreateLogs, setAccountCreateLogs] = useState<PULLIN.AccountCreateLogsProps[]>([])  // 账户
@@ -113,6 +113,10 @@ const Create: React.FC = () => {
             } else {
                 params.siteSet = siteSet
             }
+            params.taskType = putInType
+            if (putInType === 'GAME') {
+                params.marketingSubGoal = marketingSubGoal
+            }
             getCreativeDetails.run(params).then(res => {
                 if (res?.adcreativeTemplateStructAdpermits?.length > 0) {
                     let adcreativeTemplateStructAdpermits = res?.adcreativeTemplateStructAdpermits[0]
@@ -139,7 +143,7 @@ const Create: React.FC = () => {
                 }
             })
         }
-    }, [creativeTemplateId, deliveryMode, marketingGoal, marketingAssetOuterSpec, marketingCarrierType, siteSet, sceneSpec?.wechatPosition, automaticSiteEnabled])
+    }, [creativeTemplateId, deliveryMode, marketingGoal, marketingAssetOuterSpec, marketingCarrierType, siteSet, sceneSpec?.wechatPosition, automaticSiteEnabled, putInType])
 
     /** 获取分组里账号 */
     const getGroupAccountList = (ids: number[]) => {
@@ -386,7 +390,7 @@ const Create: React.FC = () => {
             return
         }
 
-        if (!accountCreateLogs?.some(item => item?.pageList?.length)) {
+        if (!accountCreateLogs?.some(item => item?.pageList?.length) && !['PAGE_TYPE_WECHAT_MINI_GAME'].includes(dynamic?.creativeComponents?.mainJumpInfo?.[0]?.value?.pageType)) {
             message.error('请先选择落地页')
             return
         }
@@ -520,6 +524,7 @@ const Create: React.FC = () => {
 
             newAdCount += data.length
             let newData: any[] = []
+            // 激励
             if ([910].includes(dynamic.creativeTemplateId)) {
                 if (dynamic?.landingPageType === 1) {
                     let averageAdPageList: any[] = distributeArray(item.pageList, productList.length * targeting.length)
@@ -767,7 +772,9 @@ const Create: React.FC = () => {
 
             let map: any = {
                 userActionSetsList: userActionSetsListDto,
-                pageList: pageList?.map((item: { pageId: any }) => item.pageId)
+            }
+            if (!['PAGE_TYPE_WECHAT_MINI_GAME'].includes(dynamic?.creativeComponents?.mainJumpInfo?.[0]?.value?.pageType)) {
+                map.pageList = pageList?.map((item: { pageId: any }) => item.pageId)
             }
             if (productList && ['MARKETING_TARGET_TYPE_FICTION', 'MARKETING_TARGET_TYPE_SHORT_DRAMA'].includes(marketingAssetOuterSpec?.marketingTargetType)) {
                 map.productDTOS = productList?.map(item => {
@@ -974,7 +981,7 @@ const Create: React.FC = () => {
                     </div>
                 </div>
                 <Space className={style.bts} wrap>
-                    <Save addelivery={addelivery} />
+                    <Save addelivery={addelivery} putInType={putInType} />
                     <Button type='primary' onClick={severBd}>存为预设</Button>
                     <Popconfirm
                         title="确定清空?"

+ 11 - 0
src/pages/launchSystemV3/tencentAdPutIn/create/tableConfig.tsx

@@ -56,6 +56,11 @@ const columns = (): TableProps<any>['columns'] => {
                                 <Text style={{ fontSize: 12 }}>推广产品:企业微信(产品本地ID:{b?.adgroupsDto?.sysCorpWechatId})</Text>
                                 <Text style={{ fontSize: 12 }}>转化归因:{b?.userActionSetsList ? b?.userActionSetsList.map((item: { name: any; }) => item.name).toString() : b?.conversionList ? b?.conversionList.map((item: { conversionName: any; conversionId: any; }) => `${item?.conversionName}(${item.conversionId})`).toString() : '暂未配置'}</Text>
                             </Space>
+                        } else if (['MARKETING_TARGET_TYPE_WECHAT_MINI_GAME'].includes(b.adgroupsDto?.marketingAssetOuterSpec?.marketingTargetType)) {
+                            return <Space size={0} direction="vertical">
+                                <Text style={{ fontSize: 12 }}>推广产品:微信小游戏(appId:{b?.adgroupsDto?.wxGameAppId})</Text>
+                                <Text style={{ fontSize: 12 }}>转化归因:{b?.userActionSetsList ? b?.userActionSetsList.map((item: { name: any; }) => item.name).toString() : b?.conversionList ? b?.conversionList.map((item: { conversionName: any; conversionId: any; }) => `${item?.conversionName}(${item.conversionId})`).toString() : '暂未配置'}</Text>
+                            </Space>
                         }
                         return 'ERROR,请联系管理员'
                     },
@@ -223,6 +228,9 @@ const columns = (): TableProps<any>['columns'] => {
                     render: (_, b) => {
                         let pageListDto = b?.pageListDto
                         let pageType = b?.dynamicDto?.creativeComponents?.mainJumpInfo?.[0]?.value?.pageType
+                        if (pageType === 'PAGE_TYPE_WECHAT_MINI_GAME') {
+                            return <Text style={{ fontSize: 12 }}>无需配置</Text>
+                        }
                         return <Text style={{ fontSize: 12, wordBreak: 'break-all' }}>
                             {pageType === 'PAGE_TYPE_OFFICIAL' ? '灵鹊落地页' : pageType === 'PAGE_TYPE_WECHAT_MINI_PROGRAM' ? '微信小程序' : '原生推广页'}:
                             {pageListDto?.map((item: { pageName: any; }) => item?.pageName)?.join(',')}
@@ -389,6 +397,9 @@ export const columnsAddDynamic = (): TableProps<any>['columns'] => {
                     render: (_, b) => {
                         let pageListDto = b?.pageListDto
                         let pageType = b?.dynamicDto?.creativeComponents?.mainJumpInfo?.[0]?.value?.pageType
+                        if (pageType === 'PAGE_TYPE_WECHAT_MINI_GAME') {
+                            return <Text style={{ fontSize: 12 }}>无需配置</Text>
+                        }
                         return <Text style={{ fontSize: 12, wordBreak: 'break-all' }}>
                             {pageType === 'PAGE_TYPE_OFFICIAL' ? '灵鹊落地页' : pageType === 'PAGE_TYPE_WECHAT_MINI_PROGRAM' ? '微信小程序' : '原生推广页'}:
                             {pageListDto?.map((item: { pageName: any; }) => item?.pageName)?.join(',')}

+ 14 - 9
src/pages/launchSystemV3/tencentAdPutIn/taskList/tableConfig.tsx

@@ -33,7 +33,8 @@ const columns = (geoLocationList: any, modelList: any, callback: (data: any, typ
             align: 'center',
             fixed: 'left',
             render(value) {
-                return { 0: <Badge status="processing" text={<span style={{ fontSize: 12 }} >执行中</span>} />, 1: <Badge style={{ fontSize: 12 }} status="error" text={<span style={{ fontSize: 12 }} >全部失败</span>} />, 2: <Badge style={{ fontSize: 12 }} status="warning" text={<span style={{ fontSize: 12 }} >部分成功</span>} />, 100: <Badge style={{ fontSize: 12 }} status="success" text={<span style={{ fontSize: 12 }} >全部成功</span>} /> }[value]
+                let a = { 0: <Badge status="processing" text={<span style={{ fontSize: 12 }} >执行中</span>} />, 1: <Badge style={{ fontSize: 12 }} status="error" text={<span style={{ fontSize: 12 }} >全部失败</span>} />, 2: <Badge style={{ fontSize: 12 }} status="warning" text={<span style={{ fontSize: 12 }} >部分成功</span>} />, 100: <Badge style={{ fontSize: 12 }} status="success" text={<span style={{ fontSize: 12 }} >全部成功</span>} /> }
+                return a[value as keyof typeof a]
             },
         },
         {
@@ -67,7 +68,7 @@ const columns = (geoLocationList: any, modelList: any, callback: (data: any, typ
             render: (_, b) => {
                 let configuredStatus = b?.adgroupDTO?.configuredStatus
                 if (configuredStatus) {
-                    return <span style={{ fontSize: "12px" }}>{AD_STATUS_ENUM[configuredStatus]}</span>
+                    return <span style={{ fontSize: "12px" }}>{AD_STATUS_ENUM[configuredStatus as keyof typeof AD_STATUS_ENUM]}</span>
                 } else {
                     return <span>--</span>
                 }
@@ -79,7 +80,7 @@ const columns = (geoLocationList: any, modelList: any, callback: (data: any, typ
             key: 'adgroupDTO',
             width: 200,
             ellipsis: true,
-            render(value) {
+            render(value, records) {
                 return <div style={{ width: '100%', display: 'flex', alignItems: 'center' }}>
                     <div style={{ width: 'calc(100% - 20px)' }}><Typography.Text style={{ fontSize: 12 }} ellipsis={{ tooltip: true }}>{value?.adgroupName}</Typography.Text></div>
                     <Popover
@@ -87,6 +88,7 @@ const columns = (geoLocationList: any, modelList: any, callback: (data: any, typ
                         overlayInnerStyle={{ maxWidth: 350, maxHeight: 350, overflow: 'hidden', overflowY: 'auto' }}
                         mouseEnterDelay={0.5}
                         content={<AdgroupTooltip
+                            taskType={records?.taskType}
                             data={value}
                         />}
                     >
@@ -100,7 +102,7 @@ const columns = (geoLocationList: any, modelList: any, callback: (data: any, typ
             dataIndex: 'targetings',
             key: 'targetings',
             width: 300,
-            render(value) {
+            render(value, records) {
                 return <div style={{ width: '100%', display: 'flex', alignItems: 'center', gap: 10, overflow: 'hidden', overflowX: 'auto' }}>
                     {value?.map((item: any, index: number) => <Popover
                         key={index}
@@ -111,6 +113,7 @@ const columns = (geoLocationList: any, modelList: any, callback: (data: any, typ
                             data={item}
                             geoLocationList={geoLocationList}
                             modelList={modelList}
+                            taskType={records?.taskType}
                         />}
                     >
                         <div style={{ width: 80, cursor: 'help' }}><Typography.Text style={{ fontSize: 12 }} ellipsis>{index + 1}、{item?.targetingName || '--'}</Typography.Text></div>
@@ -210,7 +213,7 @@ export const columnsLog = (sync: (value: any) => void): TableProps<any>['columns
             ellipsis: true,
             align: 'center',
             render(value) {
-                return <span style={{ fontSize: 12 }}>{MARKETING_GOAL_ENUM[value]}</span>
+                return <span style={{ fontSize: 12 }}>{MARKETING_GOAL_ENUM[value  as keyof typeof MARKETING_GOAL_ENUM]}</span>
             },
         },
         {
@@ -230,7 +233,8 @@ export const columnsLog = (sync: (value: any) => void): TableProps<any>['columns
             width: 90,
             align: 'center',
             render(value) {
-                return { 0: <Badge status="processing" text={<span style={{ fontSize: 12 }}>执行中</span>} />, 1: <Badge status="error" style={{ fontSize: 12 }} text={<span>失败</span>} />, 101: <Badge status="warning" style={{ fontSize: 12 }} text={<span>同步异常</span>} />, 100: <Badge style={{ fontSize: 12 }} status="success" text={<span>成功</span>} /> }[value]
+                const a = { 0: <Badge status="processing" text={<span style={{ fontSize: 12 }}>执行中</span>} />, 1: <Badge status="error" style={{ fontSize: 12 }} text={<span>失败</span>} />, 101: <Badge status="warning" style={{ fontSize: 12 }} text={<span>同步异常</span>} />, 100: <Badge style={{ fontSize: 12 }} status="success" text={<span>成功</span>} /> }
+                return a[value as keyof typeof a]
             },
         },
         {
@@ -299,7 +303,7 @@ export const columnsDynamicLog = (): TableProps<any>['columns'] => {
             ellipsis: true,
             align: 'center',
             render(value) {
-                return <span style={{ fontSize: 12 }}>{DELIVERY_MODE_ENUM[value]}</span>
+                return <span style={{ fontSize: 12 }}>{DELIVERY_MODE_ENUM[value as keyof typeof DELIVERY_MODE_ENUM]}</span>
             }
         },
         {
@@ -310,7 +314,7 @@ export const columnsDynamicLog = (): TableProps<any>['columns'] => {
             ellipsis: true,
             align: 'center',
             render(value) {
-                return <span style={{ fontSize: 12 }}>{DYNAMIC_CREATIVE_TYPE_ENUM[value]}</span>
+                return <span style={{ fontSize: 12 }}>{DYNAMIC_CREATIVE_TYPE_ENUM[value as keyof typeof DYNAMIC_CREATIVE_TYPE_ENUM]}</span>
             }
         },
         {
@@ -353,7 +357,8 @@ export const columnsDynamicLog = (): TableProps<any>['columns'] => {
             width: 80,
             align: 'center',
             render(value) {
-                return { 0: <Badge status="processing" text={<span style={{ fontSize: 12 }}>执行中</span>} />, 1: <Badge status="error" style={{ fontSize: 12 }} text={<span>失败</span>} />, 100: <Badge style={{ fontSize: 12 }} status="success" text={<span>成功</span>} /> }[value]
+                const a = { 0: <Badge status="processing" text={<span style={{ fontSize: 12 }}>执行中</span>} />, 1: <Badge status="error" style={{ fontSize: 12 }} text={<span>失败</span>} />, 100: <Badge style={{ fontSize: 12 }} status="success" text={<span>成功</span>} /> }
+                return a[value as keyof typeof a]
             },
         },
         {

+ 4 - 1
src/pages/launchSystemV3/tencentAdPutIn/typings.d.ts

@@ -139,6 +139,7 @@ declare namespace PULLIN {
      */
     type NewAddDynamic = {
         adData: any[],
+        putInType?: 'NOVEL' | 'GAME'
         visible?: boolean,
         tactics?: any,
         onClose?: () => void,
@@ -150,11 +151,13 @@ declare namespace PULLIN {
         strategyKey: string,
         strategyValue: string,
         remark?: string
+        putInType?: 'NOVEL' | 'GAME'
     }
     type GetV3StrategyListProps = {
         pageNum: number,
         pageSize: number,
         strategyKey?: string,
-        type?: string
+        type?: string,
+        putInType?: 'NOVEL' | 'GAME'
     }
 }

+ 24 - 0
src/services/adqV3/global.ts

@@ -660,3 +660,27 @@ export async function getGameLibraryDetailApi(id: number) {
         method: 'GET'
     })
 }
+
+/**
+ * 获取游戏详情
+ * @param wxGameAppId 
+ * @returns 
+ */
+export async function getGameLibraryAppIdDetailApi(wxGameAppId: number) {
+    return request(api + `/adq/v3/gameLibrary/getByAppId/${wxGameAppId}`, {
+        method: 'GET'
+    })
+}
+
+
+/**
+ * 获取弹幕
+ * @param data 
+ * @returns 
+ */
+export async function getBarrageRecommendListApi(params: { adAccountId?: number, taskType?: 'GAME' | 'NOVEL' }) {
+    return request(api + `/adq/v3/launch/tools/creative/tools/barrageRecommend`, {
+        method: 'GET',
+        params
+    })
+}