|
@@ -0,0 +1,344 @@
|
|
|
+
|
|
|
+import { useAjax } from "@/Hook/useAjax"
|
|
|
+import { CheckOutlined, CloseOutlined, QuestionCircleOutlined, SyncOutlined } from "@ant-design/icons"
|
|
|
+import { Button, Checkbox, Input, message, Modal, Select, Space, Table, Tooltip, Typography } from "antd"
|
|
|
+import React, { useEffect, useState } from "react"
|
|
|
+import style from '../GoodsModal/index.less'
|
|
|
+import columns from "./tableConfig"
|
|
|
+import { getAdqLandingPageOfficialListApi, getWXDownPageAuthInfoListApi } from "@/services/adqV3/global"
|
|
|
+import New1Radio from "../New1Radio"
|
|
|
+const { Title, Text } = Typography;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 获取adq落地页
|
|
|
+ * @returns
|
|
|
+ */
|
|
|
+interface Props {
|
|
|
+ visible?: boolean,
|
|
|
+ onClose?: () => void,
|
|
|
+ onChange?: (value: { data: PULLIN.AccountCreateLogsProps[], landingPageType: 0 | 1 }) => void,
|
|
|
+ adgroups: any
|
|
|
+ dynamic: any
|
|
|
+ data: PULLIN.AccountCreateLogsProps[]
|
|
|
+}
|
|
|
+const PageOfficialModal: React.FC<Props> = (props) => {
|
|
|
+
|
|
|
+ /*************************/
|
|
|
+ const { visible, onClose, data: data1, adgroups, onChange, dynamic } = props
|
|
|
+ const { marketingGoal, marketingAssetOuterSpec: { marketingTargetType }, marketingCarrierType, siteSet } = adgroups
|
|
|
+ const { creativeTemplateId, deliveryMode, creativeComponents: { mainJumpInfo }, landingPageType } = dynamic
|
|
|
+ const [selectAdz, setSelectAdz] = useState<number>(1) // 选择广告主
|
|
|
+ const [data, setData] = useState<PULLIN.AccountCreateLogsProps[]>(data1 || [])
|
|
|
+ const [queryForm, setQueryForm] = useState<{ accountId?: number, pageName?: string, ownerUid?: number, pageSize: number, pageNum: number, isSqDownPage: boolean }>({ pageNum: 1, pageSize: 20, isSqDownPage: false })
|
|
|
+ const [loading, setLoading] = useState<boolean>(false)
|
|
|
+ const [wXDownPageAuthInfo, setWXDownPageAuthInfo] = useState<any>({})
|
|
|
+ const [tableData, setTableData] = useState<any>({})
|
|
|
+ const [pageAllocationType, setPageAllocationType] = useState<0 | 1>(landingPageType || 0)
|
|
|
+
|
|
|
+ const listAjax = useAjax((params) => getAdqLandingPageOfficialListApi(params))
|
|
|
+ /*************************/
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (data?.length > 0) {
|
|
|
+ setQueryForm({ ...queryForm, pageNum: 1, accountId: data[selectAdz - 1].accountId })
|
|
|
+ }
|
|
|
+ }, [])
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (data?.length > 0) {
|
|
|
+ setLoading(true)
|
|
|
+ let accountDataList = data.map(item => item.accountId)
|
|
|
+ let infoAjax = accountDataList.map(accountId => getWXDownPageAuthInfoListApi(accountId))
|
|
|
+ let newData: any = {}
|
|
|
+ Promise.all(infoAjax).then(res => {
|
|
|
+ res?.forEach((item, index) => {
|
|
|
+ newData[accountDataList[index]] = item?.data || []
|
|
|
+ })
|
|
|
+ setWXDownPageAuthInfo(newData)
|
|
|
+ setLoading(false)
|
|
|
+ }).catch(() => setLoading(false))
|
|
|
+ }
|
|
|
+ }, [])
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (queryForm?.accountId) {
|
|
|
+ getList()
|
|
|
+ }
|
|
|
+ }, [queryForm, marketingGoal, marketingTargetType, marketingCarrierType, siteSet, mainJumpInfo, creativeTemplateId])
|
|
|
+
|
|
|
+ // 获取落地页列表
|
|
|
+ const getList = () => {
|
|
|
+ let params: any = { ...queryForm, pageStatus: 'NORMAL', marketingGoal, marketingTargetType, marketingCarrierType, siteSet, pageType: 'PAGE_TYPE_OFFICIAL', creativeTemplateId: 311 }
|
|
|
+ if (params.isSqDownPage) {
|
|
|
+ if (!params?.ownerUid) {
|
|
|
+ setTableData({ total: 0, records: [] })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ delete params?.ownerUid
|
|
|
+ }
|
|
|
+ delete params.isSqDownPage
|
|
|
+ listAjax.run(params).then(res => {
|
|
|
+ setTableData(res || {})
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleOk = () => {
|
|
|
+ if (deliveryMode === "DELIVERY_MODE_COMPONENT" && !data?.every(item => item.pageList?.length === mainJumpInfo?.length)) {
|
|
|
+ message.error(`当前落地页数量不足,跳转类型选择了${mainJumpInfo.length}组,落地页应当选择${mainJumpInfo.length}组`)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (data?.every(item => item.pageList)) {
|
|
|
+ onChange && onChange({ data, landingPageType: pageAllocationType })
|
|
|
+ } else {
|
|
|
+ message.error('还有账号未选择落地页!')
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 设置选中广告主 */
|
|
|
+ const handleSelectAdz = (value: number, item: any) => {
|
|
|
+ if (value === selectAdz) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let accountId = data[value - 1].accountId
|
|
|
+ setQueryForm({ ...queryForm, pageNum: 1, accountId, ownerUid: wXDownPageAuthInfo[accountId]?.[0]?.accountId })
|
|
|
+ setSelectAdz(value)
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 表格选折 */
|
|
|
+ // const onChangeTable = (_: React.Key[], selectedRows: any) => {
|
|
|
+ // let newData = JSON.parse(JSON.stringify(data))
|
|
|
+ // newData[selectAdz - 1]['pageList'] = selectedRows
|
|
|
+ // setData([...newData])
|
|
|
+ // }
|
|
|
+
|
|
|
+ /** 一键设置 */
|
|
|
+ const setOnekey = () => {
|
|
|
+ let pageName: string = data[selectAdz - 1]['pageList']?.[0]?.pageName
|
|
|
+ let newData: PULLIN.AccountCreateLogsProps[] = JSON.parse(JSON.stringify(data))
|
|
|
+ const hide = message.loading(`正在设置...`, 0, () => {
|
|
|
+ message.success('设置成功');
|
|
|
+ });
|
|
|
+ let filterData = newData?.filter(item => item.accountId !== data[selectAdz - 1].accountId)
|
|
|
+ let ajax = filterData?.map(item => {
|
|
|
+ let params: any = { ...queryForm, pageNum: 1, accountId: item.accountId, ownerUid: wXDownPageAuthInfo[item.accountId]?.[0]?.accountId, pageName, pageStatus: 'NORMAL', marketingGoal, marketingTargetType, marketingCarrierType, siteSet, pageType: 'PAGE_TYPE_OFFICIAL', creativeTemplateId }
|
|
|
+ if (!params.isSqDownPage) {
|
|
|
+ delete params?.ownerUid
|
|
|
+ }
|
|
|
+ delete params.isSqDownPage
|
|
|
+ return getAdqLandingPageOfficialListApi(params)
|
|
|
+ })
|
|
|
+ Promise.all(ajax).then(res => {
|
|
|
+ if (res && Array.isArray(res)) {
|
|
|
+ res.forEach((item: any, index) => {
|
|
|
+ let records = item?.data?.records
|
|
|
+ if (Array.isArray(records) && records?.length > 0) {
|
|
|
+ let record = records[0]
|
|
|
+ let filterD = filterData[index]
|
|
|
+ newData = newData.map(item => {
|
|
|
+ if (item.accountId.toString() === filterD.accountId.toString() && record) {
|
|
|
+ return { ...item, pageList: [{ ...record, id: record.pageId }] }
|
|
|
+ }
|
|
|
+ return item
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ setData(newData)
|
|
|
+ }
|
|
|
+ message.success('设置完成');
|
|
|
+ hide()
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ return <Modal
|
|
|
+ title={<Space>
|
|
|
+ <strong>选择落地页</strong>
|
|
|
+ {data?.length > 1 && <Button style={{ padding: 0, margin: 0 }} disabled={!data[selectAdz - 1]['pageList']?.length} onClick={setOnekey} type="link" loading={listAjax.loading}>
|
|
|
+ <Space>
|
|
|
+ <span style={{ fontSize: 12 }}>一键设置</span>
|
|
|
+ <Tooltip color="#FFF" overlayInnerStyle={{ color: '#000' }} title="设置其它账号有相同名称的落地页为那个账号的落地页(需要落地页名称相同,否则不设置,注意只会根据当前条件去搜索,比如选择了被授权落地页,只会去被授权落地页里找对应落地页)">
|
|
|
+ <QuestionCircleOutlined />
|
|
|
+ </Tooltip>
|
|
|
+ </Space>
|
|
|
+ </Button>}
|
|
|
+ <Text type="warning">请确保账号开通了权限</Text>
|
|
|
+ </Space>}
|
|
|
+ visible={visible}
|
|
|
+ onCancel={() => { onClose && onClose() }}
|
|
|
+ onOk={handleOk}
|
|
|
+ width={1100}
|
|
|
+ className={`${style.SelectPackage} modalResetCss`}
|
|
|
+ bodyStyle={{ padding: '0 10px 0 10px' }}
|
|
|
+ >
|
|
|
+ {[910].includes(creativeTemplateId) && <div className={style.pageType}>
|
|
|
+ <Space size={12}>
|
|
|
+ <strong>落地页分配规则</strong>
|
|
|
+ <New1Radio
|
|
|
+ data={[{ label: '全部相同', value: 0 }, { label: '平均分配', value: 1 }]}
|
|
|
+ value={pageAllocationType}
|
|
|
+ onChange={(e) => {
|
|
|
+ setPageAllocationType(e)
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </Space>
|
|
|
+ </div>}
|
|
|
+ <div className={style.content}>
|
|
|
+ <div className={style.left}>
|
|
|
+ <h4 className={style.title}>媒体账户</h4>
|
|
|
+ {data?.map((item, index) => (
|
|
|
+ <div key={index} onClick={() => { if (!loading) handleSelectAdz(index + 1, item) }} className={`${style.accItem} ${selectAdz === index + 1 && style.select} `}>
|
|
|
+ {item?.accountId}
|
|
|
+ {data[index].pageList?.length > 0 && <CheckOutlined style={{ color: '#1890ff' }} />}
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ <div className={style.right}>
|
|
|
+ <Space style={{ marginBottom: 10 }}>
|
|
|
+ <Checkbox
|
|
|
+ onChange={(e) => {
|
|
|
+ if (e.target.checked && wXDownPageAuthInfo && Object.keys(wXDownPageAuthInfo).length) {
|
|
|
+ setQueryForm({ ...queryForm, pageNum: 1, ownerUid: wXDownPageAuthInfo[data[selectAdz - 1].accountId]?.[0]?.accountId, isSqDownPage: true })
|
|
|
+ } else {
|
|
|
+ setQueryForm({ ...queryForm, pageNum: 1, ownerUid: undefined, isSqDownPage: false })
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ checked={queryForm.isSqDownPage}
|
|
|
+ ><span style={{ fontSize: 12 }}>被授权落地页</span></Checkbox>
|
|
|
+ {queryForm.isSqDownPage && <Select
|
|
|
+ placeholder='选择原生页授权方信息'
|
|
|
+ style={{ width: 210 }}
|
|
|
+ showSearch
|
|
|
+ filterOption={(input: any, option: any) =>
|
|
|
+ (option!.children as unknown as string).toLowerCase().includes(input.toLowerCase())
|
|
|
+ }
|
|
|
+ allowClear
|
|
|
+ onChange={(value) => {
|
|
|
+ setQueryForm({ ...queryForm, pageNum: 1, ownerUid: value })
|
|
|
+ }}
|
|
|
+ value={queryForm?.ownerUid}
|
|
|
+ dropdownMatchSelectWidth={false}
|
|
|
+ >
|
|
|
+ {wXDownPageAuthInfo?.[data[selectAdz - 1].accountId]?.map((item: { accountId: number; accountName: string }) => {
|
|
|
+ return <Select.Option value={item.accountId} key={item.accountId}>{item.accountName}({item.accountId})</Select.Option>
|
|
|
+ })}
|
|
|
+ </Select>}
|
|
|
+ <Input value={queryForm?.pageName} style={{ width: 150 }} allowClear placeholder='请输入落地页名称' onChange={(e) => setQueryForm({ ...queryForm, pageNum: 1, pageName: e.target.value })} />
|
|
|
+ <Button style={{ padding: 0, margin: 0 }} icon={<SyncOutlined />} type='link' loading={listAjax?.loading} onClick={() => { listAjax?.refresh() }}><span style={{ fontSize: 12 }}>刷新</span></Button>
|
|
|
+ </Space>
|
|
|
+ <Table
|
|
|
+ columns={columns(2)}
|
|
|
+ dataSource={tableData?.records}
|
|
|
+ size="small"
|
|
|
+ loading={listAjax?.loading || loading}
|
|
|
+ scroll={{ y: 300 }}
|
|
|
+ bordered
|
|
|
+ rowKey={'pageId'}
|
|
|
+ pagination={{
|
|
|
+ total: tableData?.total,
|
|
|
+ defaultPageSize: 20,
|
|
|
+ current: tableData?.current,
|
|
|
+ pageSize: tableData?.size
|
|
|
+ }}
|
|
|
+ onChange={(pagination) => {
|
|
|
+ const { current, pageSize } = pagination
|
|
|
+ setQueryForm({ ...queryForm, pageNum: current as number, pageSize: pageSize as number || 20 })
|
|
|
+ }}
|
|
|
+ /**
|
|
|
+ * canvasType
|
|
|
+ * VIDEO
|
|
|
+ * VIDEO_1280_960 横板1280*960
|
|
|
+ * VIDEO_1280_720 横板1280*720
|
|
|
+ * VERTICAL_VIDEO_NEW_916 9:16 视频
|
|
|
+ * COMMON_PAGE 引用外层素材原生页
|
|
|
+ * IMAGE
|
|
|
+ */
|
|
|
+ rowSelection={{
|
|
|
+ type: ([910].includes(creativeTemplateId) || deliveryMode === "DELIVERY_MODE_COMPONENT") ? 'checkbox' : 'radio',
|
|
|
+ getCheckboxProps: (record) => {
|
|
|
+ let { disableCode } = record
|
|
|
+ if (disableCode !== 0) {
|
|
|
+ return {
|
|
|
+ disabled: true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 组件化创意
|
|
|
+ if (deliveryMode === "DELIVERY_MODE_COMPONENT") {
|
|
|
+ if (data[selectAdz - 1]?.pageList?.length >= mainJumpInfo?.length) {
|
|
|
+ return {
|
|
|
+ disabled: data[selectAdz - 1]?.pageList?.some((item: any) => item?.pageId === record?.pageId) ? false : true
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return {
|
|
|
+ disabled: false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ disabled: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ selectedRowKeys: data[selectAdz - 1]?.pageList?.map((item: any) => item?.pageId),
|
|
|
+ // onChange: onChangeTable,
|
|
|
+ hideSelectAll: deliveryMode === "DELIVERY_MODE_COMPONENT",
|
|
|
+ onSelect: (record: any, selected: boolean) => {
|
|
|
+ let newData = JSON.parse(JSON.stringify(data))
|
|
|
+ if (([910].includes(creativeTemplateId) || deliveryMode === "DELIVERY_MODE_COMPONENT")) {
|
|
|
+ let selectedRows = newData?.[selectAdz - 1]?.['pageList'] || []
|
|
|
+ if (selected) {
|
|
|
+ selectedRows.push({ ...record })
|
|
|
+ newData[selectAdz - 1]['pageList'] = selectedRows
|
|
|
+ } else {
|
|
|
+ newData[selectAdz - 1]['pageList'] = selectedRows.filter((item: { pageId: number }) => item.pageId !== record.pageId)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ newData[selectAdz - 1]['pageList'] = [record]
|
|
|
+ }
|
|
|
+ setData([...newData])
|
|
|
+ },
|
|
|
+ onSelectAll: (selected: boolean, _: any[], changeRows: { pageId: number }[]) => {
|
|
|
+ let newData = JSON.parse(JSON.stringify(data))
|
|
|
+ let selectedRows = newData?.[selectAdz - 1]?.['pageList'] || []
|
|
|
+ if (selected) {
|
|
|
+ let newSelectAccData = [...selectedRows]
|
|
|
+ changeRows.forEach((item: { pageId: number }) => {
|
|
|
+ let index = newSelectAccData.findIndex((ite: { pageId: number }) => ite.pageId === item.pageId)
|
|
|
+ if (index === -1) {
|
|
|
+ let data: any = { ...item }
|
|
|
+ newSelectAccData.push(data)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ newData[selectAdz - 1]['pageList'] = newSelectAccData
|
|
|
+ } else {
|
|
|
+ newData[selectAdz - 1]['pageList'] = selectedRows.filter((item: { pageId: number }) => {
|
|
|
+ let index = changeRows.findIndex((ite: { pageId: number }) => ite.pageId === item.pageId)
|
|
|
+ if (index !== -1) {
|
|
|
+ return false
|
|
|
+ } else {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ setData([...newData])
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div className={style.center}>
|
|
|
+ <Title level={5}>已选:{data[selectAdz - 1]?.pageList?.length || 0}</Title>
|
|
|
+ <div className={style.select_content} style={{ height: 416 }}>
|
|
|
+ {data[selectAdz - 1]?.pageList?.map((item: any) => <div key={item.pageId}>
|
|
|
+ <Text ellipsis={{ tooltip: true }} className={style.marketingAssetName}>{item.pageName}</Text>
|
|
|
+ <CloseOutlined className={style.close} onClick={() => {
|
|
|
+ let newData: PULLIN.AccountCreateLogsProps[] = JSON.parse(JSON.stringify(data))
|
|
|
+ newData[selectAdz - 1].pageList = newData[selectAdz - 1]?.pageList?.filter((i: any) => i?.pageId !== item.pageId)
|
|
|
+ setData(newData)
|
|
|
+ }} />
|
|
|
+ </div>)}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </Modal>
|
|
|
+}
|
|
|
+
|
|
|
+export default React.memo(PageOfficialModal)
|