|  | @@ -23,6 +23,7 @@ import { createAdgroupTaskApi, getSelectTaskDetailApi } from "@/services/adqV3"
 | 
	
		
			
				|  |  |  import WechatAccount from "../../components/WechatAccount"
 | 
	
		
			
				|  |  |  import Title from "antd/lib/typography/Title"
 | 
	
		
			
				|  |  |  import { getCreativeDetailsApi } from "@/services/adqV3/global"
 | 
	
		
			
				|  |  | +import ConversionSelect from "../../components/ConversionSelect"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  export const DispatchAddelivery = React.createContext<PULLIN.DispatchAddelivery | null>(null);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -36,13 +37,14 @@ 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 } = addelivery.adgroups
 | 
	
		
			
				|  |  | -    const { deliveryMode, creativeTemplateId } = addelivery.dynamic
 | 
	
		
			
				|  |  | +    const { marketingAssetOuterSpec, marketingCarrierType, marketingGoal, siteSet, automaticSiteEnabled, sceneSpec, isConversion } = addelivery.adgroups
 | 
	
		
			
				|  |  | +    const { deliveryMode, creativeTemplateId, creativeComponents } = addelivery.dynamic
 | 
	
		
			
				|  |  |      const [accSearch, setAccSearch] = useState<string>()
 | 
	
		
			
				|  |  |      const [accountCreateLogs, setAccountCreateLogs] = useState<PULLIN.AccountCreateLogsProps[]>([])  // 账户
 | 
	
		
			
				|  |  |      const [goodsVisible, setGoodsVisible] = useState<boolean>(false) // 选择小说弹窗控制
 | 
	
		
			
				|  |  |      const [wechatVisible, setWechatVisible] = useState<boolean>(false) // 选择微信公众号弹窗控制
 | 
	
		
			
				|  |  |      const [sourceVisible, setSourceVisible] = useState<boolean>(false) // 选择数据源弹窗控制
 | 
	
		
			
				|  |  | +    const [conversionVisible, setConversionVisible] = useState<boolean>(false) // 选择转化归因控制
 | 
	
		
			
				|  |  |      const [materialData, setMaterialData] = useState<any>({}) // 素材数据
 | 
	
		
			
				|  |  |      const [textData, setTextData] = useState<any>({})
 | 
	
		
			
				|  |  |      const [tableData, setTableData] = useState<any>({})
 | 
	
	
		
			
				|  | @@ -223,19 +225,9 @@ const Create: React.FC = () => {
 | 
	
		
			
				|  |  |                          })
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                    setAddelivery({
 | 
	
		
			
				|  |  | -                        adgroups: { ...adgroupDTO, adgroupName: adgroupDTO.adgroupName + '_副本' + randomString(true, 3, 5), endDate, beginDate },
 | 
	
		
			
				|  |  | -                        targeting: targetings.map((item: any) => {
 | 
	
		
			
				|  |  | -                            const { targetingName, ...targeting } = item
 | 
	
		
			
				|  |  | -                            return { targetingName, targeting }
 | 
	
		
			
				|  |  | -                        }),
 | 
	
		
			
				|  |  | -                        dynamic,
 | 
	
		
			
				|  |  | -                        dynamicMaterialDTos: dynamicGroup.length > 0 ? { dynamicGroup } : {},
 | 
	
		
			
				|  |  | -                        dynamicCreativesTextDTOS: dynamicCreativesTextDTO,
 | 
	
		
			
				|  |  | -                        mediaType: mediaType || 0
 | 
	
		
			
				|  |  | -                    })
 | 
	
		
			
				|  |  | +                    let isConversion = false
 | 
	
		
			
				|  |  |                      setAccountCreateLogs(Object.keys(accountIdParamVOMap || {}).map(accountId => {
 | 
	
		
			
				|  |  | -                        const { productDTOS, wechatOfficialAccountsVO, pageList, landingPageVOS, userActionSetsList } = accountIdParamVOMap[accountId]
 | 
	
		
			
				|  |  | +                        const { productDTOS, wechatOfficialAccountsVO, pageList, landingPageVOS, userActionSetsList, conversionInfo } = accountIdParamVOMap[accountId]
 | 
	
		
			
				|  |  |                          let data: PULLIN.AccountCreateLogsProps = {
 | 
	
		
			
				|  |  |                              accountId: Number(accountId),
 | 
	
		
			
				|  |  |                              productList: productDTOS
 | 
	
	
		
			
				|  | @@ -249,8 +241,24 @@ const Create: React.FC = () => {
 | 
	
		
			
				|  |  |                          if (userActionSetsList) {
 | 
	
		
			
				|  |  |                              data.userActionSetsList = userActionSetsList
 | 
	
		
			
				|  |  |                          }
 | 
	
		
			
				|  |  | +                        if (conversionInfo) {
 | 
	
		
			
				|  |  | +                            isConversion = true
 | 
	
		
			
				|  |  | +                            data.newConversionList = [conversionInfo]
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  |                          return data
 | 
	
		
			
				|  |  |                      }))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    setAddelivery({
 | 
	
		
			
				|  |  | +                        adgroups: { ...adgroupDTO, isConversion, adgroupName: adgroupDTO.adgroupName + '_副本' + randomString(true, 3, 5), endDate, beginDate },
 | 
	
		
			
				|  |  | +                        targeting: targetings.map((item: any) => {
 | 
	
		
			
				|  |  | +                            const { targetingName, ...targeting } = item
 | 
	
		
			
				|  |  | +                            return { targetingName, targeting }
 | 
	
		
			
				|  |  | +                        }),
 | 
	
		
			
				|  |  | +                        dynamic,
 | 
	
		
			
				|  |  | +                        dynamicMaterialDTos: dynamicGroup.length > 0 ? { dynamicGroup } : {},
 | 
	
		
			
				|  |  | +                        dynamicCreativesTextDTOS: dynamicCreativesTextDTO,
 | 
	
		
			
				|  |  | +                        mediaType: mediaType || 0
 | 
	
		
			
				|  |  | +                    })
 | 
	
		
			
				|  |  |                      sessionStorage.removeItem('TASKID3.0')
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              })
 | 
	
	
		
			
				|  | @@ -284,14 +292,18 @@ const Create: React.FC = () => {
 | 
	
		
			
				|  |  |              message.error('请先配置广告信息')
 | 
	
		
			
				|  |  |              return
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        if (['MARKETING_TARGET_TYPE_FICTION'].includes(marketingAssetOuterSpec?.marketingTargetType) && !accountCreateLogs?.some(item => item?.productList?.length)) {
 | 
	
		
			
				|  |  | -            message.error('请先选择小说')
 | 
	
		
			
				|  |  | +        if (['MARKETING_TARGET_TYPE_FICTION', 'MARKETING_TARGET_TYPE_SHORT_DRAMA'].includes(marketingAssetOuterSpec?.marketingTargetType) && !accountCreateLogs?.some(item => item?.productList?.length)) {
 | 
	
		
			
				|  |  | +            message.error(marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_FICTION' ? '请先选择小说' : '请先选择短剧')
 | 
	
		
			
				|  |  |              return
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        if ((['MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT'].includes(marketingAssetOuterSpec?.marketingTargetType) || marketingCarrierType === 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT') && !accountCreateLogs?.some(item => item?.wechatChannelList?.length)) {
 | 
	
		
			
				|  |  | +        if ((['MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT'].includes(marketingAssetOuterSpec?.marketingTargetType) || marketingCarrierType === 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT' || dynamic?.creativeComponents?.brand?.[0]?.value?.jumpInfo?.pageType === 'PAGE_TYPE_WECHAT_OFFICIAL_ACCOUNT_DETAIL') && !accountCreateLogs?.some(item => item?.wechatChannelList?.length)) {
 | 
	
		
			
				|  |  |              message.error('请先选择公众号')
 | 
	
		
			
				|  |  |              return
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +        if (isConversion && !accountCreateLogs?.some(item => item?.newConversionList?.length)) {
 | 
	
		
			
				|  |  | +            message.error('请先选择转化归因')
 | 
	
		
			
				|  |  | +            return
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |          if (!(targeting?.length)) {
 | 
	
		
			
				|  |  |              message.error('请先添加定向')
 | 
	
		
			
				|  |  |              return
 | 
	
	
		
			
				|  | @@ -346,7 +358,7 @@ const Create: React.FC = () => {
 | 
	
		
			
				|  |  |              let adLength = 0
 | 
	
		
			
				|  |  |              accountCreateLogs.forEach(item => {
 | 
	
		
			
				|  |  |                  let productList: any[] = []
 | 
	
		
			
				|  |  | -                if (['MARKETING_TARGET_TYPE_FICTION'].includes(marketingAssetOuterSpec?.marketingTargetType)) { // 小说
 | 
	
		
			
				|  |  | +                if (['MARKETING_TARGET_TYPE_FICTION', 'MARKETING_TARGET_TYPE_SHORT_DRAMA'].includes(marketingAssetOuterSpec?.marketingTargetType)) { // 小说
 | 
	
		
			
				|  |  |                      productList = item?.productList || []
 | 
	
		
			
				|  |  |                  } else if (['MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT'].includes(marketingAssetOuterSpec?.marketingTargetType)) { // 公众号
 | 
	
		
			
				|  |  |                      productList = item?.wechatChannelList || []
 | 
	
	
		
			
				|  | @@ -403,7 +415,7 @@ const Create: React.FC = () => {
 | 
	
		
			
				|  |  |          let accountIndex = 0, accountIndex1 = 0
 | 
	
		
			
				|  |  |          accountCreateLogs.forEach(item => {
 | 
	
		
			
				|  |  |              let productList: any[] = []
 | 
	
		
			
				|  |  | -            if (['MARKETING_TARGET_TYPE_FICTION'].includes(marketingAssetOuterSpec?.marketingTargetType)) { // 小说
 | 
	
		
			
				|  |  | +            if (['MARKETING_TARGET_TYPE_FICTION', 'MARKETING_TARGET_TYPE_SHORT_DRAMA'].includes(marketingAssetOuterSpec?.marketingTargetType)) { // 小说
 | 
	
		
			
				|  |  |                  productList = item?.productList || []
 | 
	
		
			
				|  |  |              } else if (['MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT'].includes(marketingAssetOuterSpec?.marketingTargetType)) { // 公众号
 | 
	
		
			
				|  |  |                  productList = item?.wechatChannelList || []
 | 
	
	
		
			
				|  | @@ -416,6 +428,7 @@ const Create: React.FC = () => {
 | 
	
		
			
				|  |  |                      id: item.accountId + '_' + index,
 | 
	
		
			
				|  |  |                      accountId: item.accountId,                    // 账户
 | 
	
		
			
				|  |  |                      userActionSetsList: item.userActionSetsList,  // 数据源
 | 
	
		
			
				|  |  | +                    conversionList: item.newConversionList,       // 转化归因
 | 
	
		
			
				|  |  |                      pageListDto: item.pageList,                   // 落地页
 | 
	
		
			
				|  |  |                      productDto,                                   // 商品
 | 
	
		
			
				|  |  |                      targetDto: {                                  // 定向
 | 
	
	
		
			
				|  | @@ -458,7 +471,7 @@ const Create: React.FC = () => {
 | 
	
		
			
				|  |  |                                  isRowSpan: true
 | 
	
		
			
				|  |  |                              })
 | 
	
		
			
				|  |  |                          })
 | 
	
		
			
				|  |  | -                        
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                      })
 | 
	
		
			
				|  |  |                  } else {
 | 
	
		
			
				|  |  |                      newData = cartesianProduct(data, item.pageList).map((item, index) => {
 | 
	
	
		
			
				|  | @@ -570,7 +583,7 @@ const Create: React.FC = () => {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // 提交
 | 
	
		
			
				|  |  |      const onSubmit = (values: any) => {
 | 
	
		
			
				|  |  | -        const { adgroups, targeting, dynamic, dynamicMaterialDTos, dynamicCreativesTextDTOS, mediaType } = addelivery
 | 
	
		
			
				|  |  | +        const { adgroups, targeting, dynamic, dynamicMaterialDTos, dynamicCreativesTextDTOS, mediaType } = JSON.parse(JSON.stringify(addelivery)) as PULLIN.AddeliveryProps
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          let dynamicMaterialDTOS = []
 | 
	
		
			
				|  |  |          if (dynamic.deliveryMode === 'DELIVERY_MODE_CUSTOMIZE') {
 | 
	
	
		
			
				|  | @@ -680,7 +693,7 @@ const Create: React.FC = () => {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          let accountIdParamDTOMap: any = {}
 | 
	
		
			
				|  |  |          accountCreateLogs.forEach(item => {
 | 
	
		
			
				|  |  | -            let { pageList, productList, userActionSetsList, accountId, wechatChannelList } = item
 | 
	
		
			
				|  |  | +            let { pageList, productList, userActionSetsList, accountId, wechatChannelList, newConversionList } = item
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              let userActionSetsListDto = userActionSetsList?.map((item: any) => ({ id: item?.userActionSetId, type: item?.type })) // dataSourceId
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -696,6 +709,9 @@ const Create: React.FC = () => {
 | 
	
		
			
				|  |  |              if (wechatChannelList) {
 | 
	
		
			
				|  |  |                  map.wechatChannelId = wechatChannelList?.[0]?.wechatOfficialAccountId
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | +            if (newConversionList) {
 | 
	
		
			
				|  |  | +                map.conversionId = newConversionList[0].conversionId
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              accountIdParamDTOMap[accountId] = map
 | 
	
		
			
				|  |  |          })
 | 
	
	
		
			
				|  | @@ -703,6 +719,7 @@ const Create: React.FC = () => {
 | 
	
		
			
				|  |  |          if (dynamic.deliveryMode === 'DELIVERY_MODE_COMPONENT') {
 | 
	
		
			
				|  |  |              dynamicCreativesDTO.creativeTemplateId = 711
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +        delete adgroups?.isConversion  // 前端控制新链路字段
 | 
	
		
			
				|  |  |          let params = {
 | 
	
		
			
				|  |  |              ...values,
 | 
	
		
			
				|  |  |              adgroupDTO: adgroups,
 | 
	
	
		
			
				|  | @@ -833,9 +850,13 @@ const Create: React.FC = () => {
 | 
	
		
			
				|  |  |                      </Selector>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                      {accountCreateLogs?.length > 0 && <>
 | 
	
		
			
				|  |  | -                        {marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_FICTION' && <Button type="primary" danger={!accountCreateLogs?.some(item => item?.productList?.length)} onClick={() => { setGoodsVisible(true) }}>{accountCreateLogs?.some(item => item?.productList?.length) ? <>重新选择小说 <CheckOutlined style={{ color: '#FFFFFF' }} /></> : '请选择小说'}</Button>}
 | 
	
		
			
				|  |  | -                        {(marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT' || marketingCarrierType === 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT') && <Button type="primary" danger={!accountCreateLogs?.some(item => item?.wechatChannelList?.length)} onClick={() => { setWechatVisible(true) }}>{accountCreateLogs?.some(item => item?.wechatChannelList?.length) ? <>重新选择公众号 <CheckOutlined style={{ color: '#FFFFFF' }} /></> : '请选择公众号'}</Button>}
 | 
	
		
			
				|  |  | -                        <Button onClick={() => { setSourceVisible(true) }}>精准匹配归因(选填){accountCreateLogs?.some(item => item?.userActionSetsList?.length) && <CheckOutlined style={{ color: '#1890ff' }} />}</Button>
 | 
	
		
			
				|  |  | +                        {['MARKETING_TARGET_TYPE_FICTION', 'MARKETING_TARGET_TYPE_SHORT_DRAMA'].includes(marketingAssetOuterSpec?.marketingTargetType) && <Button type="primary" danger={!accountCreateLogs?.some(item => item?.productList?.length)} onClick={() => { setGoodsVisible(true) }}>{accountCreateLogs?.some(item => item?.productList?.length) ? <>重新选择{marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_FICTION' ? '小说' : '短剧'} <CheckOutlined style={{ color: '#FFFFFF' }} /></> : `请选择${marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_FICTION' ? '小说' : '短剧'}`}</Button>}
 | 
	
		
			
				|  |  | +                        {(marketingAssetOuterSpec?.marketingTargetType === 'MARKETING_TARGET_TYPE_WECHAT_OFFICIAL_ACCOUNT' || marketingCarrierType === 'MARKETING_CARRIER_TYPE_WECHAT_OFFICIAL_ACCOUNT' || creativeComponents?.brand?.[0]?.value?.jumpInfo?.pageType === 'PAGE_TYPE_WECHAT_OFFICIAL_ACCOUNT_DETAIL') && <Button type="primary" danger={!accountCreateLogs?.some(item => item?.wechatChannelList?.length)} onClick={() => { setWechatVisible(true) }}>{accountCreateLogs?.some(item => item?.wechatChannelList?.length) ? <>重新选择公众号 <CheckOutlined style={{ color: '#FFFFFF' }} /></> : '请选择公众号'}</Button>}
 | 
	
		
			
				|  |  | +                        {!isConversion ?
 | 
	
		
			
				|  |  | +                            <Button onClick={() => { setSourceVisible(true) }}>精准匹配归因(选填){accountCreateLogs?.some(item => item?.userActionSetsList?.length) && <CheckOutlined style={{ color: '#1890ff' }} />}</Button>
 | 
	
		
			
				|  |  | +                            :
 | 
	
		
			
				|  |  | +                            <Button type="primary" danger={!accountCreateLogs?.some(item => item?.newConversionList?.length)} onClick={() => { setConversionVisible(true) }}>{accountCreateLogs?.some(item => item?.newConversionList?.length) ? <>重新选择转化归因<CheckOutlined style={{ color: '#FFF' }} /></> : '请选择转化归因'}</Button>
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  |                      </>}
 | 
	
		
			
				|  |  |                  </Space>
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -859,7 +880,7 @@ const Create: React.FC = () => {
 | 
	
		
			
				|  |  |                                  {/* 定向 */}
 | 
	
		
			
				|  |  |                                  <Target />
 | 
	
		
			
				|  |  |                                  {/* 创意 */}
 | 
	
		
			
				|  |  | -                                <Dynamic 
 | 
	
		
			
				|  |  | +                                <Dynamic
 | 
	
		
			
				|  |  |                                      creativeTemplateAppellation={creativeTemplateAppellation}
 | 
	
		
			
				|  |  |                                      creativeTemplateStyle={creativeTemplateStyle}
 | 
	
		
			
				|  |  |                                  />
 | 
	
	
		
			
				|  | @@ -888,6 +909,7 @@ const Create: React.FC = () => {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  {/* 选择小说 */}
 | 
	
		
			
				|  |  |                  {goodsVisible && <GoodsModal
 | 
	
		
			
				|  |  | +                    marketingTargetType={marketingAssetOuterSpec?.marketingTargetType}
 | 
	
		
			
				|  |  |                      visible={goodsVisible}
 | 
	
		
			
				|  |  |                      data={accountCreateLogs}
 | 
	
		
			
				|  |  |                      onClose={() => setGoodsVisible(false)}
 | 
	
	
		
			
				|  | @@ -919,6 +941,18 @@ const Create: React.FC = () => {
 | 
	
		
			
				|  |  |                          clearData()
 | 
	
		
			
				|  |  |                      }}
 | 
	
		
			
				|  |  |                  />}
 | 
	
		
			
				|  |  | +                {/* 转化归因 */}
 | 
	
		
			
				|  |  | +                {conversionVisible && <ConversionSelect
 | 
	
		
			
				|  |  | +                    adgroups={addelivery.adgroups}
 | 
	
		
			
				|  |  | +                    visible={conversionVisible}
 | 
	
		
			
				|  |  | +                    data={accountCreateLogs}
 | 
	
		
			
				|  |  | +                    onClose={() => setConversionVisible(false)}
 | 
	
		
			
				|  |  | +                    onChange={(e) => {
 | 
	
		
			
				|  |  | +                        setAccountCreateLogs(e);
 | 
	
		
			
				|  |  | +                        setConversionVisible(false);
 | 
	
		
			
				|  |  | +                        clearData()
 | 
	
		
			
				|  |  | +                    }}
 | 
	
		
			
				|  |  | +                />}
 | 
	
		
			
				|  |  |              </Card>
 | 
	
		
			
				|  |  |          </Spin>
 | 
	
		
			
				|  |  |  
 |