import { useAjax } from '@/Hook/useAjax' import { Col, Row, message, Space, Button, Switch, notification, Modal, Tooltip, Dropdown, Menu } from 'antd' import React, { useEffect, useCallback, useState, useRef } from 'react' import TableData from '../../components/TableData' import { putAdqAdgroupsSync, delListAdqAdgroupsApi, newEditAdqAdgroupsDataApi, editAdqAdgroupsDataApi, putAdqAdgroupsSyncBatch, putModifyCustomAudienceApi, getPutUserApi, delUserTagApi } from '@/services/launchAdq/adq' import { CopyOutlined, DeleteOutlined, DownOutlined, ExclamationCircleOutlined, FieldTimeOutlined, FormOutlined, PauseCircleOutlined, PlayCircleOutlined, QuestionCircleOutlined, SyncOutlined, TransactionOutlined } from '@ant-design/icons' import UpdateAd from './updateAd' import Copy from './copy' import { planAdConfig } from '../config' import Log from '../log' import SetEarlyWarning from '@/components/EarlyWarning/setEarlyWarning' import CrowdPackModal from '../../components/crowdPackModal' import './index.less' import tablePlanConfig from './tablePlanListConfig' import { AdListProps, getAdListApi } from '@/services/adMonitor/adMonitor' import FilterQuery from './FilterQuery' import Details from '@/pages/adMonitor/adMonitorList/components/Details' import AdExpandedRowRender from './adExpandedRowRender' import { useSize } from 'ahooks' import RuleAccountLog from '@/components/EarlyWarning/ruleAccountLog' import PlanTag from './planTag' const AdPlanList: React.FC<{ userId: string }> = (props) => { /***********************/ const { userId } = props const [selectedRows, setSelectedRows] = useState([]) const [update, setUpdate] = useState<{ visible: boolean, title: string }>({ visible: false, title: '' }) const [model, setModel] = useState(true) const [copyData, setCopyData] = useState<{ visible: boolean }>({ visible: false }) const [detailShow, setDetailShow] = useState(false) const [detailData, setDetailData] = useState({}) const [czjlShow, setCzjlShow] = useState(false) const [cpVisible, setCpVisible] = useState(false) const [accountCreateLogs, setAccountCreateLogs] = useState<{ adAccountId: number, id: number, customAudienceList?: any[], excludedCustomAudienceList?: any[] }[]>([]) const [queryForm, setQueryForm] = useState({ pageNum: 1, pageSize: 20, columns: [], isDeleted: false }) const [filterForm, setFilterForm] = useState() const getAdList = useAjax((params) => getAdListApi(params), { formatResult: true }) const syncAjax = useAjax((adAccountId) => putAdqAdgroupsSync(adAccountId)) const delListAdqAdgroups = useAjax((params) => delListAdqAdgroupsApi(params)) const editAdqAdgroupsData = useAjax((params) => newEditAdqAdgroupsDataApi(params)) const editAdqAdgroups = useAjax((params) => editAdqAdgroupsDataApi(params)) const putModifyCustomAudience = useAjax((params) => putModifyCustomAudienceApi(params)) const putAdqAdgroupsSyncBatchApi = useAjax((params) => putAdqAdgroupsSyncBatch(params)) const getPutUser = useAjax((params) => getPutUserApi(params)) const delUserTag = useAjax((params) => delUserTagApi(params)) const [logVisible, setLogVisible] = useState(false) const [adgroupId, setAdgroupId] = useState('') const [adgroupName, setAdgroupName] = useState('') const [accountIdRule, setAccountIdRule] = useState('') const [tagVisible, setTagVisible] = useState(false) const [tagData, setTagData] = useState({}) const configName = '广告列表New' const ref = useRef(null) const size = useSize(ref) const [scrollLeft, setScrollLeft] = useState(0) /************************/ useEffect(() => { getList() }, [filterForm, queryForm]) const getList = () => { let message = localStorage.getItem(`myAdMonitorConfig1.0.0_${configName}`) if (message) { message = JSON.parse(message) } let columns: string[] = [] if (message && Array.isArray(message)) { message.forEach((item: { serverIndex: any; dataIndex: string; }) => { if (!['cz', 'cost_speed'].includes(item.dataIndex)) { columns.push(item?.serverIndex || 'adgroup_data.' + item.dataIndex) } }) } else { planAdConfig.forEach((item: any) => { item?.data?.forEach((d: { default: any, serverIndex: string, dataIndex: string }) => { if (d.default && !['cz', 'cost_speed'].includes(d.dataIndex)) { columns.push(d?.serverIndex || 'adgroup_data.' + d.dataIndex) } }) }) } getAdList.run({ ...queryForm, ...filterForm, columns }) } useEffect(() => { getPutUser.run({ userId }) }, [userId]) // 同步 const sync = useCallback(() => { let arr = [...new Set(selectedRows?.map(item => item.accountId))] syncAjax.run({ accountIdList: arr }).then(res => { res && getAdList.refresh() res ? message.success('同步成功!') : message.error('同步失败!') }) }, [getAdList, selectedRows]) /** 删除 */ const deleteHandle = (type: 0 | 1, adgroupId?: number) => { const hide = message.loading('删除中。。。', 0) delListAdqAdgroups.run({ adgroupIds: type === 1 ? selectedRows.map(item => item.adgroup_id) : [adgroupId] }).then(res => { hide() message.success('删除成功') setSelectedRows([]) getAdList.refresh() }).catch(() => hide()) } /** 修改排期出价 */ const editScheduling = () => { setUpdate({ visible: true, title: '批量修改' }) } /** 修改排期出价 */ const editDeepConversion = () => { setUpdate({ visible: true, title: '批量修改深度优化' }) } // 单个启停 const onChange = () => { getAdList.refresh() setSelectedRows([]) } // 批量启停 const adStatus = (type: 'play' | 'suspend') => { let params: any = {} if (type === 'play') { params.configuredStatus = 'AD_STATUS_NORMAL' params.adgroupIds = selectedRows.filter((item: { configuredStatus: string, adgroup_id: number }) => item.configuredStatus === 'AD_STATUS_SUSPEND').map(item => item.adgroup_id) } else { params.configuredStatus = 'AD_STATUS_SUSPEND' params.adgroupIds = selectedRows.filter((item: { configuredStatus: string, adgroup_id: number }) => item.configuredStatus === 'AD_STATUS_NORMAL').map(item => item.adgroup_id) } if (params.adgroupIds.length === 0) { message.warn(`所以账号都是${type === 'play' ? '启动' : '暂停'}状态,无需${type === 'play' ? '启动' : '暂停'}操作`) return } editAdqAdgroupsData.run(params).then(res => { message.success(`${type === 'play' ? '启动' : '暂停'}成功: ${res.success},失败: ${res.fail}`)// if (res?.fail) { notification.error({ message: `${type === 'play' ? '启动' : '暂停'}失败`, description: `成功: ${res.success},修改失败${res.fail}条,失败的请到任务列表查看`, duration: 0 }); } getAdList.refresh() setSelectedRows([]) }) } //同步广告 const syncAd = useCallback(() => { const hide = message.loading('同步中。。。', 0) putAdqAdgroupsSyncBatchApi.run({ adgroupIds: selectedRows?.map(item => item.adgroup_id) }).then(res => { hide() if (res) { message.success('同步成功!') getAdList.refresh() } }).catch(() => hide()) }, [selectedRows]) // 批量复制 const copyHandle = () => { setCopyData({ visible: true }) } const handleSave = (row: any) => { const hide = message.loading(`广告“${row.adgroup_id}”广告名称修改成<${row.adgroup_name}>,修改中`, 0, () => { message.success('修改成功'); }); editAdqAdgroups.run({ adgroupIds: [row.adgroup_id], adgroupName: row.adgroup_name }).then(res => { message.success('修改广告名称成功') getAdList.refresh() hide() }) } const handleSaveDaily = (row: any) => { console.log('row--->', row) const hide = message.loading(`广告“${row.adgroup_id}”广告预算修改成<${row.daily_budget}元>,修改中`, 0, () => { message.success('修改成功'); }); editAdqAdgroups.run({ adgroupIds: [row.adgroup_id], dailyBudget: row.daily_budget * 100 }).then(res => { message.success('修改广告预算成功') getAdList.refresh() hide() }) } const details = (data: any) => { setDetailData(data) setDetailShow(true) } // 设置人群包 const setRqb = () => { const { accountId } = selectedRows[0] setAccountCreateLogs([{ id: accountId, adAccountId: accountId }]) setCpVisible(true) } // 确认提交人群包 const handleRqb = (value: any[]) => { if ((value[0]?.customAudienceList && value[0]?.customAudienceList?.length > 0) || (value[0]?.excludedCustomAudienceList && value[0]?.excludedCustomAudienceList?.length > 0)) { let { adAccountId, customAudienceList = [], excludedCustomAudienceList = [] } = value[0] let adgroupIds = selectedRows.map((item: { adgroup_id: number }) => item.adgroup_id) let customAudienceIds = customAudienceList.map((item: { id: number }) => item.id) let excludedCustomAudienceIds = excludedCustomAudienceList.map((item: { id: number }) => item.id) const hide = message.loading('正在修改。。。', 0) setAccountCreateLogs([]) setCpVisible(false) let params: any = { adAccountId, adgroupIds }; if (excludedCustomAudienceIds.length > 0) { params['excludedCustomAudienceIds'] = excludedCustomAudienceIds } if (customAudienceIds?.length > 0) { params['customAudienceIds'] = customAudienceIds } putModifyCustomAudience.run(params).then(res => { hide() setSelectedRows([]) message.success('修改成功,请到腾讯广告平台查看') }).catch(err => hide()) } else { message.error('请选择用户群') } } useEffect(() => { const headerBodyScroll = (e: any) => { let el = document.querySelector(`.expandClassname .expendTable .ant-table-body`); if (el) { setScrollLeft(e.target.scrollLeft) } } document.querySelector(`.expandClassname .expendTable .ant-table-body`)?.addEventListener('scroll', headerBodyScroll); () => { document.querySelector(`.expandClassname .expendTable .ant-table-body`)?.removeEventListener('scroll', headerBodyScroll); } }, []) const log = (value: any) => { setAccountIdRule(value.account_id) setAdgroupId(value.adgroup_id) setAdgroupName(value.adgroup_name) setLogVisible(true) } const handleTag = (value: any) => { setTagData(value) setTagVisible(true) } const delTag = (value: any) => { delUserTag.run({ accountId: value.account_id, adgroupId: value.adgroup_id }).then(res => { if (res) { message.success('删除成功') getAdList.refresh() } }) } return
{/* 打标签 */} {tagVisible && setTagVisible(false)} onChange={() => { getAdList.refresh() setTagVisible(false) }} />} {/* 修改广告 */} {update.visible && { setUpdate({ visible: false, title: '' }) getAdList.refresh() setSelectedRows([]) }} onClose={() => { setUpdate({ visible: false, title: '' }) }} />} {/* 复制广告 */} {copyData.visible && setCopyData({ visible: false })} onChange={() => { setCopyData({ visible: false }); getAdList.refresh(); setSelectedRows([]) }} />} { setFilterForm({ ...value, pageNum: 1 }) }} />
tablePlanConfig(onChange, details, handleSave, handleSaveDaily, log, handleTag, delTag)} ajax={getAdList} syncAjax={sync} fixed={{ left: 2, right: 4 }} dataSource={getAdList?.data?.data?.records} loading={getAdList?.loading || syncAjax?.loading} scroll={{ y: 560 }} total={getAdList?.data?.data?.total} page={getAdList?.data?.data?.current} pageSize={getAdList?.data?.data?.size} myKey={'adgroup_id'} gutter={[0, 10]} config={planAdConfig} configName={configName} rowClassName={(record) => { if (record?.tag_value === 100) { return 'row_error' }else if (record?.tag_value === 90) { return 'row_warning' } else { return '' } }} leftChild={ { setModel(checked); setSelectedRows([]) }} style={model ? {} : { background: '#67c23a' }} /> {!model && } getAdList.refresh()} /> { switch (e.key) { case '1': editScheduling() break case '2': setRqb() break case '3': syncAd() break case '4': Modal.confirm({ title: '删除', content: '确定删除?', icon: , okType: 'danger', onOk() { deleteHandle(1) } }); break } }} items={[ { key: '1', disabled: selectedRows.length === 0, label: , }, { key: '2', disabled: selectedRows.length > 0 ? !selectedRows.every((item: { accountId: number }) => item.accountId === selectedRows[0].accountId) : true, label: , }, { key: '3', disabled: selectedRows.length === 0, label: , }, { key: '4', disabled: selectedRows.length === 0, label: , }, ]} />}> e.preventDefault()}> 更多 } rowSelection={{ selectedRowKeys: selectedRows.map(item => item.adgroup_id.toString()), getCheckboxProps: (record: any) => ({ disabled: model ? record.status === 'STATUS_DELETED' : record.status === 'STATUS_DELETED' || !(!model && JSON.parse(record?.deep_conversion_spec_json)?.deepConversionWorthSpec?.goal === 'GOAL_1DAY_PURCHASE_ROAS' ) }), onSelect: (record: { adgroup_id: number, mpName: string }, selected: boolean) => { if (selected) { selectedRows.push({ ...record }) setSelectedRows([...selectedRows]) } else { let newSelectAccData = selectedRows.filter((item: { adgroup_id: number }) => item.adgroup_id !== record.adgroup_id) setSelectedRows([...newSelectAccData]) } }, onSelectAll: (selected: boolean, selectedRowss: { adgroup_id: number }[], changeRows: { adgroup_id: number }[]) => { if (selected) { let newSelectAccData = [...selectedRows] changeRows.forEach((item: { adgroup_id: number }) => { let index = newSelectAccData.findIndex((ite: { adgroup_id: number }) => ite.adgroup_id === item.adgroup_id) if (index === -1) { newSelectAccData.push({ ...item }) } }) setSelectedRows([...newSelectAccData]) } else { let newSelectAccData = selectedRows.filter((item: { adgroup_id: number }) => { let index = changeRows.findIndex((ite: { adgroup_id: number }) => ite.adgroup_id === item.adgroup_id) if (index !== -1) { return false } else { return true } }) setSelectedRows([...newSelectAccData]) } } }} onChange={(props: any) => { let { sortData, pagination } = props let { current, pageSize } = pagination let newQueryForm = JSON.parse(JSON.stringify(queryForm)) newQueryForm.pageNum = current newQueryForm.pageSize = pageSize if (sortData && JSON.stringify('sortData') !== '{}') { let { field, order } = sortData // descend 降序 大到小 ascend 升序 小到大 if (order) { newQueryForm.sortColumn = field newQueryForm.sortAsc = order === 'ascend' } else { Object.keys(newQueryForm).forEach(key => { if (key === 'sortColumn' || key === 'sortAsc') { delete newQueryForm[key] } }) } } else { Object.keys(newQueryForm).forEach(key => { if (key === 'sortField' || key === 'sort') { delete newQueryForm[key] } }) } setQueryForm({ ...newQueryForm }) }} expandedRowRender={(data) => } />
{detailShow &&
{ setDetailShow(false) }} data={detailData} />} {czjlShow && { setCzjlShow(false) }} onOk={() => { setCzjlShow(false) }} width={1200} footer={null} title={"广告操作记录"} > } {cpVisible && setCpVisible(false)} onChange={(e) => { handleRqb(e) }} />} {logVisible && setLogVisible(false)} />}
} export default AdPlanList