wjx hai 1 ano
pai
achega
d702242dd4

+ 36 - 0
src/components/VirtualTable/index.less

@@ -0,0 +1,36 @@
+.virtual-table .ant-table-container:before,
+.virtual-table .ant-table-container:after {
+  display: none;
+}
+.virtual-table-cell {
+  box-sizing: border-box;
+  padding: 2px 5px;
+  border-bottom: 1px solid #e8e8e8;
+  border-right: 1px solid #e8e8e8;
+  background: #fff;
+  overflow-wrap: break-word;
+  position: relative;
+  display: flex;
+  align-items: center;
+  font-size: 13px;
+}
+[data-theme="dark"] .virtual-table-cell {
+  box-sizing: border-box;
+  padding: 2px 5px;
+  border-bottom: 1px solid #303030;
+  border-right: 1px solid #303030;
+  background: #141414;
+  font-size: 13px;
+  overflow-wrap: break-word;
+  position: relative;
+  display: flex;
+  align-items: center;
+}
+
+.virtual-table-cell-last {
+    border-right: none;
+}
+.virtual-table-cell-fix-left {
+    position: sticky !important;
+    z-index: 2;
+}

+ 201 - 6
src/components/VirtualTable/index.tsx

@@ -1,10 +1,205 @@
-import type { TableProps } from 'antd';
-import React from 'react';
+import React, { useEffect, useRef, useState } from "react";
+import "antd/dist/antd.css";
+import "./index.less";
+import { Table } from "antd";
+import type { TableProps } from "antd";
+import classNames from "classnames";
+import ResizeObserver from "rc-resize-observer";
+import type { ColumnsType } from "antd/es/table";
+import { VariableSizeGrid as Grid } from "react-window";
 
 
-const VirtualTable = <RecordType extends object>(props: TableProps<RecordType>) => {
-    
+const VirtualTable = <RecordType extends object>(
+    props: TableProps<RecordType>
+) => {
+    const { columns, scroll, className } = props;
+    const [tableWidth, setTableWidth] = useState(0);
 
 
-    return <div>1111</div>
+    //   const widthColumnCount = columns!.filter(({ width }) => !width).length;
+    const mergedColumns = columns!.map((column) => {
+        if (column.width) {
+            return column;
+        }
+
+        return {
+            ...column,
+            //   width: Math.floor(tableWidth / widthColumnCount)
+            width: 100
+        };
+    });
+
+    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={() => 100}
+                width={tableWidth}
+                onScroll={({ scrollLeft }: { scrollLeft: number }) => {
+                    onScroll({ scrollLeft });
+                }}
+            >
+                {({ columnIndex, rowIndex, style }: { columnIndex: number; rowIndex: number; style: React.CSSProperties; }) => {
+                    const { render, dataIndex, align } = (mergedColumns as any)[columnIndex];
+                    const myStyle = {
+                        justifyContent:
+                            align === "left"
+                                ? "flex-start"
+                                : align === "right"
+                                    ? "flex-end"
+                                    : align,
+                        ...style
+                    }
+                    return (
+                        <div
+                            className={classNames("virtual-table-cell", {
+                                "virtual-table-cell-last": columnIndex === mergedColumns.length - 1
+                            })}
+                            style={myStyle}
+                        >
+                            {render
+                                ? render(
+                                    (rawData[rowIndex] as any)[dataIndex],
+                                    rawData[rowIndex] as any
+                                )
+                                : (rawData[rowIndex] as any)[dataIndex]}
+                        </div>
+                    );
+                }}
+            </Grid>
+        );
+    };
+
+    return (
+        <ResizeObserver
+            onResize={({ width }) => {
+                setTableWidth(width);
+            }}
+        >
+            <Table
+                {...props}
+                bordered
+                className={`virtual-table all_table ${className ? className : ''}`}
+                columns={mergedColumns}
+                pagination={false}
+                components={{
+                    body: renderVirtualList as any
+                }}
+            />
+        </ResizeObserver>
+    );
 };
 };
 
 
-export default React.memo(VirtualTable)
+// Usage
+const columns: ColumnsType<any> = [
+    { title: <span>YYY</span>, dataIndex: "key", width: 150, align: "center", sorter: true },
+    { title: "B", dataIndex: "key" },
+    { title: "C", dataIndex: "key" },
+    { title: "D", dataIndex: "key" },
+    { title: "E", dataIndex: "key", width: 200 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100, align: "center" },
+    {
+        title: "dd11",
+        dataIndex: "key",
+        width: 100,
+        align: "center",
+        render: (a) => {
+            return <span>{a * 20}</span>;
+        }
+    },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 200 },
+    { title: "F", dataIndex: "key", width: 200 },
+    { title: "F", dataIndex: "key", width: 200 },
+    { title: "F", dataIndex: "key", width: 200 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "key", width: 100 },
+    { title: "F", dataIndex: "dd", width: 100 }
+];
+
+const data = Array.from({ length: 100000 }, (_, key) => ({
+    key,
+    dd: "啊大大撒旦啊实打实大苏打阿斯顿撒打算阿三打撒"
+}));
+
+const App1: React.FC = () => (
+    <VirtualTable
+        columns={columns}
+        dataSource={data}
+        scroll={{ y: 600, x: "100vw" }}
+    />
+);
+
+export default App1;

+ 2 - 0
src/global.less

@@ -287,6 +287,8 @@ body {
 .ant-tag,
 .ant-tag,
 .ant-pagination-item,
 .ant-pagination-item,
 .ant-picker-panel-container,
 .ant-picker-panel-container,
+.ant-input-number-input,
+.ant-input-number,
 .ant-select-dropdown {
 .ant-select-dropdown {
   border-radius: 6px !important;
   border-radius: 6px !important;
 }
 }

+ 10 - 10
src/pages/gameDataStatistics/gameData/active/tableConfig.tsx

@@ -38,7 +38,7 @@ function columnsUser12(): { label: string, fieldSHow?: { label: string, saveFiel
                             if (b?.[field]) {
                             if (b?.[field]) {
                                 data = b?.[field]
                                 data = b?.[field]
                                 return <div>
                                 return <div>
-                                    <div style={{ alignItems: 'center', fontSize: 12, fontWeight: 'bold' }}>注册留存</div>
+                                    {/* <div style={{ alignItems: 'center', fontSize: 12, fontWeight: 'bold' }}>注册留存</div> */}
                                     <div className={style.dbox}>
                                     <div className={style.dbox}>
                                         <span style={{ color: '#d81b60', fontWeight: 600 }}>活跃人数:<span>{data?.activeNum}</span></span>
                                         <span style={{ color: '#d81b60', fontWeight: 600 }}>活跃人数:<span>{data?.activeNum}</span></span>
                                         <span style={{ color: 'rgb(12,130,16)', fontWeight: 600 }}>留存率:<span>{(data?.regActiveRate * 100)?.toFixed(2)}%</span></span>
                                         <span style={{ color: 'rgb(12,130,16)', fontWeight: 600 }}>留存率:<span>{(data?.regActiveRate * 100)?.toFixed(2)}%</span></span>
@@ -50,12 +50,12 @@ function columnsUser12(): { label: string, fieldSHow?: { label: string, saveFiel
                             if (b?.[field]) {
                             if (b?.[field]) {
                                 data = b?.[field]
                                 data = b?.[field]
                                 return <div>
                                 return <div>
-                                    <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 5, fontSize: 12, fontWeight: 'bold' }}>
+                                    {/* <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 5, fontSize: 12, fontWeight: 'bold' }}>
                                         角色留存
                                         角色留存
                                         <Tooltip title="鼠标悬停展示完整名称">
                                         <Tooltip title="鼠标悬停展示完整名称">
                                             <QuestionCircleOutlined />
                                             <QuestionCircleOutlined />
                                         </Tooltip>
                                         </Tooltip>
-                                    </div>
+                                    </div> */}
                                     <div className={style.dbox}>
                                     <div className={style.dbox}>
                                         <span style={{ color: '#d81b60', fontWeight: 600 }}>
                                         <span style={{ color: '#d81b60', fontWeight: 600 }}>
                                             <Tooltip title="累计到第N天的活跃用户数" placement='left'>
                                             <Tooltip title="累计到第N天的活跃用户数" placement='left'>
@@ -95,12 +95,12 @@ function columnsUser12(): { label: string, fieldSHow?: { label: string, saveFiel
                             if (b?.[field]) {
                             if (b?.[field]) {
                                 data = b?.[field]
                                 data = b?.[field]
                                 return <div>
                                 return <div>
-                                    <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 5, fontSize: 12, fontWeight: 'bold' }}>
+                                    {/* <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 5, fontSize: 12, fontWeight: 'bold' }}>
                                         付费留存
                                         付费留存
                                         <Tooltip title="鼠标悬停展示完整名称">
                                         <Tooltip title="鼠标悬停展示完整名称">
                                             <QuestionCircleOutlined />
                                             <QuestionCircleOutlined />
                                         </Tooltip>
                                         </Tooltip>
-                                    </div>
+                                    </div> */}
                                     <div className={style.dbox}>
                                     <div className={style.dbox}>
                                         <span style={{ color: '#d81b60', fontWeight: 600 }}>
                                         <span style={{ color: '#d81b60', fontWeight: 600 }}>
                                             <Tooltip title="累计到第N天的活跃用户数" placement='left'>
                                             <Tooltip title="累计到第N天的活跃用户数" placement='left'>
@@ -177,7 +177,7 @@ function columnsUser12(): { label: string, fieldSHow?: { label: string, saveFiel
                             if (b?.[field]) {
                             if (b?.[field]) {
                                 data = b?.[field]
                                 data = b?.[field]
                                 return <div>
                                 return <div>
-                                    <div style={{ alignItems: 'center', fontSize: 12, fontWeight: 'bold' }}>注册留存</div>
+                                    {/* <div style={{ alignItems: 'center', fontSize: 12, fontWeight: 'bold' }}>注册留存</div> */}
                                     <div className={style.dbox}>
                                     <div className={style.dbox}>
                                         <span style={{ color: '#d81b60', fontWeight: 600 }}>活跃人数:<span>{data?.activeNum}</span></span>
                                         <span style={{ color: '#d81b60', fontWeight: 600 }}>活跃人数:<span>{data?.activeNum}</span></span>
                                         <span style={{ color: 'rgb(12,130,16)', fontWeight: 600 }}>留存率:<span>{(data?.regActiveRate * 100)?.toFixed(2)}%</span></span>
                                         <span style={{ color: 'rgb(12,130,16)', fontWeight: 600 }}>留存率:<span>{(data?.regActiveRate * 100)?.toFixed(2)}%</span></span>
@@ -189,12 +189,12 @@ function columnsUser12(): { label: string, fieldSHow?: { label: string, saveFiel
                             if (b?.[field]) {
                             if (b?.[field]) {
                                 data = b?.[field]
                                 data = b?.[field]
                                 return <div>
                                 return <div>
-                                    <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 5, fontSize: 12, fontWeight: 'bold' }}>
+                                    {/* <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 5, fontSize: 12, fontWeight: 'bold' }}>
                                         角色留存
                                         角色留存
                                         <Tooltip title="鼠标悬停展示完整名称">
                                         <Tooltip title="鼠标悬停展示完整名称">
                                             <QuestionCircleOutlined />
                                             <QuestionCircleOutlined />
                                         </Tooltip>
                                         </Tooltip>
-                                    </div>
+                                    </div> */}
                                     <div className={style.dbox}>
                                     <div className={style.dbox}>
                                         <span style={{ color: '#d81b60', fontWeight: 600 }}>
                                         <span style={{ color: '#d81b60', fontWeight: 600 }}>
                                             <Tooltip title="累计到第N天的活跃用户数" placement='left'>
                                             <Tooltip title="累计到第N天的活跃用户数" placement='left'>
@@ -234,12 +234,12 @@ function columnsUser12(): { label: string, fieldSHow?: { label: string, saveFiel
                             if (b?.[field]) {
                             if (b?.[field]) {
                                 data = b?.[field]
                                 data = b?.[field]
                                 return <div>
                                 return <div>
-                                    <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 5, fontSize: 12, fontWeight: 'bold' }}>
+                                    {/* <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 5, fontSize: 12, fontWeight: 'bold' }}>
                                         付费留存
                                         付费留存
                                         <Tooltip title="鼠标悬停展示完整名称">
                                         <Tooltip title="鼠标悬停展示完整名称">
                                             <QuestionCircleOutlined />
                                             <QuestionCircleOutlined />
                                         </Tooltip>
                                         </Tooltip>
-                                    </div>
+                                    </div> */}
                                     <div className={style.dbox}>
                                     <div className={style.dbox}>
                                         <span style={{ color: '#d81b60', fontWeight: 600 }}>
                                         <span style={{ color: '#d81b60', fontWeight: 600 }}>
                                             <Tooltip title="累计到第N天的活跃用户数" placement='left'>
                                             <Tooltip title="累计到第N天的活跃用户数" placement='left'>

+ 2 - 1
src/pages/gameDataStatistics/rankingList/gamer/index.tsx

@@ -6,6 +6,7 @@ import columns12 from "./tableConfig"
 import QueryForm from "@/components/QueryForm"
 import QueryForm from "@/components/QueryForm"
 import moment from "moment"
 import moment from "moment"
 import { getPresetsRanking } from "@/components/QueryForm/const"
 import { getPresetsRanking } from "@/components/QueryForm/const"
+import App1 from "@/components/VirtualTable"
 
 
 const Gamer: React.FC = () => {
 const Gamer: React.FC = () => {
 
 
@@ -19,7 +20,7 @@ const Gamer: React.FC = () => {
     }, [queryForm])
     }, [queryForm])
 
 
     return <div>
     return <div>
-
+        {/* <App1 /> */}
         <TableData
         <TableData
             leftChild={<QueryForm
             leftChild={<QueryForm
                 initialValues={{ sourceSystem: 'ZX_ONE', rechargeDay: [moment(), moment()] }}
                 initialValues={{ sourceSystem: 'ZX_ONE', rechargeDay: [moment(), moment()] }}