wjx 3 月之前
父節點
當前提交
feeb1d5a1f

+ 13 - 0
config/routerConfig.ts

@@ -222,6 +222,19 @@ const gameDataStatistics = {
                 }
             ]
         },
+        {
+            path: '/gameDataStatistics/dynamic',
+            name: '创意列表',
+            access: 'dynamic',
+            routes: [
+                {
+                    path: '/gameDataStatistics/dynamic/tencentMonitor',
+                    name: '腾讯创意监控',
+                    access: 'tencentMonitor',
+                    component: './gameDataStatistics/dynamic/tencentMonitor',
+                }
+            ]
+        },
         {
             path: '/gameDataStatistics/gameData',
             name: '游戏数据',

+ 32 - 3
src/components/QueryForm/index.tsx

@@ -152,6 +152,9 @@ interface Props {
     isProjectId?: boolean
     /** 是否开启 计划名称 搜索 */
     isProjectName?: boolean
+    /** 是否开启 创意名称 搜索 */
+    isDynamicCreativeName?: boolean
+    isDynamicCreativeId?: boolean
     /** 是否开启 广告ID 搜索 */
     isProjectId1?: boolean
     /** 是否开启 广告ID 搜索 */
@@ -263,6 +266,8 @@ interface Props {
     isRechargeTotalAmountWithin24h?: boolean
     /** 是否开启 玩家注册渠道类型 搜索 */
     isRegisterType?: boolean
+    /** 是否开启 创意状态 搜索 */
+    isConfiguredStatus?: boolean
 }
 /**
  * 游戏数据系统 请求参数
@@ -273,11 +278,11 @@ const QueryForm: React.FC<Props> = (props) => {
     /**************************/
     const {
         onChange, initialValues, isSource, isAccount, isAccountId, isAccountIds, isCompanyId, isAgentKey, isAgentName, isCpId, isCpName, isCpOrderId, isCpStatus, isCreateDay, isCreateDayXz, isDevice, isGameName, isRechargeGameName, isGameId, isGameIds, isOrderGameId, isGameRoleId,
-        isGameRoleName, isFirstRecharge, isSwitch, isMerchantNo, isOrderId, isMerchantOrderNo, isPayStatus, isPayWay, isProductName, isRegAgent, isAgentId, isPutAgent, isRegDay, isOs, isParentId, isParentIds, isProjectId, isProjectName, isPromotionId, isPromotionId1, isPromotionName,
+        isGameRoleName, isFirstRecharge, isSwitch, isMerchantNo, isOrderId, isMerchantOrderNo, isPayStatus, isPayWay, isProductName, isRegAgent, isAgentId, isPutAgent, isRegDay, isOs, isParentId, isParentIds, isProjectId, isProjectName, isDynamicCreativeName, isPromotionId, isPromotionId1, isPromotionName,
         isSysUserName, isRechargeDate, LastRechargeDay, isBGGameClassify, isGameUserId, isSysUserId, isSysUserIds, isUserName, isUserId, isSelectRanking, isGameType, isConsumeDay, rechargeDay, isBeginDay, isType, isAdTTStatus, isUserEnterType, isServerName, isServerId, isServerDay, isAdTXStatus,
         payTimeDay, placeAnOrderDay, isPayIntervalTime, isActiveTypes, isNickname, isMobile, isRegIp, isIsAuth, isIsBindMobile, isIsRecharge, isUserStatus, isCreateRole, isRoleCount, isVipLevel, isRoleLevel, isCreateRoleDay, isLastActiveTime, isIsChange, isIsSendMail, isWeChatCompany, isWeChat,
-        isCustomerServerId, isOperatorId, isGsId, isServerIds, isRankingNum, isIsMergeServer, isIsParticipateMerge, isSuperParentGameId, isGameServerName, isIp, isDeviceType, isLoginType, isServerIdUn, isSourceServerName, isProjectId1, isRemoveGame, isRemoveGameForSystem, isOrderLy, isAddCorpWechat,
-        isWakeUp, isUserPhoneStatus, isBackStatus, isGameDimension, isUserLastRegTime, isUserLastRegAgentId, isUserLastPitcherId, isRechargeAmountWithin24h, isRechargeTotalAmountWithin24h, isRegisterType
+        isCustomerServerId, isOperatorId, isGsId, isServerIds, isRankingNum, isIsMergeServer, isIsParticipateMerge, isSuperParentGameId, isGameServerName, isIp, isDeviceType, isLoginType, isServerIdUn, isSourceServerName, isProjectId1, isDynamicCreativeId, isRemoveGame, isRemoveGameForSystem, isOrderLy, isAddCorpWechat,
+        isWakeUp, isUserPhoneStatus, isBackStatus, isGameDimension, isUserLastRegTime, isUserLastRegAgentId, isUserLastPitcherId, isRechargeAmountWithin24h, isRechargeTotalAmountWithin24h, isRegisterType, isConfiguredStatus
     } = props
     const [form] = Form.useForm()
     const parentId = Form.useWatch('parentId', form)
@@ -732,6 +737,14 @@ const QueryForm: React.FC<Props> = (props) => {
             {isPromotionId1 && <Col><Form.Item name='promotionId'>
                 <Input placeholder="计划ID" allowClear style={{ width: 140 }} />
             </Form.Item></Col>}
+            {/* 创意名称 */}
+            {isDynamicCreativeName && <Col><Form.Item name='dynamicCreativeName'>
+                <Input placeholder="创意名称" allowClear style={{ width: 140 }} />
+            </Form.Item></Col>}
+            {/* 创意ID */}
+            {isDynamicCreativeId && <Col><Form.Item name='dynamicCreativeId'>
+                <Input placeholder="创意ID" allowClear style={{ width: 140 }} />
+            </Form.Item></Col>}
             {/* 广告状态 */}
             {isAdTTStatus && <Col><Form.Item name='status'>
                 <Select
@@ -1626,6 +1639,22 @@ const QueryForm: React.FC<Props> = (props) => {
                 </Select>
             </Form.Item></Col>}
 
+            {/* 创意状态 */}
+            {isConfiguredStatus && <Col><Form.Item name='creativeStatus'>
+                <Select
+                    showSearch
+                    style={{ width: 100 }}
+                    allowClear
+                    placeholder={'创意状态'}
+                    filterOption={(input, option) =>
+                        (option?.children as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
+                    }
+                >
+                    <Select.Option value={'AD_STATUS_NORMAL'}>有效</Select.Option>
+                    <Select.Option value={'AD_STATUS_SUSPEND'}>暂停</Select.Option>
+                </Select>
+            </Form.Item></Col>}
+
             {/* 玩家最新染色时间 */}
             {isUserLastRegTime && <Col><Form.Item name='userLastRegTime'>
                 <DatePicker placeholder={'最新染色时间'} />

+ 50 - 0
src/pages/gameDataStatistics/dynamic/tencentMonitor/const.tsx

@@ -0,0 +1,50 @@
+import { Badge } from "antd";
+import React from "react";
+
+/** 广告状态 */
+export const ADSTATUSEnum = {
+    'STATUS_PENDING': <Badge status="success" text={<span style={{ fontSize: 12 }}>审核中</span>} />,
+    'STATUS_DENIED': <Badge status="error" text={<span style={{ fontSize: 12 }}>审核不通过</span>} />,
+    'STATUS_SUSPEND': <Badge status="warning" text={<span style={{ fontSize: 12 }}>暂停中</span>} />,
+    'STATUS_READY': <Badge status="default" text={<span style={{ fontSize: 12 }}>未到投放时间</span>} />,
+    'STATUS_ACTIVE': <Badge status="processing" text={<span style={{ fontSize: 12 }}>投放中</span>} />,
+    'STATUS_STOP': '投放结束',
+    'STATUS_ACTIVE_CAMPAIGN_SUSPEND': '广告被暂停',
+    'STATUS_PART_READY': '部分待投放',
+    'STATUS_PART_ACTIVE': '部分投放中',
+    'STATUS_DELETED': <Badge status="error" text={<span style={{ fontSize: 12 }}>已删除</span>} />,
+    'STATUS_UNKNOWN': '未知状态',
+    'STATUS_FROZEN': '冻结',
+    'STATUS_PREPARE': '准备中',
+    'STATUS_ACTIVE_ACCOUNT_LIMIT': <Badge status="warning" text={<span style={{ fontSize: 12 }}>账户达日限额</span>} />,
+    'STATUS_ACTIVE_ACCOUNT_EMPTY': <Badge status="warning" text={<span style={{ fontSize: 12 }}>账户余额不足</span>} />,
+    'STATUS_ACTIVE_ACCOUNT_FROZEN': <Badge status="warning" text={<span style={{ fontSize: 12 }}>账户余额不足</span>} />,
+    'STATUS_ACTIVE_AD_LIMIT': <Badge status="error" text={<span style={{ fontSize: 12 }}>广告达日限额(预算不足)</span>} />,
+    'STATUS_ACCOUNT_BALANCE_NOT_ENOUGH': '余额不足'
+}
+
+/** 出价方式 */
+export enum PRICINGEnum {
+    "BID_MODE_CPC" = "CPC",
+    "BID_MODE_CPA" = "CPA",
+    "BID_MODE_CPM" = "CPM",
+    "BID_MODE_OCPC" = "oCPC",
+    "BID_MODE_OCPM" = "oCPM"
+}
+
+export enum LANDINGTYPEEnum {
+    'PROMOTED_OBJECT_TYPE_APP_ANDROID' = 'Android 应用',
+    'PROMOTED_OBJECT_TYPE_APP_IOS' = 'IOS 应用',
+    'PROMOTED_OBJECT_TYPE_ECOMMERCE' = '电商推广',
+    'PROMOTED_OBJECT_TYPE_LINK_WECHAT' = '品牌活动推广',
+    'PROMOTED_OBJECT_TYPE_APP_ANDROID_MYAPP' = '应用宝推广',
+    'PROMOTED_OBJECT_TYPE_LOCAL_ADS_WECHAT' = '本地广告',
+    'PROMOTED_OBJECT_TYPE_QQ_BROWSER_MINI_PROGRAM' = 'QQ 浏览器小程序',
+    'PROMOTED_OBJECT_TYPE_QQ_MESSAGE' = 'QQ 消息',
+    'PROMOTED_OBJECT_TYPE_QZONE_VIDEO_PAGE' = '视频说说',
+    'PROMOTED_OBJECT_TYPE_LEAD_AD' = '销售线索收集',
+    'PROMOTED_OBJECT_TYPE_MINI_GAME_WECHAT' = '微信小游戏',
+    'PROMOTED_OBJECT_TYPE_MINI_GAME_QQ' = 'QQ 小游戏',
+    'PROMOTED_OBJECT_TYPE_WECHAT_OFFICIAL_ACCOUNT' = '微信公众号',
+    'PROMOTED_OBJECT_TYPE_APP_QUICK_APP' = '快应用',
+}

+ 101 - 0
src/pages/gameDataStatistics/dynamic/tencentMonitor/dayAd.tsx

@@ -0,0 +1,101 @@
+import { useAjax } from "@/Hook/useAjax"
+import { PromotionDataDay, getPromotionDataTencentDayListApi, getPromotionDataTencentDayTotalApi } from "@/services/gameData/adlist"
+import { Button, Drawer, Space } from "antd"
+import React, { useEffect, useState } from "react"
+import TableData from "../../components/TableData"
+import columns12 from './tableConfigDay'
+import { getPresets } from "@/components/QueryForm/const"
+import QueryForm from "@/components/QueryForm"
+import { CloseOutlined } from "@ant-design/icons"
+
+interface Props {
+    queryForm: PromotionDataDay
+    adName: string,
+    promotionId?: number
+    onClose?: () => void
+    visible?: boolean
+}
+
+/**
+ * 广告每日监控
+ * @returns 
+ */
+const DayAd: React.FC<Props> = ({ adName, queryForm, promotionId, onClose, visible }) => {
+
+    /***********************************/
+    const [data, setData] = useState<{ pageSize: number, pageNum: number, sortFiled?: string, sortType?: string }>({ pageNum: 1, pageSize: 100 })
+    const [date, setDate] = useState<[string, string]>()
+    const [totalData, setTotalData] = useState<any[]>([])
+    const getPromotionDataTencentDayList = useAjax((params) => getPromotionDataTencentDayListApi(params))
+    const getPromotionDataTencentDayTotal = useAjax((params) => getPromotionDataTencentDayTotalApi(params))
+    /***********************************/
+
+    useEffect(() => {
+        let params = JSON.parse(JSON.stringify(queryForm))
+        delete params.sortType
+        delete params.sortFiled
+        delete params.pageSize
+        delete params.pageNum
+        if (promotionId) {
+            params.promotionId = promotionId
+        }
+        if (date && date?.length > 0) {
+            params.costBeginDate = date[0]
+            params.costEndDate = date[1]
+        } else {
+            delete params?.costBeginDate
+            delete params?.costEndDate
+        }
+        getPromotionDataTencentDayList.run({ ...params, ...data })
+        getPromotionDataTencentDayTotal.run({ ...params, ...data }).then(res => {
+            res.id = 1
+            res.dt = '总计'
+            setTotalData([res])
+        })
+    }, [promotionId, queryForm, data, date])
+
+    return <Drawer title={<div style={{ display: 'flex', justifyContent: 'space-between' }}><span>{`${adName} 腾讯广告每日数据`}</span> <Button type="text" icon={<CloseOutlined />} onClick={() => onClose?.()}></Button> </div>} closable={false} placement="right" width={'90%'} onClose={onClose} visible={visible}>
+        <TableData
+            leftChild={<QueryForm
+                onChange={(data: any) => {
+                    const { costBeginDay, costEndDay } = data
+                    if (costBeginDay && costEndDay) {
+                        setDate([costBeginDay, costEndDay])
+                    } else {
+                        setDate(undefined)
+                    }
+                }}
+                isConsumeDay={{ ranges: getPresets() }}
+            />}
+            isZj
+            totalData={totalData}
+            scroll={{ x: 1000, y: 600 }}
+            ajax={getPromotionDataTencentDayList}
+            fixed={{ left: 3, right: 0 }}
+            dataSource={getPromotionDataTencentDayList?.data?.records?.map((item: any, index: number) => ({ ...item, id: Number(data.pageNum.toString() + index.toString()) }))}
+            total={getPromotionDataTencentDayList?.data?.total}
+            page={queryForm.pageNum}
+            pageSize={queryForm.pageSize}
+            title='腾讯广告每日监控'
+            onChange={(props: any) => {
+                let { pagination, sortData } = props
+                let { current, pageSize } = pagination
+                let newQueryForm = JSON.parse(JSON.stringify(data))
+                if (sortData && sortData?.order) {
+                    newQueryForm['sortType'] = sortData?.order === 'ascend' ? 'asc' : 'desc'
+                    newQueryForm['sortFiled'] = sortData?.field
+                } else {
+                    delete newQueryForm['sortType']
+                    delete newQueryForm['sortFiled']
+                }
+                newQueryForm.pageNum = current
+                newQueryForm.pageSize = pageSize
+                setData({ ...newQueryForm })
+            }}
+            config={columns12()}
+            configName={'腾讯广告每日监控'}
+        />
+    </Drawer>
+}
+
+export default React.memo(DayAd)

+ 7 - 0
src/pages/gameDataStatistics/dynamic/tencentMonitor/index.less

@@ -0,0 +1,7 @@
+.adDataBackColorClass {
+    background-color: #fff2e8;
+}
+
+.payDataBackColorClass {
+    background-color: #f9f0ff;
+}

+ 219 - 0
src/pages/gameDataStatistics/dynamic/tencentMonitor/index.tsx

@@ -0,0 +1,219 @@
+import React, { useEffect, useState } from "react"
+import DayAd from "./dayAd"
+import columns12 from "./tableConfig"
+import { getPresets } from "@/components/QueryForm/const"
+import TableData from "../../components/TableData"
+import QueryForm from "@/components/QueryForm"
+import { PromotionDataDay, getDynamicTencentListApi, getDynamicTencentTotalApi, updateBatchDynamicCreativesInfoApi } from "@/services/gameData/adlist"
+import { useAjax } from "@/Hook/useAjax"
+import moment from "moment"
+import { Button, Modal, Space, Table, message, notification } from "antd"
+import { PauseCircleOutlined, PlayCircleOutlined } from "@ant-design/icons"
+
+
+
+const TencentMonitor: React.FC = () => {
+
+    /***************************************/
+    const [queryForm, setQueryForm] = useState<PromotionDataDay>({ pageNum: 1, pageSize: 50, sourceSystem: 'ZX_ONE', costBeginDate: moment().format('YYYY-MM-DD'), costEndDate: moment().format('YYYY-MM-DD') })
+    const [totalData, setTotalData] = useState<any[]>([])
+    const [visible, setVisible] = useState<boolean>(false)
+    const [promotionId, setPromotionId] = useState<number>()
+    const [adName, setAdName] = useState<string>('')
+    const [selectedRows, setSelectedRows] = useState<any[]>([])
+    const [isZj, setIsZj] = useState<boolean>(true)
+    const [failIdList, setFailIdList] = useState<{ adgroupId: number, code: number, message: string, messageCn: string }[]>([])
+    const [failVisible, setFailVisible] = useState<boolean>(false)
+
+    const getDynamicTencentList = useAjax((params) => getDynamicTencentListApi(params))
+    const getDynamicTencentTotal = useAjax((params) => getDynamicTencentTotalApi(params))
+    const updateBatchDynamicCreativesInfo = useAjax((params) => updateBatchDynamicCreativesInfoApi(params))
+    /***************************************/
+
+    useEffect(() => {
+        getDynamicTencentList.run(queryForm)
+        getDynamicTencentTotal.run(queryForm).then((res: { id: number; accountName: string }) => {
+            res.id = 1
+            res.accountName = '总计'
+            setTotalData([res])
+        })
+    }, [queryForm])
+
+    const dayHandle = (data: any) => {
+        setVisible(true)
+        setAdName(data.promotionName)
+        setPromotionId(data.promotionId)
+    }
+
+    // 批量启停
+    const adStatus = (type: '启动' | '暂停') => {
+        const accountAdgroupMaps = [...new Set(selectedRows?.map(item => item.accountId + ',' + item.dynamicCreativeId))]
+        updateBatchDynamicCreativesInfo.run({ accountAdgroupMaps, suspend: type === '暂停' }).then(res => {
+            if (res?.failIdList?.length === 0) {
+                message.success(`修改操作完成!`)
+                getDynamicTencentList.refresh()
+                getDynamicTencentTotal.refresh()
+                setSelectedRows([])
+            } else {
+                setFailIdList(res?.list || [])
+                setFailVisible(true)
+            }
+        })
+    }
+
+    return <div>
+        <TableData
+            czChild={<Space>
+                {/* <Switch checkedChildren="开启全选" unCheckedChildren="关闭全选" checked={!isZj} onChange={(e) => { setIsZj(!e); }} /> */}
+                <Button type='primary' size="small" style={{ background: '#67c23a', borderColor: '#67c23a' }} loading={updateBatchDynamicCreativesInfo.loading} icon={<PlayCircleOutlined />} disabled={selectedRows.length === 0} onClick={() => adStatus('启动')}>启动</Button>
+                <Button type='primary' size="small" style={{ background: '#e6a23c', borderColor: '#e6a23c' }} loading={updateBatchDynamicCreativesInfo.loading} icon={<PauseCircleOutlined />} disabled={selectedRows.length === 0} onClick={() => adStatus('暂停')}>暂停</Button>
+                {selectedRows.length > 0 && <Button type="link" danger onClick={() => setSelectedRows([])}>清空</Button>}
+                <span style={{ color: 'red' }}>操作完数据结果延时5分钟之内,即时结果去腾讯后台查看</span>
+            </Space>}
+            leftChild={<QueryForm
+                initialValues={{ sourceSystem: 'ZX_ONE', consumeDay: [moment(), moment()] }}
+                onChange={(data: any) => {
+                    const { type, gameClassify, costBeginDay, costEndDay, sysUserName, ...params } = data
+                    let newQueryForm = JSON.parse(JSON.stringify(queryForm))
+                    newQueryForm.pageNum = 1
+                    newQueryForm.pitcherName = sysUserName
+                    newQueryForm.accountType = type
+                    newQueryForm.classify = gameClassify
+                    if (costBeginDay && costEndDay) {
+                        newQueryForm.costBeginDate = costBeginDay
+                        newQueryForm.costEndDate = costEndDay
+                    } else {
+                        delete newQueryForm.costBeginDate
+                        delete newQueryForm.costEndDate
+                    }
+                    setQueryForm({ ...newQueryForm, ...params })
+                }}
+                isSource
+                isAccountId
+                isAccount
+                isType
+                isAgentId
+                isBGGameClassify
+                isConsumeDay={{ ranges: getPresets() }}
+                isCpName
+                isGameId
+                isSysUserId
+                isProjectId
+                isProjectName
+                isDynamicCreativeName
+                isPromotionId
+                isDynamicCreativeId
+                isPromotionName
+                isAdTXStatus
+                isConfiguredStatus
+            />}
+            isZj={isZj}
+            totalData={totalData}
+            scroll={{ x: 1000, y: 600 }}
+            ajax={getDynamicTencentList}
+            fixed={{ left: 3, right: 0 }}
+            dataSource={getDynamicTencentList?.data?.records?.map((item: any) => ({ ...item, id: Number(item.dynamicCreativeId) }))}
+            total={getDynamicTencentList?.data?.total}
+            page={queryForm.pageNum}
+            pageSize={queryForm.pageSize}
+            sortData={{
+                field: queryForm?.sortFiled,
+                order: queryForm?.sortType === 'asc' ? 'ascend' : 'descend'
+            }}
+            title='腾讯创意监控'
+            onChange={(props: any) => {
+                let { pagination, sortData } = props
+                let { current, pageSize } = pagination
+                let newQueryForm = JSON.parse(JSON.stringify(queryForm))
+                if (sortData && sortData?.order) {
+                    newQueryForm['sortType'] = sortData?.order === 'ascend' ? 'asc' : 'desc'
+                    newQueryForm['sortFiled'] = sortData?.field
+                } else {
+                    delete newQueryForm['sortType']
+                    delete newQueryForm['sortFiled']
+                }
+                newQueryForm.pageNum = current
+                newQueryForm.pageSize = pageSize
+                setQueryForm({ ...newQueryForm })
+            }}
+            rowSelection={{
+                selectedRowKeys: selectedRows.map(item => item.dynamicCreativeId + ''),
+                getCheckboxProps: (record: any) => ({
+                    disabled: record.status === 'STATUS_DELETED' || record?.accountName === '总计'
+                }),
+                onSelect: (record: { dynamicCreativeId: number }, selected: boolean) => {
+                    if (selected) {
+                        selectedRows.push({ ...record })
+                        setSelectedRows([...selectedRows])
+                    } else {
+                        let newSelectAccData = selectedRows.filter((item: { dynamicCreativeId: number }) => item.dynamicCreativeId !== record.dynamicCreativeId)
+                        setSelectedRows([...newSelectAccData])
+                    }
+                },
+                onSelectAll: (selected: boolean, selectedRowss: { dynamicCreativeId: number }[], changeRows: { dynamicCreativeId: number }[]) => {
+                    if (selected) {
+                        let newSelectAccData = [...selectedRows]
+                        changeRows.forEach((item: { dynamicCreativeId: number }) => {
+                            let index = newSelectAccData.findIndex((ite: { dynamicCreativeId: number }) => ite.dynamicCreativeId === item.dynamicCreativeId)
+                            if (index === -1) {
+                                newSelectAccData.push({ ...item })
+                            }
+                        })
+                        setSelectedRows([...newSelectAccData])
+                    } else {
+                        let newSelectAccData = selectedRows.filter((item: { dynamicCreativeId: number }) => {
+                            let index = changeRows.findIndex((ite: { dynamicCreativeId: number }) => ite.dynamicCreativeId === item.dynamicCreativeId)
+                            if (index !== -1) {
+                                return false
+                            } else {
+                                return true
+                            }
+                        })
+                        setSelectedRows([...newSelectAccData])
+                    }
+                }
+            }}
+            config={columns12(dayHandle, () => { getDynamicTencentList.refresh() })}
+            configName={'腾讯创意监控'}
+        />
+
+        {visible && <DayAd adName={adName} visible={visible} onClose={() => { setVisible(false); setPromotionId(undefined) }} queryForm={queryForm} promotionId={promotionId} />}
+
+        {failVisible && <Modal
+            title={<strong>报错信息</strong>}
+            visible={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>}
+    </div>
+}
+
+export default TencentMonitor

+ 41 - 0
src/pages/gameDataStatistics/dynamic/tencentMonitor/switchStatus.tsx

@@ -0,0 +1,41 @@
+import { useAjax } from "@/Hook/useAjax"
+import { updateBatchDynamicCreativesInfoApi } from "@/services/gameData/adlist"
+import { message, notification, Switch } from "antd"
+import React from "react"
+
+
+
+/**
+ * 修改启停
+ */
+interface Props {
+    configuredStatus: string,
+    isDeleted?: boolean,
+    accountId: number,
+    dynamicCreativeId: number,
+    onChange?: () => void
+}
+const SwitchStatus: React.FC<Props> = (prosp) => {
+
+    const { configuredStatus, isDeleted, accountId, dynamicCreativeId, onChange } = prosp
+    const updateBatchDynamicCreativesInfo = useAjax((params) => updateBatchDynamicCreativesInfoApi(params))
+    
+    const switchHandle = (status: boolean) => {
+        updateBatchDynamicCreativesInfo.run({ accountAdgroupMaps: [accountId + ',' + dynamicCreativeId], suspend: !status }).then(res => {
+            message.success(`${configuredStatus === 'AD_STATUS_NORMAL' ? '启动' : '暂停'}成功`)
+            if (res?.fail) {
+                notification.error({
+                    message: `${configuredStatus === 'AD_STATUS_NORMAL' ? '启动' : '暂停'}失败`,
+                    description: `修改失败${res.fail}条,失败的请到任务列表查看`,
+                    duration: 0
+                });
+            }
+            onChange?.()
+        })
+    }
+
+    return <Switch size="small" checked={configuredStatus === 'AD_STATUS_NORMAL'} loading={updateBatchDynamicCreativesInfo.loading} disabled={isDeleted} onChange={(checked) => switchHandle(checked)}/>
+}
+
+
+export default React.memo(SwitchStatus)

+ 633 - 0
src/pages/gameDataStatistics/dynamic/tencentMonitor/tableConfig.tsx

@@ -0,0 +1,633 @@
+import { TYPE, gameClassifyEnum } from "@/components/QueryForm/const"
+import WidthEllipsis from "@/components/widthEllipsis"
+import { Statistic } from "antd"
+import React from "react"
+import { ADSTATUSEnum, LANDINGTYPEEnum, PRICINGEnum } from './const'
+import './index.less'
+import SwitchStatus from "./switchStatus"
+
+function columns12(dayHandle: (data: any) => void, onChange?: () => void): { label: string, fieldSHow?: { label: string, saveField: string, defaultValue: any[], data: any[] }, data: any[] }[] {
+
+    const data = [{ lable: '次日', value: 2 }, { lable: 'D3', value: 3 }, { lable: 'D7', value: 7 }, { lable: 'D15', value: 15 }]
+    let date = data.map(item => {
+        let field = `d${item.value}Trend`
+        return {
+            title: item.lable,
+            dataIndex: `D${item.value}`,
+            label: '付费数据',
+            align: 'center',
+            width: 85,
+            className: 'payDataBackColorClass',
+            children: [
+                {
+                    title: 'ROI',
+                    dataIndex: 'roi',
+                    key: 'roi',
+                    width: 80,
+                    align: 'center',
+                    render: (_: any, b: any) => {
+                        let data: any = {}
+                        if (b?.[field]) {
+                            data = b?.[field]
+                            return <Statistic value={data?.roi ? data?.roi * 100 : 0} precision={2} valueStyle={!data?.roi ? {} : data?.roi >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                        }
+                        return '--'
+                    }
+                },
+                {
+                    title: '付费',
+                    dataIndex: 'rechargeMoney',
+                    key: 'rechargeMoney',
+                    width: 60,
+                    align: 'center',
+                    render: (_: any, b: any) => {
+                        let data: any = {}
+                        if (b?.[field]) {
+                            data = b?.[field]
+                            return <Statistic value={data?.rechargeMoney || 0} />
+                        }
+                        return '--'
+                    }
+                },
+                {
+                    title: '倍数',
+                    dataIndex: 'multiples',
+                    key: 'multiples',
+                    width: 40,
+                    align: 'center',
+                    render: (_: any, b: any) => {
+                        let data: any = {}
+                        if (b?.[field]) {
+                            data = b?.[field]
+                            return <span>{data?.multiples || 0}</span>
+                        }
+                        return '--'
+                    }
+                },
+            ]
+        }
+    })
+
+    return [
+        {
+            label: '账户信息',
+            data: [
+                {
+                    title: '推广账号名称', dataIndex: 'accountName', label: '账户信息', align: 'center', width: 100, default: 2,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '推广账号ID', dataIndex: 'accountId', label: '账户信息', align: 'center', width: 120, default: 3,
+                    render: (a: string, b: any) => (<WidthEllipsis isCopy value={a} />)
+                },
+                {
+                    title: '备注', dataIndex: 'notes', label: '账户信息', align: 'center', width: 120,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '投手', dataIndex: 'pitcherName', label: '账户信息', align: 'center', width: 70,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '投放渠道', dataIndex: 'agentName', label: '账户信息', align: 'center', width: 75, default: 4,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '服务商', dataIndex: 'service', label: '账户信息', align: 'center', width: 95,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '投放媒体', dataIndex: 'accountType', label: '账户信息', align: 'center', width: 70,
+                    render: (a: string, b: any) => (<WidthEllipsis value={TYPE[a as keyof typeof TYPE]} />)
+                },
+                {
+                    title: '余额', dataIndex: 'balance', label: '账户信息', align: 'center', width: 70, sorter: true,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                }
+            ]
+        },
+        {
+            label: '推广内容',
+            data: [
+                {
+                    title: '推广游戏名称', dataIndex: 'gameName', label: '推广内容', align: 'center', width: 70,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '推广游戏应用类型', dataIndex: 'classify', label: '推广内容', align: 'center', width: 95,
+                    render: (a: string) => (<span>{gameClassifyEnum[a as keyof typeof gameClassifyEnum]}</span>)
+                }
+            ]
+        },
+        {
+            label: '广告信息',
+            data: [
+                {
+                    title: '推广广告名称', dataIndex: 'promotionName', label: '广告信息', align: 'center', width: 130, default: 5,
+                    render: (a: string, b: any) => (<WidthEllipsis isCopy value={a} />)
+                },
+                {
+                    title: '广告ID', dataIndex: 'promotionId', label: '广告信息', align: 'center', width: 90, default: 6,
+                    render: (a: string, b: any) => (<WidthEllipsis isCopy value={a} />)
+                },
+                {
+                    title: '推广创意名称', dataIndex: 'dynamicCreativeName', label: '广告信息', align: 'center', width: 130, default: 7,
+                    render: (a: string, b: any) => (<WidthEllipsis isCopy value={a} />)
+                },
+                {
+                    title: '创意ID', dataIndex: 'dynamicCreativeId', label: '广告信息', align: 'center', width: 90, default: 8,
+                    render: (a: string, b: any) => (<WidthEllipsis isCopy value={a} />)
+                },
+                {
+                    title: '项目名称', dataIndex: 'projectName', label: '广告信息', align: 'center', width: 130,
+                    render: (a: string) => (<WidthEllipsis isCopy value={a} />)
+                },
+                {
+                    title: '项目ID', dataIndex: 'projectId', label: '广告信息', align: 'center', width: 90,
+                    render: (a: string) => (<WidthEllipsis isCopy value={a} />)
+                },
+                {
+                    title: '广告状态', dataIndex: 'status', label: '广告信息', align: 'left', width: 120, default: 9,
+                    render: (a: string) => (ADSTATUSEnum[a?.replace('ADGROUP_', '') as keyof typeof ADSTATUSEnum])
+                },
+                {
+                    title: '推广目标', dataIndex: 'landingType', label: '广告信息', align: 'center', width: 80,
+                    render: (a: string, b: any) => (<WidthEllipsis value={LANDINGTYPEEnum[a as keyof typeof LANDINGTYPEEnum]} />)
+                },
+                {
+                    title: '出价方式', dataIndex: 'pricing', label: '广告信息', align: 'center', width: 100, default: 10,
+                    render: (a: string, b: any) => (<WidthEllipsis value={PRICINGEnum[a as keyof typeof PRICINGEnum]} />)
+                },
+                {
+                    title: '当前出价', dataIndex: 'cpaBid', label: '广告信息', align: 'center', width: 70, default: 11,
+                    render: (a: any) => <Statistic value={a || '--'} />
+                },
+                {
+                    title: '深度转化ROI系数', dataIndex: 'roiGoal', label: '广告信息', align: 'center', width: 65,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '日预算', dataIndex: 'budget', label: '广告信息', align: 'center', width: 70, default: 12, sorter: true,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '投放时间', dataIndex: 'scheduleTime', label: '广告信息', align: 'center', width: 135, default: 13,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                }
+            ]
+        },
+        {
+            label: '消耗',
+            data: [
+                {
+                    title: '今日消耗', dataIndex: 'todayCost', label: '消耗', align: 'center', width: 85, sorter: true, default: 14,
+                    render: (a: any) => <Statistic valueStyle={{ fontWeight: 'bold', fontSize: 14 }} value={a || 0} />
+                },
+                {
+                    title: '总消耗', dataIndex: 'promotionTotalCost', label: '消耗', align: 'center', width: 100, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                }
+            ]
+        },
+        {
+            label: '广告媒体端数据',
+            data: [
+                {
+                    title: '曝光量', dataIndex: 'showCount', label: '广告媒体端数据', align: 'center', width: 60, sorter: true, default: 15, className: "adDataBackColorClass",
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '千次曝光成本', dataIndex: 'thousandDisplayPrice', label: '广告媒体端数据', align: 'center', width: 70, sorter: true, className: "adDataBackColorClass", default: 17,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '点击量', dataIndex: 'clickCount', label: '广告媒体端数据', align: 'center', width: 60, sorter: true, className: "adDataBackColorClass", default: 16,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '点击均价', dataIndex: 'avgClickCost', label: '广告媒体端数据', align: 'center', width: 60, sorter: true, className: "adDataBackColorClass", default: 18,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '点击率', dataIndex: 'ctr', label: '广告媒体端数据', align: 'center', width: 70, sorter: true, className: "adDataBackColorClass", default: 19,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '转化目标', dataIndex: 'convertTarget', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 70,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '转化目标量', dataIndex: 'convertCount', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 60, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '转化目标成本', dataIndex: 'convertCost', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} valueStyle={a > 700 ? { color: 'red', fontWeight: 'bold' } : {}} />
+                },
+                {
+                    title: '目标转化率', dataIndex: 'convertRate', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 60, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏注册人数', dataIndex: 'miniGameRegisterUsers', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 80, sorter: true, default: 20,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册成本', dataIndex: 'miniGameRegisterCost', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 80, sorter: true, default: 21,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册率', dataIndex: 'miniGameRegisterRate', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 95, sorter: true, default: 22,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏付费次数', dataIndex: 'miniGamePayingCount', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 80, sorter: true, default: 23,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏付费金额', dataIndex: 'miniGamePayingAmount', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true, default: 24,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏首日付费人数', dataIndex: 'miniGamePayingUsersD1', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true, default: 25,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏首日付费金额', dataIndex: 'miniGamePayingAmountD1', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true, default: 26,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏3日付费金额', dataIndex: 'miniGamePayingAmountD3', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true, default: 27,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏7日付费金额', dataIndex: 'miniGamePayingAmountD7', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏14日付费金额', dataIndex: 'miniGamePayingAmountD14', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏30日付费金额', dataIndex: 'miniGamePayingAmountD30', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏首次付费人数', dataIndex: 'miniGameFirstPayingUsers', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏首日付费ROI', dataIndex: 'miniGameFirstDayPayingRoi', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏付费ROI', dataIndex: 'miniGamePayingRoi', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏付费ARPU', dataIndex: 'miniGamePayingArpu', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏3日付费ROI', dataIndex: 'miniGamePayD3Roi', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏7日付费ROI', dataIndex: 'miniGamePayD7Roi', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏14日付费ROI', dataIndex: 'miniGamePayD14Roi', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏30日付费ROI', dataIndex: 'miniGamePayD30Roi', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏首日付费次数', dataIndex: 'minigame1dPayCount', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏首24小时付费人数', dataIndex: 'minigame24hPayUv', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏首24小时付费金额', dataIndex: 'minigame24hPayAmount', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏首24小时付费ROI', dataIndex: 'minigame24hPayRoi', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏首24小时付费ARPU', dataIndex: 'minigame24hPayArpu', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: 'ltv1(实际数据) ', dataIndex: 'ltvDay1ActualData', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 70, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: 'ltv1(广告)', dataIndex: 'ltvDay1', label: '广告媒体端数据', align: 'center', width: 60, sorter: true, className: 'adDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                }
+            ]
+        },
+        {
+            label: '用户数据',
+            data: [
+                {
+                    title: '注册人数',
+                    tips: '新增用户数(首次注册用户)',
+                    dataIndex: 'regNum',
+                    label: '用户数据',
+                    align: 'center',
+                    width: 70,
+                    sorter: true,
+                    default: 32,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总注册人数', dataIndex: 'regTotalNum', label: '用户数据', align: 'center', width: 70, tips: '广告的总注册人数', sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日创角人数', dataIndex: 'firstRoleNum', label: '用户数据', align: 'center', width: 60, sorter: true, default: 34,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '新用户累计创角人数', dataIndex: 'newUserTotalRoleNum', label: '用户数据', align: 'center', width: 70, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总创角人数', dataIndex: 'roleTotalNum', label: '用户数据', align: 'center', width: 60, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '注册成本', dataIndex: 'regCost', label: '用户数据', align: 'center', width: 70, sorter: true, default: 33,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总注册成本', dataIndex: 'regTotalCost', label: '用户数据', align: 'center', width: 70, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日创角成本', dataIndex: 'firstRoleCost', label: '用户数据', align: 'center', width: 70, sorter: true, default: 35,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '新用户创角成本', dataIndex: 'newUserTotalRoleCost', label: '用户数据', align: 'center', width: 65, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总创角成本', dataIndex: 'roleTotalCost', label: '用户数据', align: 'center', width: 60, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日创角率', dataIndex: 'firstRoleRate', label: '用户数据', align: 'center', width: 70, sorter: true, default: 36,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '新用户创角率', dataIndex: 'newUserTotalRoleRate', label: '用户数据', align: 'center', width: 70, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '总创角率', dataIndex: 'roleTotalRate', label: '用户数据', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+            ]
+        },
+        {
+            label: '付费数据',
+            data: [
+                {
+                    title: '首日充值次数', tips: "新增付费次数(首次注册并充值的总次数)", dataIndex: 'firstNewUserAmountCount', label: '付费数据', align: 'center', width: 80, sorter: true, className: 'payDataBackColorClass', default: 28,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日充值人数', tips: '新增付费人数(首次注册并充值人数)', dataIndex: 'firstNewUserAmountNum', label: '付费数据', align: 'center', width: 80, sorter: true, className: 'payDataBackColorClass', default: 29,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日充值金额', tips: '新增付费金额(首次注册并充值金额)', dataIndex: 'firstNewUserAmount', label: '付费数据', align: 'center', width: 90, sorter: true, className: 'payDataBackColorClass', default: 30,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费次数', dataIndex: 'newUserTotalAmountCount', label: '付费数据', align: 'center', width: 60, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费人数', dataIndex: 'newUserTotalAmountNum', label: '付费数据', align: 'center', width: 60, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费金额', dataIndex: 'newUserTotalAmount', label: '付费数据', align: 'center', width: 80, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '新用户24小时充值金额', dataIndex: 'twentyFourHoursAmount', label: '付费数据', align: 'center', width: 80, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总充值次数', dataIndex: 'totalAmountCount', label: '付费数据', align: 'center', width: 50, className: 'payDataBackColorClass', sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总充值人数', dataIndex: 'totalAmountNum', label: '付费数据', align: 'center', width: 50, className: 'payDataBackColorClass', sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总充值金额', dataIndex: 'totalAmount', label: '付费数据', align: 'center', width: 70, className: 'payDataBackColorClass', sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日ROI', dataIndex: 'firstRoi', label: '付费数据', align: 'center', width: 65, sorter: true, default: 37, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '24小时ROI', dataIndex: 'twentyFourHoursRoi', label: '付费数据', align: 'center', width: 70, sorter: true, default: 38, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '总ROI', dataIndex: 'totalRoi', label: '付费数据', align: 'center', width: 70, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '广告总ROI', dataIndex: 'promotionTotalRoi', label: '付费数据', align: 'center', width: 70, className: 'payDataBackColorClass', sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日充值成本', tips: '新增付费成本(首次注册并充值的用户成本)', dataIndex: 'firstNewUserRechargeCost', label: '付费数据', align: 'center', width: 80, sorter: true, default: 31, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费成本', dataIndex: 'newUserTotalRechargeCost', label: '付费数据', align: 'center', width: 70, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总付费成本', tips: '总付费成本(广告总付费用户成本)', dataIndex: 'totalRechargeCost', label: '付费数据', align: 'center', width: 70, className: 'payDataBackColorClass', sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日付费用户ARPPU', tips: '首日充值金额/首日充值人数', dataIndex: 'firstNewUserArppu', label: '付费数据', align: 'center', width: 70, sorter: true, default: 40, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费ARPPU', dataIndex: 'newUserTotalAmountArppu', label: '付费数据', align: 'center', width: 60, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日付费100+用户数', tips: '首次注册并在注册当天单笔充值金额大于100的用户人数', dataIndex: 'firstNewUserHundredUserNum', label: '付费数据', align: 'center', width: 90, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日付费100+用户付费成本', tips: '今日消耗/首日付费100+用户数', dataIndex: 'firstNewUserHundredUserCost', label: '付费数据', align: 'center', width: 95, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费100+用户付费成本', dataIndex: 'newUserTotalHundredUserCost', label: '付费数据', align: 'center', width: 85, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首充50~100元用户数', dataIndex: 'firstRechargeFiftyHundredNum', label: '付费数据', align: 'center', width: 80, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首充50~100元占比', dataIndex: 'firstRechargeFiftyHundredRate', label: '付费数据', align: 'center', width: 70, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日付费200+人数', tips: '首次注册并在注册当天单笔充值金额大于200的用户人数', dataIndex: 'firstNewUserTwoHundredUserNum', label: '付费数据', align: 'center', width: 90, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日付费200+用户付费成本', tips: '今日消耗/首日付费200+用户数', dataIndex: 'firstNewUserTwoHundredUserCost', label: '付费数据', align: 'center', width: 95, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费100+用户数', dataIndex: 'newUserTotalHundredUserNum', label: '付费数据', align: 'center', width: 80, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日IOS付费次数', dataIndex: 'firstIosAmountCount', label: '付费数据', align: 'center', width: 75, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日IOS付费人数', dataIndex: 'firstIosAmountNum', label: '付费数据', align: 'center', width: 75, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日IOS付费金额', dataIndex: 'firstIosAmount', label: '付费数据', align: 'center', width: 75, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日IOS付费人数占比', dataIndex: 'firstIosAmountNumRate', label: '付费数据', align: 'center', width: 75, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日IOS付费金额占比', dataIndex: 'firstIosAmountRate', label: '付费数据', align: 'center', width: 75, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日IOS付费ROI', dataIndex: 'firstIosAmountRoi', label: '付费数据', align: 'center', width: 75, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日Android付费次数', dataIndex: 'firstAndroidAmountCount', label: '付费数据', align: 'center', width: 78, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日Android付费人数', dataIndex: 'firstAndroidAmountNum', label: '付费数据', align: 'center', width: 78, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日Android付费金额', dataIndex: 'firstAndroidAmount', label: '付费数据', align: 'center', width: 78, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日Android付费人数占比', dataIndex: 'firstAndroidAmountNumRate', label: '付费数据', align: 'center', width: 95, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日Android付费金额占比', dataIndex: 'firstAndroidAmountRate', label: '付费数据', align: 'center', width: 95, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日Android付费ROI', dataIndex: 'firstAndroidAmountRoi', label: '付费数据', align: 'center', width: 80, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日付费率', dataIndex: 'firstAmountRate', label: '付费数据', align: 'center', width: 70, sorter: true, default: 39, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日客单价', tips: '首日客单价(数新增客单价)=首日新用户充值金额/首日新用户充值次', dataIndex: 'firstNewUserAvgPrice', label: '付费数据', align: 'center', width: 70, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今客单价', dataIndex: 'newUserTotalAvgPrice', label: '付费数据', align: 'center', width: 60, default: 41, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '每日扣单数', dataIndex: 'subOrderNum', label: '付费数据', align: 'center', width: 60, sorter: true, default: 42, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '每日扣单金额', dataIndex: 'subOrderAmount', label: '付费数据', align: 'center', width: 60, sorter: true, default: 43, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总充值次数成本', dataIndex: 'totalAmountCountCost', label: '付费数据', align: 'center', width: 70, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '新增付费次数成本', dataIndex: 'firstNewUserAmountCountCost', label: '付费数据', align: 'center', width: 70, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费次数成本', dataIndex: 'newUserTotalAmountCountCost', label: '付费数据', align: 'center', width: 70, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                ...date
+            ]
+        },
+        {
+            label: '操作',
+            data: [
+                // {
+                //     title: '操作', dataIndex: 'cz', label: '操作', align: 'center', width: 150, default: 42,
+                //     render: (_: number, b: any) => {
+                //         if (b?.accountName === '总计') return '--'
+                //         return <Space>
+                //             <a onClick={() => dayHandle(b)}>广告每日监控</a>
+                //             {
+                //                 b?.accountType === 'BYTE' ? <a onClick={() => {
+                //                     window.open(`https://ad.oceanengine.com/superior/promote-manage/ad?aadvid=${b?.accountId}&searchInput=%2522${b?.promotionId}%2522&searchType=%25229%2522`)
+                //                 }}>头条广告</a> : <a onClick={() => {
+                //                     window.open(`https://ad.qq.com/atlas/${b?.accountId}/admanage/adgroup?tab=adgroup&query={%22operation_status%22:[%22CALCULATE_STATUS_EXCLUDE_DEL%22],%22system_status%22:[],%22search_name%22:%22${b.promotionId}%22}`)
+                //                 }}>腾讯广告</a>
+                //             }
+                //         </Space>
+                //     }
+                // },
+                {
+                    title: '启停',
+                    dataIndex: 'configuredStatus', 
+                    label: '操作', 
+                    align: 'center', 
+                    width: 42, 
+                    default: 1,
+                    render: (a: string, b: any) => {
+                        if (b?.accountName === '总计') {
+                            return '--'
+                        }
+                        return <SwitchStatus configuredStatus={a} isDeleted={b?.dynamicCreativeIsDeleted == 1} accountId={b?.accountId} dynamicCreativeId={b?.dynamicCreativeId} onChange={onChange} />
+                    }
+                }
+            ]
+        }
+    ]
+}
+
+export default columns12

+ 598 - 0
src/pages/gameDataStatistics/dynamic/tencentMonitor/tableConfigDay.tsx

@@ -0,0 +1,598 @@
+import { TYPE, gameClassifyEnum } from "@/components/QueryForm/const"
+import WidthEllipsis from "@/components/widthEllipsis"
+import { Statistic } from "antd"
+import React from "react"
+import { ADSTATUSEnum, LANDINGTYPEEnum, PRICINGEnum } from './const'
+import './index.less'
+
+function columns12(): { label: string, fieldSHow?: { label: string, saveField: string, defaultValue: any[], data: any[] }, data: any[] }[] {
+
+    const data = [{ lable: '次日', value: 2 }, { lable: 'D3', value: 3 }, { lable: 'D7', value: 7 }, { lable: 'D15', value: 15 }]
+    let date = data.map(item => {
+        let field = `d${item.value}Trend`
+        return {
+            title: item.lable,
+            dataIndex: `D${item.value}`,
+            label: '付费数据',
+            align: 'center',
+            width: 85,
+            className: 'payDataBackColorClass',
+            children: [
+                {
+                    title: 'ROI',
+                    dataIndex: 'roi',
+                    key: 'roi',
+                    width: 60,
+                    align: 'center',
+                    render: (_: any, b: any) => {
+                        let data: any = {}
+                        if (b?.[field]) {
+                            data = b?.[field]
+                            return <Statistic value={data?.roi ? data?.roi * 100 : 0} precision={2} valueStyle={!data?.roi ? {} : data?.roi >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                        }
+                        return '--'
+                    }
+                },
+                {
+                    title: '付费',
+                    dataIndex: 'rechargeMoney',
+                    key: 'rechargeMoney',
+                    width: 60,
+                    align: 'center',
+                    render: (_: any, b: any) => {
+                        let data: any = {}
+                        if (b?.[field]) {
+                            data = b?.[field]
+                            return <Statistic value={data?.rechargeMoney || 0} />
+                        }
+                        return '--'
+                    }
+                },
+                {
+                    title: '倍数',
+                    dataIndex: 'multiples',
+                    key: 'multiples',
+                    width: 40,
+                    align: 'center',
+                    render: (_: any, b: any) => {
+                        let data: any = {}
+                        if (b?.[field]) {
+                            data = b?.[field]
+                            return <span>{data?.multiples || 0}</span>
+                        }
+                        return '--'
+                    }
+                },
+            ]
+        }
+    })
+
+    return [
+        {
+            label: '时间',
+            data: [
+                {
+                    title: '日期', dataIndex: 'dt', label: '时间', align: 'center', width: 100, default: 1,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                }
+            ]
+        },
+        {
+            label: '账户信息',
+            data: [
+                {
+                    title: '推广账号名称', dataIndex: 'accountName', label: '账户信息', align: 'center', width: 100, default: 2,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '推广账号ID', dataIndex: 'accountId', label: '账户信息', align: 'center', width: 120, default: 3,
+                    render: (a: string, b: any) => (<WidthEllipsis isCopy value={a} />)
+                },
+                {
+                    title: '备注', dataIndex: 'notes', label: '账户信息', align: 'center', width: 120,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '投手', dataIndex: 'pitcherName', label: '账户信息', align: 'center', width: 70,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '投放渠道', dataIndex: 'agentName', label: '账户信息', align: 'center', width: 75, default: 4,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '服务商', dataIndex: 'service', label: '账户信息', align: 'center', width: 95,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '投放媒体', dataIndex: 'accountType', label: '账户信息', align: 'center', width: 70,
+                    render: (a: string, b: any) => (<WidthEllipsis value={TYPE[a]} />)
+                },
+                {
+                    title: '余额', dataIndex: 'balance', label: '账户信息', align: 'center', width: 70, sorter: true,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                }
+            ]
+        },
+        {
+            label: '推广内容',
+            data: [
+                {
+                    title: '推广游戏名称', dataIndex: 'gameName', label: '推广内容', align: 'center', width: 70,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '推广游戏应用类型', dataIndex: 'classify', label: '推广内容', align: 'center', width: 95,
+                    render: (a: string) => (<span>{gameClassifyEnum[a]}</span>)
+                }
+            ]
+        },
+        {
+            label: '广告信息',
+            data: [
+                {
+                    title: '推广广告名称', dataIndex: 'promotionName', label: '广告信息', align: 'center', width: 130, default: 5,
+                    render: (a: string, b: any) => (<WidthEllipsis isCopy value={a} />)
+                },
+                {
+                    title: '广告ID', dataIndex: 'promotionId', label: '广告信息', align: 'center', width: 90, default: 6,
+                    render: (a: string, b: any) => (<WidthEllipsis isCopy value={a} />)
+                },
+                {
+                    title: '项目名称', dataIndex: 'projectName', label: '广告信息', align: 'center', width: 130,
+                    render: (a: string, b: any) => (<WidthEllipsis isCopy value={a} />)
+                },
+                {
+                    title: '项目ID', dataIndex: 'projectId', label: '广告信息', align: 'center', width: 90,
+                    render: (a: string, b: any) => (<WidthEllipsis isCopy value={a} />)
+                },
+                {
+                    title: '广告状态', dataIndex: 'status', label: '广告信息', align: 'left', width: 120, default: 7,
+                    render: (a: string, b: any) => (<WidthEllipsis value={ADSTATUSEnum[a]} />)
+                },
+                {
+                    title: '推广目标', dataIndex: 'landingType', label: '广告信息', align: 'center', width: 80,
+                    render: (a: string, b: any) => (<WidthEllipsis value={LANDINGTYPEEnum[a]} />)
+                },
+                {
+                    title: '出价方式', dataIndex: 'pricing', label: '广告信息', align: 'center', width: 100, default: 8,
+                    render: (a: string, b: any) => (<WidthEllipsis value={PRICINGEnum[a]} />)
+                },
+                {
+                    title: '当前出价', dataIndex: 'cpaBid', label: '广告信息', align: 'center', width: 70, default: 9,
+                    render: (a: any) => <Statistic value={a || '--'} />
+                },
+                {
+                    title: '深度转化ROI系数', dataIndex: 'roiGoal', label: '广告信息', align: 'center', width: 65, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '日预算', dataIndex: 'budget', label: '广告信息', align: 'center', width: 70, default: 10, sorter: true,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '投放时间', dataIndex: 'scheduleTime', label: '广告信息', align: 'center', width: 135, default: 11,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                }
+            ]
+        },
+        {
+            label: '消耗',
+            data: [
+                {
+                    title: '今日消耗', dataIndex: 'todayCost', label: '消耗', align: 'center', width: 85, sorter: true, default: 12,
+                    render: (a: any) => <Statistic valueStyle={{ fontWeight: 'bold', fontSize: 14 }} value={a || 0} />
+                },
+                {
+                    title: '总消耗', dataIndex: 'promotionTotalCost', label: '消耗', align: 'center', width: 100, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                }
+            ]
+        },
+        {
+            label: '广告媒体端数据',
+            data: [
+                {
+                    title: '曝光量', dataIndex: 'showCount', label: '广告媒体端数据', align: 'center', width: 60, sorter: true, default: 13, className: "adDataBackColorClass",
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '千次曝光成本', dataIndex: 'thousandDisplayPrice', label: '广告媒体端数据', align: 'center', width: 65, sorter: true, className: "adDataBackColorClass", default: 15,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '点击量', dataIndex: 'clickCount', label: '广告媒体端数据', align: 'center', width: 60, sorter: true, className: "adDataBackColorClass", default: 14,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '点击均价', dataIndex: 'avgClickCost', label: '广告媒体端数据', align: 'center', width: 60, sorter: true, className: "adDataBackColorClass", default: 16,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '点击率', dataIndex: 'ctr', label: '广告媒体端数据', align: 'center', width: 60, sorter: true, className: "adDataBackColorClass", default: 17,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '转化目标', dataIndex: 'convertTarget', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 70,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '转化目标量', dataIndex: 'convertCount', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 60, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '转化目标成本', dataIndex: 'convertCost', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} valueStyle={a > 700 ? { color: 'red', fontWeight: 'bold' } : {}} />
+                },
+                {
+                    title: '目标转化率', dataIndex: 'convertRate', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 60, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏注册人数', dataIndex: 'miniGameRegisterUsers', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 80, sorter: true, default: 18,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册成本', dataIndex: 'miniGameRegisterCost', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 80, sorter: true, default: 19,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册率', dataIndex: 'miniGameRegisterRate', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 80, sorter: true, default: 20,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏付费次数', dataIndex: 'miniGamePayingCount', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 80, sorter: true, default: 21,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏付费金额', dataIndex: 'miniGamePayingAmount', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true, default: 22,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏首日付费人数', dataIndex: 'miniGamePayingUsersD1', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true, default: 23,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏首日付费金额', dataIndex: 'miniGamePayingAmountD1', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true, default: 24,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏3日付费金额', dataIndex: 'miniGamePayingAmountD3', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true, default: 25,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏7日付费金额', dataIndex: 'miniGamePayingAmountD7', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏14日付费金额', dataIndex: 'miniGamePayingAmountD14', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏30日付费金额', dataIndex: 'miniGamePayingAmountD30', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏首次付费人数', dataIndex: 'miniGameFirstPayingUsers', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏首日付费ROI', dataIndex: 'miniGameFirstDayPayingRoi', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏付费ROI', dataIndex: 'miniGamePayingRoi', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏付费ARPU', dataIndex: 'miniGamePayingArpu', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏3日付费ROI', dataIndex: 'miniGamePayD3Roi', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏7日付费ROI', dataIndex: 'miniGamePayD7Roi', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏14日付费ROI', dataIndex: 'miniGamePayD14Roi', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏30日付费ROI', dataIndex: 'miniGamePayD30Roi', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏首日付费次数', dataIndex: 'minigame1dPayCount', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏首24小时付费人数', dataIndex: 'minigame24hPayUv', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏首24小时付费金额', dataIndex: 'minigame24hPayAmount', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏首24小时付费ROI', dataIndex: 'minigame24hPayRoi', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏首24小时付费ARPU', dataIndex: 'minigame24hPayArpu', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 85, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: 'ltv1(实际数据) ', dataIndex: 'ltvDay1ActualData', label: '广告媒体端数据', align: 'center', className: "adDataBackColorClass", width: 70, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: 'ltv1(广告)', dataIndex: 'ltvDay1', label: '广告媒体端数据', align: 'center', width: 60, sorter: true, className: 'adDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+            ]
+        },
+        {
+            label: '用户数据',
+            data: [
+                {
+                    title: '注册人数',
+                    tips: '新增用户数(首次注册用户)',
+                    dataIndex: 'regNum',
+                    label: '用户数据',
+                    align: 'center',
+                    width: 70,
+                    sorter: true,
+                    default: 30,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总注册人数', dataIndex: 'regTotalNum', label: '用户数据', align: 'center', width: 70, tips: '广告的总注册人数', sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日创角人数', dataIndex: 'firstRoleNum', label: '用户数据', align: 'center', width: 60, sorter: true, default: 32,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '新用户累计创角人数', dataIndex: 'newUserTotalRoleNum', label: '用户数据', align: 'center', width: 70, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总创角人数', dataIndex: 'roleTotalNum', label: '用户数据', align: 'center', width: 60, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '注册成本', dataIndex: 'regCost', label: '用户数据', align: 'center', width: 70, sorter: true, default: 31,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总注册成本', dataIndex: 'regTotalCost', label: '用户数据', align: 'center', width: 70, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日创角成本', dataIndex: 'firstRoleCost', label: '用户数据', align: 'center', width: 60, sorter: true, default: 33,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '新用户创角成本', dataIndex: 'newUserTotalRoleCost', label: '用户数据', align: 'center', width: 65, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总创角成本', dataIndex: 'roleTotalCost', label: '用户数据', align: 'center', width: 60, sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日创角率', dataIndex: 'firstRoleRate', label: '用户数据', align: 'center', width: 70, sorter: true, default: 34,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '新用户创角率', dataIndex: 'newUserTotalRoleRate', label: '用户数据', align: 'center', width: 70, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '总创角率', dataIndex: 'roleTotalRate', label: '用户数据', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+            ]
+        },
+        {
+            label: '付费数据',
+            data: [
+                {
+                    title: '首日充值次数', tips: "新增付费次数(首次注册并充值的总次数)", dataIndex: 'firstNewUserAmountCount', label: '付费数据', align: 'center', width: 80, sorter: true, className: 'payDataBackColorClass', default: 26,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日充值人数', tips: '新增付费人数(首次注册并充值人数)', dataIndex: 'firstNewUserAmountNum', label: '付费数据', align: 'center', width: 80, sorter: true, className: 'payDataBackColorClass', default: 27,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日充值金额', tips: '新增付费金额(首次注册并充值金额)', dataIndex: 'firstNewUserAmount', label: '付费数据', align: 'center', width: 90, sorter: true, className: 'payDataBackColorClass', default: 28,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费次数', dataIndex: 'newUserTotalAmountCount', label: '付费数据', align: 'center', width: 60, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费人数', dataIndex: 'newUserTotalAmountNum', label: '付费数据', align: 'center', width: 60, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费金额', dataIndex: 'newUserTotalAmount', label: '付费数据', align: 'center', width: 80, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '新用户24小时充值金额', dataIndex: 'twentyFourHoursAmount', label: '付费数据', align: 'center', width: 80, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总充值次数', dataIndex: 'totalAmountCount', label: '付费数据', align: 'center', width: 50, className: 'payDataBackColorClass', sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总充值人数', dataIndex: 'totalAmountNum', label: '付费数据', align: 'center', width: 50, className: 'payDataBackColorClass', sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总充值金额', dataIndex: 'totalAmount', label: '付费数据', align: 'center', width: 70, className: 'payDataBackColorClass', sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日ROI', dataIndex: 'firstRoi', label: '付费数据', align: 'center', width: 65, sorter: true, default: 35, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '24小时ROI', dataIndex: 'twentyFourHoursRoi', label: '付费数据', align: 'center', width: 70, sorter: true, default: 36, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '总ROI', dataIndex: 'totalRoi', label: '付费数据', align: 'center', width: 70, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '广告总ROI', dataIndex: 'promotionTotalRoi', label: '付费数据', align: 'center', width: 70, className: 'payDataBackColorClass', sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日充值成本', tips: '新增付费成本(首次注册并充值的用户成本)', dataIndex: 'firstNewUserRechargeCost', label: '付费数据', align: 'center', width: 80, sorter: true, default: 29, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费成本', dataIndex: 'newUserTotalRechargeCost', label: '付费数据', align: 'center', width: 70, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总付费成本', tips: '总付费成本(广告总付费用户成本)', dataIndex: 'totalRechargeCost', label: '付费数据', align: 'center', width: 70, className: 'payDataBackColorClass', sorter: true,
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日付费用户ARPPU', tips: '首日充值金额/首日充值人数', dataIndex: 'firstNewUserArppu', label: '付费数据', align: 'center', width: 70, sorter: true, default: 38, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费ARPPU', dataIndex: 'newUserTotalAmountArppu', label: '付费数据', align: 'center', width: 60, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日付费100+用户数', tips: '首次注册并在注册当天单笔充值金额大于100的用户人数', dataIndex: 'firstNewUserHundredUserNum', label: '付费数据', align: 'center', width: 90, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日付费100+用户付费成本', tips: '今日消耗/首日付费100+用户数', dataIndex: 'firstNewUserHundredUserCost', label: '付费数据', align: 'center', width: 95, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费100+用户付费成本', dataIndex: 'newUserTotalHundredUserCost', label: '付费数据', align: 'center', width: 85, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首充50~100元用户数', dataIndex: 'firstRechargeFiftyHundredNum', label: '付费数据', align: 'center', width: 80, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首充50~100元占比', dataIndex: 'firstRechargeFiftyHundredRate', label: '付费数据', align: 'center', width: 70, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日付费200+人数', tips: '首次注册并在注册当天单笔充值金额大于200的用户人数', dataIndex: 'firstNewUserTwoHundredUserNum', label: '付费数据', align: 'center', width: 90, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日付费200+用户付费成本', tips: '今日消耗/首日付费200+用户数', dataIndex: 'firstNewUserTwoHundredUserCost', label: '付费数据', align: 'center', width: 95, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费100+用户数', dataIndex: 'newUserTotalHundredUserNum', label: '付费数据', align: 'center', width: 80, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日IOS付费次数', dataIndex: 'firstIosAmountCount', label: '付费数据', align: 'center', width: 75, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日IOS付费人数', dataIndex: 'firstIosAmountNum', label: '付费数据', align: 'center', width: 75, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日IOS付费金额', dataIndex: 'firstIosAmount', label: '付费数据', align: 'center', width: 75, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日IOS付费人数占比', dataIndex: 'firstIosAmountNumRate', label: '付费数据', align: 'center', width: 75, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日IOS付费金额占比', dataIndex: 'firstIosAmountRate', label: '付费数据', align: 'center', width: 75, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日IOS付费ROI', dataIndex: 'firstIosAmountRoi', label: '付费数据', align: 'center', width: 75, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日Android付费次数', dataIndex: 'firstAndroidAmountCount', label: '付费数据', align: 'center', width: 78, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日Android付费人数', dataIndex: 'firstAndroidAmountNum', label: '付费数据', align: 'center', width: 78, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日Android付费金额', dataIndex: 'firstAndroidAmount', label: '付费数据', align: 'center', width: 78, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '首日Android付费人数占比', dataIndex: 'firstAndroidAmountNumRate', label: '付费数据', align: 'center', width: 95, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日Android付费金额占比', dataIndex: 'firstAndroidAmountRate', label: '付费数据', align: 'center', width: 95, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日Android付费ROI', dataIndex: 'firstAndroidAmountRoi', label: '付费数据', align: 'center', width: 80, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日付费率', dataIndex: 'firstAmountRate', label: '付费数据', align: 'center', width: 70, sorter: true, default: 37, className: 'payDataBackColorClass',
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 1 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '首日客单价', tips: '首日客单价(数新增客单价)=首日新用户充值金额/首日新用户充值次', dataIndex: 'firstNewUserAvgPrice', label: '付费数据', align: 'center', width: 70, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今客单价', dataIndex: 'newUserTotalAvgPrice', label: '付费数据', align: 'center', width: 60, sorter: true, default: 39, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '每日扣单数', dataIndex: 'subOrderNum', label: '付费数据', align: 'center', width: 60, sorter: true, default: 40, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '每日扣单金额', dataIndex: 'subOrderAmount', label: '付费数据', align: 'center', width: 60, sorter: true, default: 41, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '总充值次数成本', dataIndex: 'totalAmountCountCost', label: '付费数据', align: 'center', width: 70, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '新增付费次数成本', dataIndex: 'firstNewUserAmountCountCost', label: '付费数据', align: 'center', width: 70, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '至今付费次数成本', dataIndex: 'newUserTotalAmountCountCost', label: '付费数据', align: 'center', width: 70, sorter: true, className: 'payDataBackColorClass',
+                    render: (a: any) => <Statistic value={a || 0} />
+                },
+                ...date
+            ]
+        }
+    ]
+}
+
+export default columns12

+ 45 - 0
src/services/gameData/adlist.ts

@@ -25,6 +25,8 @@ export interface PromotionDataDay extends Paging, SortProps {
     promotionName?: string, // 广告名称
     sourceSystem?: string,  // SDK来源
     status?: string     //广告状态
+    dynamicCreativeId?: number // 创意ID
+    dynamicCreativeName?: string // 创意名称
 }
 /**
  * 头条广告监控数据
@@ -100,6 +102,33 @@ export async function getPromotionDataTencentTotalApi(data: PromotionDataDay) {
     });
 }
 
+
+/**
+ * 腾讯广告监控数据
+ * @param data 
+ * @returns 
+ */
+export async function getDynamicTencentListApi(data: PromotionDataDay) {
+    return request(wapi + `/creativeData/tencent/day`, {
+        method: 'POST',
+        data
+    });
+}
+
+
+/**
+ * 腾讯广告监控数据总计
+ * @param data 
+ * @returns 
+ */
+export async function getDynamicTencentTotalApi(data: PromotionDataDay) {
+    return request(wapi + `/creativeData/tencent/total`, {
+        method: 'POST',
+        data
+    });
+}
+
+
 /**
  * 腾讯广告每日监控
  * @param data 
@@ -174,6 +203,22 @@ export async function newEditAdqAdgroupsDataApi(data: EditAdqAdgroupsProps) {
     });
 }
 
+export interface ModifyStatusBatchProps {
+    accountAdgroupMaps: string[]
+    suspend: boolean
+}
+/**
+ * 批量修改创意信息
+ * @param data 
+ * @returns 
+ */
+export async function updateBatchDynamicCreativesInfoApi(data: ModifyStatusBatchProps) {
+    return request(api + '/adq/adgroup/updateBatchDynamicCreativesInfo', {
+        method: 'PUT',
+        data
+    });
+}
+
 export interface EditTTAdgroupsProps {
     suspend: boolean
     accountAdgroupMaps: string[] // "广告id和广告账号id的映射关系字符串 (逗号拼接)"