wjx il y a 7 mois
Parent
commit
61a9c533cb
40 fichiers modifiés avec 2606 ajouts et 271 suppressions
  1. 1 1
      config/config.ts
  2. 1 1
      config/defaultSettings.ts
  3. 2 1
      config/proxy.ts
  4. 30 5
      config/routerConfig.ts
  5. BIN
      public/image/play.png
  6. 10 1
      src/Hook/useAjax.tsx
  7. 2 2
      src/components/CustomList/index.tsx
  8. 2 2
      src/components/Expression/index.tsx
  9. 2 2
      src/components/QueryForm/index.tsx
  10. 30 6
      src/components/RightContent/index.tsx
  11. 124 0
      src/pages/iaaData/components/CreativePreview/cpTableConfig.tsx
  12. 100 0
      src/pages/iaaData/components/CreativePreview/index.less
  13. 111 0
      src/pages/iaaData/components/CreativePreview/index.tsx
  14. 42 0
      src/pages/iaaData/components/newsModal/index.less
  15. 3 0
      src/pages/iaaData/components/newsModal/index1.less
  16. 41 0
      src/pages/iaaData/components/newsModal/videoNews.tsx
  17. 37 0
      src/pages/iaaData/const.ts
  18. 49 0
      src/pages/iaaData/tencentIaa/adList/const.tsx
  19. 94 0
      src/pages/iaaData/tencentIaa/adList/dayAd.tsx
  20. 0 0
      src/pages/iaaData/tencentIaa/adList/index.less
  21. 214 0
      src/pages/iaaData/tencentIaa/adList/index.tsx
  22. 40 0
      src/pages/iaaData/tencentIaa/adList/switchStatus.tsx
  23. 440 0
      src/pages/iaaData/tencentIaa/adList/tableConfig.tsx
  24. 35 39
      src/pages/iaaData/tencentIaa/adList/tableConfigDay.tsx
  25. 98 0
      src/pages/iaaData/tencentIaa/appEveryDayData/index.tsx
  26. 425 0
      src/pages/iaaData/tencentIaa/appEveryDayData/tableConfig.tsx
  27. 100 0
      src/pages/iaaData/tencentIaa/pitcherEveryDay/index.tsx
  28. 276 0
      src/pages/iaaData/tencentIaa/pitcherEveryDay/tableConfig.tsx
  29. 0 15
      src/pages/iaaData/tencentIaaAd/const.ts
  30. 0 122
      src/pages/iaaData/tencentIaaAd/index.tsx
  31. 0 3
      src/pages/iaaSystem/manage/backPolicy/modalBackPolicy.tsx
  32. 0 6
      src/pages/iaaSystem/manage/backPolicy/tableConfig.tsx
  33. 4 0
      src/pages/iaaSystem/manage/channel/index.tsx
  34. 2 2
      src/pages/iaaSystem/manage/channel/modalChannel.tsx
  35. 36 0
      src/pages/iaaSystem/manage/useApp/index.tsx
  36. 36 0
      src/pages/iaaSystem/manage/useApp/tableConfig.tsx
  37. 2 2
      src/pages/user/login/index.tsx
  38. 52 0
      src/services/gameData/index.ts
  39. 79 0
      src/services/iaaData/index.ts
  40. 86 61
      src/utils/utils.ts

+ 1 - 1
config/config.ts

@@ -19,7 +19,7 @@ export default defineConfig({
     hmr: true,
   },
   layout: {
-    name: 'IAA应用系统',
+    name: '趣程集团IAA业务应用数据系统',
     locale: false,
     siderWidth: 208,
   },

+ 1 - 1
config/defaultSettings.ts

@@ -13,7 +13,7 @@ export default {
   menu: {
     locale: false,
   },
-  title: 'IAA应用系统',
+  title: '趣程集团IAA系统',
   pwa: false,
   iconfontUrl: '',
 } as LayoutSettings & {

+ 2 - 1
config/proxy.ts

@@ -10,7 +10,8 @@
  export default {
   dev: {
     '/api/': {
-      target: 'https://api.zanxiangwl.com',
+      target: 'http://api.zanxiangwl.com',
+      // target: 'https://testapi.zanxiangwl.com',
       changeOrigin: true,
       pathRewrite: { '/api': '' },
     },

+ 30 - 5
config/routerConfig.ts

@@ -92,6 +92,12 @@ const iaaSystem = {
             name: 'IAA后台管理',
             access: 'manage',
             routes: [
+                {
+                    path: '/iaaSystem/manage/useApp',
+                    name: '应用管理',
+                    access: 'useApp',
+                    component: './iaaSystem/manage/useApp',
+                },
                 {
                     path: '/iaaSystem/manage/power',
                     name: '角色分配',
@@ -125,11 +131,30 @@ const iaaData = {
     path: '/iaaData',
     routes: [
         {
-            path: '/iaaData/tencentIaaAd',
-            name: '腾讯广告列表',
-            access: 'tencentIaaAd',
-            component: './iaaData/tencentIaaAd',
-        },
+            path: '/iaaData/tencentIaa',
+            name: '腾讯',
+            access: 'tencentIaa',
+            routes: [
+                {
+                    path: '/iaaData/tencentIaa/adList',
+                    name: '广告列表',
+                    access: 'adList',
+                    component: './iaaData/tencentIaa/adList',
+                },
+                {
+                    path: '/iaaData/tencentIaa/appEveryDayData',
+                    name: '应用每日数据',
+                    access: 'appEveryDayData',
+                    component: './iaaData/tencentIaa/appEveryDayData',
+                },
+                {
+                    path: '/iaaData/tencentIaa/pitcherEveryDay',
+                    name: '投手每日数据',
+                    access: 'pitcherEveryDay',
+                    component: './iaaData/tencentIaa/pitcherEveryDay',
+                },
+            ]
+        }
     ]
 }
 

BIN
public/image/play.png


+ 10 - 1
src/Hook/useAjax.tsx

@@ -22,7 +22,7 @@ export interface AjaxPromise {
  * @returns data 请求结果数据
  * @returns initData 初始data
  * */
-export function useAjax(fnc: (params?: any) => Promise<any>, options?: { type: 'table' }): AjaxPromise {
+export function useAjax(fnc: (params?: any) => Promise<any>, options?: { type: 'table' | "noPage" }): AjaxPromise {
     // const {message}= App.useApp()
     const [loading, setLoding] = useState(false)//状态
     const [data, setData] = useState<any>()//数据
@@ -51,6 +51,15 @@ export function useAjax(fnc: (params?: any) => Promise<any>, options?: { type: '
                     success: res.success
                 }
             }
+            if(options?.type === 'noPage'){
+                return {
+                    current: 1,
+                    data: res.data,
+                    pageSize: 20,
+                    total: res.data.length,
+                    success: true
+                }
+            }
             return res//返回data
         }).catch(err => {
             console.log(err)

+ 2 - 2
src/components/CustomList/index.tsx

@@ -31,10 +31,10 @@ const SortableItem = SortableElement(({ item, del, setConfig }: any) => {
                     </div>
                 }
                 trigger="click"
-                visible={visible}
+                open={visible}
                 placement='left'
 
-                onVisibleChange={(visible) => { setVisible(visible) }}
+                onOpenChange={(visible) => { setVisible(visible) }}
             >
                 <Tooltip title='宽度设置'><a><ColumnWidthOutlined /></a></Tooltip>
             </Popover>

+ 2 - 2
src/components/Expression/index.tsx

@@ -68,8 +68,8 @@ function Expression(props: Props) {
                 </div>
             }
             trigger="click"
-            visible={isShow}
-            onVisibleChange={exit}
+            open={isShow}
+            onOpenChange={exit}
         >
             <MehOutlined onClick={exit} />
         </Popover>

+ 2 - 2
src/components/QueryForm/index.tsx

@@ -1,5 +1,5 @@
 import { useAjax } from "@/Hook/useAjax"
-import { AD_STATUS_ENUM, BID_MODE_ENUM } from "@/pages/iaaData/tencentIaaAd/const"
+import { AD_STATUS_ENUM, BID_MODE_ENUM } from "@/pages/iaaData/const"
 import { getAppListApi, getPutUserListApi } from "@/services/iaaData"
 import { Button, Col, Form, Row, Space, DatePicker, Select, Input, InputNumber } from "antd"
 import { RangePickerProps } from "antd/lib/date-picker"
@@ -96,7 +96,7 @@ const QueryForm: React.FC<Props> = (props) => {
                     showSearch
                     allowClear
                     mode="multiple"
-                    style={{ width: 120 }}
+                    style={{ minWidth: 120 }}
                     placeholder={'投手'}
                     filterOption={(input, option) =>
                         (option?.label as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0

+ 30 - 6
src/components/RightContent/index.tsx

@@ -21,16 +21,25 @@ const GlobalHeaderRight: React.FC<{}> = () => {
   if (!initialState || !initialState.settings) {
     return null;
   }
-  const [appList, setApplist] = useState<{ label: string, value: string }[]>([])
+  const [appList, setApplist] = useState<{ label: string, value: string, third: string; }[]>([])
   const getAppList = useAjax(() => getAppListApi())
+  const [productTypeList, setProductTypeList] = useState<{ label: string, value: string }[]>([])
+  const [productType, setProductType] = useState<string>()
 
   useEffect(() => {
     if (location.hash.includes('/iaaData')) {
       getAppList.run().then(res => {
         if (res?.data) {
-          let data: { label: string, value: string }[] = res.data.map((item: { second: any; first: string; third: string; }) => ({ label: item.second, value: item.first + '||' + item.third }))
-          let iaaApp = initialState?.iaaApp
-          setInitialState({ ...initialState, iaaApp: data.some(item => item.value === iaaApp) ? iaaApp : data?.[0].value || undefined as any })
+          const thirdSet = new Set();
+          let data: { label: string, value: string, third: string; }[] = res.data.map((item: { second: any; first: string; third: string; }) => {
+            thirdSet.add(item.third)
+            return { label: item.second, value: item.first + '||' + item.third, third: item.third }
+          })
+          setProductTypeList([{ label: '游戏业务', value: 'PRODUCT_TYPE_GAME' }, { label: '小说业务', value: 'PRODUCT_TYPE_NOVEL' }, { label: '短剧业务', value: 'PRODUCT_TYPE_PLAYLET' }].filter(item => [...thirdSet].includes(item.value)))
+          let app = initialState?.iaaApp
+          let iaaApp = data.some(item => item.value === app) ? app : data?.[0].value || undefined as any
+          setProductType(iaaApp ? iaaApp.split('||')?.[1] : undefined)
+          setInitialState({ ...initialState, iaaApp })
           setApplist(data)
         }
       })
@@ -116,7 +125,22 @@ const GlobalHeaderRight: React.FC<{}> = () => {
       {location.hash.includes('/iaaData') && <div style={{ left: left + 10, position: 'absolute' }}>
         <Select
           showSearch
-          style={{ width: 150 }}
+          style={{ width: 100 }}
+          placeholder={'请选择业务类型'}
+          filterOption={(input, option) =>
+            (option?.label as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
+          }
+          onChange={(type) => {
+            let newApplist = appList.filter(item => item.third === type)
+            setInitialState({ ...initialState, iaaApp: newApplist?.[0]?.value })
+            setProductType(type)
+          }}
+          value={productType}
+          options={productTypeList}
+        />
+        <Select
+          showSearch
+          style={{ width: 150, marginLeft: 10 }}
           placeholder={'请选择应用'}
           filterOption={(input, option) =>
             (option?.label as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
@@ -124,7 +148,7 @@ const GlobalHeaderRight: React.FC<{}> = () => {
           value={initialState?.iaaApp}
           onChange={(e) => setInitialState({ ...initialState, iaaApp: e })}
           loading={getAppList.loading}
-          options={appList}
+          options={appList.filter(item => item.third === productType)}
         />
       </div>}
 

+ 124 - 0
src/pages/iaaData/components/CreativePreview/cpTableConfig.tsx

@@ -0,0 +1,124 @@
+import React from "react"
+import { Space, Typography } from "antd"
+import style from './index.less'
+import VideoNews from "../newsModal/videoNews";
+
+const { Text, Title } = Typography;
+
+function cpTableConfig(): any {
+    return [
+        {
+            title: '品牌形象',
+            dataIndex: 'brand',
+            key: 'brand',
+            width: 120,
+            ellipsis: true,
+            render: (a: any[]) => {
+                return a?.length > 0 ? <Space>
+                    <img src={a?.[0]?.value?.brandImageUrl} height={18} />
+                    <span>{a?.[0]?.value?.brandName}</span>
+                </Space> : '--'
+            }
+        },
+        {
+            title: '创意素材',
+            dataIndex: 'dynamicGroup',
+            key: 'dynamicGroup',
+            width: 400,
+            ellipsis: true,
+            render: (_: any, b: any) => {
+                let deliveryMode = b?.deliveryMode
+                if (b?.image || b?.video || b?.shortVideo || b?.elementStory || b?.imageList) {
+                    if (deliveryMode === "DELIVERY_MODE_CUSTOMIZE") {
+                        return <>
+                            <div className={style.detail_body_m}>
+                                {(b?.video || b?.shortVideo) ? <>
+                                    <div className={style.video}>
+                                        <VideoNews src={b?.video?.[0]?.value?.videoUrl || b?.shortVideo?.[0]?.value?.videoUrl} coverUrl={b?.video?.[0]?.value?.coverUrl || b?.shortVideo?.[0]?.value?.coverUrl} />
+                                    </div>
+                                </> : b?.image ? <>
+                                    <div className={style.cover_image}>
+                                        <img src={b?.image?.[0]?.value?.imageUrl} />
+                                    </div>
+                                </> : (b?.elementStory || b?.imageList) ? <>
+                                    {b?.[b?.imageList ? 'imageList' : 'elementStory']?.[0]?.value?.list?.map((item: { imageUrl: string }, index: undefined) => <div className={style.cover_image} key={index} style={{ width: 30, height: 24, minWidth: 32 }}>
+                                        <img src={item?.imageUrl} />
+                                    </div>)}
+                                </> : null}
+                            </div>
+                        </>
+                    } else {
+                        return <div style={{ display: 'flex', gap: 5, flexWrap: 'wrap' }}>
+                            {b?.imageList && b?.imageList.map((item: any, index: number) => {
+                                return <div className={style.boxList_body_item} key={'list' + index} style={{ width: 60, height: 60 }}>
+                                    <div className={style.content} style={{ width: 60, height: 60 }}>
+                                        {item?.value?.list?.map((u: { imageUrl: string }, i: number, data: any[]) => <img src={u?.imageUrl} key={i} style={{ width: data.length === 6 ? 9.999 : 14.999 }} />)}
+                                    </div>
+                                </div>
+                            })}
+                            {b?.video && b?.video.map((item: any, index: number) => {
+                                return <div className={style.boxList_body_item} key={'video' + index} style={{ width: 60, height: 60 }}>
+                                    <div className={style.content} style={{ width: 60, height: 60 }}>
+                                        <VideoNews src={item?.value?.videoUrl} coverUrl={b?.video?.[0]?.value?.coverUrl || b?.shortVideo?.[0]?.value?.coverUrl} style={{ width: 60, height: 60 }} maskBodyStyle={{ backgroundColor: "rgba(242, 246, 254, 0.1)" }} />
+                                    </div>
+                                </div>
+                            })}
+                            {b?.image && b?.image.map((item: any, index: number) => {
+                                return <div className={style.boxList_body_item} key={'image' + index} style={{ width: 60, height: 60 }}>
+                                    <div className={style.content} style={{ width: 60, height: 60 }}><img src={item?.value?.imageUrl} /></div>
+                                </div>
+                            })}
+                        </div>
+                    }
+                } else {
+                    return <Text style={{ fontSize: 12 }}>无需配置</Text>
+                }
+            }
+        },
+        {
+            title: '创意文案',
+            dataIndex: 'description',
+            key: 'description',
+            width: 200,
+            render: (a: any[] = [], b: any) => {
+                let title: any[] = b?.title || []
+                if (a?.length || title?.length) {
+                    return <div className={style.detail_body} style={{ height: 'auto' }}>
+                        {title?.length > 0 && <div>
+                            <Title level={5} style={{ fontSize: 12 }}>{'标题'}</Title>
+                            {title.map((t: any, index: number) => <div className={style.text} key={index}><Text ellipsis={{ tooltip: true }}>{t?.value?.content}</Text></div>)}
+                        </div>}
+                        {a?.length > 0 && <div>
+                            <Title level={5} style={{ fontSize: 12 }}>{'描述'}</Title>
+                            {a.map((t: any, index: number) => <div className={style.text} key={index}><Text ellipsis={{ tooltip: true }}>{t?.value?.content}</Text></div>)}
+                        </div>}
+                    </div>
+                } else {
+                    return '--'
+                }
+            }
+        },
+        
+        // {
+        //     title: '轮播',
+        //     dataIndex: 'floatingZone',
+        //     key: 'floatingZone',
+        //     width: 150,
+        //     ellipsis: true,
+        //     render: (a: any[]) => {
+        //         return a?.length > 0 ? <div className='tableScrollbar' style={{ overflow: 'hidden', overflowX: 'auto' }}>
+        //             {a?.map((item, index) => <div key={index} style={{ display: 'flex', alignItems: 'center', gap: 1 }}>
+        //                 <div style={{ width: 40 }}>
+        //                     <Image src={item?.value?.floatingZoneImageUrl} width={40} height={40} />
+        //                 </div>
+        //                 <div>
+        //                     <span>{item?.value?.floatingZoneName}</span><br />
+        //                     <span>{item?.value?.floatingZoneDesc}</span>
+        //                 </div>
+        //             </div>)}
+        //         </div> : '--'
+        //     }
+        // },
+    ]
+}
+export default cpTableConfig

+ 100 - 0
src/pages/iaaData/components/CreativePreview/index.less

@@ -0,0 +1,100 @@
+.creativePreview {
+    .ant-table-pagination.ant-pagination {
+        margin: 0;
+    }
+}
+
+.detail_body_m {
+    display: flex;
+    // flex-direction: column;
+    flex-wrap: wrap;
+    row-gap: 10px;
+
+    >div {
+        min-width: 90px;
+    }
+
+    .video {
+        display: flex;
+        justify-content: space-between;
+        padding-right: 15px;
+
+        >div {
+            max-width: 80px;
+            max-height: 60px;
+
+            img {
+                max-width: 80px;
+                max-height: 60px;
+            }
+        }
+    }
+
+    .imageList {
+        display: flex;
+        gap: 6px;
+    }
+
+    .cover_image {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        background-color: #e6e6e6;
+        border-radius: 6px;
+        width: 80px;
+        height: 60px;
+        overflow: hidden;
+
+        >img {
+            max-width: 96%;
+            max-height: 96%;
+        }
+    }
+}
+
+.boxList_body_item {
+    border: 1px solid #e6e8ed;
+    border-radius: 6px;
+    background-color: rgb(242, 246, 254);
+    position: relative;
+
+    .content {
+        width: 100px;
+        height: 100px;
+        overflow: hidden;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        flex-wrap: wrap;
+
+        >img {
+            max-width: 100%;
+            max-height: 100%;
+        }
+    }
+
+    .tag {
+        position: absolute;
+        top: 4px;
+        left: 4px;
+        padding: 0 3px;
+        border-radius: 3px;
+        background: rgba(255, 255, 255, 0.8);
+        color: rgb(98, 99, 102);
+        font-size: 12px;
+    }
+
+    .clear {
+        position: absolute;
+        top: -9px;
+        right: -6px;
+        color: red;
+        cursor: pointer;
+        opacity: 0;
+        transition: opacity ease-out .1s;
+    }
+
+    &:hover .clear {
+        opacity: 1;
+    }
+}

+ 111 - 0
src/pages/iaaData/components/CreativePreview/index.tsx

@@ -0,0 +1,111 @@
+import { Popover, Space, Table } from "antd"
+import React from "react"
+import './index.less'
+import cpTableConfig from "./cpTableConfig"
+
+interface Props {
+    deliveryMode: string[]
+    creativePreview: {
+        brand?: {
+            value: {
+                brandName: string,
+                brandImageUrl: string
+            }
+        }[],
+        title?: {
+            value: {
+                content: string
+            }
+        }[],
+        description?: {
+            value: {
+                content: string
+            }
+        }[],
+        video?: {
+            value: {
+                videoUrl: string
+            }
+        }[],
+        shortVideo?: {
+            value: {
+                videoUrl: string
+            }
+        }[],
+        image?: {
+            value: {
+                imageUrl: string
+            }
+        }[],
+        elementStory?: {
+            value: {
+                list: {
+                    imageUrl: string
+                }[]
+            }
+        }[],
+        imageList?: {
+            value: {
+                list: {
+                    imageUrl: string
+                }[]
+            }
+        }[]
+    }[]
+}
+
+/**
+ * 创意预览
+ * @param param0 
+ * @returns 
+ */
+const CreativePreview: React.FC<Props> = ({ creativePreview, deliveryMode }) => {
+
+    /***************************/
+    let video = creativePreview?.[0]?.video?.[0]?.value?.videoUrl
+    let imageUrl = creativePreview?.[0]?.image?.[0]?.value?.imageUrl
+    if (!imageUrl && creativePreview?.[0]?.elementStory) {
+        imageUrl = creativePreview?.[0]?.elementStory?.[0]?.value?.list?.[0]?.imageUrl
+    }
+    if (!imageUrl && creativePreview?.[0]?.imageList) {
+        imageUrl = creativePreview?.[0]?.imageList?.[0]?.value?.list?.[0]?.imageUrl
+    }
+    if (!video && !imageUrl && creativePreview?.[0]?.shortVideo) {
+        video = creativePreview?.[0]?.shortVideo?.[0]?.value?.videoUrl
+    }
+    let titles = creativePreview?.[0]?.brand
+    let descriptions = creativePreview?.[0]?.description
+    let title = creativePreview?.[0]?.title
+    /***************************/
+
+    return <>
+        <Popover
+            content={<div style={{ width: 600, height: creativePreview.length > 10 ? 450 : 'auto' }}>
+                <Table
+                    bordered
+                    columns={cpTableConfig()}
+                    dataSource={creativePreview?.map((item, index) => ({ ...item, deliveryMode: deliveryMode[index], id: index + 1 }))}
+                    scroll={{ y: 380 }}
+                    rowKey={'id'}
+                    size="small"
+                    className="creativePreview"
+                />
+            </div>}
+            mouseEnterDelay={0.5}
+            destroyTooltipOnHide={true}
+            placement="left"
+            zIndex={10}
+        >
+            <div>
+                {video ? <video src={video} style={{ maxHeight: 18, maxWidth: 25 }} /> : imageUrl ? <div>
+                    {imageUrl ? <img src={imageUrl} height={18} /> : <span>无图片地址</span>}
+                </div> : (titles && titles?.length > 0) ? <Space>
+                    <img src={titles?.[0]?.value?.brandImageUrl} height={18} />
+                    <span>{titles?.[0]?.value?.brandName}</span>
+                </Space> : (title && title?.length > 0) ? <span>{title?.[0]?.value?.content}</span> : (descriptions && descriptions?.length > 0) ? <span>{descriptions?.[0]?.value?.content}</span> : <span>没有素材</span>}
+            </div>
+        </Popover>
+    </>
+}
+
+export default React.memo(CreativePreview)

+ 42 - 0
src/pages/iaaData/components/newsModal/index.less

@@ -0,0 +1,42 @@
+.imgNews {
+    display: inline-block;
+    overflow: hidden;
+    position: relative;
+    border-radius: 6px;
+
+    &>div {
+        .img {
+            width: 130px;
+            height: 100px;
+            cursor: pointer;
+            object-fit: contain;
+        }
+    }
+
+    .mask {
+        position: absolute;
+        width: 100%;
+        height: 100%;
+        top: 0;
+        left: 0;
+        background-color: rgba(0, 0, 0, .1);
+        display: flex;
+        justify-content: center;
+        align-items: center;
+
+        &>img {
+            width: 20px;
+            height: 20px;
+            display: inline-block;
+            cursor: pointer;
+        }
+    }
+}
+
+.video {
+    width: 100%;
+    max-width: 320px;
+    max-height: 600px;
+    display: block;
+    margin: auto;
+}

+ 3 - 0
src/pages/iaaData/components/newsModal/index1.less

@@ -0,0 +1,3 @@
+.imgNews .ant-image {
+    display: block;
+}

+ 41 - 0
src/pages/iaaData/components/newsModal/videoNews.tsx

@@ -0,0 +1,41 @@
+import React, { useState } from "react"
+import style from './index.less'
+import { Image, ImageProps, Modal } from 'antd'
+import play from "../../../../../public/image/play.png"
+import { CloseOutlined } from '@ant-design/icons';
+import './index1.less'
+import { getVideoImgUrl } from "@/utils/utils";
+
+interface Props extends ImageProps {
+    coverUrl?: string
+    maskBodyStyle?: React.CSSProperties
+    maskImgStyle?: React.CSSProperties
+}
+
+const VideoNews: React.FC<Props> = ({ preview = false, src, coverUrl, maskBodyStyle, maskImgStyle, ...data }) => {
+
+    /*****************************/
+    const [toPlay, setToPlay] = useState<boolean>(false)
+    /*****************************/
+
+    return <>
+        <div className={`${style.imgNews} imgNews`}>
+            <Image src={coverUrl ? coverUrl : src ? getVideoImgUrl(src) : 'error'} preview={false} {...data} className={style.img} />
+            <div className={style.mask} style={maskBodyStyle}>
+                <img src={play} style={maskImgStyle} onClick={(e) => { e.stopPropagation(); e.preventDefault(); setToPlay(true) }} />
+            </div>
+        </div>
+        {toPlay && <Modal
+            open={toPlay}
+            bodyStyle={{ backgroundColor: 'rgba(0,0,0,0.8)', overflow: 'hidden', borderRadius: 6 }}
+            footer={null}
+            closeIcon={<CloseOutlined style={{ color: '#FFF' }} />}
+            onCancel={(e) => { e.stopPropagation(); setToPlay(false) }}
+            zIndex={20}
+        >
+            <video className={style.video} style={{ borderRadius: 6 }} src={src} autoPlay controls>您的浏览器不支持 video 标签。</video>
+        </Modal>}
+    </>
+}
+
+export default React.memo(VideoNews)

+ 37 - 0
src/pages/iaaData/const.ts

@@ -0,0 +1,37 @@
+
+/** 出价方式 */
+export enum BID_MODE_ENUM {
+	BID_MODE_OCPM = 'oCPM',
+	BID_MODE_CPM = 'CPM',
+	BID_MODE_CPC = 'CPC',
+	BID_MODE_CPA = 'CPA',
+	BID_MODE_OCPC = 'oCPC',
+}
+
+/**广告状态*/
+export enum AD_STATUS_ENUM {
+	ADGROUP_STATUS_FROZEN = '已冻结',
+	ADGROUP_STATUS_SUSPEND = '暂停中',
+	ADGROUP_STATUS_NOT_IN_DELIVERY_TIME = '广告未到投放时间',
+	ADGROUP_STATUS_ACTIVE = '投放中',
+	ADGROUP_STATUS_DELETED = '已删除',
+	ADGROUP_STATUS_ACCOUNT_BALANCE_NOT_ENOUGH = '账户余额不足',
+	ADGROUP_STATUS_DAILY_BUDGET_REACHED = '广告达到日预算上限',
+	ADGROUP_STATUS_PARTIAL_ACTIVE = '部分投放中',
+	ADGROUP_STATUS_WECHAT_CHANNELS_STOP = '投放结束(直播结束)',
+	ADGROUP_STATUS_CREATIVE_STATUS_PENDING = '创意未投放',
+	ADGROUP_STATUS_CREATIVE_EMPTY = '创意准备中',
+	ADGROUP_STATUS_JOINT_BUDGET_REACHED = '广告被暂停(联合预算达上限)',
+	ADGROUP_STATUS_TOTAL_BUDGET_REACHED = '广告达到总预算上限',
+	ADGROUP_STATUS_PRE_LOCK = '待锁定预算',
+	ADGROUP_STATUS_UNLOCKING = '解锁预算中',
+	ADGROUP_STATUS_STOP = '投放结束',
+}
+
+
+/** 业务类型 */
+export enum PRODUCT_TYPE_ENUM {
+	PRODUCT_TYPE_GAME = '游戏业务',
+	PRODUCT_TYPE_NOVEL = '小说业务',
+	PRODUCT_TYPE_PLAYLET = '短剧业务',
+}

+ 49 - 0
src/pages/iaaData/tencentIaa/adList/const.tsx

@@ -0,0 +1,49 @@
+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>} />,
+}
+
+/** 出价方式 */
+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' = '快应用',
+}

+ 94 - 0
src/pages/iaaData/tencentIaa/adList/dayAd.tsx

@@ -0,0 +1,94 @@
+import { useAjax } from "@/Hook/useAjax"
+import { Button, Drawer } from "antd"
+import React, { useEffect, useState } from "react"
+import columns12 from './tableConfigDay'
+import QueryForm from "@/components/QueryForm"
+import { CloseOutlined } from "@ant-design/icons"
+import TablePro from "@/components/TablePro"
+import moment from "moment"
+import { getGDTDailyListApi } from "@/services/iaaData"
+
+interface Props {
+    queryForm: {
+        costDayBegin?: string,
+        costDayEnd?: string
+    }
+    iaaApp: string,
+    adName: string,
+    promotionId?: number
+    onClose?: () => void
+    visible?: boolean
+}
+
+/**
+ * 广告每日监控
+ * @returns 
+ */
+const DayAd: React.FC<Props> = ({ iaaApp, adName, queryForm, promotionId, onClose, visible }) => {
+
+    /***********************************/
+    const [data, setData] = useState<{ pageSize: number, pageNum: number, sortFiled?: string, sortType?: string }>({ pageNum: 1, pageSize: 30 })
+    const [date, setDate] = useState<[string, string] | undefined>((queryForm?.costDayBegin && queryForm.costDayEnd) ? [queryForm.costDayBegin, queryForm.costDayEnd] : undefined)
+    const getGDTDailyList = useAjax((params) => getGDTDailyListApi(params))
+    /***********************************/
+
+    useEffect(() => {
+        let params: any = {}
+        const [appId, productType] = iaaApp.split('||')
+        if (promotionId) {
+            params.promotionId = promotionId
+        }
+        if (date && date?.length > 0) {
+            params.costDayBegin = date[0]
+            params.costDayEnd = date[1]
+        } else {
+            delete params?.costDayBegin
+            delete params?.costDayEnd
+        }
+        getGDTDailyList.run({ ...params, ...data, appId, productType })
+    }, [promotionId, queryForm, data, date, iaaApp])
+
+    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} open={visible}>
+        <TablePro
+            leftChild={<QueryForm
+                initialValues={{ day1: queryForm?.costDayBegin ? [moment(queryForm?.costDayBegin), moment(queryForm?.costDayEnd)] : null }}
+                onChange={(data: any) => {
+                    const { day1 } = data
+                    if (day1 && day1?.length === 2) {
+                        setDate([moment(day1[0]).format('YYYY-MM-DD'), moment(day1[1]).format('YYYY-MM-DD')])
+                    } else {
+                        setDate(undefined)
+                    }
+                }}
+                day1={{ placeholder: ['消耗日期开始', '消耗日期结束'] }}
+            />}
+            scroll={{ x: 1000, y: 600 }}
+            ajax={getGDTDailyList}
+            loading={getGDTDailyList.loading}
+            fixed={{ left: 3, right: 0 }}
+            dataSource={getGDTDailyList?.data?.data?.records?.map((item: any, index: number) => ({ ...item, id: Number(data.pageNum.toString() + index.toString()) }))}
+            page={getGDTDailyList?.data?.data?.current || 1}
+            pageSize={getGDTDailyList?.data?.data?.size || 20}
+            total={getGDTDailyList?.data?.data?.total || 0}
+            title='腾讯广告每日监控'
+            onChange={(pagination: any, _: any, sortData: any) => {
+                let { current, pageSize } = pagination
+                let newQueryForm = JSON.parse(JSON.stringify(data))
+                if (sortData && sortData?.order) {
+                    newQueryForm['sortAsc'] = sortData?.order === 'ascend' ? true : false
+                    newQueryForm['sortFiled'] = sortData?.field
+                } else {
+                    delete newQueryForm['sortAsc']
+                    delete newQueryForm['sortFiled']
+                }
+                newQueryForm.pageNum = current || newQueryForm.pageNum
+                newQueryForm.pageSize = pageSize || newQueryForm.pageSize
+                setData({ ...newQueryForm })
+            }}
+            config={columns12()}
+            configName={'腾讯广告每日监控'}
+        />
+    </Drawer>
+}
+
+export default React.memo(DayAd)

+ 0 - 0
src/pages/iaaData/tencentIaa/adList/index.less


+ 214 - 0
src/pages/iaaData/tencentIaa/adList/index.tsx

@@ -0,0 +1,214 @@
+import React, { useEffect, useState } from "react"
+import { useAjax } from "@/Hook/useAjax"
+import { getGDTListApi, GetGDTListProps, getGDTTotalApi } from "@/services/iaaData"
+import TablePro from "@/components/TablePro"
+import columns12 from "./tableConfig"
+import QueryForm from "@/components/QueryForm"
+import moment from "moment"
+import { useModel } from "umi"
+import { Button, message, notification, Space } from "antd"
+import { newEditAdqAdgroupsDataApi } from "@/services/gameData"
+import { PauseCircleOutlined, PlayCircleOutlined } from "@ant-design/icons"
+import DayAd from "./dayAd"
+
+/**
+ * 腾讯广告列表
+ * @returns 
+ */
+const TencentIaaAd: React.FC = () => {
+
+    /****************************************/
+    const { initialState } = useModel('@@initialState');
+    const [selectedRows, setSelectedRows] = useState<any[]>([])
+    const [queryForm, setQueryForm] = useState<GetGDTListProps>({
+        pageNum: 1,
+        pageSize: 30,
+        costDayBegin: moment().format('YYYY-MM-DD'),
+        costDayEnd: 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 editAdqAdgroupsData = useAjax((params) => newEditAdqAdgroupsDataApi(params))
+    const getGDTList = useAjax((params) => getGDTListApi(params))
+    const getGDTTotal = useAjax((params) => getGDTTotalApi(params))
+    /****************************************/
+
+    useEffect(() => {
+        if (initialState?.iaaApp) {
+            const [appId, productType] = initialState.iaaApp.split('||')
+            getGDTList.run({ ...queryForm, appId, productType })
+            getGDTTotal.run({ ...queryForm, appId, productType }).then((res: { data: { id: number; accountId: string } }) => {
+                if (res?.data) {
+                    let data = res?.data
+                    data.id = 1
+                    data.accountId = '总计'
+                    setTotalData([data])
+                } else {
+                    setTotalData([{ id: 1, accountId: '总计' }])
+                }
+            })
+        }
+
+    }, [queryForm, initialState?.iaaApp])
+
+    const dayHandle = (data: any) => {
+        setVisible(true)
+        setAdName(data.promotionName)
+        setPromotionId(data.promotionId)
+    }
+
+    // 批量启停
+    const adStatus = (type: 'play' | 'suspend') => {
+        let params: any = {}
+        if (type === 'play') {
+            params.configuredStatus = 'AD_STATUS_NORMAL'
+            params.adgroupIds = selectedRows.filter((item: { configuredStatus: string, promotionId: number }) => item.configuredStatus === 'AD_STATUS_SUSPEND').map(item => item.promotionId)
+        } else {
+            params.configuredStatus = 'AD_STATUS_SUSPEND'
+            params.adgroupIds = selectedRows.filter((item: { configuredStatus: string, promotionId: number }) => item.configuredStatus === 'AD_STATUS_NORMAL').map(item => item.promotionId)
+        }
+        if (params.adgroupIds.length === 0) {
+            message.warn(`所以账号都是${type === 'play' ? '启动' : '暂停'}状态,无需${type === 'play' ? '启动' : '暂停'}操作`)
+            return
+        }
+        editAdqAdgroupsData.run(params).then(res => {
+            message.success(`${type === 'play' ? '启动' : '暂停'}成功: ${res.success},失败: ${res.fail}`)//
+            if (res?.fail) {
+                notification.error({
+                    message: `${type === 'play' ? '启动' : '暂停'}失败`,
+                    description: `成功: ${res.success},修改失败${res.fail}条,失败的请到任务列表查看`,
+                    duration: 0
+                });
+            }
+            getGDTList.refresh()
+            setSelectedRows([])
+        })
+    }
+
+
+    return <div>
+        <TablePro
+            czChild={<Space>
+                {/* <Switch checkedChildren="开启全选" unCheckedChildren="关闭全选" checked={!isZj} onChange={(e) => { setIsZj(!e); }} /> */}
+                <Button type='primary' size="small" style={{ background: '#67c23a', borderColor: '#67c23a' }} loading={editAdqAdgroupsData.loading} icon={<PlayCircleOutlined />} disabled={selectedRows.length === 0} onClick={() => adStatus('play')}>启动</Button>
+                <Button type='primary' size="small" style={{ background: '#e6a23c', borderColor: '#e6a23c' }} loading={editAdqAdgroupsData.loading} icon={<PauseCircleOutlined />} disabled={selectedRows.length === 0} onClick={() => adStatus('suspend')}>暂停</Button>
+                <span style={{ color: 'red' }}>操作完数据结果延时5分钟之内,即时结果去腾讯后台查看</span>
+            </Space>}
+            leftChild={<QueryForm
+                initialValues={{ day3: [moment(), moment()] }}
+                isAccountId
+                isPromotionName
+                isPutUserIdList
+                isCpaBid
+                isDeleted
+                isPricing
+                isStatus
+                isPromotionId
+                day1={{ placeholder: ['广告创建日期开始', '广告创建日期结束'] }}
+                day2={{ placeholder: ['投放日期开始', '投放日期结束'] }}
+                day3={{ placeholder: ['消耗日期开始', '消耗日期结束'] }}
+                onChange={(data: any) => {
+                    console.log(data)
+                    const { day1, day2, day3, ...params } = data
+                    let newQueryForm = JSON.parse(JSON.stringify(queryForm))
+
+                    if (day1 && day1?.length === 2) {
+                        newQueryForm['adCreateBegin'] = moment(day1[0]).format('YYYY-MM-DD')
+                        newQueryForm['adCreateEnd'] = moment(day1[1]).format('YYYY-MM-DD')
+                    } else {
+                        delete newQueryForm['adCreateBegin']
+                        delete newQueryForm['adCreateEnd']
+                    }
+
+                    if (day2 && day2?.length === 2) {
+                        newQueryForm['putDayBegin'] = moment(day2[0]).format('YYYY-MM-DD')
+                        newQueryForm['putDayEnd'] = moment(day2[1]).format('YYYY-MM-DD')
+                    } else {
+                        delete newQueryForm['putDayBegin']
+                        delete newQueryForm['putDayEnd']
+                    }
+
+                    if (day3 && day3?.length === 2) {
+                        newQueryForm['costDayBegin'] = moment(day3[0]).format('YYYY-MM-DD')
+                        newQueryForm['costDayEnd'] = moment(day3[1]).format('YYYY-MM-DD')
+                    } else {
+                        delete newQueryForm['costDayBegin']
+                        delete newQueryForm['costDayEnd']
+                    }
+                    setQueryForm({ ...newQueryForm, ...params })
+                }}
+            />}
+            isZj
+            totalData={totalData}
+            config={columns12(dayHandle, () => { getGDTList.refresh() })}
+            configName={'腾讯广告列表'}
+            fixed={{ left: 4, right: 2 }}
+            scroll={{ x: 1000, y: 620 }}
+            title='腾讯广告列表'
+            loading={getGDTList.loading}
+            ajax={getGDTList}
+            page={getGDTList?.data?.data?.current || 1}
+            pageSize={getGDTList?.data?.data?.size || 20}
+            total={getGDTList?.data?.data?.total || 0}
+            dataSource={getGDTList?.data?.data?.records?.map((item: any, index: number) => ({ ...item, id: Number(queryForm.pageNum.toString() + (index + '')) }))}
+            onChange={(pagination: any, _: any, sortData: any) => {
+                let { current, pageSize } = pagination
+                let newQueryForm = JSON.parse(JSON.stringify(queryForm))
+                if (sortData && sortData?.order) {
+                    newQueryForm['sortAsc'] = sortData?.order === 'ascend' ? true : false
+                    newQueryForm['sortFiled'] = sortData?.field
+                } else {
+                    delete newQueryForm['sortAsc']
+                    delete newQueryForm['sortFiled']
+                }
+                newQueryForm.pageNum = current || newQueryForm.pageNum
+                newQueryForm.pageSize = pageSize || newQueryForm.pageSize
+                setQueryForm({ ...newQueryForm })
+            }}
+            rowSelection={{
+                selectedRowKeys: selectedRows.map(item => item.promotionId + ''),
+                getCheckboxProps: (record: any) => ({
+                    disabled: record.status === 'STATUS_DELETED' || record?.accountId === '总计'
+                }),
+                onSelect: (record: { promotionId: number }, selected: boolean) => {
+                    if (selected) {
+                        selectedRows.push({ ...record })
+                        setSelectedRows([...selectedRows])
+                    } else {
+                        let newSelectAccData = selectedRows.filter((item: { promotionId: number }) => item.promotionId !== record.promotionId)
+                        setSelectedRows([...newSelectAccData])
+                    }
+                },
+                onSelectAll: (selected: boolean, selectedRowss: { promotionId: number }[], changeRows: { promotionId: number }[]) => {
+                    if (selected) {
+                        let newSelectAccData = [...selectedRows]
+                        changeRows.forEach((item: { promotionId: number }) => {
+                            let index = newSelectAccData.findIndex((ite: { promotionId: number }) => ite.promotionId === item.promotionId)
+                            if (index === -1) {
+                                newSelectAccData.push({ ...item })
+                            }
+                        })
+                        setSelectedRows([...newSelectAccData])
+                    } else {
+                        let newSelectAccData = selectedRows.filter((item: { promotionId: number }) => {
+                            let index = changeRows.findIndex((ite: { promotionId: number }) => ite.promotionId === item.promotionId)
+                            if (index !== -1) {
+                                return false
+                            } else {
+                                return true
+                            }
+                        })
+                        setSelectedRows([...newSelectAccData])
+                    }
+                }
+            }}
+        />
+
+        {visible && <DayAd iaaApp={initialState?.iaaApp as string} adName={adName} visible={visible} onClose={() => { setVisible(false); setPromotionId(undefined) }} queryForm={queryForm} promotionId={promotionId} />}
+    </div>
+}
+
+export default TencentIaaAd

+ 40 - 0
src/pages/iaaData/tencentIaa/adList/switchStatus.tsx

@@ -0,0 +1,40 @@
+import { useAjax } from "@/Hook/useAjax"
+import { newEditAdqAdgroupsDataApi } from "@/services/gameData"
+import { message, notification, Switch } from "antd"
+import React from "react"
+
+
+
+/**
+ * 修改启停
+ */
+interface Props {
+    configuredStatus: string,
+    isDeleted?: boolean,
+    adgroupId: number,
+    onChange?: () => void
+}
+const SwitchStatus: React.FC<Props> = (prosp) => {
+
+    const { configuredStatus, isDeleted, adgroupId, onChange } = prosp
+    const editAdqAdgroupsData = useAjax((params) => newEditAdqAdgroupsDataApi(params))
+    
+    const switchHandle = (adgroupIds: number[], configuredStatus: string) => {
+        editAdqAdgroupsData.run({ adgroupIds, configuredStatus }).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={editAdqAdgroupsData.loading} disabled={isDeleted} onChange={(checked) => switchHandle([adgroupId] ,checked ? 'AD_STATUS_NORMAL' : 'AD_STATUS_SUSPEND')}/>
+}
+
+
+export default React.memo(SwitchStatus)

+ 440 - 0
src/pages/iaaData/tencentIaa/adList/tableConfig.tsx

@@ -0,0 +1,440 @@
+import WidthEllipsis from "@/components/widthEllipsis"
+import { Badge, Space, Statistic } from "antd"
+import React from "react"
+import { AD_STATUS_ENUM, BID_MODE_ENUM, PRODUCT_TYPE_ENUM } from "../../const"
+import SwitchStatus from "./switchStatus"
+import CreativePreview from "../../components/CreativePreview"
+
+function columns12(dayHandle: (data: any) => void, onChange?: () => void): { label: string, fieldSHow?: { label: string, saveField: string, defaultValue: any[], data: any[] }, data: any[] }[] {
+
+
+    return [
+        {
+            label: '腾讯广告列表',
+            data: [
+                {
+                    title: '广告账号', dataIndex: 'accountId', label: '腾讯广告列表', align: 'center', width: 80, default: 2,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '业务类型', dataIndex: 'productType', label: '腾讯广告列表', align: 'center', width: 80, default: 3,
+                    render: (a: string) => (<WidthEllipsis value={PRODUCT_TYPE_ENUM[a as keyof typeof PRODUCT_TYPE_ENUM]} />)
+                },
+                {
+                    title: '应用', dataIndex: 'appName', label: '腾讯广告列表', align: 'center', width: 100, default: 4,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '小程序ID', dataIndex: 'mpId', label: '腾讯广告列表', align: 'center', width: 100, default: 5,
+                    render: (a: string, b: any) => (<WidthEllipsis isCopy value={a} />)
+                },
+                {
+                    title: '投手', dataIndex: 'pitcherName', label: '腾讯广告列表', align: 'center', width: 60, default: 6,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '广告名称', dataIndex: 'promotionName', label: '腾讯广告列表', align: 'center', width: 120, default: 7,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '广告ID', dataIndex: 'promotionId', label: '腾讯广告列表', align: 'center', width: 90, default: 8,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '广告状态', dataIndex: 'status', label: '腾讯广告列表', align: 'center', width: 75, default: 9,
+                    render: (a: string) => (<WidthEllipsis value={AD_STATUS_ENUM[a as keyof typeof AD_STATUS_ENUM]} />)
+                },
+                {
+                    title: '服务商', dataIndex: 'service', label: '腾讯广告列表', align: 'center', width: 75, default: 10,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '余额', dataIndex: 'balance', label: '腾讯广告列表', align: 'right', width: 75, sorter: true, default: 11,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '出价方式', dataIndex: 'pricing', label: '腾讯广告列表', align: 'center', width: 70, default: 12,
+                    render: (a: string) => (<WidthEllipsis value={BID_MODE_ENUM[a as keyof typeof BID_MODE_ENUM]} />)
+                },
+                {
+                    title: '当前出价', dataIndex: 'cpaBid', label: '腾讯广告列表', align: 'center', width: 75, default: 13, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '深度转化ROI系数', dataIndex: 'roiGoal', label: '腾讯广告列表', align: 'right', width: 75, default: 14,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '广告日预算', dataIndex: 'budget', label: '腾讯广告列表', align: 'right', width: 75, default: 15, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '广告创建时间', dataIndex: 'adTime', label: '基本信息', align: 'center', width: 90, default: 16,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '广告已删除?', dataIndex: 'isDeleted', label: '基本信息', align: 'center', width: 50, default: 17,
+                    render: (a: number, b: any) => (b?.accountId === '总计' ? '--' : a === 1 ? <Badge status="error" text="是" /> : <Badge status="success" text="否" />)
+                },
+                {
+                    title: '投放日期', dataIndex: 'startTime', label: '基本信息', align: 'center', width: 180, default: 18,
+                    render: (a: string, b: any) => (<WidthEllipsis value={b?.accountId === '总计' ? '--' : `${a}-${b?.endTime}`} />)
+                },
+                {
+                    title: '消耗时间', dataIndex: 'dt', label: '基本信息', align: 'center', width: 90, default: 19,
+                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '今日消耗', dataIndex: 'cost', label: '腾讯广告列表', align: 'right', width: 70, default: 20, sorter: true,
+                    render: (a: string) => <Statistic style={{ fontWeight: 'bold' }} value={a || 0} />
+                },
+                {
+                    title: '广告总消耗', dataIndex: 'totalCost', label: '腾讯广告列表', align: 'right', width: 85, default: 21, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '点击量', dataIndex: 'validClickCount', label: '腾讯广告列表', align: 'center', width: 70, default: 22, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '点击率', dataIndex: 'ctr', label: '腾讯广告列表', align: 'center', width: 70, default: 23, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 50 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '曝光量', dataIndex: 'viewCount', label: '腾讯广告列表', align: 'center', width: 70, default: 24, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '千次曝光成本', dataIndex: 'thousandDisplayPrice', label: '腾讯广告列表', align: 'right', width: 65, default: 25, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '点击均价', dataIndex: 'cpc', label: '腾讯广告列表', align: 'center', width: 65, default: 26, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '转化目标', dataIndex: 'convertTarget', label: '基本信息', align: 'center', width: 65, default: 27, sorter: true,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '转化目标量', dataIndex: 'conversionsCount', label: '基本信息', align: 'center', width: 65, default: 28, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '转化目标成本', dataIndex: 'convertCost', label: '基本信息', align: 'center', width: 65, default: 29, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '转化目标率', dataIndex: 'convertRate', label: '腾讯广告列表', align: 'center', width: 70, default: 30, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 50 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏注册人数', dataIndex: 'miniGameRegisterUsers', label: '基本信息', align: 'center', width: 80, default: 31, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册成本', dataIndex: 'miniGameRegisterCost', label: '基本信息', align: 'center', width: 80, default: 32, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册率', dataIndex: 'miniGameRegisterRate', label: '腾讯广告列表', align: 'center', width: 75, default: 33, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 50 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '创意预览', dataIndex: 'dynamicCreativeVOList', label: '腾讯广告列表', width: 150, default: 34,
+                    render: (a: any, b: any) => {
+                        if (b?.accountId === '总计') {
+                            return '--'
+                        }
+                        if (a?.length) {
+                            let deliveryMode: string[] = []
+                            let creativePreview = a?.map((item: { creativeComponents: any, deliveryMode: string }) => {
+                                deliveryMode.push(item.deliveryMode)
+                                return { ...item?.creativeComponents }
+                            })
+                            return <CreativePreview creativePreview={creativePreview} deliveryMode={deliveryMode} />
+                        }
+                        return null
+                    }
+                }
+            ]
+        },
+        {
+            label: 'IAA补充指标',
+            data: [
+                {
+                    title: '首日ROI', dataIndex: 'firstRoi', label: 'IAA补充指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 50 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '24小时ROI', dataIndex: 'twentyFourHoursRoi', label: 'IAA补充指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 50 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '总ROI', dataIndex: 'totalRoi', label: 'IAA补充指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 50 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '广告总ROI', dataIndex: 'promotionTotalRoi', label: 'IAA补充指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 50 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                }
+            ]
+        },
+        {
+            label: '其他业务(平台上报指标)',
+            data: [
+                {
+                    title: '激活首24小时广告变现ARPPU(平台上报)', dataIndex: 'firstDayAdPurArppuCost24hPla', label: '其他业务(平台上报指标)', width: 130, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首24小时广告变现ROI(平台上报)', dataIndex: 'incomeRoi124hPla', label: '其他业务(平台上报指标)', width: 110, align: 'center', sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 50 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '激活首24小时广告变现次数(平台上报)', dataIndex: 'incomePv24hPla', label: '其他业务(平台上报指标)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首日广告变现次数(平台上报)', dataIndex: 'incomePv1dPla', label: '其他业务(平台上报指标)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活3日广告变现次数(平台上报)', dataIndex: 'adMonetizationPlaDedupActive3dPv', label: '其他业务(平台上报指标)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活7日广告变现次数(平台上报)', dataIndex: 'minigame7dIncomeCount', label: '其他业务(平台上报指标)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '注册3日广告变现次数(平台上报)', dataIndex: 'minigame3dIncomeCount', label: '其他业务(平台上报指标)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首24小时广告变现金额(平台上报)', dataIndex: 'incomeVal24hPla', label: '其他业务(平台上报指标)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '注册首日广告变现金额(平台上报)', dataIndex: 'miniGameFirstDayAdMonetizationAmount', label: '其他业务(平台上报指标)', width: 120, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '注册7日广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmountD7', label: '其他业务(平台上报指标)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活14日广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmountD14', label: '其他业务(平台上报指标)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmount', label: '其他业务(平台上报指标)', width: 100, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首24小时广告变现人数(平台上报)', dataIndex: 'adPayingUsers24hPla', label: '其他业务(平台上报指标)', width: 115, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首日广告变现人数(平台上报)', dataIndex: 'adMonetizationPlaDedupActive1dPv', label: '其他业务(平台上报指标)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活7日变现人数(平台上报)', dataIndex: 'adMonetizationPlaDedupActive7dPv', label: '其他业务(平台上报指标)', width: 100, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                }
+            ]
+        },
+        {
+            label: '其他业务(其他指标)',
+            data: [
+                {
+                    title: '激活首24小时广告变现ARPPU', dataIndex: 'firstDayAdPurArppuCost24h', label: '其他业务(其他指标)', width: 100, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首日广告变现ARPPU', dataIndex: 'firstDayAdPurArppuCost', label: '其他业务(其他指标)', width: 90, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '广告变现ARPPU', dataIndex: 'adMonetizationArppu', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首24小时广告变现ROI', dataIndex: 'incomeRoi124h', label: '其他业务(其他指标)', width: 90, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首日广告变现ROI', dataIndex: 'incomeRoi1', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活3日广告变现ROI', dataIndex: 'incomeRoi3', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活7日广告变现ROI', dataIndex: 'incomeRoi7', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活14日广告变现ROI', dataIndex: 'incomeRoi14', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '广告变现ROI', dataIndex: 'adMonetizationRoi', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首日广告变现成本(人数)', dataIndex: 'adPayingCostD1', label: '其他业务(其他指标)', width: 100, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '广告变现成本', dataIndex: 'adMonetizationCost', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活3日广告变现次数', dataIndex: 'adMonetizationActive3dPv', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活7日广告变现次数', dataIndex: 'adMonetizationActive7dPv', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '广告变现次数(平台上报)', dataIndex: 'incomePvPla', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首24小时广告变现金额', dataIndex: 'incomeVal24h', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首日广告变现金额', dataIndex: 'incomeVal1', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活3日广告变现金额', dataIndex: 'incomeVal3', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活7日广告变现金额', dataIndex: 'incomeVal7', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活14日广告变现金额', dataIndex: 'incomeVal14', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '广告变现金额', dataIndex: 'adMonetizationAmount', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首24小时广告变现人数', dataIndex: 'adPayingUsers24h', label: '其他业务(其他指标)', width: 90, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首日广告变现人数', dataIndex: 'adPayingUsersD1', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活3日广告变现人数', dataIndex: 'adMonetizationDedupActive3dPv', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活7日广告变现人数', dataIndex: 'adMonetizationDedupActive7dPv', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                }
+            ]
+        },
+        {
+            label: '小游戏(平台上报)',
+            data: [
+                {
+                    title: '小游戏注册首日广告变现ARPU(平台上报)', dataIndex: 'miniGameFirstDayAdPayingArpu', label: '小游戏(平台上报)', width: 130, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏广告变现ARPU(平台上报)', dataIndex: 'miniGameAdMonetizationArpu', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册首日广告变现ROI(平台上报)', dataIndex: 'miniGameIncomeRoi1', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册3日广告变现ROI(平台上报)', dataIndex: 'minigame3dIncomeRoi', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册7日广告变现ROI(平台上报)', dataIndex: 'minigame7dIncomeRoi', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏广告变现ROI(平台上报)', dataIndex: 'miniGameAdMonetizationRoi', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册首日广告变现成本(平台上报)', dataIndex: 'miniGameFirstDayAdPayingCost', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏广告变现成本(平台上报)', dataIndex: 'miniGameAdMonetizationCost', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册3日广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmountD3', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册首日广告变现人数(平台上报)', dataIndex: 'miniGameFirstDayAdMonetizationUsers', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册3日广告变现人数(平台上报)', dataIndex: 'minigame3dIncomeUv', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册7日广告变现人数(平台上报)', dataIndex: 'minigame7dIncomeUv', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏广告变现人数(平台上报)', dataIndex: 'miniGameAdMonetizationUsers', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                }
+            ]
+        },
+        {
+            label: '操作',
+            data: [
+                {
+                    title: '操作', dataIndex: 'cz', label: '操作', align: 'center', width: 150, default: 35,
+                    render: (_: number, b: any) => {
+                        if (b?.accountId === '总计') return '--'
+                        return <Space>
+                            <a onClick={() => dayHandle(b)}>广告每日监控</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: 45,
+                    default: 1,
+                    render: (a: string, b: any) => {
+                        if (b?.accountId === '总计') {
+                            return '--'
+                        }
+                        return <SwitchStatus configuredStatus={a} isDeleted={b?.isDeleted} adgroupId={b?.promotionId} onChange={onChange} />
+                    }
+                }
+            ]
+        }
+    ]
+}
+
+export default columns12

+ 35 - 39
src/pages/iaaData/tencentIaaAd/tableConfig.tsx → src/pages/iaaData/tencentIaa/adList/tableConfigDay.tsx

@@ -1,7 +1,7 @@
 import WidthEllipsis from "@/components/widthEllipsis"
-import { Statistic } from "antd"
+import { Badge, Statistic } from "antd"
 import React from "react"
-import { AD_STATUS_ENUM, BID_MODE_ENUM } from "./const"
+import { AD_STATUS_ENUM, BID_MODE_ENUM, PRODUCT_TYPE_ENUM } from "../../const"
 
 function columns12(): { label: string, fieldSHow?: { label: string, saveField: string, defaultValue: any[], data: any[] }, data: any[] }[] {
 
@@ -11,43 +11,39 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
             label: '腾讯广告列表',
             data: [
                 {
-                    title: '广告账号', dataIndex: 'accountId', label: '腾讯广告列表', align: 'center', width: 80, default: 1,
+                    title: '广告账号', dataIndex: 'accountId', label: '腾讯广告列表', align: 'center', width: 80, default: 2,
                     render: (a: string) => (<WidthEllipsis value={a} />)
                 },
                 {
-                    title: '业务类型', dataIndex: 'productType', label: '腾讯广告列表', align: 'center', width: 80, default: 2,
-                    render: (a: string) => (<WidthEllipsis value={a} />)
+                    title: '业务类型', dataIndex: 'productType', label: '腾讯广告列表', align: 'center', width: 80, default: 3,
+                    render: (a: string) => (<WidthEllipsis value={PRODUCT_TYPE_ENUM[a as keyof typeof PRODUCT_TYPE_ENUM]} />)
                 },
                 {
-                    title: '应用', dataIndex: 'appName', label: '腾讯广告列表', align: 'center', width: 80, default: 3,
+                    title: '应用', dataIndex: 'appName', label: '腾讯广告列表', align: 'center', width: 100, default: 4,
                     render: (a: string) => (<WidthEllipsis value={a} />)
                 },
                 {
-                    title: '小程序ID', dataIndex: 'mpId', label: '腾讯广告列表', align: 'center', width: 100, default: 4,
-                    render: (a: string, b: any) => (<WidthEllipsis value={a} />)
+                    title: '小程序ID', dataIndex: 'mpId', label: '腾讯广告列表', align: 'center', width: 100, default: 5,
+                    render: (a: string, b: any) => (<WidthEllipsis isCopy value={a} />)
                 },
                 {
-                    title: '投手', dataIndex: 'pitcherName', label: '腾讯广告列表', align: 'center', width: 60, default: 5,
+                    title: '投手', dataIndex: 'pitcherName', label: '腾讯广告列表', align: 'center', width: 60, default: 6,
                     render: (a: string) => (<WidthEllipsis value={a} />)
                 },
                 {
-                    title: '广告名称', dataIndex: 'promotionName', label: '腾讯广告列表', align: 'center', width: 120, default: 6,
+                    title: '广告名称', dataIndex: 'promotionName', label: '腾讯广告列表', align: 'center', width: 120, default: 7,
                     render: (a: string) => (<WidthEllipsis value={a} />)
                 },
                 {
-                    title: '广告ID', dataIndex: 'promotionId', label: '腾讯广告列表', align: 'center', width: 90, default: 7,
+                    title: '广告ID', dataIndex: 'promotionId', label: '腾讯广告列表', align: 'center', width: 90, default: 8,
                     render: (a: string) => (<WidthEllipsis value={a} />)
                 },
                 {
-                    title: '广告状态', dataIndex: 'status', label: '腾讯广告列表', align: 'center', width: 75, default: 8,
+                    title: '广告状态', dataIndex: 'status', label: '腾讯广告列表', align: 'center', width: 75, default: 9,
                     render: (a: string) => (<WidthEllipsis value={AD_STATUS_ENUM[a as keyof typeof AD_STATUS_ENUM]} />)
                 },
                 {
-                    title: '服务商', dataIndex: 'service', label: '腾讯广告列表', align: 'center', width: 75, default: 9,
-                    render: (a: string) => (<WidthEllipsis value={a} />)
-                },
-                {
-                    title: '投放媒体(腾讯)', dataIndex: 'accountType', label: '腾讯广告列表', align: 'center', width: 75, default: 10,
+                    title: '服务商', dataIndex: 'service', label: '腾讯广告列表', align: 'center', width: 75, default: 10,
                     render: (a: string) => (<WidthEllipsis value={a} />)
                 },
                 {
@@ -63,83 +59,83 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                     render: (a: string) => <Statistic value={a || 0} />
                 },
                 {
-                    title: '深度转化ROI系数', dataIndex: 'roiGoal', label: '腾讯广告列表', align: 'right', width: 75, default: 16,
+                    title: '深度转化ROI系数', dataIndex: 'roiGoal', label: '腾讯广告列表', align: 'right', width: 75, default: 14,
                     render: (a: string) => <Statistic value={a || 0} />
                 },
                 {
-                    title: '广告日预算', dataIndex: 'budget', label: '腾讯广告列表', align: 'right', width: 75, default: 17, sorter: true,
+                    title: '广告日预算', dataIndex: 'budget', label: '腾讯广告列表', align: 'right', width: 75, default: 15, sorter: true,
                     render: (a: string) => <Statistic value={a || 0} />
                 },
                 {
-                    title: '广告创建时间', dataIndex: 'adTime', label: '基本信息', align: 'center', width: 90, default: 20,
+                    title: '广告创建时间', dataIndex: 'adTime', label: '基本信息', align: 'center', width: 90, default: 16,
                     render: (a: string, b: any) => (<WidthEllipsis value={a} />)
                 },
                 {
-                    title: '广告已删除?', dataIndex: 'isDeleted', label: '基本信息', align: 'center', width: 50, default: 21,
-                    render: (a: boolean) => (<WidthEllipsis value={a === true ? '是' : a === false ? '否' : '--'} />)
+                    title: '广告已删除?', dataIndex: 'isDeleted', label: '基本信息', align: 'center', width: 50, default: 17,
+                    render: (a: number, b: any) => (b?.accountId === '总计' ? '--' : a === 1 ? <Badge status="error" text="是" /> : <Badge status="success" text="否" />)
                 },
                 {
-                    title: '投放日期', dataIndex: 'startTime', label: '基本信息', align: 'center', width: 180, default: 22,
+                    title: '投放日期', dataIndex: 'startTime', label: '基本信息', align: 'center', width: 180, default: 18,
                     render: (a: string, b: any) => (<WidthEllipsis value={b?.accountId === '总计' ? '--' : `${a}-${b?.endTime}`} />)
                 },
                 {
-                    title: '消耗时间', dataIndex: 'dt', label: '基本信息', align: 'center', width: 90, default: 24,
+                    title: '消耗时间', dataIndex: 'dt', label: '基本信息', align: 'center', width: 90, default: 19,
                     render: (a: string, b: any) => (<WidthEllipsis value={a} />)
                 },
                 {
-                    title: '今日消耗', dataIndex: 'cost', label: '腾讯广告列表', align: 'right', width: 70, default: 25, sorter: true,
+                    title: '今日消耗', dataIndex: 'cost', label: '腾讯广告列表', align: 'right', width: 70, default: 20, sorter: true,
                     render: (a: string) => <Statistic value={a || 0} />
                 },
                 {
-                    title: '广告总消耗', dataIndex: 'totalCost', label: '腾讯广告列表', align: 'right', width: 85, default: 26, sorter: true,
+                    title: '广告总消耗', dataIndex: 'totalCost', label: '腾讯广告列表', align: 'right', width: 85, default: 21, sorter: true,
                     render: (a: string) => <Statistic value={a || 0} />
                 },
                 {
-                    title: '点击量', dataIndex: 'validClickCount', label: '腾讯广告列表', align: 'center', width: 70, default: 27, sorter: true,
+                    title: '点击量', dataIndex: 'validClickCount', label: '腾讯广告列表', align: 'center', width: 70, default: 22, sorter: true,
                     render: (a: string) => <Statistic value={a || 0} />
                 },
                 {
-                    title: '点击率', dataIndex: 'ctr', label: '腾讯广告列表', align: 'center', width: 70, default: 28, sorter: true,
+                    title: '点击率', dataIndex: 'ctr', label: '腾讯广告列表', align: 'center', width: 70, default: 23, sorter: true,
                     render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 50 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
                 },
                 {
-                    title: '曝光量', dataIndex: 'viewCount', label: '腾讯广告列表', align: 'center', width: 70, default: 29, sorter: true,
+                    title: '曝光量', dataIndex: 'viewCount', label: '腾讯广告列表', align: 'center', width: 70, default: 24, sorter: true,
                     render: (a: string) => <Statistic value={a || 0} />
                 },
                 {
-                    title: '千次曝光成本', dataIndex: 'thousandDisplayPrice', label: '腾讯广告列表', align: 'right', width: 65, default: 30, sorter: true,
+                    title: '千次曝光成本', dataIndex: 'thousandDisplayPrice', label: '腾讯广告列表', align: 'right', width: 65, default: 25, sorter: true,
                     render: (a: string) => <Statistic value={a || 0} />
                 },
                 {
-                    title: '点击均价', dataIndex: 'cpc', label: '腾讯广告列表', align: 'center', width: 65, default: 31, sorter: true,
+                    title: '点击均价', dataIndex: 'cpc', label: '腾讯广告列表', align: 'center', width: 65, default: 26, sorter: true,
                     render: (a: string) => <Statistic value={a || 0} />
                 },
                 {
-                    title: '转化目标', dataIndex: 'convertTarget', label: '基本信息', align: 'center', width: 65, default: 32, sorter: true,
+                    title: '转化目标', dataIndex: 'convertTarget', label: '基本信息', align: 'center', width: 65, default: 27, sorter: true,
                     render: (a: string) => (<WidthEllipsis value={a} />)
                 },
                 {
-                    title: '转化目标量', dataIndex: 'conversionsCount', label: '基本信息', align: 'center', width: 65, default: 33, sorter: true,
+                    title: '转化目标量', dataIndex: 'conversionsCount', label: '基本信息', align: 'center', width: 65, default: 28, sorter: true,
                     render: (a: string) => <Statistic value={a || 0} />
                 },
                 {
-                    title: '转化目标成本', dataIndex: 'convertCost', label: '基本信息', align: 'center', width: 65, default: 34, sorter: true,
+                    title: '转化目标成本', dataIndex: 'convertCost', label: '基本信息', align: 'center', width: 65, default: 29, sorter: true,
                     render: (a: string) => <Statistic value={a || 0} />
                 },
                 {
-                    title: '转化目标率', dataIndex: 'convertRate', label: '腾讯广告列表', align: 'center', width: 70, default: 35, sorter: true,
+                    title: '转化目标率', dataIndex: 'convertRate', label: '腾讯广告列表', align: 'center', width: 70, default: 30, sorter: true,
                     render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 50 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
                 },
                 {
-                    title: '小游戏注册人数', dataIndex: 'miniGameRegisterUsers', label: '基本信息', align: 'center', width: 80, default: 36, sorter: true,
+                    title: '小游戏注册人数', dataIndex: 'miniGameRegisterUsers', label: '基本信息', align: 'center', width: 80, default: 31, sorter: true,
                     render: (a: string) => <Statistic value={a || 0} />
                 },
                 {
-                    title: '小游戏注册成本', dataIndex: 'miniGameRegisterCost', label: '基本信息', align: 'center', width: 80, default: 37, sorter: true,
+                    title: '小游戏注册成本', dataIndex: 'miniGameRegisterCost', label: '基本信息', align: 'center', width: 80, default: 32, sorter: true,
                     render: (a: string) => <Statistic value={a || 0} />
                 },
                 {
-                    title: '小游戏注册率', dataIndex: 'miniGameRegisterRate', label: '腾讯广告列表', align: 'center', width: 75, default: 38, sorter: true,
+                    title: '小游戏注册率', dataIndex: 'miniGameRegisterRate', label: '腾讯广告列表', align: 'center', width: 75, default: 33, sorter: true,
                     render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 50 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
                 }
             ]
@@ -205,7 +201,7 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                     render: (a: string) => <Statistic value={a || 0} />
                 },
                 {
-                    title: '激活7日广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmountD7', label: '其他业务(平台上报指标)', width: 110, align: 'center', sorter: true,
+                    title: '注册7日广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmountD7', label: '其他业务(平台上报指标)', width: 110, align: 'center', sorter: true,
                     render: (a: string) => <Statistic value={a || 0} />
                 },
                 {

+ 98 - 0
src/pages/iaaData/tencentIaa/appEveryDayData/index.tsx

@@ -0,0 +1,98 @@
+import QueryForm from "@/components/QueryForm";
+import TablePro from "@/components/TablePro";
+import { useAjax } from "@/Hook/useAjax";
+import { getAppTxEveryDayListApi, GetAppTxEveryDayListProps, getAppTxEveryDayTotalApi } from "@/services/iaaData";
+import React, { useEffect, useState } from "react"
+import { useModel } from "umi";
+import moment from "moment";
+import columns12 from "./tableConfig";
+
+/**
+ * 应用每日数据
+ * @returns 
+ */
+const AppEveryDayData: React.FC = () => {
+
+    /****************************************/
+    const { initialState } = useModel('@@initialState');
+    const [queryForm, setQueryForm] = useState<GetAppTxEveryDayListProps>({
+        pageNum: 1,
+        pageSize: 30,
+        costDayBegin: moment().format('YYYY-MM-DD'),
+        costDayEnd: moment().format('YYYY-MM-DD'),
+    })
+    const [totalData, setTotalData] = useState<any[]>([])
+
+    const getAppTxEveryDayList = useAjax((params) => getAppTxEveryDayListApi(params))
+    const getAppTxEveryDayTotal = useAjax((params) => getAppTxEveryDayTotalApi(params))
+    /****************************************/
+
+    useEffect(() => {
+        if (initialState?.iaaApp) {
+            const [appId, productType] = initialState.iaaApp.split('||')
+            getAppTxEveryDayList.run({ ...queryForm, appId, productType })
+            getAppTxEveryDayTotal.run({ ...queryForm, appId, productType }).then((res: { data: { id: number; appName: string } }) => {
+                if (res?.data) {
+                    let data = res?.data
+                    data.id = 1
+                    data.appName = '总计'
+                    setTotalData([data])
+                } else {
+                    setTotalData([{ id: 1, appName: '总计' }])
+                }
+            })
+        }
+
+    }, [queryForm, initialState?.iaaApp])
+
+    return <div>
+        <TablePro
+            leftChild={<QueryForm
+                initialValues={{ day1: [moment(), moment()] }}
+                day1={{ placeholder: ['消耗日期开始', '消耗日期结束'] }}
+                onChange={(data: any) => {
+                    console.log(data)
+                    const { day1, ...params } = data
+                    let newQueryForm = JSON.parse(JSON.stringify(queryForm))
+                    if (day1 && day1?.length === 2) {
+                        newQueryForm['costDayBegin'] = moment(day1[0]).format('YYYY-MM-DD')
+                        newQueryForm['costDayEnd'] = moment(day1[1]).format('YYYY-MM-DD')
+                    } else {
+                        delete newQueryForm['costDayBegin']
+                        delete newQueryForm['costDayEnd']
+                    }
+                    setQueryForm({ ...newQueryForm, ...params })
+                }}
+            />}
+            isZj
+            totalData={totalData}
+            config={columns12()}
+            configName={'应用每日数据'}
+            fixed={{ left: 4, right: 0 }}
+            scroll={{ x: 1000, y: 620 }}
+            title='应用每日数据'
+            loading={getAppTxEveryDayList.loading}
+            ajax={getAppTxEveryDayList}
+            page={getAppTxEveryDayList?.data?.data?.current || 1}
+            pageSize={getAppTxEveryDayList?.data?.data?.size || 20}
+            total={getAppTxEveryDayList?.data?.data?.total || 0}
+            dataSource={getAppTxEveryDayList?.data?.data?.records?.map((item: any, index: number) => ({ ...item, id: Number(queryForm.pageNum.toString() + (index + '')) }))}
+            onChange={(pagination: any, _: any, sortData: any) => {
+                let { current, pageSize } = pagination
+                let newQueryForm = JSON.parse(JSON.stringify(queryForm))
+                if (sortData && sortData?.order) {
+                    newQueryForm['sortAsc'] = sortData?.order === 'ascend' ? true : false
+                    newQueryForm['sortFiled'] = sortData?.field
+                } else {
+                    delete newQueryForm['sortAsc']
+                    delete newQueryForm['sortFiled']
+                }
+                newQueryForm.pageNum = current || newQueryForm.pageNum
+                newQueryForm.pageSize = pageSize || newQueryForm.pageSize
+                setQueryForm({ ...newQueryForm })
+            }}
+        />
+    </div>
+}
+
+export default AppEveryDayData

+ 425 - 0
src/pages/iaaData/tencentIaa/appEveryDayData/tableConfig.tsx

@@ -0,0 +1,425 @@
+import WidthEllipsis from "@/components/widthEllipsis"
+import { Badge, Statistic } from "antd"
+import React from "react"
+import { PRODUCT_TYPE_ENUM } from "../../const"
+import { formatSecondsToTime } from "@/utils/utils"
+
+function columns12(): { label: string, fieldSHow?: { label: string, saveField: string, defaultValue: any[], data: any[] }, data: any[] }[] {
+
+
+    return [
+        {
+            label: '基本信息',
+            data: [
+                {
+                    title: '应用', dataIndex: 'appName', label: '基本信息', align: 'center', width: 120, default: 1,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '应用ID', dataIndex: 'appId', label: '基本信息', align: 'center', width: 80,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '小程序名称', dataIndex: 'mpName', label: '基本信息', align: 'center', width: 85, default: 2,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '小程序ID', dataIndex: 'mpId', label: '基本信息', align: 'center', width: 80,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '业务类型', dataIndex: 'productType', label: '基本信息', align: 'center', width: 80, default: 3,
+                    render: (a: string) => (<WidthEllipsis value={PRODUCT_TYPE_ENUM[a as keyof typeof PRODUCT_TYPE_ENUM]} />)
+                },
+                {
+                    title: '消耗时间', dataIndex: 'dt', label: '基本信息', align: 'center', width: 80, default: 4,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '累计消耗', dataIndex: 'costToday', label: '基本信息', align: 'center', width: 95, default: 5, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '每日真实消耗', dataIndex: 'costTotal', label: '基本信息', align: 'center', width: 90, default: 6, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '每日消耗', dataIndex: 'cost', label: '基本信息', align: 'center', width: 85, default: 7, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '每日赔付金', dataIndex: 'payout', label: '基本信息', align: 'center', width: 80, default: 8, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '推广广告账号数量', tips: '消耗大于0', dataIndex: 'accountCount', label: '基本信息', align: 'center', width: 80, default: 9, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '推广广告数量', tips: '消耗大于0', dataIndex: 'adCount', label: '基本信息', align: 'center', width: 80, default: 10, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+            ]
+        },
+        {
+            label: '应用端指标',
+            data: [
+                {
+                    title: '累计注册人数', dataIndex: 'regUserTotal', label: '应用端指标', align: 'center', width: 80, default: 11, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '新增注册人数', dataIndex: 'regUserNew', label: '应用端指标', align: 'center', width: 80, default: 12, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: 'DAU', tips: '日活用户人数', dataIndex: 'dau', label: '应用端指标', align: 'center', width: 80, default: 13, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '新增占比', tips: '新增注册人数/DAU', dataIndex: 'newProportion', label: '应用端指标', align: 'center', width: 90, default: 14, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '累计利润', tips: '广告变现累计收入-累计消耗', dataIndex: 'totalProfit', label: '应用端指标', align: 'center', width: 100, default: 15, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '利润率', tips: '(广告变现累计收入-累计消耗)/累计消耗*100%', dataIndex: 'profitRate', label: '应用端指标', align: 'center', width: 80, default: 16, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '广告变现收入', dataIndex: 'adMonRevenue', label: '应用端指标', align: 'center', width: 80, default: 17, sorter: true,
+                    render: (a: number) => <Statistic value={(a || 0) / 100} precision={2} />
+                },
+                {
+                    title: '广告变现累计收入', dataIndex: 'adMonRevenueTotal', label: '应用端指标', align: 'center', width: 85, default: 18, sorter: true,
+                    render: (a: number) => <Statistic value={(a || 0) / 100} precision={2} />
+                },
+                {
+                    title: '新增用户成本', tips: '总消耗/新增注册人数', dataIndex: 'newUserRate', label: '应用端指标', align: 'center', width: 80, default: 19, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '人均新增成本', tips: '累计消耗/累计注册人数', dataIndex: 'avgUserRate', label: '应用端指标', align: 'center', width: 80, default: 20, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '人均活跃成本', tips: '累计消耗/DAU', dataIndex: 'avgActiveRate', label: '应用端指标', align: 'center', width: 80, default: 21, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '分享用户人数', dataIndex: 'shareUser', label: '应用端指标', align: 'center', width: 70, default: 22, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '分享次数', dataIndex: 'shareCount', label: '应用端指标', align: 'center', width: 60, default: 23, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '人均分享次数', tips: '分享次数/分享用户人数', dataIndex: 'avgShareCount', label: '应用端指标', align: 'center', width: 80, default: 24, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '分享用户占比', tips: '分享用户人数/DAU', dataIndex: 'shareUserProportion', label: '应用端指标', align: 'center', width: 80, default: 25, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '新增次日留存人数', dataIndex: 'newRetainedTomorrow', label: '应用端指标', align: 'center', width: 80, default: 26, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '新增注册次日留存率', tips: '新增注册次日留存人数/新增注册人数', dataIndex: 'newRetainedTomorrowRate', label: '应用端指标', align: 'center', width: 80, default: 27, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '活跃用户次日留存人数', dataIndex: 'retainedUserTomorrow', label: '应用端指标', align: 'center', width: 85, default: 28, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '活跃用户次日留存率', tips: '指定时间活跃(即访问小游戏)的用户,在之后的第1天(或周、月),再次访问小游戏的用户数占比', dataIndex: 'retainedUserTomorrowRate', label: '应用端指标', align: 'center', width: 85, default: 29, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '活跃用户人均访问次数', tips: '活跃用户访问次数/活跃用户人数', dataIndex: 'avgActiveUserAccessCount', label: '应用端指标', align: 'center', width: 100, default: 30, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '活跃用户停留总时长', tips: '活跃用户人均停留时长*活跃用户人数', dataIndex: 'activeDuration', label: '应用端指标', align: 'center', width: 90, default: 31, sorter: true,
+                    render: (a: number) => {
+                        return formatSecondsToTime(a || 0)
+                    }
+                },
+                {
+                    title: '活跃用户人均停留时长', tips: '活跃用户停留总时长/活跃用户人数', dataIndex: 'avgActiveDuration', label: '应用端指标', align: 'center', width: 100, default: 32, sorter: true,
+                    render: (a: number) => {
+                        return formatSecondsToTime(a || 0)
+                    }
+                },
+                {
+                    title: '广告新增ARPU', tips: '广告变现收入/新增注册人数', dataIndex: 'nweAdArpu', label: '应用端指标', align: 'center', width: 80, default: 33, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '广告总ARPU', tips: '广告累计变现收入/累计注册人数', dataIndex: 'adArpuTotal', label: '应用端指标', align: 'center', width: 80, default: 34, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '激励视频广告收入', dataIndex: 'videoAdIncome', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '激励视频广告ecpm', dataIndex: 'videoAdEcpm', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '激励视频拉取量', dataIndex: 'videoAdCount', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '人均视频次数', dataIndex: 'avgUserVideoCount', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '插屏广告收入', dataIndex: 'plaqueAdIncome', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '插屏广告ecpm', dataIndex: 'plaqueAdEcpm', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '插屏广告拉取量', dataIndex: 'plaqueAdCount', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '插屏广告曝光量', dataIndex: 'interstitialExposureCount', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '插屏广告点击量', dataIndex: 'interstitialClickCount', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激励视频曝光量', dataIndex: 'videoExposureCount', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激励视频点击量', dataIndex: 'videoClickCount', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: 'Banner广告点击量', dataIndex: 'bannerClickCount', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: 'Banner广告曝光量', dataIndex: 'bannerExposureCount', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: 'Banner广告收入', dataIndex: 'bannerIncome', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: 'Banner广告ecpm', dataIndex: 'bannerEcpm', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: 'banner广告拉取量', dataIndex: 'bannerReqSuccCount', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '人均Banner广告广告收益', dataIndex: 'avgUserBannerIncome', label: '应用端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '人均激励视频收益', dataIndex: 'avgUserVideoIncome', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '人均插屏广告次数', dataIndex: 'avgUserInterstitialCount', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '人均Banner广告次数', dataIndex: 'avgUserBannerCount', label: '应用端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                }
+            ]
+        },
+        {
+            label: '广告媒体端指标',
+            data: [
+                {
+                    title: '点击量', dataIndex: 'validClickCount', label: '广告媒体端指标', align: 'center', width: 65, default: 35, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册人数', dataIndex: 'miniGameRegisterUsers', label: '广告媒体端指标', align: 'center', width: 80, default: 36, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册率', dataIndex: 'miniGameRegisterRate', label: '广告媒体端指标', align: 'center', width: 80, default: 37, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏注册成本', dataIndex: 'miniGameRegisterCost', label: '广告媒体端指标', align: 'center', width: 80, default: 38, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '小游戏注册首日广告变现人数(平台上报)', dataIndex: 'miniGameFirstDayAdMonetizationUsers', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首日广告变现人数(平台上报)', dataIndex: 'adMonetizationPlaDedupActive1dPv', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首日广告变现次数(平台上报)', dataIndex: 'incomePv1dPla', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '注册首日广告变现金额(平台上报)', dataIndex: 'miniGameFirstDayAdMonetizationAmount', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '首日变现ARPPU', tips: '注册首日广告变现金额(平台上报)/小游戏注册首日广告变现人数(平台上报)', dataIndex: 'miniGameFirstDayAdPayingArpu', label: '广告媒体端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '首日变现ARPU', tips: '小游戏注册首日广告变现金额(平台上报)/小游戏注册人数', dataIndex: 'miniGameFirstDayAdPayingArppu', label: '广告媒体端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '首日广告变现成本(平台上报)', dataIndex: 'miniGameFirstDayAdPayingCost', label: '广告媒体端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '首日ROI', tips: '小游戏注册首日广告变现金额(平台上报)/消耗*100%', dataIndex: 'miniGameFirstDayAdPayingRoi', label: '广告媒体端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '激活首24小时广告变现人数(平台上报)', dataIndex: 'adPayingUsers24hPla', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首24小时广告变现次数(平台上报)', dataIndex: 'incomePv24hPla', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首24小时广告变现金额(平台上报)', dataIndex: 'incomeVal24hPla', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '激活首24小时广告变现ARPPU(平台上报)', dataIndex: 'firstDayAdPurArppuCost24hPla', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '24小时广告变现ARPU(平台上报)', dataIndex: 'firstDayAdPurArpuCost24hPla', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '24小时广告变现成本', dataIndex: 'firstDayAdPurArpuCost24hPlaCost', label: '广告媒体端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '24小时广告变现ROI', dataIndex: 'firstDayAdPurArpuCost24hPlaRoi', label: '广告媒体端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏注册3日广告变现人数(平台上报)', dataIndex: 'minigame3dIncomeUv', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '注册3日广告变现次数(平台上报)', dataIndex: 'minigame3dIncomeCount', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活3日广告变现次数(平台上报)', dataIndex: 'adMonetizationPlaDedupActive3dPv', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册3日广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmountD3', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '3日广告变现ARPPU(平台上报)', dataIndex: 'adPurArppuDay3Cost', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '3日广告变现ARPU(平台上报)', dataIndex: 'adPurArpuDay3Cost', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '3日广告变现成本(平台上报)', dataIndex: 'adPurDay3Cost', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '3日广告变现ROI', dataIndex: 'adPurDay3Roi', label: '广告媒体端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏注册7日广告变现人数(平台上报)', dataIndex: 'minigame7dIncomeUv', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活7日变现人数(平台上报)', dataIndex: 'adMonetizationPlaDedupActive7dPv', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活7日广告变现次数(平台上报)', dataIndex: 'minigame7dIncomeCount', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册7日广告变现金额(平台上报)', dataIndex: 'miniGameRegD7Amount', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '7日广告变现ARPPU(平台上报)', dataIndex: 'miniGameRegD7Arppu', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '7日广告变现ARPU(平台上报)', dataIndex: 'miniGameRegD7Arpu', label: '广告媒体端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '7日广告变现成本(平台上报', dataIndex: 'miniGameRegD7Cost', label: '广告媒体端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '7日广告变现ROI', dataIndex: 'miniGameRegD7Roi', label: '广告媒体端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+                {
+                    title: '小游戏广告变现人数(平台上报)', dataIndex: 'miniGameAdMonetizationUsers', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '广告变现次数(平台上报)', dataIndex: 'incomePvPla', label: '广告媒体端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmount', label: '广告媒体端指标', align: 'center', width: 100, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '广告变现ARPPU(平台上报)', dataIndex: 'miniGameAdMonetizationArppu', label: '广告媒体端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '广告变现ARPU(平台上报)', dataIndex: 'miniGameAdMonetizationArpu', label: '广告媒体端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '广告变现成本(平台上报)', dataIndex: 'miniGameAdMonetizationCost', label: '广告媒体端指标', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                },
+                {
+                    title: '广告变现总ROI', dataIndex: 'miniGameAdMonetizationRoi', label: '广告媒体端指标', align: 'center', width: 80, default: 39, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                }
+            ]
+        }
+    ]
+}
+
+export default columns12

+ 100 - 0
src/pages/iaaData/tencentIaa/pitcherEveryDay/index.tsx

@@ -0,0 +1,100 @@
+import { useAjax } from "@/Hook/useAjax";
+import { getPutUserTxEveryDayListApi, getPutUserTxEveryDayListProps, getPutUserTxEveryDayTotalApi } from "@/services/iaaData";
+import React, { useEffect, useState } from "react"
+import { useModel } from "umi";
+import moment from "moment";
+import TablePro from "@/components/TablePro";
+import QueryForm from "@/components/QueryForm";
+import columns12 from "./tableConfig";
+
+/**
+ * 投手每日数据
+ * @returns 
+ */
+const PitcherEveryDay: React.FC = () => {
+
+
+    /****************************************/
+    const { initialState } = useModel('@@initialState');
+    const [queryForm, setQueryForm] = useState<getPutUserTxEveryDayListProps>({
+        pageNum: 1,
+        pageSize: 30,
+        costDayBegin: moment().format('YYYY-MM-DD'),
+        costDayEnd: moment().format('YYYY-MM-DD'),
+    })
+    const [totalData, setTotalData] = useState<any[]>([])
+
+    const getPutUserTxEveryDayList = useAjax((params) => getPutUserTxEveryDayListApi(params))
+    const getPutUserTxEveryDayTotal = useAjax((params) => getPutUserTxEveryDayTotalApi(params))
+    /****************************************/
+
+    useEffect(() => {
+        if (initialState?.iaaApp) {
+            const [appId, productType] = initialState.iaaApp.split('||')
+            getPutUserTxEveryDayList.run({ ...queryForm, appId, productType })
+            getPutUserTxEveryDayTotal.run({ ...queryForm, appId, productType }).then((res: { data: { id: number; pitcher: string } }) => {
+                if (res?.data) {
+                    let data = res?.data
+                    data.id = 1
+                    data.pitcher = '总计'
+                    setTotalData([data])
+                } else {
+                    setTotalData([{ id: 1, pitcher: '总计' }])
+                }
+            })
+        }
+
+    }, [queryForm, initialState?.iaaApp])
+
+    return <div>
+        <TablePro
+            leftChild={<QueryForm
+                initialValues={{ day1: [moment(), moment()] }}
+                day1={{ placeholder: ['消耗日期开始', '消耗日期结束'] }}
+                isPutUserIdList
+                onChange={(data: any) => {
+                    console.log(data)
+                    const { day1, ...params } = data
+                    let newQueryForm = JSON.parse(JSON.stringify(queryForm))
+                    if (day1 && day1?.length === 2) {
+                        newQueryForm['costDayBegin'] = moment(day1[0]).format('YYYY-MM-DD')
+                        newQueryForm['costDayEnd'] = moment(day1[1]).format('YYYY-MM-DD')
+                    } else {
+                        delete newQueryForm['costDayBegin']
+                        delete newQueryForm['costDayEnd']
+                    }
+                    setQueryForm({ ...newQueryForm, ...params })
+                }}
+            />}
+            isZj
+            totalData={totalData}
+            config={columns12()}
+            configName={'投手每日数据'}
+            fixed={{ left: 4, right: 0 }}
+            scroll={{ x: 1000, y: 620 }}
+            title='投手每日数据'
+            loading={getPutUserTxEveryDayList.loading}
+            ajax={getPutUserTxEveryDayList}
+            page={getPutUserTxEveryDayList?.data?.data?.current || 1}
+            pageSize={getPutUserTxEveryDayList?.data?.data?.size || 20}
+            total={getPutUserTxEveryDayList?.data?.data?.total || 0}
+            dataSource={getPutUserTxEveryDayList?.data?.data?.records?.map((item: any, index: number) => ({ ...item, id: Number(queryForm.pageNum.toString() + (index + '')) }))}
+            onChange={(pagination: any, _: any, sortData: any) => {
+                let { current, pageSize } = pagination
+                let newQueryForm = JSON.parse(JSON.stringify(queryForm))
+                if (sortData && sortData?.order) {
+                    newQueryForm['sortAsc'] = sortData?.order === 'ascend' ? true : false
+                    newQueryForm['sortFiled'] = sortData?.field
+                } else {
+                    delete newQueryForm['sortAsc']
+                    delete newQueryForm['sortFiled']
+                }
+                newQueryForm.pageNum = current || newQueryForm.pageNum
+                newQueryForm.pageSize = pageSize || newQueryForm.pageSize
+                setQueryForm({ ...newQueryForm })
+            }}
+        />
+    </div>
+}
+
+export default PitcherEveryDay

+ 276 - 0
src/pages/iaaData/tencentIaa/pitcherEveryDay/tableConfig.tsx

@@ -0,0 +1,276 @@
+import WidthEllipsis from "@/components/widthEllipsis"
+import { Badge, Statistic } from "antd"
+import React from "react"
+import { PRODUCT_TYPE_ENUM } from "../../const"
+
+function columns12(): { label: string, fieldSHow?: { label: string, saveField: string, defaultValue: any[], data: any[] }, data: any[] }[] {
+
+
+    return [
+        {
+            label: '基本信息',
+            data: [
+                {
+                    title: '投手', dataIndex: 'pitcher', label: '基本信息', align: 'center', width: 120, default: 1,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '业务类型', dataIndex: 'productType', label: '基本信息', align: 'center', width: 80, default: 2,
+                    render: (a: string) => (<WidthEllipsis value={PRODUCT_TYPE_ENUM[a as keyof typeof PRODUCT_TYPE_ENUM]} />)
+                },
+                {
+                    title: '应用名称', dataIndex: 'appName', label: '基本信息', align: 'center', width: 80, default: 3,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '应用ID', dataIndex: 'appId', label: '基本信息', align: 'center', width: 80,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '小程序ID', dataIndex: 'mpId', label: '基本信息', align: 'center', width: 80, default: 4,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '消耗时间', dataIndex: 'dt', label: '基本信息', align: 'center', width: 80, default: 5,
+                    render: (a: string) => (<WidthEllipsis value={a} />)
+                },
+                {
+                    title: '总消耗', dataIndex: 'cost', label: '基本信息', align: 'center', width: 90, default: 6, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '消耗', dataIndex: 'costToday', label: '基本信息', align: 'center', width: 85, default: 7, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '赔付金', dataIndex: 'payout', label: '基本信息', align: 'center', width: 80, default: 8, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '推广广告账号数量', tips: '消耗大于0', dataIndex: 'accountCount', label: '基本信息', align: 'center', width: 80, default: 9, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '推广广告数量', tips: '消耗大于0', dataIndex: 'adCount', label: '基本信息', align: 'center', width: 80, default: 10, sorter: true,
+                    render: (a: string) => <Statistic value={a || 0} />
+                },
+            ]
+        },
+        {
+            label: '基础数据',
+            data: [
+                {
+                    title: '点击量', dataIndex: 'validClickCount', label: '基础数据', align: 'center', width: 80, default: 11, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '曝光量', dataIndex: 'viewCount', label: '基础数据', align: 'center', width: 80, default: 12, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '千次曝光成本', dataIndex: 'thousandDisplayPrice', label: '基础数据', align: 'center', width: 80, default: 13, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '点击均价', dataIndex: 'cpc', label: '基础数据', align: 'center', width: 80, default: 14, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '小游戏注册人数', dataIndex: 'miniGameRegisterUsers', label: '基础数据', align: 'center', width: 80, default: 15, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册成本', dataIndex: 'miniGameRegisterCost', label: '基础数据', align: 'center', width: 80, default: 16, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '小游戏注册率', dataIndex: 'miniGameRegisterRate', label: '基础数据', align: 'center', width: 80, default: 17, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+            ]
+        },
+        {
+            label: 'D1数据',
+            data: [
+                {
+                    title: '小游戏注册首日广告变现人数(平台上报)', dataIndex: 'miniGameFirstDayAdMonetizationUsers', label: 'D1数据', align: 'center', width: 100, default: 18, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首日广告变现人数(平台上报)', dataIndex: 'adMonetizationPlaDedupActive1dPv', label: 'D1数据', align: 'center', width: 90, default: 19, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首日广告变现次数(平台上报)', dataIndex: 'incomePv1dPla', label: 'D1数据', align: 'center', width: 90, default: 20, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '注册首日广告变现金额(平台上报)', dataIndex: 'miniGameFirstDayAdMonetizationAmount', label: 'D1数据', align: 'center', width: 90, default: 21, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '首日变现ARPPU', dataIndex: 'miniGameFirstDayAdPayingArppu', label: 'D1数据', align: 'center', width: 80, default: 22, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '首日变现ARPU', dataIndex: 'miniGameFirstDayAdPayingArpu', label: 'D1数据', align: 'center', width: 80, default: 23, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '首日广告变现成本(平台上报)', dataIndex: 'miniGameFirstDayAdPayingCost', label: 'D1数据', align: 'center', width: 80, default: 24, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '首日ROI', dataIndex: 'miniGameFirstDayAdPayingRoi', label: 'D1数据', align: 'center', width: 80, default: 25, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+            ]
+        },
+        {
+            label: '24小时数据',
+            data: [
+                {
+                    title: '激活首24小时广告变现人数(平台上报)', dataIndex: 'adPayingUsers24hPla', label: '24小时数据', align: 'center', width: 90, default: 26, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首24小时广告变现次数(平台上报)', dataIndex: 'incomePv24hPla', label: '24小时数据', align: 'center', width: 90, default: 27, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活首24小时广告变现金额(平台上报)', dataIndex: 'incomeVal24hPla', label: '24小时数据', align: 'center', width: 90, default: 28, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '激活首24小时广告变现ARPPU(平台上报)', dataIndex: 'firstDayAdPurArppuCost24hPla', label: '24小时数据', align: 'center', width: 100, default: 29, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '24小时广告变现ARPU(平台上报)', dataIndex: 'firstDayAdPurArpuCost24hPla', label: '24小时数据', align: 'center', width: 90, default: 30, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '24小时广告变现成本', dataIndex: 'firstDayAdPurArpuCost24hPlaCost', label: '24小时数据', align: 'center', width: 80, default: 31, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '24小时广告变现ROI', dataIndex: 'firstDayAdPurArpuCost24hPlaRoi', label: '24小时数据', align: 'center', width: 80, default: 32, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+            ]
+        },
+        {
+            label: 'D3数据',
+            data: [
+                {
+                    title: '小游戏注册3日广告变现人数(平台上报)', dataIndex: 'minigame3dIncomeUv', label: 'D3数据', align: 'center', width: 90, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活3日广告变现人数(平台上报)', dataIndex: 'regUserTotal', label: 'D3数据', align: 'center', width: 90, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册3日广告变现次数(平台上报)', dataIndex: 'minigame3dIncomeCount', label: 'D3数据', align: 'center', width: 90, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活3日广告变现次数(平台上报)', dataIndex: 'adMonetizationPlaDedupActive3dPv', label: 'D3数据', align: 'center', width: 90, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册3日广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmountD3', label: 'D3数据', align: 'center', width: 90, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '3日广告变现ARPPU(平台上报)', dataIndex: 'adPurArppuDay3Cost', label: 'D3数据', align: 'center', width: 90, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '3日广告变现ARPU(平台上报)', dataIndex: 'adPurArpuDay3Cost', label: 'D3数据', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '3日广告变现成本(平台上报)', dataIndex: 'adPurDay3Cost', label: 'D3数据', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '3日广告变现ROI', dataIndex: 'adPurDay3Roi', label: 'D3数据', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+            ]
+        },
+        {
+            label: 'D7数据',
+            data: [
+                {
+                    title: '小游戏注册7日广告变现人数(平台上报)', dataIndex: 'minigame7dIncomeUv', label: 'D7数据', align: 'center', width: 90, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活7日变现人数(平台上报)', dataIndex: 'adMonetizationPlaDedupActive7dPv', label: 'D7数据', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '激活7日广告变现次数(平台上报)', dataIndex: 'minigame7dIncomeCount', label: 'D7数据', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '小游戏注册7日广告变现金额(平台上报)', dataIndex: 'miniGameRegD7Amount', label: 'D7数据', align: 'center', width: 90, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '7日广告变现ARPPU(平台上报)', dataIndex: 'miniGameRegD7Arppu', label: 'D7数据', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '7日广告变现ARPU(平台上报)', dataIndex: 'miniGameRegD7Arpu', label: 'D7数据', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '7日广告变现成本(平台上报)', dataIndex: 'miniGameRegD7Cost', label: 'D7数据', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '7日广告变现ROI', dataIndex: 'miniGameRegD7Roi', label: 'D7数据', align: 'center', width: 80, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                }
+            ]
+        },
+        {
+            label: 'D总数据',
+            data: [
+                {
+                    title: '广告变现人数(平台上报)', dataIndex: 'miniGameAdMonetizationUsers', label: 'D总数据', align: 'center', width: 80, default: 33, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '广告变现次数(平台上报)', dataIndex: 'incomePvPla', label: 'D总数据', align: 'center', width: 80, default: 34, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} />
+                },
+                {
+                    title: '广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmount', label: 'D总数据', align: 'center', width: 80, default: 35, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '广告变现ARPPU(平台上报)', dataIndex: 'miniGameAdMonetizationArppu', label: 'D总数据', align: 'center', width: 80, default: 36, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '广告变现ARPU(平台上报)', dataIndex: 'miniGameAdMonetizationArpu', label: 'D总数据', align: 'center', width: 80, default: 37, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '广告变现成本(平台上报)', dataIndex: 'miniGameAdMonetizationCost', label: 'D总数据', align: 'center', width: 80, default: 38, sorter: true,
+                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                },
+                {
+                    title: '广告变现总ROI', dataIndex: 'miniGameAdMonetizationRoi', label: 'D总数据', align: 'center', width: 80, default: 39, sorter: true,
+                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                },
+            ]
+        }
+    ]
+}
+
+export default columns12

+ 0 - 15
src/pages/iaaData/tencentIaaAd/const.ts

@@ -1,15 +0,0 @@
-
-/** 出价方式 */
-export enum BID_MODE_ENUM {
-	BID_MODE_OCPM = 'oCPM',
-	BID_MODE_CPM = 'CPM',
-	BID_MODE_CPC = 'CPC',
-	BID_MODE_CPA = 'CPA',
-	BID_MODE_OCPC = 'oCPC',
-}
-
-/**广告状态*/
-export enum AD_STATUS_ENUM {
-	AD_STATUS_NORMAL = '有效',
-	AD_STATUS_SUSPEND = '暂停',
-}

+ 0 - 122
src/pages/iaaData/tencentIaaAd/index.tsx

@@ -1,122 +0,0 @@
-import React, { useEffect, useState } from "react"
-import { useAjax } from "@/Hook/useAjax"
-import { getGDTListApi, GetGDTListProps, getGDTTotalApi } from "@/services/iaaData"
-import TablePro from "@/components/TablePro"
-import columns12 from "./tableConfig"
-import QueryForm from "@/components/QueryForm"
-import moment from "moment"
-import { useModel } from "umi"
-
-/**
- * 腾讯广告列表
- * @returns 
- */
-const TencentIaaAd: React.FC = () => {
-
-    /****************************************/
-    const { initialState } = useModel('@@initialState');
-    const [queryForm, setQueryForm] = useState<GetGDTListProps>({
-        pageNum: 1,
-        pageSize: 30
-    })
-    const [totalData, setTotalData] = useState<any[]>([])
-
-    const getGDTList = useAjax((params) => getGDTListApi(params))
-    const getGDTTotal = useAjax((params) => getGDTTotalApi(params))
-    /****************************************/
-
-    useEffect(() => {
-        if (initialState?.iaaApp) {
-            const [appId, productType] = initialState.iaaApp.split('||')
-            getGDTList.run({ ...queryForm, appId, productType })
-            getGDTTotal.run({ ...queryForm, appId, productType }).then((res: { data: { id: number; accountId: string } }) => {
-                if (res?.data) {
-                    let data = res?.data
-                    data.id = 1
-                    data.accountId = '总计'
-                    setTotalData([data])
-                } else {
-                    setTotalData([{ id: 1, accountId: '总计' }])
-                }
-            })
-        }
-
-    }, [queryForm, initialState?.iaaApp])
-
-    return <div>
-        <TablePro
-            leftChild={<QueryForm
-                initialValues={{}}
-                isAccountId
-                isPromotionName
-                isPutUserIdList
-                isCpaBid
-                isDeleted
-                isPricing
-                isStatus
-                day1={{ placeholder: ['广告创建日期开始', '广告创建日期结束'] }}
-                day2={{ placeholder: ['投放日期开始', '投放日期结束'] }}
-                day3={{ placeholder: ['消耗日期开始', '消耗日期结束'] }}
-                onChange={(data: any) => {
-                    console.log(data)
-                    const { day1, day2, day3, ...params } = data
-                    let newQueryForm = JSON.parse(JSON.stringify(queryForm))
-
-                    if (day1 && day1?.length === 2) {
-                        newQueryForm['adCreateBegin'] = moment(day1[0]).format('YYYY-MM-DD')
-                        newQueryForm['adCreateEnd'] = moment(day1[1]).format('YYYY-MM-DD')
-                    } else {
-                        delete newQueryForm['adCreateBegin']
-                        delete newQueryForm['adCreateEnd']
-                    }
-
-                    if (day2 && day2?.length === 2) {
-                        newQueryForm['putDayBegin'] = moment(day2[0]).format('YYYY-MM-DD')
-                        newQueryForm['putDayEnd'] = moment(day2[1]).format('YYYY-MM-DD')
-                    } else {
-                        delete newQueryForm['putDayBegin']
-                        delete newQueryForm['putDayEnd']
-                    }
-
-                    if (day3 && day3?.length === 2) {
-                        newQueryForm['costDayBegin'] = moment(day3[0]).format('YYYY-MM-DD')
-                        newQueryForm['costDayEnd'] = moment(day3[1]).format('YYYY-MM-DD')
-                    } else {
-                        delete newQueryForm['costDayBegin']
-                        delete newQueryForm['costDayEnd']
-                    }
-                    setQueryForm({ ...newQueryForm, ...params })
-                }}
-            />}
-            isZj
-            totalData={totalData}
-            config={columns12()}
-            configName={'腾讯广告列表'}
-            fixed={{ left: 4, right: 0 }}
-            scroll={{ x: 1000, y: 620 }}
-            title='腾讯广告列表'
-            loading={getGDTList.loading}
-            ajax={getGDTList}
-            page={getGDTList?.data?.data?.current || 1}
-            pageSize={getGDTList?.data?.data?.size || 20}
-            total={getGDTList?.data?.data?.total || 0}
-            dataSource={getGDTList?.data?.data?.records?.map((item: any, index: number) => ({ ...item, id: Number(queryForm.pageNum.toString() + (index + '')) }))}
-            onChange={(pagination: any, _: any, sortData: any) => {
-                let { current, pageSize } = pagination
-                let newQueryForm = JSON.parse(JSON.stringify(queryForm))
-                if (sortData && sortData?.order) {
-                    newQueryForm['sortAsc'] = sortData?.order === 'ascend' ? true : false
-                    newQueryForm['sortFiled'] = sortData?.field
-                } else {
-                    delete newQueryForm['sortAsc']
-                    delete newQueryForm['sortFiled']
-                }
-                newQueryForm.pageNum = current || newQueryForm.pageNum
-                newQueryForm.pageSize = pageSize || newQueryForm.pageSize
-                setQueryForm({ ...newQueryForm })
-            }}
-        />
-    </div>
-}
-
-export default TencentIaaAd

+ 0 - 3
src/pages/iaaSystem/manage/backPolicy/modalBackPolicy.tsx

@@ -65,9 +65,6 @@ const ModalBackPolicy: React.FC<Props> = ({ onChange, visible, onClose, initialV
             <Form.Item label={<strong>广告千次收益(分)</strong>} name="ecpm">
                 <InputNumber min={0} placeholder="请输入广告千次收益" style={{ minWidth: 472 }} />
             </Form.Item>
-            <Form.Item label={<strong>广告总收益(分)</strong>} name="costTotal">
-                <InputNumber min={0} placeholder="请输入广告千次收益" style={{ minWidth: 472 }} />
-            </Form.Item>
             <Form.Item label={<strong>有效窗口时间(分钟)</strong>} name="validWindowTime">
                 <InputNumber min={0} placeholder="请输入广告千次收益" style={{ minWidth: 472 }} />
             </Form.Item>

+ 0 - 6
src/pages/iaaSystem/manage/backPolicy/tableConfig.tsx

@@ -24,12 +24,6 @@ const tableConfig = (handleEdit: (data: any) => void) => {
             search: false,
             align: 'center'
         },
-        {
-            title: '广告总收益(分)',
-            dataIndex: 'costTotal',
-            search: false,
-            align: 'center'
-        },
         {
             title: '有效窗口时间(分钟)',
             dataIndex: 'validWindowTime',

+ 4 - 0
src/pages/iaaSystem/manage/channel/index.tsx

@@ -12,6 +12,7 @@ import ConfigBackPolicy from "./configBackPolicy";
 import { getAllOfOwnerUserApi, getTtAllUserListApi } from "@/services/iaaSystem";
 import { getAppAuthListApi } from "@/services/iaaSystem/application";
 import { DefaultOptionType } from "antd/lib/select";
+import { copy } from "@/utils/utils";
 
 
 /**
@@ -89,6 +90,9 @@ const Channel: React.FC = () => {
             }}
             headerTitle={<strong>推广渠道</strong>}
             toolBarRender={() => [
+                <Button type="primary" style={{ backgroundColor: '#FF9100', border: '#FF9100' }} onClick={() => copy('https://game.84game.cn/iaaSdk/api/listen/link/oceanengine/callback?promotionId=__PROMOTION_ID__&projectId=__PROJECT_ID__&mid1=__MID1__&mid2=__MID2__&mid3=__MID3__&mid4=__MID4__&mid5=__MID5__&mid6=__MID6__&aid=__AID__&cid=__CID__&campaignId=__CAMPAIGN_ID__&ctype=__CTYPE__&advertiserId=__ADVERTISER_ID__&csite=__CSITE__&convertId=__CONVERT_ID__&requestId=__REQUEST_ID__&trackId=__TRACK_ID__&sl=__SL__&idfa=__IDFA__&idfaMd5=__IDFA_MD5__&androidid=__ANDROIDID__&oaid=__OAID__&oaidMd5=__OAID_MD5__&os=__OS__&mac=__MAC__&mac1=MAC1&ipv4=__IPV4__&ip=__IP__&ua=__UA__&geo=__GEO__&ts=__TS__&callbackParam=__CALLBACK_PARAM__&callbackUrl=__CALLBACK_URL__&model=__MODEL__&unionSite=__UNION_SITE__&caid=__CAID__&outerid=__OUTERID__')}>
+                    复制头条推广链接
+                </Button>,
                 <Button type="primary" onClick={() => {
                     setVisible(true)
                 }}>

+ 2 - 2
src/pages/iaaSystem/manage/channel/modalChannel.tsx

@@ -33,7 +33,7 @@ const ModalChannel: React.FC<Props> = ({ onChange, visible, onClose, initialValu
     const handleOk = async () => {
         form.submit()
         let data: any = await form.validateFields()
-        if (data.accountType === 'OUTSIDE_APPLICATION') {
+        if (data.accountType === 'OUTSIDE_APPLICATION' || data.accountType === 'OCENAENGINE_MINI_GAME') {
             data.accountIdList = data.accountIdList.replace(/[,,\s]/g, ',')
             data.accountIdList = data.accountIdList.split(',')
         }
@@ -83,7 +83,7 @@ const ModalChannel: React.FC<Props> = ({ onChange, visible, onClose, initialValu
                 />
             </Form.Item>
             {accountType && <Form.Item label={<strong>广告账号</strong>} name="accountIdList" rules={[{ required: true, message: '请输入广告账号!' }]}>
-                {['TENCENT_MINI_GAME', 'OCENAENGINE_MINI_GAME'].includes(accountType) ? <Select
+                {['TENCENT_MINI_GAME'].includes(accountType) ? <Select
                     placeholder="请选择广告账号"
                     mode="multiple"
                     filterOption={(input, option) =>

+ 36 - 0
src/pages/iaaSystem/manage/useApp/index.tsx

@@ -0,0 +1,36 @@
+import { useAjax } from "@/Hook/useAjax"
+import { getAppAllApi } from "@/services/iaaSystem/application"
+import ProTable from "@ant-design/pro-table"
+import React from "react"
+import tableConfig from "./tableConfig"
+
+
+/**
+ * 应用管理
+ * @returns 
+ */
+const UseApp: React.FC = () => {
+
+
+    /********************************/
+    const getAppAll = useAjax(() => getAppAllApi(), { type: 'noPage' })
+    /********************************/
+
+    return <>
+        <ProTable<any>
+            columns={tableConfig()}
+            cardBordered
+            request={async (params) => {
+                return await getAppAll.run(params)
+            }}
+            editable={{
+                type: 'multiple',
+            }}
+            rowKey="id"
+            search={false}
+            headerTitle={<strong>应用管理</strong>}
+        />
+    </>
+}
+
+export default UseApp

+ 36 - 0
src/pages/iaaSystem/manage/useApp/tableConfig.tsx

@@ -0,0 +1,36 @@
+import { ProColumns } from "@ant-design/pro-table";
+import React from "react";
+
+
+const tableConfig = () => {
+
+    const columns: ProColumns<any>[] = [
+        {
+            title: '应用',
+            dataIndex: 'name',
+            key: 'name',
+            search: false
+        },
+        {
+            title: 'CP',
+            key: 'cpName',
+            dataIndex: 'cpName',
+            search: false
+        },
+        {
+            title: 'MP名称',
+            key: 'mpName',
+            dataIndex: 'mpName',
+            search: false
+        },
+        {
+            title: 'MPID',
+            key: 'mpId',
+            dataIndex: 'mpId',
+            search: false
+        }
+    ];
+    return columns
+}
+
+export default tableConfig

+ 2 - 2
src/pages/user/login/index.tsx

@@ -272,7 +272,7 @@ const Login: React.FC<{}> = () => {
 						<div className={styles.content}>
 
 							{localStorage.getItem('Admin-Token') && companyList?.length > 0 ? <div className={`${styles.company}  ${isMobile ? '' : show ? '' : styles.login_hide}`}>
-								<h1>IAA应用系统</h1>
+								<h1>趣程集团IAA业务应用数据系统</h1>
 
 								<div className={styles.companyAccount}>
 									<h3 className={styles.title}>请选择公司账户登录</h3>
@@ -292,7 +292,7 @@ const Login: React.FC<{}> = () => {
 								</div>
 
 							</div> : <div className={`${styles.main}  ${isMobile ? '' : show ? '' : styles.login_hide}`}>
-								<h1>IAA应用系统</h1>
+								<h1>趣程集团IAA业务应用数据系统</h1>
 								{/*  (isMobile || location.origin === 'http://localhost:8000' || location.origin.includes('test')) */}
 								{true && <div className={styles.tabs}>
 									<span onClick={() => { setTab(1) }} style={tab === 1 ? { color: localStorage.getItem('color') || '#24DB95' } : {}}>手机</span>

+ 52 - 0
src/services/gameData/index.ts

@@ -173,4 +173,56 @@ export async function getPitcherListNewApi(data: { sourceSystem: string }) {
  */
 export async function getVipLevelApi() {
     return request(api + `/gameData/choice/vip/level`);
+}
+
+
+
+export interface EditAdqAdgroupsProps {
+    /** 广告组id列表 */
+    adgroupIds: number[],
+    /** 广告名称 */
+    adgroupName?: string,
+    /** 出价 */
+    adgroupsUpdateBidAmountDTO?: {
+        bidAmount: number,  // 出价
+        bidMode: string,    // 出价方式
+        bidStrategy: string,// 出价策略
+        optimizationGoal: string,  // 出价目标
+    },
+    /** 排期 */
+    adgroupsUpdateDatetimeDTO?: {
+        beginDate: string,
+        endDate?: string,
+        firstDayBeginTime?: string,
+        timeSeries?: string
+    },
+    /** 深度优化 */
+    deepConversionSpec?: {
+        deepConversionType: string,
+        deepConversionBehaviorSpec?: {
+            bidAmount: number,
+            goal: string
+        },
+        deepConversionWorthAdvancedSpec?: {
+            expectedRoi: number,
+            goal: string
+        },
+        deepConversionWorthSpec?: {
+            expectedRoi: number,
+            goal: string
+        }
+    },
+    /** 启停状态 */
+    configuredStatus?: string
+}
+/**
+ * 腾讯广告启停
+ * @param data 
+ * @returns 
+ */
+export async function newEditAdqAdgroupsDataApi(data: EditAdqAdgroupsProps) {
+    return request(api + `/adq/adgroups/configStatus/update/batch`, {
+        method: 'POST',
+        data
+    });
 }

+ 79 - 0
src/services/iaaData/index.ts

@@ -70,9 +70,88 @@ export async function getGDTListApi(data: GetGDTListProps) {
 }
 
 
+export interface GetGDTDailyListProps extends Paging, SortProps {
+    promotionId: number,
+    costDayBegin?: string,
+    costDayEnd?: string
+}
+/**
+ * 每日
+ * @param data 
+ * @returns 
+ */
+export async function getGDTDailyListApi(data: GetGDTDailyListProps) {
+    return request(wapi + `/monitor/gdt/daily/detail`, {
+        method: 'POST',
+        data
+    });
+}
+
+
 export async function getGDTTotalApi(data: GetGDTListProps) {
     return request(wapi + `/monitor/gdt/total`, {
         method: 'POST',
         data
     });
+}
+
+
+
+export interface GetAppTxEveryDayListProps extends Paging, SortProps {
+    costDayBegin?: string
+    costDayEnd?: string
+}
+/**
+ * 应用每日数据
+ * @param data 
+ * @returns 
+ */
+export async function getAppTxEveryDayListApi(data: GetAppTxEveryDayListProps) {
+    return request(wapi + `/monitor/app/gdt/listOfPage`, {
+        method: 'POST',
+        data
+    });
+}
+
+/**
+ * 应用每日数据 总计
+ * @param data 
+ * @returns 
+ */
+export async function getAppTxEveryDayTotalApi(data: GetAppTxEveryDayListProps) {
+    return request(wapi + `/monitor/app/gdt/total`, {
+        method: 'POST',
+        data
+    });
+}
+
+
+
+export interface getPutUserTxEveryDayListProps extends Paging, SortProps {
+    costDayBegin?: string
+    costDayEnd?: string
+    putUserIdList?: number[]
+}
+/**
+ * 投手每日数据
+ * @param data 
+ * @returns 
+ */
+export async function getPutUserTxEveryDayListApi(data: getPutUserTxEveryDayListProps) {
+    return request(wapi + `/monitor/putUser/gdt/listOfPage`, {
+        method: 'POST',
+        data
+    });
+}
+
+/**
+ * 投手每日数据 总计
+ * @param data 
+ * @returns 
+ */
+export async function getPutUserTxEveryDayTotalApi(data: getPutUserTxEveryDayListProps) {
+    return request(wapi + `/monitor/putUser/gdt/total`, {
+        method: 'POST',
+        data
+    });
 }

+ 86 - 61
src/utils/utils.ts

@@ -8,96 +8,96 @@ const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(
 export const isUrl = (path: string): boolean => reg.test(path);
 
 export const isAntDesignPro = (): boolean => {
-  if (ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site') {
-    return true;
-  }
-  return window.location.hostname === 'preview.pro.ant.design';
+    if (ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site') {
+        return true;
+    }
+    return window.location.hostname === 'preview.pro.ant.design';
 };
 
 // 给官方演示站点用,用于关闭真实开发环境不需要使用的特性
 export const isAntDesignProOrDev = (): boolean => {
-  const { NODE_ENV } = process.env;
-  if (NODE_ENV === 'development') {
-    return true;
-  }
-  return isAntDesignPro();
+    const { NODE_ENV } = process.env;
+    if (NODE_ENV === 'development') {
+        return true;
+    }
+    return isAntDesignPro();
 };
 
 export const getPageQuery = () => {
-  const { href } = window.location;
-  const qsIndex = href.indexOf('?');
-  const sharpIndex = href.indexOf('#');
+    const { href } = window.location;
+    const qsIndex = href.indexOf('?');
+    const sharpIndex = href.indexOf('#');
 
-  if (qsIndex !== -1) {
-    if (qsIndex > sharpIndex) {
-      return parse(href.split('?')[1]);
-    }
+    if (qsIndex !== -1) {
+        if (qsIndex > sharpIndex) {
+            return parse(href.split('?')[1]);
+        }
 
-    return parse(href.slice(qsIndex + 1, sharpIndex));
-  }
+        return parse(href.slice(qsIndex + 1, sharpIndex));
+    }
 
-  return {};
+    return {};
 };
 
 // 排序这是比较函数
 export const compare = (field: string, order: 'descend' | 'ascend') => {
-  // descend 降序 大到小  ascend 升序 小到大
-  if (order === 'ascend') {
-    return function (m: any, n: any) {
-      var a = m[field];
-      var b = n[field];
-      return a - b; //升序
-    }
-  } else {
-    return function (m: any, n: any) {
-      var a = m[field];
-      var b = n[field];
-      return b - a; //降序
+    // descend 降序 大到小  ascend 升序 小到大
+    if (order === 'ascend') {
+        return function (m: any, n: any) {
+            var a = m[field];
+            var b = n[field];
+            return a - b; //升序
+        }
+    } else {
+        return function (m: any, n: any) {
+            var a = m[field];
+            var b = n[field];
+            return b - a; //降序
+        }
     }
-  }
 }
 
 // 返回别名
 export const getChannelName = (name: string) => {
-  let newName = name
-  let abridgeServer: string[] = ['知定', '巨网', '广联', '太古', '云广', '傲星', '弘捷', '开域']
-  let asName = abridgeServer.find((item: string) => name?.indexOf(item) !== -1)
-  if (asName) {
-    newName = asName
-  } else if (newName?.length > 5) {
-    newName = newName?.slice(2, 5) + '...'
-  }
-  return newName
+    let newName = name
+    let abridgeServer: string[] = ['知定', '巨网', '广联', '太古', '云广', '傲星', '弘捷', '开域']
+    let asName = abridgeServer.find((item: string) => name?.indexOf(item) !== -1)
+    if (asName) {
+        newName = asName
+    } else if (newName?.length > 5) {
+        newName = newName?.slice(2, 5) + '...'
+    }
+    return newName
 }
 
 // 输入文案时判断
 export const txtLength = (value?: string) => {
-  if (value) {
-      let length = value?.length
-      let text = value?.replace(/[\x00-\xff]/g, '')
-      return text?.length + Number(((length - text?.length) / 2).toFixed())
-  } else {
-      return 0
-  }
+    if (value) {
+        let length = value?.length
+        let text = value?.replace(/[\x00-\xff]/g, '')
+        return text?.length + Number(((length - text?.length) / 2).toFixed())
+    } else {
+        return 0
+    }
 }
 
 // 点击复制
 export const copy = (str: string) => {
-  let element = document.createElement("textarea");
-  element.id = 'myTextarea'
-  element.textContent = str
-  document.body.append(element);
-  (document.getElementById('myTextarea') as any).select();
-  document.execCommand("Copy")
-  document.body.removeChild(element);
-  message.success(`复制成功:${str}`)
+    let element = document.createElement("textarea");
+    element.id = 'myTextarea'
+    element.textContent = str
+    document.body.append(element);
+    (document.getElementById('myTextarea') as any).select();
+    document.execCommand("Copy")
+    document.body.removeChild(element);
+    message.success(`复制成功:${str}`)
 }
 
 type Type = "day" | "week" | "month" | "year" | "years" | "y" | "months" | "M" | "weeks" | "w" | "days" | "d" | "hour" | "hours" | "h" | "minute"
 type Format = 'YYYY-MM-DD' | 'YYYY-MM-DD HH' | 'YYYY-MM-DD HH:mm' | 'YYYY-MM-DD HH:mm:ss'
 /**往后日期 */
 export function useAddTime(num: number, type: Type, format?: Format, date?: Date | string): string {
-  return moment(date || new Date()).add(num, type).format(format || 'YYYY-MM-DD')
+    return moment(date || new Date()).add(num, type).format(format || 'YYYY-MM-DD')
 }
 
 
@@ -109,8 +109,33 @@ export function useAddTime(num: number, type: Type, format?: Format, date?: Date
  * @returns 
  */
 export const getNumber = (num1: number, num2: number, operator: '+' | '-' | '*' | '/') => {
-  if (!num1) {
-    return '0.00'
-  }
-  return Number(eval(`${num1.toFixed(10)}${operator}${num2.toFixed(10)}`).toFixed(10))
+    if (!num1) {
+        return '0.00'
+    }
+    return Number(eval(`${num1.toFixed(10)}${operator}${num2.toFixed(10)}`).toFixed(10))
+}
+
+/**
+ * 拼接oss参数获取视频首针图
+ * @param videoUrl t_0 0秒的视频截图 t_10000 10秒的视频截图帧
+ */
+export const getVideoImgUrl = (videoUrl: string) => {
+    if (['.mp4', '.swf', '.flv', '.rm', '.ram', '.mov', '.mpg', '.mpeg', '.wmv', '.avi'].some(item => videoUrl.includes(item))) {
+        return videoUrl + "?x-oss-process=video/snapshot,t_0,f_jpg,w_0,h_0,m_fast,ar_auto"
+    }
+    return videoUrl
+}
+
+/**
+ * 秒数格式化
+ * @param seconds 秒
+ * @returns 
+ */
+export function formatSecondsToTime(seconds: number): string {
+    const hours = Math.floor(seconds / 3600);
+    const minutes = Math.floor((seconds % 3600) / 60);
+    const secs = seconds % 60;
+
+    // 使用 padStart 确保每个部分都是两位数  
+    return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
 }