wjx 1 rok pred
rodič
commit
f06b6bb009

+ 117 - 0
src/components/VirtualTable/index.tsx

@@ -0,0 +1,117 @@
+import { Table } from 'antd';
+import type { TableProps } from 'antd';
+import classNames from 'classnames';
+import ResizeObserver from 'rc-resize-observer';
+import React, { useEffect, useRef, useState } from 'react';
+import { VariableSizeGrid as Grid } from 'react-window';
+
+const VirtualTable = <RecordType extends object>(props: TableProps<RecordType>) => {
+    const { columns, scroll } = props;
+    const [tableWidth, setTableWidth] = useState(0);
+
+    const widthColumnCount = columns!.filter(({ width }) => !width).length;
+    const mergedColumns = columns!.map(column => {
+        if (column.width) {
+            return column;
+        }
+
+        return {
+            ...column,
+            width: Math.floor(tableWidth / widthColumnCount),
+        };
+    });
+
+    const gridRef = useRef<any>();
+    const [connectObject] = useState<any>(() => {
+        const obj = {};
+        Object.defineProperty(obj, 'scrollLeft', {
+            get: () => {
+                if (gridRef.current) {
+                    return gridRef.current?.state?.scrollLeft;
+                }
+                return null;
+            },
+            set: (scrollLeft: number) => {
+                if (gridRef.current) {
+                    gridRef.current.scrollTo({ scrollLeft });
+                }
+            },
+        });
+
+        return obj;
+    });
+
+    const resetVirtualGrid = () => {
+        gridRef.current?.resetAfterIndices({
+            columnIndex: 0,
+            shouldForceUpdate: true,
+        });
+    };
+
+    useEffect(() => resetVirtualGrid, [tableWidth]);
+
+    const renderVirtualList = (rawData: object[], { scrollbarSize, ref, onScroll }: any) => {
+        ref.current = connectObject;
+        const totalHeight = rawData.length * 54;
+
+        return (
+            <Grid
+                ref={gridRef}
+                className="virtual-grid"
+                columnCount={mergedColumns.length}
+                columnWidth={(index: number) => {
+                    const { width } = mergedColumns[index];
+                    return totalHeight > (scroll!.y! as any) && index === mergedColumns.length - 1
+                        ? (width as number) - scrollbarSize - 1
+                        : (width as number);
+                }}
+                height={scroll!.y as number}
+                rowCount={rawData.length}
+                rowHeight={() => 54}
+                width={tableWidth}
+                onScroll={({ scrollLeft }: { scrollLeft: number }) => {
+                    onScroll({ scrollLeft });
+                }}
+            >
+                {({
+                    columnIndex,
+                    rowIndex,
+                    style,
+                }: {
+                    columnIndex: number;
+                    rowIndex: number;
+                    style: React.CSSProperties;
+                }) => (
+                    <div
+                        className={classNames('virtual-table-cell', {
+                            'virtual-table-cell-last': columnIndex === mergedColumns.length - 1,
+                        })}
+                        style={style}
+                    >
+                        {(rawData[rowIndex] as any)[(mergedColumns as any)[columnIndex].dataIndex]}
+                    </div>
+                )}
+            </Grid>
+        );
+    };
+
+    return (
+        <ResizeObserver
+            onResize={({ width }) => {
+                setTableWidth(width);
+            }}
+        >
+            <Table
+                {...props}
+                className="virtual-table"
+                columns={mergedColumns}
+                pagination={false}
+                components={{
+                    body: renderVirtualList as any,
+                }}
+            />
+        </ResizeObserver>
+    );
+};
+
+export default React.memo(VirtualTable)

+ 10 - 1
src/pages/gameDataStatistics/adlist/monitor/dayAd.tsx

@@ -1,5 +1,5 @@
 import { useAjax } from "@/Hook/useAjax"
 import { useAjax } from "@/Hook/useAjax"
-import { PromotionDataDay, getPromotionDataDayListApi } from "@/services/gameData/adlist"
+import { PromotionDataDay, getPromotionDataDayListApi, getPromotionDataDayTotalApi } from "@/services/gameData/adlist"
 import { Button, Drawer } from "antd"
 import { Button, Drawer } from "antd"
 import React, { useEffect, useState } from "react"
 import React, { useEffect, useState } from "react"
 import TableData from "../../components/TableData"
 import TableData from "../../components/TableData"
@@ -25,7 +25,9 @@ const DayAd: React.FC<Props> = ({ adName, queryForm, promotionId, onClose, visib
     /***********************************/
     /***********************************/
     const [data, setData] = useState<{ pageSize: number, pageNum: number, sortFiled?: string, sortType?: string }>({ pageNum: 1, pageSize: 100 })
     const [data, setData] = useState<{ pageSize: number, pageNum: number, sortFiled?: string, sortType?: string }>({ pageNum: 1, pageSize: 100 })
     const [date, setDate] = useState<[string, string]>()
     const [date, setDate] = useState<[string, string]>()
+    const [totalData, setTotalData] = useState<any[]>([])
     const getPromotionDataDayList = useAjax((params) => getPromotionDataDayListApi(params))
     const getPromotionDataDayList = useAjax((params) => getPromotionDataDayListApi(params))
+    const getPromotionDataDayTotal = useAjax((params) => getPromotionDataDayTotalApi(params))
     /***********************************/
     /***********************************/
 
 
     useEffect(() => {
     useEffect(() => {
@@ -45,6 +47,11 @@ const DayAd: React.FC<Props> = ({ adName, queryForm, promotionId, onClose, visib
             delete params?.costEndDate
             delete params?.costEndDate
         }
         }
         getPromotionDataDayList.run({ ...params, ...data })
         getPromotionDataDayList.run({ ...params, ...data })
+        getPromotionDataDayTotal.run({ ...params, ...data }).then(res => {
+            res.id = 1
+            res.dt = '总计'
+            setTotalData([res])
+        })
     }, [promotionId, queryForm, data, date])
     }, [promotionId, queryForm, data, date])
 
 
     return <Drawer title={<div style={{ display: 'flex', justifyContent: 'space-between' }}><span>{`${adName} 广告每日数据`}</span> <Button type="text" icon={<CloseOutlined />} onClick={() => onClose?.()}></Button> </div>} closable={false} placement="right" width={'90%'} onClose={onClose} visible={visible}>
     return <Drawer title={<div style={{ display: 'flex', justifyContent: 'space-between' }}><span>{`${adName} 广告每日数据`}</span> <Button type="text" icon={<CloseOutlined />} onClick={() => onClose?.()}></Button> </div>} closable={false} placement="right" width={'90%'} onClose={onClose} visible={visible}>
@@ -60,6 +67,8 @@ const DayAd: React.FC<Props> = ({ adName, queryForm, promotionId, onClose, visib
                 }}
                 }}
                 isConsumeDay={{ ranges: getPresets() }}
                 isConsumeDay={{ ranges: getPresets() }}
             />}
             />}
+            isZj
+            totalData={totalData}
             scroll={{ x: 1000, y: 600 }}
             scroll={{ x: 1000, y: 600 }}
             ajax={getPromotionDataDayList}
             ajax={getPromotionDataDayList}
             fixed={{ left: 3, right: 0 }}
             fixed={{ left: 3, right: 0 }}

+ 10 - 1
src/pages/gameDataStatistics/adlist/tencentMonitor/dayAd.tsx

@@ -1,5 +1,5 @@
 import { useAjax } from "@/Hook/useAjax"
 import { useAjax } from "@/Hook/useAjax"
-import { PromotionDataDay, getPromotionDataTencentDayListApi } from "@/services/gameData/adlist"
+import { PromotionDataDay, getPromotionDataTencentDayListApi, getPromotionDataTencentDayTotalApi } from "@/services/gameData/adlist"
 import { Button, Drawer, Space } from "antd"
 import { Button, Drawer, Space } from "antd"
 import React, { useEffect, useState } from "react"
 import React, { useEffect, useState } from "react"
 import TableData from "../../components/TableData"
 import TableData from "../../components/TableData"
@@ -25,7 +25,9 @@ const DayAd: React.FC<Props> = ({ adName, queryForm, promotionId, onClose, visib
     /***********************************/
     /***********************************/
     const [data, setData] = useState<{ pageSize: number, pageNum: number, sortFiled?: string, sortType?: string }>({ pageNum: 1, pageSize: 100 })
     const [data, setData] = useState<{ pageSize: number, pageNum: number, sortFiled?: string, sortType?: string }>({ pageNum: 1, pageSize: 100 })
     const [date, setDate] = useState<[string, string]>()
     const [date, setDate] = useState<[string, string]>()
+    const [totalData, setTotalData] = useState<any[]>([])
     const getPromotionDataTencentDayList = useAjax((params) => getPromotionDataTencentDayListApi(params))
     const getPromotionDataTencentDayList = useAjax((params) => getPromotionDataTencentDayListApi(params))
+    const getPromotionDataTencentDayTotal = useAjax((params) => getPromotionDataTencentDayTotalApi(params))
     /***********************************/
     /***********************************/
 
 
     useEffect(() => {
     useEffect(() => {
@@ -45,6 +47,11 @@ const DayAd: React.FC<Props> = ({ adName, queryForm, promotionId, onClose, visib
             delete params?.costEndDate
             delete params?.costEndDate
         }
         }
         getPromotionDataTencentDayList.run({ ...params, ...data })
         getPromotionDataTencentDayList.run({ ...params, ...data })
+        getPromotionDataTencentDayTotal.run({ ...params, ...data }).then(res => {
+            res.id = 1
+            res.dt = '总计'
+            setTotalData([res])
+        })
     }, [promotionId, queryForm, data, date])
     }, [promotionId, queryForm, data, date])
 
 
     return <Drawer title={<div style={{ display: 'flex', justifyContent: 'space-between' }}><span>{`${adName} 腾讯广告每日数据`}</span> <Button type="text" icon={<CloseOutlined />} onClick={() => onClose?.()}></Button> </div>} closable={false} placement="right" width={'90%'} onClose={onClose} visible={visible}>
     return <Drawer title={<div style={{ display: 'flex', justifyContent: 'space-between' }}><span>{`${adName} 腾讯广告每日数据`}</span> <Button type="text" icon={<CloseOutlined />} onClick={() => onClose?.()}></Button> </div>} closable={false} placement="right" width={'90%'} onClose={onClose} visible={visible}>
@@ -60,6 +67,8 @@ const DayAd: React.FC<Props> = ({ adName, queryForm, promotionId, onClose, visib
                 }}
                 }}
                 isConsumeDay={{ ranges: getPresets() }}
                 isConsumeDay={{ ranges: getPresets() }}
             />}
             />}
+            isZj
+            totalData={totalData}
             scroll={{ x: 1000, y: 600 }}
             scroll={{ x: 1000, y: 600 }}
             ajax={getPromotionDataTencentDayList}
             ajax={getPromotionDataTencentDayList}
             fixed={{ left: 3, right: 0 }}
             fixed={{ left: 3, right: 0 }}

+ 11 - 9
src/pages/gameDataStatistics/components/TableData/index.tsx

@@ -294,31 +294,33 @@ function TableData(props: Prosp) {
 /**表格 */
 /**表格 */
 const Tab = React.memo((props: any) => {
 const Tab = React.memo((props: any) => {
     const { size, newColumns, className, handelResize, scroll, isFull, page, isZj, rowClassName, pageSize, totalData, dataSource, onChange, expandedRowRender, total, ajax, summary } = props
     const { size, newColumns, className, handelResize, scroll, isFull, page, isZj, rowClassName, pageSize, totalData, dataSource, onChange, expandedRowRender, total, ajax, summary } = props
+    let ran = Math.ceil(Math.random() * 100)
 
 
     useEffect(() => {
     useEffect(() => {
         const contentBodyScroll = (e: any) => {
         const contentBodyScroll = (e: any) => {
-            let el = document.querySelector('.header_table_body .ant-table-body');
+            let el = document.querySelector(`.header_table_body_${ran} .ant-table-body`);
             if (el) {
             if (el) {
                 el.scrollLeft = e.target.scrollLeft
                 el.scrollLeft = e.target.scrollLeft
             }
             }
         }
         }
         const headerBodyScroll = (e: any) => {
         const headerBodyScroll = (e: any) => {
-            let el = document.querySelector('.content_table_body .ant-table-body');
+            let el = document.querySelector(`.content_table_body_${ran} .ant-table-body`);
             if (el) {
             if (el) {
                 el.scrollLeft = e.target.scrollLeft
                 el.scrollLeft = e.target.scrollLeft
             }
             }
         }
         }
         if (isZj) {
         if (isZj) {
-            document.querySelector('.content_table_body .ant-table-body')?.addEventListener('scroll', contentBodyScroll);
-            document.querySelector('.header_table_body .ant-table-body')?.addEventListener('scroll', headerBodyScroll);
+            document.querySelector(`.content_table_body_${ran} .ant-table-body`)?.addEventListener('scroll', contentBodyScroll);
+            document.querySelector(`.header_table_body_${ran} .ant-table-body`)?.addEventListener('scroll', headerBodyScroll);
+            // document.querySelectorAll('.content_table_body .ant-table-body')
         }
         }
         () => {
         () => {
             if (isZj) {
             if (isZj) {
-                document.querySelector('.content_table_body .ant-table-body')?.removeEventListener('scroll', contentBodyScroll);
-                document.querySelector('.header_table_body .ant-table-body')?.removeEventListener('scroll', headerBodyScroll);
+                document.querySelector(`.content_table_body_${ran} .ant-table-body`)?.removeEventListener('scroll', contentBodyScroll);
+                document.querySelector(`.header_table_body_${ran} .ant-table-body`)?.removeEventListener('scroll', headerBodyScroll);
             }
             }
         }
         }
-    }, [isZj])
+    }, [isZj, ran])
 
 
     return < Col span={24} >
     return < Col span={24} >
         <div className={`${style[size]} ${className ? style[className] : ''} `}>
         <div className={`${style[size]} ${className ? style[className] : ''} `}>
@@ -334,7 +336,7 @@ const Tab = React.memo((props: any) => {
                     current={page}
                     current={page}
                     pageSize={pageSize}
                     pageSize={pageSize}
                     loading={ajax?.loading}
                     loading={ajax?.loading}
-                    className={`all_table header_table_body ${className ? className : ''}`}
+                    className={`all_table header_table_body_${ran} ${className ? className : ''}`}
                     sortDirections={['ascend', 'descend', null]}
                     sortDirections={['ascend', 'descend', null]}
                     handelResize={((columns: any) => handelResize(columns))}
                     handelResize={((columns: any) => handelResize(columns))}
                     onChange={(pagination: any, filters: any, sorter: any) => onChange && onChange({ pagination, filters, sortData: sorter })}
                     onChange={(pagination: any, filters: any, sorter: any) => onChange && onChange({ pagination, filters, sortData: sorter })}
@@ -342,7 +344,7 @@ const Tab = React.memo((props: any) => {
             }
             }
             <Tables
             <Tables
                 showHeader={!isZj}
                 showHeader={!isZj}
-                className={`all_table content_table_body ${className ? className : ''}`}
+                className={`all_table content_table_body_${ran} ${className ? className : ''}`}
                 bordered
                 bordered
                 sortDirections={['ascend', 'descend', null]}
                 sortDirections={['ascend', 'descend', null]}
                 current={page}
                 current={page}

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

@@ -61,6 +61,18 @@ export async function getPromotionDataDayListApi(data: PromotionDataDay) {
     });
     });
 }
 }
 
 
+/**
+ * 头条广告每日监控总计
+ * @param data 
+ * @returns 
+ */
+export async function getPromotionDataDayTotalApi(data: PromotionDataDay) {
+    return request(wapi + `/promotionData/day/listTotal`, {
+        method: 'POST',
+        data
+    });
+}
+
 
 
 /**
 /**
  * 腾讯广告监控数据
  * 腾讯广告监控数据
@@ -97,4 +109,15 @@ export async function getPromotionDataTencentDayListApi(data: PromotionDataDay)
         method: 'POST',
         method: 'POST',
         data
         data
     });
     });
+}
+/**
+ * 腾讯广告每日总计监控
+ * @param data 
+ * @returns 
+ */
+export async function getPromotionDataTencentDayTotalApi(data: PromotionDataDay) {
+    return request(wapi + `/promotionData/tencent/day/listTotal`, {
+        method: 'POST',
+        data
+    });
 }
 }