import { useAjax } from '@/Hook/useAjax' import { Col, Row, message, Space, Button, Table, Statistic } from 'antd' import React, { useEffect, useCallback, useState, useRef } from 'react' import { getPutUserApi, delUserTagApi } from '@/services/launchAdq/adq' import { LineChartOutlined, PauseCircleOutlined, PlayCircleOutlined, TransactionOutlined } from '@ant-design/icons' import { planAdConfig } from './config' import '../../launchSystemNew/adq/ad/index.less' import tablePlanConfig from './tablePlanListConfig' import { AdListProps, getAdV3ListApi } from '@/services/adMonitor/adMonitor' import FilterQuery from './FilterQuery' import AdExpandedRowRender from './adExpandedRowRender' import { useSize, useUpdateEffect } from 'ahooks' import PlanTag from '../../launchSystemNew/adq/ad/planTag' import moment from 'moment' import ColumnTrend from '@/pages/adMonitor/adMonitorList/columnTrend' import TableData from '../../launchSystemNew/components/TableData' import RuleAccountLog from '@/components/EarlyWarning/ruleAccountLog' import Details from './Details' import { modifyStatusBatchApi, syncBatchApi } from '@/services/launchAdq/adqv3' import UpdateAd from '../adqv3/ad/updateAd' import SaveSearch from './SaveSearch' const AdPlanList: React.FC<{ userId: string }> = (props) => { /***********************/ const refF = useRef(null) const { userId } = props const [selectedRows, setSelectedRows] = useState([]) const [detailShow, setDetailShow] = useState(false) const [detailData, setDetailData] = useState({}) const [update, setUpdate] = useState<{ visible: boolean }>({ visible: false }) const [queryForm, setQueryForm] = useState({ pageNum: 1, pageSize: 20, columns: [], isDeleted: false, dataTimeMin: moment().subtract(7, 'days').format('YYYY-MM-DD'), dataTimeMax: moment().format('YYYY-MM-DD') }) const [filterForm, setFilterForm] = useState() const getAdList = useAjax((params) => getAdV3ListApi(params), { formatResult: true }) 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 = '广告列表3.0' const ref = useRef(null) const size = useSize(ref) const [scrollLeft, setScrollLeft] = useState(0) const [totalData, setTotalData] = useState({}) const [tableField, setTableField] = useState<{ title: string, dataIndex: string }[]>([]) const [initialValues, setInitialValues] = useState() const [trendVisible, setTrendVisible] = useState(false) const [trendData, setTrendData] = useState({}) const syncBatch = useAjax((params) => syncBatchApi(params)) const modifyStatusBatch = useAjax((params) => modifyStatusBatchApi(params)) /************************/ useEffect(() => { getList() }, [filterForm, queryForm]) const getList = () => { let message = localStorage.getItem(`myAdMonitorConfig1.0.1_${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 }) } useUpdateEffect(() => { let data: any = {} if (getAdList.data?.data?.sumRecord) { data = getAdList.data?.data?.sumRecord } setTotalData(data) }, [getAdList.data]) useEffect(() => { let localData = localStorage.getItem('myAdMonitorConfig1.0.1_广告列表3.0') let data: any[] = [] if (localData) { data = JSON.parse(localData) } else { let newSelectData: any[] = []; (planAdConfig as any).forEach((item: { data: { default: any }[] }) => { item?.data?.forEach((d: { default: any }) => { if (d.default) { newSelectData[d.default - 1] = d } }) }) data = newSelectData } data.unshift({ title: '选择框', dataIndex: 'xzk' }) data.unshift({ title: '总计', dataIndex: 'zj' }) setTableField(data) }, [localStorage.getItem('myAdMonitorConfig1.0.1_广告列表3.0')]) useEffect(() => { getPutUser.run({ userId }) }, [userId]) // 同步 const sync = useCallback(() => { if (selectedRows?.length > 0) { let accountAdgroupMaps = [...new Set(selectedRows?.map(item => item.account_id + ',' + item.adgroup_id))] syncBatch.run({ accountAdgroupMaps }).then(res => { res && getAdList.refresh() res ? message.success('同步成功!') : message.error('同步失败!') }) } else { message.error('请勾选') } }, [getAdList, selectedRows]) // 单个启停 const onChange = () => { getAdList.refresh() setSelectedRows([]) } const details = (data: any) => { setDetailData(data) setDetailShow(true) } 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() } }) } const handleColumnTrend = (value: string) => { let message = localStorage.getItem(`myAdMonitorConfig1.0.1_${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) } }) }) } setTrendData({ ...queryForm, ...filterForm, columns, field: value.replace('_total', '') }) setTrendVisible(true) } // 批量启停 const adStatus = (type: boolean) => { let newSelectedRows = [] if (type) { newSelectedRows = selectedRows.filter((item: { configuredStatus: string, adgroupId: number }) => item.configuredStatus === 'AD_STATUS_SUSPEND') } else { newSelectedRows = selectedRows.filter((item: { configuredStatus: string, adgroupId: number }) => item.configuredStatus === 'AD_STATUS_NORMAL') } if (newSelectedRows.length === 0) { message.warn(`所有广告都是${type ? '启动' : '暂停'}状态,无需${type ? '启动' : '暂停'}操作`) return } let accountAdgroupMaps = [...new Set(newSelectedRows?.map(item => item.accountId + ',' + item.adgroupId))] modifyStatusBatch.run({ accountAdgroupMaps, suspend: !type }).then(res => { message.success(`${type ? '启动' : '暂停'}成功`) getAdList.refresh() setSelectedRows([]) }) } const countDecimals = (num: number) => { // 匹配数字的小数部分 const match = String(num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/); // 返回小数位数 return match ? Math.max(0, (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0)) : 0; } return
{/* 列表指标趋势 */} {trendVisible && { setTrendVisible(false) }} />} {/* 打标签 */} {tagVisible && setTagVisible(false)} onChange={() => { getAdList.refresh() setTagVisible(false) }} />} { setFilterForm({ ...value }) }} initialValues={filterForm} ref={refF} />
tablePlanConfig(onChange, details, log, handleTag, delTag)} ajax={getAdList} syncAjax={sync} fixed={{ left: 2, right: 4 }} dataSource={getAdList?.data?.data?.records} loading={getAdList?.loading || syncBatch?.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={ { let { queryForm, filterForm } = JSON.parse(value) setQueryForm(data => ({ ...queryForm, pageNum: data.pageNum, pageSize: data.pageSize })) setFilterForm(filterForm); (refF.current as any)?.onOpen(filterForm) }} /> } rowSelection={{ selectedRowKeys: selectedRows.map(item => item.adgroup_id.toString()), getCheckboxProps: (record: any) => ({ disabled: record.status === 'STATUS_DELETED' }), 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) => } summary={() => ( {tableField.map((item, index) => { let data = totalData[item.dataIndex] if (item.dataIndex === 'zj') { return 总计 } else if (['ctr_total', 'mp_follow_rate_total', 'add_quick_app_rate_total', 'scan_follow_rate_total', 'first_day_order_roi_total', 'order_rate_total', 'order_roi_total', 'conversions_rate_total', 'income_roi124h_pla_total', 'income_roi124h_total', 'income_roi1_total', 'income_roi3_total', 'income_roi7_total', 'income_roi14_total', 'ad_monetization_roi_total', 'mini_game_income_roi1_total', 'minigame3d_income_roi_total', 'minigame7d_income_roi_total', 'mini_game_ad_monetization_roi_total', 'reg_click_rate_pla_total', 'reg_rate_total' ].includes(item.dataIndex)) { let value = (data === 0 || data) ? data : '--' return {value !== '--' ? : '--'} {value !== '--' && handleColumnTrend(item.dataIndex)}>} } else { let value = (data === 0 || data) ? countDecimals(data) > 2 ? Math.floor(data * 100) / 100 : data : '--' return {value !== '--' && handleColumnTrend(item.dataIndex)}>} } })} )} />
{detailShow &&
{ setDetailShow(false) }} data={detailData} />} {logVisible && setLogVisible(false)} />} {/* 修改广告 */} {update.visible && ({ ...item, accountId: item.account_id, adgroupId: item.adgroup_id }))} onChange={() => { setUpdate({ visible: false }) getAdList.refresh() setSelectedRows([]) }} onClose={() => { setUpdate({ visible: false }) }} />}
} export default AdPlanList