123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- import { useAjax } from "@/Hook/useAjax"
- import { delBatchCreativeApi, getDynamicCreativeV3ListApi, syncBatchCreativeApi, updateBatchDynamicCreativesInfoApi } from "@/services/launchAdq/adqv3"
- import { Badge, Button, Col, DatePicker, Form, Input, Modal, Popconfirm, Row, Select, Space, Table, message } from "antd"
- import React, { useEffect, useState } from "react"
- import { txDynamicConfig } from "../config"
- import tableConfig from "./tableConfig"
- import TableData from "@/pages/launchSystemNew/components/TableData"
- import ReviewDetails from "./reviewDetails"
- import { DeleteOutlined, PauseCircleOutlined, PlayCircleOutlined } from "@ant-design/icons"
- import '../../tencentAdPutIn/index.less'
- import HandleLog from "./handleLog"
- import moment from "moment"
- import RetriaModal from "./retriaModal"
- import ReplacePage from "./replacePage"
- import ReplaceGfPage from "./replaceGfPage"
- /** 审核结果 */
- export const AD_STATUS = {
- NORMAL: <Badge status="success" text="审核通过" />,
- PENDING: <Badge status="default" text="审核中" />,
- DENIED: <Badge status="error" text="有违规" />,
- PARTIALLY_NORMAL: <Badge status="warning" text="部分审核通过" />,
- }
- const Creative: React.FC<ADQV3.CreativeProps> = ({ queryForm, setQueryForm, userId }) => {
- /*********************************/
- const [form] = Form.useForm();
- const [dynimicData, setDynamicData] = useState<any>({})
- const [dynimicVisible, setDynamicVisible] = useState<boolean>(false)
- const [selectedRows, setSelectedRows] = useState<any[]>([])
- const [failIdList, setFailIdList] = useState<{ adgroupId: number, code: number, message: string, messageCn: string }[]>([])
- const [failVisible, setFailVisible] = useState<boolean>(false)
- const [logVisible, setLogVisible] = useState<boolean>(false)
- const [handleType, setHandleType] = useState<number>(1)
- const [replaceVisible, setReplaceVisible] = useState<boolean>(false)
- const [replaceGfVisible, setReplaceGfVisible] = useState<boolean>(false)
- const getDynamicCreativeV3List = useAjax((params) => getDynamicCreativeV3ListApi(params), { formatResult: true })
- const delBatchCreative = useAjax((params) => delBatchCreativeApi(params))
- const updateBatchDynamicCreativesInfo = useAjax((params) => updateBatchDynamicCreativesInfoApi(params))
- const syncBatchCreative = useAjax((params) => syncBatchCreativeApi(params))
- /*********************************/
- useEffect(() => {
- form.setFieldsValue({ adgroupId: queryForm.adgroupId })
- }, [queryForm.adgroupId])
- useEffect(() => {
- let params: any = { ...queryForm, userId }
- if (params?.accountId) {
- params.accountId = params.accountId?.split(/[,,\s\n]+/)
- }
- getDynamicCreativeV3List.run(params)
- }, [userId, queryForm])
- const onFinish = (values: any) => {
- console.log(values)
- const { date, ...value } = values
- let newQueryForm = { ...queryForm, ...value }
- if (date?.length) {
- newQueryForm.beginDate = moment(date[0]).format('YYYY-MM-DD')
- newQueryForm.endDate = moment(date[1]).format('YYYY-MM-DD')
- } else {
- delete newQueryForm?.beginDate
- delete newQueryForm?.endDate
- }
- setQueryForm(newQueryForm)
- }
- const reviewStatusDetails = (value: any) => {
- setDynamicData(value)
- setDynamicVisible(true)
- }
- const dynamicHandle = (type: '删除' | '启动' | '暂停', data?: any) => {
- let accountAdgroupMaps = data ? [data.accountId + ',' + data.dynamicCreativeId] : [...new Set(selectedRows?.map(item => item.accountId + ',' + item.dynamicCreativeId))]
- let hide: any
- if (data) {
- hide = message.loading(`正在设置...`, 0, () => {
- message.success('设置成功');
- });
- }
- switch (type) {
- case '删除':
- delBatchCreative.run({ accountAdgroupMaps }).then(res => {
- if (res?.failIdList?.length === 0) {
- message.success(`修改操作完成!`)
- getDynamicCreativeV3List.refresh()
- setSelectedRows([])
- } else {
- setFailIdList(res?.list || [])
- setFailVisible(true)
- }
- })
- break
- case '启动':
- case '暂停':
- updateBatchDynamicCreativesInfo.run({ accountAdgroupMaps, suspend: type === '暂停' }).then(res => {
- if (res?.failIdList?.length === 0) {
- message.success(`修改操作完成!`)
- getDynamicCreativeV3List.refresh()
- setSelectedRows([])
- } else {
- setFailIdList(res?.list || [])
- setFailVisible(true)
- }
- if (hide) {
- hide()
- }
- })
- break
- }
- }
- const sync = () => {
- if (selectedRows?.length > 0) {
- const hide = message.loading(`正在同步...`, 0, () => {
- message.success('设置成功');
- });
- let accountAdgroupMaps = [...new Set(selectedRows?.map(item => item.accountId + ',' + item.dynamicCreativeId))]
- syncBatchCreative.run({ accountAdgroupMaps }).then(res => {
- res && getDynamicCreativeV3List.refresh()
- res ? message.success('同步成功!') : message.error('同步失败!')
- hide()
- }).catch(() => hide())
- } else {
- message.error('请勾选需要同步的创意')
- }
- }
- return <>
- <Form
- layout="inline"
- form={form}
- name="basignCreative"
- initialValues={queryForm}
- onFinish={onFinish}
- style={{ marginBottom: 6 }}
- >
- <Row gutter={[10, 10]}>
- <Col><Form.Item name='accountId' style={{ marginRight: 0 }}>
- <Input placeholder="广告账号,多个逗号隔开" style={{ width: 180 }} allowClear />
- </Form.Item></Col>
- <Col><Form.Item name='adgroupId' style={{ marginRight: 0 }}>
- <Input placeholder="广告ID" style={{ width: 120 }} allowClear />
- </Form.Item></Col>
- <Col><Form.Item name='creativeName' style={{ marginRight: 0 }}>
- <Input placeholder="创意名称" style={{ width: 120 }} allowClear />
- </Form.Item></Col>
- <Col><Form.Item name='creativeId' style={{ marginRight: 0 }}>
- <Input placeholder="创意ID" style={{ width: 120 }} allowClear />
- </Form.Item></Col>
- <Col><Form.Item name='configuredStatus' style={{ marginRight: 0 }}>
- <Select
- placeholder='启用禁用状态'
- style={{ minWidth: 120 }}
- showSearch
- allowClear
- filterOption={(input: any, option: any) =>
- (option!.children as unknown as string).toLowerCase().includes(input.toLowerCase())
- }
- mode="multiple"
- >
- <Select.Option value={'AD_STATUS_NORMAL'}>有效</Select.Option>
- <Select.Option value={'AD_STATUS_SUSPEND'}>暂停</Select.Option>
- </Select>
- </Form.Item></Col>
- <Col><Form.Item name='deliveryMode' style={{ marginRight: 0 }}>
- <Select
- placeholder='投放模式'
- style={{ minWidth: 120 }}
- showSearch
- allowClear
- maxTagCount={1}
- filterOption={(input: any, option: any) =>
- (option!.children as unknown as string).toLowerCase().includes(input.toLowerCase())
- }
- mode="multiple"
- >
- <Select.Option value={'DELIVERY_MODE_CUSTOMIZE'}>自定义创意</Select.Option>
- <Select.Option value={'DELIVERY_MODE_COMPONENT'}>组件化创意</Select.Option>
- </Select>
- </Form.Item></Col>
- <Col>
- <Form.Item name='date' style={{ marginRight: 0 }}>
- <DatePicker.RangePicker style={{ width: 260 }} placeholder={['创建开始日期', '创建结束日期']} />
- </Form.Item>
- </Col>
- <Col><Form.Item name='isDeleted' style={{ marginRight: 0 }}>
- <Select
- placeholder='是否删除?'
- style={{ minWidth: 100 }}
- showSearch
- allowClear
- filterOption={(input: any, option: any) =>
- (option!.children as unknown as string).toLowerCase().includes(input.toLowerCase())
- }
- mode="multiple"
- >
- <Select.Option value={true}>是</Select.Option>
- <Select.Option value={false}>否</Select.Option>
- </Select>
- </Form.Item></Col>
- <Col><Form.Item style={{ marginRight: 0 }}>
- <Space>
- <Button type="primary" htmlType="submit">搜索</Button>
- <Button onClick={() => {
- setQueryForm({ pageNum: 1, pageSize: queryForm.pageSize, userId })
- form.resetFields()
- }}>重置</Button>
- <Button disabled={selectedRows.length === 0} style={{ padding: 0 }} danger type="link" onClick={() => setSelectedRows([])}>清空已选({selectedRows.length})</Button>
- </Space>
- </Form.Item></Col>
- </Row>
- </Form>
- <TableData
- isCard={false}
- columns={() => tableConfig(reviewStatusDetails, (data, type) => dynamicHandle(type, data))}
- ajax={getDynamicCreativeV3List}
- fixed={{ left: 2, right: 4 }}
- dataSource={getDynamicCreativeV3List?.data?.data?.records}
- loading={getDynamicCreativeV3List?.loading || syncBatchCreative.loading || updateBatchDynamicCreativesInfo.loading}
- scroll={{ y: 560 }}
- syncAjax={sync}
- total={getDynamicCreativeV3List?.data?.data?.total}
- page={getDynamicCreativeV3List?.data?.data?.current}
- pageSize={getDynamicCreativeV3List?.data?.data?.size}
- myKey={'dynamicCreativeId'}
- gutter={[0, 10]}
- config={txDynamicConfig}
- configName="创意3.0"
- leftChild={<Space>
- <Select
- style={{ width: 120 }}
- onChange={(e) => {
- setHandleType(e)
- setSelectedRows([])
- }}
- value={handleType}
- dropdownMatchSelectWidth={false}
- options={[
- { label: '基本操作', value: 1 },
- { label: '复审操作', value: 2 },
- { label: '落地页替换', value: 3 },
- ]}
- />
- {handleType === 1 ? <>
- <Button type='primary' style={{ background: '#67c23a', borderColor: '#67c23a' }} loading={updateBatchDynamicCreativesInfo.loading} icon={<PlayCircleOutlined />} disabled={selectedRows.length === 0} onClick={() => dynamicHandle('启动')}>启动</Button>
- <Button type='primary' style={{ background: '#e6a23c', borderColor: '#e6a23c' }} loading={updateBatchDynamicCreativesInfo.loading} icon={<PauseCircleOutlined />} disabled={selectedRows.length === 0} onClick={() => dynamicHandle('暂停')}>暂停</Button>
- <Popconfirm
- title="确定删除?"
- onConfirm={() => dynamicHandle('删除')}
- disabled={selectedRows.length === 0}
- >
- <Button type='primary' danger icon={<DeleteOutlined />} loading={delBatchCreative.loading} disabled={selectedRows.length === 0}>删除</Button>
- </Popconfirm>
- </> : handleType === 2 ? <>
- <RetriaModal
- selectedRows={selectedRows}
- onChange={() => setSelectedRows([])}
- />
- </> : <Button
- type='primary'
- disabled={selectedRows.length === 0}
- onClick={() => {
- if (selectedRows?.[0]?.creativeComponents?.mainJumpInfo?.[0]?.value?.pageType === "WECHAT_CANVAS") { // 原生推广页
- setReplaceVisible(true)
- } else if (selectedRows?.[0]?.creativeComponents?.mainJumpInfo?.[0]?.value?.pageType === "OFFICIAL") { // 官方落地页
- setReplaceGfVisible(true)
- } else {
- message.error('暂不支持该类型落地页替换')
- }
- }}
- >修改落地页</Button>}
- <Button type='dashed' onClick={() => { setLogVisible(true) }}>操作记录</Button>
- </Space>}
- rowSelection={{
- selectedRowKeys: selectedRows.map(item => item.dynamicCreativeId.toString()),
- getCheckboxProps: (record: any) => {
- if (handleType === 3) {
- if (selectedRows.length) {
- const { deliveryMode, creativeTemplateId, creativeComponents: { mainJumpInfo } } = selectedRows[0]
- const pageType: string | undefined = mainJumpInfo?.[0]?.value?.pageType
- const pageLength: number | undefined = mainJumpInfo?.length
- return {
- disabled: record.isDeleted ||
- record.deliveryMode !== deliveryMode ||
- record.creativeTemplateId !== creativeTemplateId ||
- record?.creativeComponents?.mainJumpInfo?.[0]?.value?.pageType !== pageType ||
- pageLength !== record?.creativeComponents?.mainJumpInfo?.length ||
- record?.creativeComponents?.mainJumpInfo?.[0]?.value?.pageSpec?.wechatCanvasSpec?.overrideCanvasHeadOption !== mainJumpInfo?.[0]?.value?.pageSpec?.wechatCanvasSpec?.overrideCanvasHeadOption
- }
- } else {
- return { disabled: record.isDeleted }
- }
- }
- return { disabled: handleType === 2 ? record.isDeleted || record.reviewStatus !== 'AD_STATUS_DENIED' : record.isDeleted }
- },
- onSelect: (record: { dynamicCreativeId: number }, selected: boolean) => {
- if (selected) {
- selectedRows.push({ ...record })
- setSelectedRows([...selectedRows])
- } else {
- const newSelectAccData = selectedRows.filter((item: { dynamicCreativeId: number }) => item.dynamicCreativeId !== record.dynamicCreativeId)
- setSelectedRows([...newSelectAccData])
- }
- },
- onSelectAll: (selected: boolean, selectedRowss: { dynamicCreativeId: number }[], changeRows: { dynamicCreativeId: number, isDeleted: boolean }[]) => {
- if (selected) {
- const newSelectAccData = [...selectedRows]
- const firstData = selectedRows?.[0] || changeRows?.find((item: { isDeleted: boolean }) => !item.isDeleted)
- changeRows.forEach((item: any) => {
- const index = newSelectAccData.findIndex((ite: { dynamicCreativeId: number }) => ite.dynamicCreativeId === item.dynamicCreativeId)
- if (index === -1) {
- if (handleType === 3) {
- const isValid = !item.isDeleted &&
- item.deliveryMode === firstData.deliveryMode &&
- item.creativeTemplateId === firstData.creativeTemplateId &&
- item?.creativeComponents?.mainJumpInfo?.[0]?.value?.pageType === firstData?.creativeComponents?.mainJumpInfo?.[0]?.value?.pageType &&
- firstData?.creativeComponents?.mainJumpInfo?.length === item?.creativeComponents?.mainJumpInfo?.length &&
- item?.creativeComponents?.mainJumpInfo?.[0]?.value?.pageSpec?.wechatCanvasSpec?.overrideCanvasHeadOption === firstData?.creativeComponents?.mainJumpInfo?.[0]?.value?.pageSpec?.wechatCanvasSpec?.overrideCanvasHeadOption;
- if (isValid) {
- newSelectAccData.push({ ...item });
- }
- } else {
- newSelectAccData.push({ ...item });
- }
- }
- })
- setSelectedRows([...newSelectAccData])
- } else {
- const newSelectAccData = selectedRows.filter((item: { dynamicCreativeId: number }) => {
- const index = changeRows.findIndex((ite: { dynamicCreativeId: number }) => ite.dynamicCreativeId === item.dynamicCreativeId)
- if (index !== -1) {
- return false
- } else {
- return true
- }
- })
- setSelectedRows([...newSelectAccData])
- }
- }
- }}
- onChange={(props: any) => {
- let { pagination } = props
- let { current, pageSize } = pagination
- setQueryForm({ ...queryForm, pageNum: current, pageSize })
- }}
- />
- {dynimicVisible && <ReviewDetails
- visible={dynimicVisible}
- dynamic={dynimicData}
- onClose={() => {
- setDynamicData({})
- setDynamicVisible(false)
- }}
- />}
- {failVisible && <Modal
- title={<strong>报错信息</strong>}
- open={failVisible}
- className='modalResetCss'
- width={650}
- onCancel={() => { setFailVisible(false); setFailIdList([]) }}
- footer={null}
- >
- <Table
- size="small"
- bordered
- rowKey={'creativeId'}
- columns={[{
- title: '创意ID',
- dataIndex: 'creativeId',
- key: 'creativeId',
- width: 110,
- render: (value) => <span style={{ fontSize: 12 }}>{value}</span>,
- }, {
- title: 'code',
- dataIndex: 'code',
- key: 'code',
- width: 70,
- align: 'center',
- render: (value) => <span style={{ fontSize: 12 }}>{value}</span>,
- }, {
- title: '错误信息',
- dataIndex: 'messageCn',
- key: 'messageCn',
- render: (value) => <span style={{ fontSize: 12 }}>{value}</span>,
- }]}
- dataSource={failIdList}
- />
- </Modal>}
- {logVisible && <HandleLog
- visible={logVisible}
- onClose={() => {
- setLogVisible(false)
- }}
- userId={userId}
- />}
- {/* 修改原生落地页 */}
- {replaceVisible && <ReplacePage
- selectedRows={selectedRows}
- visible={replaceVisible}
- onClose={() => {
- setReplaceVisible(false)
- }}
- onChange={() => {
- setReplaceVisible(false)
- setSelectedRows([])
- }}
- />}
- {/* 修改官方落地页 */}
- {replaceGfVisible && <ReplaceGfPage
- selectedRows={selectedRows}
- visible={replaceGfVisible}
- onClose={() => {
- setReplaceGfVisible(false)
- }}
- onChange={() => {
- setReplaceGfVisible(false)
- setSelectedRows([])
- }}
- />}
- </>
- }
- export default React.memo(Creative)
|