wjx hace 9 meses
padre
commit
a2d721284b

+ 3 - 3
config/defaultSettings.ts

@@ -10,9 +10,9 @@ export default {
   fixedHeader: true,
   fixSiderbar: true,
   colorWeak: false,
-  menu: {
-    locale: false,
-  },
+  // menu: {
+  //   locale: false,
+  // },
   title: '趣程集团IAA系统',
   pwa: false,
   iconfontUrl: '',

+ 11 - 13
config/routerConfig.ts

@@ -1,4 +1,3 @@
-
 /**头部路由一级菜单点击逻辑 */
 function headrRouter(initialState: any, history: any) {
     let ok = true
@@ -90,36 +89,30 @@ const iaaSystem = {
         {
             path: '/iaaSystem/manage',
             name: 'IAA后台管理',
-            access: 'manage',
             routes: [
                 {
                     path: '/iaaSystem/manage/useApp',
                     name: '应用管理',
-                    access: 'useApp',
                     component: './iaaSystem/manage/useApp',
                 },
                 {
                     path: '/iaaSystem/manage/power',
                     name: '角色分配',
-                    access: 'power',
                     component: './iaaSystem/manage/power',
                 },
                 {
                     path: '/iaaSystem/manage/application',
                     name: '应用管理',
-                    access: 'application',
                     component: './iaaSystem/manage/application',
                 },
                 {
                     path: '/iaaSystem/manage/channel',
                     name: '渠道管理',
-                    access: 'channel',
                     component: './iaaSystem/manage/channel',
                 },
                 {
                     path: '/iaaSystem/manage/backPolicy',
                     name: '回传策略管理',
-                    access: 'backPolicy',
                     component: './iaaSystem/manage/backPolicy',
                 }
             ]
@@ -133,39 +126,44 @@ const iaaData = {
         {
             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/appCashTrend',
                     name: '应用变现趋势',
-                    access: 'appCashTrend',
                     component: './iaaData/tencentIaa/appCashTrend',
                 },
                 {
                     path: '/iaaData/tencentIaa/appCashRetained',
                     name: '应用变现留存',
-                    access: 'appCashRetained',
                     component: './iaaData/tencentIaa/appCashRetained',
                 },
                 {
                     path: '/iaaData/tencentIaa/pitcherEveryDay',
                     name: '投手每日数据',
-                    access: 'pitcherEveryDay',
                     component: './iaaData/tencentIaa/pitcherEveryDay',
                 },
             ]
+        },
+        {
+            path: '/iaaData/ocenaengineIaa',
+            name: '头条',
+            routes: [
+                {
+                    path: '/iaaData/ocenaengineIaa/adList',
+                    name: '广告列表',
+                    component: './iaaData/ocenaengineIaa/adList',
+                }
+            ]
         }
     ]
 }

+ 2 - 1
package.json

@@ -83,6 +83,7 @@
     "react-dom": "^16.8.6",
     "react-helmet-async": "^1.0.4",
     "react-image-crop": "^8.6.9",
+    "react-lazyimg-component": "^1.0.1",
     "react-resizable": "^3.0.4",
     "react-responsive-carousel": "^3.2.18",
     "react-sortable-hoc": "^2.0.0",
@@ -135,4 +136,4 @@
   "engines": {
     "node": ">=10.0.0"
   }
-}
+}

+ 13 - 6
src/app.tsx

@@ -1,4 +1,4 @@
-import React, { useEffect } from 'react';
+import React from 'react';
 import { BasicLayoutProps, Settings as LayoutSettings, MenuDataItem } from '@ant-design/pro-layout';
 import { Button, notification, Result } from 'antd';
 import { history } from 'umi';
@@ -144,12 +144,13 @@ const IconMap = {
 
 //处理菜单
 const loopMenuItem = (menus: MenuDataItem[]): MenuDataItem[] => {
+    let mediaPlatform = sessionStorage.getItem('mediaPlatform')
     let menu = menus?.map(({ icon, routes, roles, ...item }) => {
         let newItem = JSON.parse(JSON.stringify(item))
         newItem.key = item?.path || item?.key
         return {
             ...newItem,
-            hideInMenu: false,//校验隐藏菜单
+            hideInMenu: newItem.key.includes('/iaaData/') ? (mediaPlatform === 'MEDIA_PLATFORM_TENCENT' ? newItem.key.includes('/iaaData/tencentIaa') ? false : true : newItem.key.includes("/iaaData/ocenaengineIaa") ? false : true) : false,//校验隐藏菜单
             icon: icon && IconMap[icon as keyof typeof IconMap],
             children: routes && loopMenuItem(routes),
         }
@@ -158,10 +159,17 @@ const loopMenuItem = (menus: MenuDataItem[]): MenuDataItem[] => {
 }
 
 export const layout = ({ initialState }: { initialState: { settings?: LayoutSettings; currentUser?: CurrentUser; menu?: any; loading: boolean, collapsed: string, onCollapse: any, mediaPlatform?: string }; }): BasicLayoutProps => {
+
     return {
-        menuDataRender: () => {
-            return loopMenuItem(initialState?.menu?.data || [])
-        },//解析服务端菜单
+        menu: {
+            locale: false,//关闭国际化
+            params: {//token变化重新获取
+                mediaPlatform: initialState.mediaPlatform
+            },
+            request: async () => {//需要在routes.tsx中配置一份完整的路由
+                return loopMenuItem(initialState?.menu?.data || [])
+            },
+        },
         rightContentRender: () => <RightContent />,
         disableContentMargin: false,
         collapsed: localStorage.collapsed === '1',
@@ -169,7 +177,6 @@ export const layout = ({ initialState }: { initialState: { settings?: LayoutSett
         breakpoint: false,
         // footerRender: () => <Footer />,
         onPageChange: () => {
-            console.log('111111111111')
             headrRouter(initialState, history)
             let { pathname, query } = history.location
             if (query?.t) {//带token直接进入对应页面

+ 25 - 0
src/components/MyUpload/global.less

@@ -0,0 +1,25 @@
+
+.myUpload {
+    position: relative;
+    .ant-upload-list-picture-card-container,
+    .ant-upload.ant-upload-select-picture-card {
+        width: 24px;
+        height: 24px;
+        margin: 0;
+    }
+
+    .look {
+        position: absolute;
+        left: 100px;
+        bottom: 5px;
+        opacity: 0;
+        transition: all .5s;
+        a {
+            font-size: 12px;
+        }
+    }
+
+    &:hover .look{
+        opacity: 1;
+    }
+}

+ 89 - 0
src/components/MyUpload/index.tsx

@@ -0,0 +1,89 @@
+import { message, Space, Upload, Avatar } from "antd"
+import { LoadingOutlined, UserOutlined } from "@ant-design/icons";
+import { RcFile } from "antd/lib/upload";
+import React, { useState } from "react";
+import './global.less'
+import { useAjax } from "@/Hook/useAjax";
+import { getOssInfoApi, updateIconApi } from "@/services/iaaSystem/application";
+import request from "umi-request";
+
+interface Props {
+    id: number
+    value?: string,  // 图片地址
+    onChange?: () => void,
+}
+const MyUpload: React.FC<Props> = (props) => {
+
+    /** 变量START */
+    const { value, id, onChange } = props
+    const [imageFile, setImageFile] = useState<string>(value || '');
+    const [loading, setLoading] = useState<boolean>(false)
+    /** 变量END */
+
+    const getOssInfo = useAjax((params) => getOssInfoApi(params))
+    const updateIcon = useAjax((params) => updateIconApi(params))
+
+    const beforeUpload = async (file: RcFile) => {
+        const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
+        if (!isJpgOrPng) {
+            message.error('您只能上传JPG/PNG文件!');
+        }
+        const isLt2M = file.size / 1024 / 1024 < 10;
+        if (!isLt2M) {
+            message.error('图像必须小于2MB!');
+        }
+        return isJpgOrPng && isLt2M;
+    };
+
+    const uploadButton = (
+        <div>
+            {loading ? <LoadingOutlined /> : <UserOutlined />}
+        </div>
+    );
+
+    return <div className="myUpload">
+        <Space align="start">
+            <Upload
+                name="avatar"
+                listType="picture-card"
+                accept='image/gif,image/jpeg,image/png,image/jpg'
+                className="avatar-uploader"
+                beforeUpload={beforeUpload}
+                maxCount={1}
+                showUploadList={false}
+                customRequest={(options: any) => {
+                    setLoading(true)
+                    getOssInfo.run({ type: 'image/jpeg', fileType: 'image' }).then(async res => {
+                        if (res && (typeof res === 'object') && res?.data) {
+                            let formData = new FormData();
+                            Object.keys(res.data).forEach((key: string) => {
+                                if (key !== 'url') {
+                                    formData.append(key, res.data[key])
+                                }
+                            })
+                            formData.append('file', options.file)
+                            let urlData = await request(res?.data?.ossUrl, { method: 'POST', data: formData }).catch(err => setLoading(false))
+                            setImageFile(urlData?.data?.url);
+                            if (urlData?.data?.url) {
+                                updateIcon.run({id, icon: urlData?.data?.url}).then(res => {
+                                    setLoading(false)
+                                    if (res?.data) {
+                                        message.success('上传成功')
+                                        onChange?.()
+                                    }
+                                }).catch(() => setLoading(false))
+                            } else {
+                                setLoading(false)
+                            }
+                        }
+                    })
+                }}
+            >
+                {imageFile ? <Avatar shape="square" size="small" icon={<UserOutlined />} src={imageFile} /> : uploadButton}
+            </Upload>
+        </Space>
+    </div>
+}
+
+
+export default React.memo(MyUpload)

+ 59 - 21
src/components/RightContent/index.tsx

@@ -1,10 +1,10 @@
-import { Tag, Space, Badge, Modal, Select } from 'antd';
+import { Tag, Space, Badge, Modal, Select, Avatar as AntdAvatar } from 'antd';
 import React, { useCallback, useEffect, useState } from 'react';
 import { useModel } from 'umi';
 import Avatar from './AvatarDropdown';
 import styles from './index.less';
 import { exitFullScreen, requestFullScreen, isFull } from '@/utils/fullScreen'
-import { BellOutlined } from '@ant-design/icons';
+import { BellOutlined, UserOutlined } from '@ant-design/icons';
 import { getAppListApi } from '@/services/iaaData';
 import { useAjax } from '@/Hook/useAjax';
 
@@ -25,45 +25,71 @@ const GlobalHeaderRight: React.FC<{}> = () => {
     const [mediaPlatformList, setMediaPlatformList] = useState<{ label: string, value: string }[]>([])
     const [productType, setProductType] = useState<string>()
 
+    const haveTo = (type: 'MEDIA_PLATFORM_TENCENT' | 'MEDIA_PLATFORM_OCENAENGINE') => {
+        switch (type) {
+            case 'MEDIA_PLATFORM_TENCENT':
+                if (!location.hash.includes('tencentIaa')) {
+                    window.location.href = '/#/iaaData/tencentIaa/adList'
+                }
+                break
+            case 'MEDIA_PLATFORM_OCENAENGINE':
+                if (!location.hash.includes('ocenaengineIaa')) {
+                    window.location.href = '/#/iaaData/ocenaengineIaa/adList'
+                }
+                break
+        }
+    }
+
     useEffect(() => {
         if (location.hash.includes('/iaaData')) {
             getAppList.run().then(res => {
                 if (res?.data) {
                     const productTypeSet = new Set();
                     const mediaPlatformSet = new Set();
-                    const data: { label: string, value: string, productType: string; mediaPlatform: string; icon?: string }[] = res.data.map((item: { name: string; id: number; productType: string; mediaPlatform: string; icon?: string }) => {
+                    const data: { label: string, value: string, productType: string; mediaPlatform: string; icon?: string }[] = res?.data?.map((item: { name: string; id: number; productType: string; mediaPlatform: string; icon?: string }) => {
                         productTypeSet.add(item.productType)
                         mediaPlatformSet.add(item.mediaPlatform)
-                        return { label: item.name, value: item.id + '||' + item.productType, productType: item.productType, mediaPlatform: item.mediaPlatform, icons: item.icon }
+                        return { label: item.name, value: item.id + '||' + item.productType, productType: item.productType, mediaPlatform: item.mediaPlatform, icon: item.icon }
                     })
                     setProductTypeList([{ label: '游戏业务', value: 'PRODUCT_TYPE_GAME' }, { label: '小说业务', value: 'PRODUCT_TYPE_NOVEL' }, { label: '短剧业务', value: 'PRODUCT_TYPE_PLAYLET' }].filter(item => [...productTypeSet].includes(item.value)))
                     setMediaPlatformList([{ label: '腾讯', value: 'MEDIA_PLATFORM_TENCENT' }, { label: '头条', value: 'MEDIA_PLATFORM_OCENAENGINE' }].filter(item => [...mediaPlatformSet].includes(item.value)))
-                    
                     const app = initialState?.iaaApp
-                    const iaaApp = data.some(item => item.value === app) ? app : data?.[0].value || undefined as any
+                    let iaaApp: string;
+                    let mediaPlatform: string;
+                    const d = data.find(item => item.value === app)
+                    if (app && d) {
+                        iaaApp = app
+                        mediaPlatform = d.mediaPlatform
+                    } else {
+                        iaaApp = data?.[0].value || undefined as any
+                        mediaPlatform = data?.[0].mediaPlatform || undefined as any
+                    }
                     const productType = iaaApp ? iaaApp.split('||')?.[1] : undefined
-                    const newAppList = data.filter(item => item.productType === productType)
-                    const mediaPlatform = newAppList?.[0].mediaPlatform
+                    haveTo(mediaPlatform as any)
+                    sessionStorage.setItem('mediaPlatform', mediaPlatform)
                     setProductType(productType)
                     setInitialState({ ...initialState, iaaApp, mediaPlatform })
                     setApplist(data)
                 }
             })
         }
-    }, [location.hash])
+    }, [])
 
 
     useEffect(() => {
-        let nav: any = document.querySelector('.top-nav-menu')
-        let navLi: any = document.querySelectorAll('.top-nav-menu > li')
-        if (nav && navLi) {
-            let l = nav.offsetLeft
-            let lw = 0
-            for (const iterator of navLi) {
-                lw += iterator.offsetWidth
+
+        setTimeout(() => {
+            let nav: any = document.querySelector('.top-nav-menu')
+            let navLi: any = document.querySelectorAll('.top-nav-menu > li')
+            if (nav && navLi) {
+                let l = nav.offsetLeft
+                let lw = 0
+                for (const iterator of navLi) {
+                    lw += iterator.offsetWidth
+                }
+                setLeft(l + lw - 50)
             }
-            setLeft(l + lw - 50)
-        }
+        }, 30)
     }, [])
 
     const { navTheme, layout } = initialState.settings;
@@ -122,6 +148,8 @@ const GlobalHeaderRight: React.FC<{}> = () => {
                     }
                     onChange={(type) => {
                         let newApplist = appList.filter(item => item.productType === type)
+                        sessionStorage.setItem('mediaPlatform', newApplist?.[0]?.mediaPlatform)
+                        newApplist?.[0]?.mediaPlatform && haveTo(newApplist?.[0]?.mediaPlatform as any);
                         setInitialState({ ...initialState, iaaApp: newApplist?.[0]?.value, mediaPlatform: newApplist?.[0]?.mediaPlatform })
                         setProductType(type)
                     }}
@@ -137,6 +165,8 @@ const GlobalHeaderRight: React.FC<{}> = () => {
                     }
                     onChange={(type) => {
                         let newApplist = appList.filter(item => item.productType === productType).filter(item => item.mediaPlatform === type)
+                        sessionStorage.setItem('mediaPlatform', type)
+                        haveTo(type as any)
                         setInitialState({ ...initialState, iaaApp: newApplist?.[0]?.value, mediaPlatform: type })
                     }}
                     value={initialState?.mediaPlatform}
@@ -144,7 +174,7 @@ const GlobalHeaderRight: React.FC<{}> = () => {
                 />
                 <Select
                     showSearch
-                    style={{ width: 150, marginLeft: 10 }}
+                    style={{ width: 200, marginLeft: 10 }}
                     placeholder={'请选择应用'}
                     filterOption={(input, option) =>
                         (option?.label as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
@@ -152,8 +182,16 @@ const GlobalHeaderRight: React.FC<{}> = () => {
                     value={initialState?.iaaApp}
                     onChange={(e) => setInitialState({ ...initialState, iaaApp: e })}
                     loading={getAppList.loading}
-                    options={appList.filter(item => item.productType === productType).filter(item => item.mediaPlatform === initialState?.mediaPlatform)}
-                />
+                >
+                    {appList.filter(item => item.productType === productType).filter(item => item.mediaPlatform === initialState?.mediaPlatform).map(item => {
+                        return <Select.Option key={item.value} value={item.value}>
+                            <Space align='center'>
+                                <AntdAvatar shape="square" style={{ marginBottom: 4 }} size={24} icon={<UserOutlined />} src={item?.icon} />
+                                <span>{item.label}</span>
+                            </Space>
+                        </Select.Option>
+                    })}
+                </Select>
             </div>}
 
             <Space className={className}>

+ 20 - 0
src/global.less

@@ -387,4 +387,24 @@ body {
   &.ant-table-cell-fix-right {
     background-color: #f9f0ff;
   }
+}
+
+.padding_0.ant-table-cell {
+  padding: 0 !important;
+
+  .ant-progress-line,
+  .ant-progress-outer {
+    height: 100%;
+  }
+
+  .ant-progress-inner {
+    border-radius: 0 !important;
+    height: 100%;
+    background-color: transparent;
+  }
+
+  .ant-progress-bg {
+    border-radius: 0 !important;
+    height: 100% !important;
+  }
 }

+ 4 - 3
src/pages/iaaData/components/CreativePreview/cpTableConfig.tsx

@@ -2,6 +2,7 @@ import React from "react"
 import { Space, Typography } from "antd"
 import style from './index.less'
 import VideoNews from "../newsModal/videoNews";
+import Lazyimg from "react-lazyimg-component";
 
 const { Text, Title } = Typography;
 
@@ -38,11 +39,11 @@ function cpTableConfig(): any {
                                     </div>
                                 </> : b?.image ? <>
                                     <div className={style.cover_image}>
-                                        <img src={b?.image?.[0]?.value?.imageUrl} />
+                                    <Lazyimg 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} />
+                                        <Lazyimg src={item?.imageUrl} />
                                     </div>)}
                                 </> : null}
                             </div>
@@ -98,7 +99,7 @@ function cpTableConfig(): any {
                 }
             }
         },
-        
+
         // {
         //     title: '轮播',
         //     dataIndex: 'floatingZone',

+ 9 - 2
src/pages/iaaData/components/CreativePreview/index.tsx

@@ -2,6 +2,7 @@ import { Popover, Space, Table } from "antd"
 import React from "react"
 import './index.less'
 import cpTableConfig from "./cpTableConfig"
+import Lazyimg from "react-lazyimg-component"
 
 interface Props {
     deliveryMode: string[]
@@ -98,9 +99,15 @@ const CreativePreview: React.FC<Props> = ({ creativePreview, deliveryMode }) =>
         >
             <div>
                 {video ? <video src={video} style={{ maxHeight: 18, maxWidth: 25 }} /> : imageUrl ? <div>
-                    {imageUrl ? <img src={imageUrl} height={18} /> : <span>无图片地址</span>}
+                    {imageUrl ? <><Lazyimg
+                        src={imageUrl}
+                        height={18}
+                    /></> : <span>无图片地址</span>}
                 </div> : (titles && titles?.length > 0) ? <Space>
-                    <img src={titles?.[0]?.value?.brandImageUrl} height={18} />
+                    <><Lazyimg
+                        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>

+ 10 - 0
src/pages/iaaData/ocenaengineIaa/adList/index.tsx

@@ -0,0 +1,10 @@
+import React from "react"
+
+
+const AdList: React.FC = () => {
+
+
+    return <div>111111</div>
+}
+
+export default AdList

+ 51 - 27
src/pages/iaaData/tencentIaa/adList/tableConfig.tsx

@@ -1,5 +1,5 @@
 import WidthEllipsis from "@/components/widthEllipsis"
-import { Badge, Space, Statistic } from "antd"
+import { Badge, Progress, Space, Statistic } from "antd"
 import React from "react"
 import { AD_STATUS_ENUM, BID_MODE_ENUM, PRODUCT_TYPE_ENUM } from "../../const"
 import SwitchStatus from "./switchStatus"
@@ -50,7 +50,7 @@ function columns12(dayHandle: (data: any) => void, onChange?: () => void): { lab
                 },
                 {
                     title: '余额', dataIndex: 'balance', label: '腾讯广告列表', align: 'right', width: 75, sorter: true, default: 11,
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '竞价信用账户', dataIndex: 'creditRollBalance', label: '腾讯广告列表', align: 'center', width: 85,
@@ -105,12 +105,36 @@ function columns12(dayHandle: (data: any) => void, onChange?: () => void): { lab
                     render: (a: string, b: any) => (<WidthEllipsis value={a} />)
                 },
                 {
-                    title: '今日消耗', dataIndex: 'cost', label: '腾讯广告列表', align: 'right', width: 85, 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: 'cost', label: '腾讯广告列表', align: 'center', width: 85, default: 20, sorter: true, 
+                    className: 'padding_0',
+                    render: (a: number) => <div style={{ height: 27, position: 'relative' }}>
+                        <Progress
+                            strokeColor={{
+                                from: '#ff5900',
+                                to: '#ffd380',
+                            }}
+                            status="active"
+                            showInfo={false}
+                            percent={a ? a / 20000 * 100 : 0}
+                        />
+                        <span style={{ position: 'absolute', left: 0, top: 2, bottom: 0, right: 0, padding: '0 5px' }}><Statistic value={a || 0} valueStyle={a >= 20000 ? { color: '#000', fontWeight: 500 } : { fontWeight: 500 }} /></span>
+                    </div>
+                },
+                {
+                    title: '广告总消耗', dataIndex: 'totalCost', label: '腾讯广告列表', align: 'center', width: 85, default: 21, sorter: true,
+                    className: 'padding_0',
+                    render: (a: number) => <div style={{ height: 27, position: 'relative' }}>
+                        <Progress
+                            strokeColor={{
+                                from: '#10c1e9',
+                                to: '#6892d0',
+                            }}
+                            status="active"
+                            showInfo={false}
+                            percent={a ? a / 20000 * 100 : 0}
+                        />
+                        <span style={{ position: 'absolute', left: 0, top: 2, bottom: 0, right: 0, padding: '0 5px' }}><Statistic value={a || 0} valueStyle={a >= 20000 ? { color: '#000', fontWeight: 500 } : { fontWeight: 500 }} /></span>
+                    </div>
                 },
                 {
                     title: '点击量', dataIndex: 'validClickCount', label: '腾讯广告列表', align: 'center', width: 70, default: 22, sorter: true,
@@ -126,11 +150,11 @@ function columns12(dayHandle: (data: any) => void, onChange?: () => void): { lab
                 },
                 {
                     title: '千次曝光成本', dataIndex: 'thousandDisplayPrice', label: '腾讯广告列表', align: 'right', width: 65, default: 25, sorter: true,
-                    render: (a: string) => <Statistic value={a || 0}precision={2} />
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '点击均价', dataIndex: 'cpc', label: '腾讯广告列表', align: 'center', width: 65, default: 26, sorter: true,
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '转化目标', dataIndex: 'convertTarget', label: '基本信息', align: 'center', width: 65, default: 27, sorter: true,
@@ -154,7 +178,7 @@ function columns12(dayHandle: (data: any) => void, onChange?: () => void): { lab
                 },
                 {
                     title: '小游戏注册成本', dataIndex: 'miniGameRegisterCost', label: '基本信息', align: 'center', width: 80, default: 32, sorter: true,
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '小游戏注册率', dataIndex: 'miniGameRegisterRate', label: '腾讯广告列表', align: 'center', width: 75, default: 33, sorter: true,
@@ -233,23 +257,23 @@ function columns12(dayHandle: (data: any) => void, onChange?: () => void): { lab
                 },
                 {
                     title: '激活首24小时广告变现金额(平台上报)', dataIndex: 'incomeVal24hPla', label: '其他业务(平台上报指标)', width: 110, align: 'center', sorter: true, className: 'green2ColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '注册首日广告变现金额(平台上报)', dataIndex: 'miniGameFirstDayAdMonetizationAmount', label: '其他业务(平台上报指标)', width: 120, align: 'center', sorter: true, className: 'green2ColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '注册7日广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmountD7', label: '其他业务(平台上报指标)', width: 110, align: 'center', sorter: true, className: 'green2ColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '激活14日广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmountD14', label: '其他业务(平台上报指标)', width: 110, align: 'center', sorter: true, className: 'green2ColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmount', label: '其他业务(平台上报指标)', width: 100, align: 'center', sorter: true, className: 'green2ColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '激活首24小时广告变现人数(平台上报)', dataIndex: 'adPayingUsers24hPla', label: '其他业务(平台上报指标)', width: 115, align: 'center', sorter: true, className: 'green2ColorClass',
@@ -306,11 +330,11 @@ function columns12(dayHandle: (data: any) => void, onChange?: () => void): { lab
                 },
                 {
                     title: '激活首日广告变现成本(人数)', dataIndex: 'adPayingCostD1', label: '其他业务(其他指标)', width: 100, align: 'center', sorter: true, className: 'volcanoColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '广告变现成本', dataIndex: 'adMonetizationCost', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true, className: 'volcanoColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '激活3日广告变现次数', dataIndex: 'adMonetizationActive3dPv', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true, className: 'volcanoColorClass',
@@ -326,27 +350,27 @@ function columns12(dayHandle: (data: any) => void, onChange?: () => void): { lab
                 },
                 {
                     title: '激活首24小时广告变现金额', dataIndex: 'incomeVal24h', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true, className: 'volcanoColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '激活首日广告变现金额', dataIndex: 'incomeVal1', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true, className: 'volcanoColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '激活3日广告变现金额', dataIndex: 'incomeVal3', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true, className: 'volcanoColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '激活7日广告变现金额', dataIndex: 'incomeVal7', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true, className: 'volcanoColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '激活14日广告变现金额', dataIndex: 'incomeVal14', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true, className: 'volcanoColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '广告变现金额', dataIndex: 'adMonetizationAmount', label: '其他业务(其他指标)', width: 80, align: 'center', sorter: true, className: 'volcanoColorClass',
-                    render: (a: string) => <Statistic value={a || 0}precision={2} />
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '激活首24小时广告变现人数', dataIndex: 'adPayingUsers24h', label: '其他业务(其他指标)', width: 90, align: 'center', sorter: true, className: 'volcanoColorClass',
@@ -487,15 +511,15 @@ function columns12(dayHandle: (data: any) => void, onChange?: () => void): { lab
                 },
                 {
                     title: '小游戏注册首日广告变现成本(平台上报)', dataIndex: 'miniGameFirstDayAdPayingCost', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true, className: 'purple1ColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '小游戏广告变现成本(平台上报)', dataIndex: 'miniGameAdMonetizationCost', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true, className: 'purple1ColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '小游戏注册3日广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmountD3', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true, className: 'purple1ColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '小游戏注册首日广告变现人数(平台上报)', dataIndex: 'miniGameFirstDayAdMonetizationUsers', label: '小游戏(平台上报)', width: 110, align: 'center', sorter: true, className: 'purple1ColorClass',

+ 34 - 10
src/pages/iaaData/tencentIaa/appCashRetained/tableConfig.tsx

@@ -1,5 +1,5 @@
 import WidthEllipsis from "@/components/widthEllipsis"
-import { Statistic } from "antd"
+import { Progress, Statistic } from "antd"
 import React from "react"
 import { PRODUCT_TYPE_ENUM } from "../../const"
 import { formatSecondsToTime } from "@/utils/utils"
@@ -62,11 +62,35 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 // },
                 {
                     title: '总消耗', dataIndex: 'totalCost', label: '基本信息', align: 'right', width: 95, default: 6, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} style={{ fontWeight: 'bold' }} precision={2} />
+                    className: 'padding_0',
+                    render: (a: number) => <div style={{ height: 53.8, position: 'relative' }}>
+                        <Progress
+                            strokeColor={{
+                                from: '#10c1e9',
+                                to: '#6892d0',
+                            }}
+                            status="active"
+                            showInfo={false}
+                            percent={a ? a / 20000 * 100 : 0}
+                        />
+                        <span style={{ position: 'absolute', left: '50%', top: '50%', width: '100%', padding: '0 5px', transform: 'translate(-50%, -50%)' }}><Statistic value={a || 0} precision={2} valueStyle={a >= 20000 ? { color: '#000', fontWeight: 'bold' } : { fontWeight: 'bold' }} /></span>
+                    </div>
                 },
                 {
                     title: '消耗', dataIndex: 'cost', label: '基本信息', align: 'right', width: 85, default: 7, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} style={{ fontWeight: 'bold' }} precision={2} />
+                    className: 'padding_0',
+                    render: (a: number) => <div style={{ height: 53.8, position: 'relative' }}>
+                        <Progress
+                            strokeColor={{
+                                from: '#ff5900',
+                                to: '#ffd380',
+                            }}
+                            status="active"
+                            showInfo={false}
+                            percent={a ? a / 20000 * 100 : 0}
+                        />
+                        <span style={{ position: 'absolute', left: '50%', top: '50%', width: '100%', padding: '0 5px', transform: 'translate(-50%, -50%)' }}><Statistic value={a || 0} precision={2} valueStyle={a >= 20000 ? { color: '#000', fontWeight: 'bold' } : { fontWeight: 'bold' }} /></span>
+                    </div>
                 },
                 {
                     title: '赔付金', dataIndex: 'payout', label: '基本信息', align: 'right', width: 80, default: 8, sorter: true,
@@ -94,17 +118,17 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 {
                     title: '人均在线时长', dataIndex: 'avgDuration', label: '基本信息', align: 'center', width: 110, default: 14, sorter: true,
-                    render: (a: number) => {
-                        return formatSecondsToTime(a ? Math.round(a) : 0)
+                    render: (a: number, b: any) => {
+                        return b.dt === '总计' ? '--' : formatSecondsToTime(a ? Math.round(a) : 0)
                     }
                 },
                 {
                     title: '人均启动次数', dataIndex: 'avgStartTimes', label: '基本信息', align: 'center', width: 70, default: 15, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number, b: any) => b.dt === '总计' ? '--' : <Statistic value={a || 0} />
                 },
                 {
                     title: '人均观看广告次数', dataIndex: 'avgAdViewTimes', label: '基本信息', align: 'center', width: 80, default: 16, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number, b: any) => b.dt === '总计' ? '--' : <Statistic value={a || 0} />
                 },
                 {
                     title: '广告变现UV', dataIndex: 'adMonetizeUv', label: '基本信息', align: 'center', width: 75, default: 17, sorter: true,
@@ -112,11 +136,11 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 {
                     title: 'ecpm', dataIndex: 'ecpm', label: '基本信息', align: 'center', width: 80, default: 18, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                    render: (a: number, b: any) => b.dt === '总计' ? '--' : <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '广告渗透率', dataIndex: 'adPermeability', label: '基本信息', align: 'center', width: 75, default: 19, sorter: true,
-                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                    render: (a: number, b: any) => b.dt === '总计' ? '--' : <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
                 },
                 {
                     title: '广告ARPU', dataIndex: 'adArpu', label: '基本信息', align: 'center', width: 80, default: 20, sorter: true,
@@ -124,7 +148,7 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 {
                     title: '广告曝光量', tips: '总收入/ecpm*1000', dataIndex: 'adViewCount', label: '基本信息', align: 'center', width: 80, default: 21, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number, b: any) => b.dt === '总计' ? '--' : <Statistic value={a || 0} />
                 },
                 {
                     title: '总收入', dataIndex: 'income', label: '基本信息', align: 'right', width: 80, default: 22, sorter: true,

+ 34 - 10
src/pages/iaaData/tencentIaa/appCashTrend/tableConfig.tsx

@@ -1,5 +1,5 @@
 import WidthEllipsis from "@/components/widthEllipsis"
-import { Statistic } from "antd"
+import { Progress, Statistic } from "antd"
 import React from "react"
 import { PRODUCT_TYPE_ENUM } from "../../const"
 import { formatSecondsToTime } from "@/utils/utils"
@@ -113,11 +113,35 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 // },
                 {
                     title: '总消耗', dataIndex: 'totalCost', label: '基本信息', align: 'right', width: 95, default: 6, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} style={{ fontWeight: 'bold' }} precision={2} />
+                    className: 'padding_0',
+                    render: (a: number) => <div style={{ height: 107, position: 'relative' }}>
+                        <Progress
+                            strokeColor={{
+                                from: '#10c1e9',
+                                to: '#6892d0',
+                            }}
+                            status="active"
+                            showInfo={false}
+                            percent={a ? a / 20000 * 100 : 0}
+                        />
+                        <span style={{ position: 'absolute', left: '50%', top: '50%', width: '100%', padding: '0 5px', transform: 'translate(-50%, -50%)' }}><Statistic style={{ fontWeight: 'bold' }} value={a || 0} precision={2} valueStyle={a >= 20000 ? { color: '#000', fontWeight: 'bold' } : { fontWeight: 'bold' }} /></span>
+                    </div>
                 },
                 {
                     title: '消耗', dataIndex: 'cost', label: '基本信息', align: 'right', width: 85, default: 7, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} style={{ fontWeight: 'bold' }} precision={2} />
+                    className: 'padding_0',
+                    render: (a: number) => <div style={{ height: 107, position: 'relative' }}>
+                        <Progress
+                            strokeColor={{
+                                from: '#ff5900',
+                                to: '#ffd380',
+                            }}
+                            status="active"
+                            showInfo={false}
+                            percent={a ? a / 20000 * 100 : 0}
+                        />
+                        <span style={{ position: 'absolute', left: '50%', top: '50%', width: '100%', padding: '0 5px', transform: 'translate(-50%, -50%)' }}><Statistic value={a || 0} precision={2} valueStyle={a >= 20000 ? { color: '#000', fontWeight: 'bold' } : { fontWeight: 'bold' }} /></span>
+                    </div>
                 },
                 {
                     title: '赔付金', dataIndex: 'payout', label: '基本信息', align: 'right', width: 80, default: 8, sorter: true,
@@ -145,17 +169,17 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 {
                     title: '人均在线时长', dataIndex: 'avgDuration', label: '基本信息', align: 'center', width: 110, default: 14, sorter: true,
-                    render: (a: number) => {
-                        return formatSecondsToTime(a ? Math.round(a) : 0)
+                    render: (a: number, b: any) => {
+                        return b.dt === '总计' ? '--' : formatSecondsToTime(a ? Math.round(a) : 0)
                     }
                 },
                 {
                     title: '人均启动次数', dataIndex: 'avgStartTimes', label: '基本信息', align: 'center', width: 70, default: 15, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number, b: any) => b.dt === '总计' ? '--' : <Statistic value={a || 0} />
                 },
                 {
                     title: '人均观看广告次数', dataIndex: 'avgAdViewTimes', label: '基本信息', align: 'center', width: 80, default: 16, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number, b: any) => b.dt === '总计' ? '--' : <Statistic value={a || 0} />
                 },
                 {
                     title: '广告变现UV', dataIndex: 'adMonetizeUv', label: '基本信息', align: 'center', width: 75, default: 17, sorter: true,
@@ -163,11 +187,11 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 {
                     title: 'ecpm', dataIndex: 'ecpm', label: '基本信息', align: 'center', width: 80, default: 18, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} precision={2} />
+                    render: (a: number, b: any) => b.dt === '总计' ? '--' : <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '广告渗透率', dataIndex: 'adPermeability', label: '基本信息', align: 'center', width: 75, default: 19, sorter: true,
-                    render: (a: number) => <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
+                    render: (a: number, b: any) => b.dt === '总计' ? '--' : <Statistic value={a ? a * 100 : 0} precision={2} valueStyle={!a ? {} : a >= 0.5 ? { color: 'red' } : { color: '#0f990f' }} suffix="%" />
                 },
                 {
                     title: '广告ARPU', dataIndex: 'adArpu', label: '基本信息', align: 'center', width: 80, default: 20, sorter: true,
@@ -175,7 +199,7 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 {
                     title: '广告曝光量', tips: '总收入/ecpm*1000', dataIndex: 'adViewCount', label: '基本信息', align: 'center', width: 80, default: 21, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} />
+                    render: (a: number, b: any) => b.dt === '总计' ? '--' : <Statistic value={a || 0} />
                 },
                 {
                     title: '总收入', dataIndex: 'income', label: '基本信息', align: 'right', width: 80, default: 22, sorter: true,

+ 35 - 11
src/pages/iaaData/tencentIaa/appEveryDayData/tableConfig.tsx

@@ -1,5 +1,5 @@
 import WidthEllipsis from "@/components/widthEllipsis"
-import { Statistic } from "antd"
+import { Progress, Statistic } from "antd"
 import React from "react"
 import { PRODUCT_TYPE_ENUM } from "../../const"
 import { formatSecondsToTime } from "@/utils/utils"
@@ -12,40 +12,64 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
             label: '基本信息',
             data: [
                 {
-                    title: '应用', dataIndex: 'appName', label: '基本信息', align: 'center', width: 120, default: 1, 
+                    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, 
+                    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, 
+                    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, 
+                    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, 
+                    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, 
+                    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, className: 'redColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2} />
+                    title: '累计消耗', dataIndex: 'costToday', label: '基本信息', align: 'center', width: 95, default: 5, sorter: true,
+                    className: 'padding_0 redColorClass',
+                    render: (a: number) => <div style={{ height: 26, position: 'relative' }}>
+                        <Progress
+                            strokeColor={{
+                                from: '#10c1e9',
+                                to: '#6892d0',
+                            }}
+                            status="active"
+                            showInfo={false}
+                            percent={a ? a / 20000 * 100 : 0}
+                        />
+                        <span style={{ position: 'absolute', left: '50%', top: '50%', width: '100%', padding: '0 5px', transform: 'translate(-50%, -50%)' }}><Statistic style={{ fontWeight: 'bold' }} value={a || 0} precision={2} valueStyle={a >= 20000 ? { color: '#000', fontWeight: 'bold' } : { fontWeight: 'bold' }} /></span>
+                    </div>
                 },
                 {
                     title: '每日真实消耗', dataIndex: 'costTotal', label: '基本信息', align: 'center', width: 90, default: 6, sorter: true, className: 'redColorClass',
                     render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
-                    title: '每日消耗', dataIndex: 'cost', label: '基本信息', align: 'center', width: 85, default: 7, sorter: true, className: 'redColorClass',
-                    render: (a: string) => <Statistic value={a || 0} precision={2} />
+                    title: '每日消耗', dataIndex: 'cost', label: '基本信息', align: 'center', width: 85, default: 7, sorter: true,
+                    className: 'padding_0 redColorClass',
+                    render: (a: number) => <div style={{ height: 26, position: 'relative' }}>
+                        <Progress
+                            strokeColor={{
+                                from: '#ff5900',
+                                to: '#ffd380',
+                            }}
+                            status="active"
+                            showInfo={false}
+                            percent={a ? a / 20000 * 100 : 0}
+                        />
+                        <span style={{ position: 'absolute', left: '50%', top: '50%', width: '100%', padding: '0 5px', transform: 'translate(-50%, -50%)' }}><Statistic value={a || 0} precision={2} valueStyle={a >= 20000 ? { color: '#000', fontWeight: 'bold' } : { fontWeight: 'bold' }} /></span>
+                    </div>
                 },
                 {
                     title: '每日赔付金', dataIndex: 'payout', label: '基本信息', align: 'center', width: 80, default: 8, sorter: true, className: 'redColorClass',

+ 51 - 27
src/pages/iaaData/tencentIaa/pitcherEveryDay/tableConfig.tsx

@@ -1,5 +1,5 @@
 import WidthEllipsis from "@/components/widthEllipsis"
-import { Badge, Statistic } from "antd"
+import { Badge, Progress, Statistic } from "antd"
 import React from "react"
 import { PRODUCT_TYPE_ENUM } from "../../const"
 
@@ -36,15 +36,39 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 {
                     title: '总消耗', dataIndex: 'cost', label: '基本信息', align: 'center', width: 90, default: 6, sorter: true,
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    className: 'padding_0',
+                    render: (a: number) => <div style={{ height: 26, position: 'relative' }}>
+                        <Progress
+                            strokeColor={{
+                                from: '#10c1e9',
+                                to: '#6892d0',
+                            }}
+                            status="active"
+                            showInfo={false}
+                            percent={a ? a / 20000 * 100 : 0}
+                        />
+                        <span style={{ position: 'absolute', left: '50%', top: '50%', width: '100%', padding: '0 5px', transform: 'translate(-50%, -50%)' }}><Statistic style={{ fontWeight: 'bold' }} value={a || 0} precision={2} valueStyle={a >= 20000 ? { color: '#000', fontWeight: 'bold' } : { fontWeight: 'bold' }} /></span>
+                    </div>
                 },
                 {
                     title: '消耗', dataIndex: 'costToday', label: '基本信息', align: 'center', width: 85, default: 7, sorter: true,
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    className: 'padding_0',
+                    render: (a: number) => <div style={{ height: 26, position: 'relative' }}>
+                        <Progress
+                            strokeColor={{
+                                from: '#ff5900',
+                                to: '#ffd380',
+                            }}
+                            status="active"
+                            showInfo={false}
+                            percent={a ? a / 20000 * 100 : 0}
+                        />
+                        <span style={{ position: 'absolute', left: '50%', top: '50%', width: '100%', padding: '0 5px', transform: 'translate(-50%, -50%)' }}><Statistic value={a || 0} precision={2} valueStyle={a >= 20000 ? { color: '#000', fontWeight: 'bold' } : { fontWeight: 'bold' }} /></span>
+                    </div>
                 },
                 {
                     title: '赔付金', dataIndex: 'payout', label: '基本信息', align: 'center', width: 80, default: 8, sorter: true,
-                    render: (a: string) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: string) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '推广广告账号数量', tips: '消耗大于0', dataIndex: 'accountCount', label: '基本信息', align: 'center', width: 80, default: 9, sorter: true,
@@ -69,11 +93,11 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 {
                     title: '千次曝光成本', dataIndex: 'thousandDisplayPrice', label: '基础数据', align: 'center', width: 80, default: 13, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                    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}/>
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '小游戏注册人数', dataIndex: 'miniGameRegisterUsers', label: '基础数据', align: 'center', width: 80, default: 15, sorter: true,
@@ -81,7 +105,7 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 {
                     title: '小游戏注册成本', dataIndex: 'miniGameRegisterCost', label: '基础数据', align: 'center', width: 80, default: 16, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '小游戏注册率', dataIndex: 'miniGameRegisterRate', label: '基础数据', align: 'center', width: 80, default: 17, sorter: true,
@@ -106,19 +130,19 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 {
                     title: '注册首日广告变现金额(平台上报)', dataIndex: 'miniGameFirstDayAdMonetizationAmount', label: 'D1数据', align: 'center', width: 90, default: 21, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                    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}/>
+                    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}/>
+                    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}/>
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '首日ROI', dataIndex: 'miniGameFirstDayAdPayingRoi', label: 'D1数据', align: 'center', width: 80, default: 25, sorter: true,
@@ -139,19 +163,19 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 {
                     title: '激活首24小时广告变现金额(平台上报)', dataIndex: 'incomeVal24hPla', label: '24小时数据', align: 'center', width: 90, default: 28, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                    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}/>
+                    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}/>
+                    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}/>
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '24小时广告变现ROI', dataIndex: 'firstDayAdPurArpuCost24hPlaRoi', label: '24小时数据', align: 'center', width: 80, default: 32, sorter: true,
@@ -180,19 +204,19 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 {
                     title: '小游戏注册3日广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmountD3', label: 'D3数据', align: 'center', width: 90, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                    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}/>
+                    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}/>
+                    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}/>
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '3日广告变现ROI', dataIndex: 'adPurDay3Roi', label: 'D3数据', align: 'center', width: 80, sorter: true,
@@ -217,19 +241,19 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 {
                     title: '小游戏注册7日广告变现金额(平台上报)', dataIndex: 'miniGameRegD7Amount', label: 'D7数据', align: 'center', width: 90, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                    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}/>
+                    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}/>
+                    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}/>
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '7日广告变现ROI', dataIndex: 'miniGameRegD7Roi', label: 'D7数据', align: 'center', width: 80, sorter: true,
@@ -250,19 +274,19 @@ function columns12(): { label: string, fieldSHow?: { label: string, saveField: s
                 },
                 {
                     title: '广告变现金额(平台上报)', dataIndex: 'miniGameAdMonetizationAmount', label: 'D总数据', align: 'center', width: 80, default: 35, sorter: true,
-                    render: (a: number) => <Statistic value={a || 0} precision={2}/>
+                    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}/>
+                    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}/>
+                    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}/>
+                    render: (a: number) => <Statistic value={a || 0} precision={2} />
                 },
                 {
                     title: '广告变现总ROI', dataIndex: 'miniGameAdMonetizationRoi', label: 'D总数据', align: 'center', width: 80, default: 39, sorter: true,

+ 24 - 12
src/pages/iaaSystem/manage/useApp/tableConfig.tsx

@@ -1,3 +1,4 @@
+import MyUpload from "@/components/MyUpload";
 import { UserOutlined } from "@ant-design/icons";
 import { ProColumns } from "@ant-design/pro-table";
 import { Avatar, Space } from "antd";
@@ -21,13 +22,22 @@ const tableConfig = () => {
             key: 'name',
             search: false,
             width: 250,
-            render(_, entity) {
+            render(_, entity, index, action) {
                 return <Space>
-                    <Avatar shape="square" size="small" icon={<UserOutlined />} src={entity?.icon} />
+                    <MyUpload id={entity.id} value={entity.icon} onChange={() => action?.reload()}/>
+                    {/* <Avatar shape="square" size="small" icon={<UserOutlined />} src={entity?.icon} /> */}
                     <span>{entity?.name}</span>
                 </Space>
             },
         },
+        {
+            title: '公司主体',
+            key: 'company',
+            dataIndex: 'company',
+            search: false,
+            width: 200,
+            ellipsis: true
+        },
         {
             title: 'CP',
             key: 'cpName',
@@ -36,27 +46,21 @@ const tableConfig = () => {
             align: 'center',
             width: 80
         },
-        {
-            title: 'CPID',
-            key: 'cpId',
-            dataIndex: 'cpId',
-            search: false,
-            align: 'center',
-            width: 60
-        },
         {
             title: '应用标识',
             key: 'appKey',
             dataIndex: 'appKey',
             search: false,
-            width: 150
+            width: 120,
+            align: 'center'
         },
         {
             title: 'MP名称',
             key: 'mpName',
             dataIndex: 'mpName',
             search: false,
-            width: 150
+            width: 150,
+            align: 'center'
         },
         {
             title: 'MPID',
@@ -107,6 +111,14 @@ const tableConfig = () => {
                 MEDIA_PLATFORM_OCENAENGINE: { text: '头条' },
             }
         },
+        {
+            title: '上线时间',
+            key: 'dataStartTime',
+            dataIndex: 'dataStartTime',
+            search: false,
+            width: 110,
+            align: 'center'
+        },
     ];
     return columns
 }

+ 23 - 0
src/services/iaaSystem/application.ts

@@ -81,4 +81,27 @@ export async function getAppAuthListApi() {
     return request(iaaApi + `/app/auth/list`, {
         method: 'GET'
     });
+}
+
+/**
+ * 获取Oss
+ * @returns 
+ */
+export async function getOssInfoApi(params: any) {
+    return request(iaaApi + `/oss/form/upload`, {
+        method: 'GET',
+        params
+    });
+}
+
+/**
+ * 更新头像
+ * @param param0 
+ * @returns 
+ */
+export async function updateIconApi(data: { id: number, icon: string }) {
+    return request(iaaApi + `/app/update/icon`, {
+        method: 'POST',
+        data
+    });
 }

+ 20 - 0
src/utils/utils.ts

@@ -1,6 +1,7 @@
 import { message } from 'antd';
 import { parse } from 'querystring';
 import moment from 'moment';
+import { RcFile } from 'antd/lib/upload';
 
 /* eslint no-useless-escape:0 import/prefer-default-export:0 */
 const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
@@ -138,4 +139,23 @@ export function formatSecondsToTime(seconds: number): string {
 
     // 使用 padStart 确保每个部分都是两位数  
     return `${hours > 24 ? `${Math.floor(hours / 24)}天${hours % 24}` : String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
+}
+
+/** 获取base64 */
+export const getBase64 = (file: RcFile, callback: (url: string) => void) => {
+    const reader = new FileReader();
+    reader.addEventListener('load', () => callback(reader.result as string));
+    reader.readAsDataURL(file);
+};
+
+/** 获取图片上传宽高 */
+export const getImgSizeProper = (file: RcFile): Promise<void> => {
+    return new Promise((resolve: (value: any | PromiseLike<void>) => void) => {
+        let img: any = new Image();
+        let _URL = window.URL || window.webkitURL;
+        img.onload = function (e: any) {
+            resolve({ width: this.width, height: this.height })
+        }
+        img.src = _URL.createObjectURL(file);
+    })
 }