فهرست منبع

添加滚动组件

Renxy 1 سال پیش
والد
کامیت
1f59e2af48

+ 67 - 0
src/components/ScrollLoading/index.js

@@ -0,0 +1,67 @@
+import { Spin } from 'antd';
+import { useEffect, useRef } from 'react';
+
+export default function ScrollLoading({
+  loading,
+  children,
+  totalLength, //当前请求到的数据总长度
+  pagination = { current: 1, total: 0 },
+  handleLoadData, //请求数据方法
+  height = 90, //除滚动区域外其他高度(只是通用标题就是90)
+}) {
+  const bottomAreaOfList = useRef();
+  const scrollContent = useRef();
+  // 是否已经发送请求 防止发送多次同样的请求
+  const load = useRef();
+
+  console.log('-----------------', pagination);
+
+  const handleScroll = () => {
+    const { current, total } = pagination;
+    if (totalLength >= total) {
+      return;
+    }
+    const rect = bottomAreaOfList.current.getBoundingClientRect();
+    const isVisible =
+      rect.top >= 0 &&
+      rect.left >= 0 &&
+      rect.bottom <=
+        (scrollContent.current.innerHeight ||
+          document.documentElement.clientHeight) &&
+      rect.right <=
+        (scrollContent.current.innerWidth ||
+          document.documentElement.clientWidth);
+
+    if (isVisible && !load.current) {
+      load.current = true;
+      handleLoadData(current + 1);
+    }
+  };
+
+  // 监听滚动事件
+  useEffect(() => {
+    load.current = false;
+    scrollContent.current.addEventListener('scroll', handleScroll);
+    return () => {
+      scrollContent.current.removeEventListener('scroll', handleScroll);
+    };
+  }, [loading]);
+
+  return (
+    <Spin spinning={loading}>
+      <div
+        ref={scrollContent}
+        style={{ overflowY: 'scroll', height: `calc(100vh - ${height + 1}px)` }}
+      >
+        {children}
+        <div
+          ref={bottomAreaOfList}
+          style={{
+            height: '1px',
+          }}
+        />
+        <div />
+      </div>
+    </Spin>
+  );
+}

+ 0 - 0
src/components/ScrollLoading/index.less


+ 15 - 44
src/pages/SafetyManagement/doorDetail.js

@@ -1,22 +1,20 @@
 import PageContent from '@/components/PageContent';
 import PageTitle from '@/components/PageTitle';
+import ScrollLoading from '@/components/ScrollLoading';
 import { queryGateOpList } from '@/services/safety';
 import { useParams, useRequest } from '@umijs/max';
 import { Table } from 'antd';
-import { useEffect, useRef, useState } from 'react';
+import { useRef, useState } from 'react';
 const DoorDetail = () => {
   const { projectId } = useParams();
   const [list, setList] = useState([]);
   const [curPagination, setCurPagination] = useState({});
 
   const bottomAreaOfList = useRef();
-  // 是否已经发送请求 防止发送多次同样的请求
-  const load = useRef();
 
   const { run, loading } = useRequest((data) => queryGateOpList(data), {
     defaultParams: [{ project_id: projectId }],
     onSuccess: (data) => {
-      load.current = false;
       setList([...list, ...data.list]);
       setCurPagination(data.pagination);
     },
@@ -65,51 +63,24 @@ const DoorDetail = () => {
     },
   ];
 
-  const handleScroll = () => {
-    const { current, total } = curPagination;
-    if (list.length >= total) {
-      return;
-    }
-    const rect = bottomAreaOfList.current.getBoundingClientRect();
-    const isVisible =
-      rect.top >= 0 &&
-      rect.left >= 0 &&
-      rect.bottom <=
-        (window.innerHeight || document.documentElement.clientHeight) &&
-      rect.right <= (window.innerWidth || document.documentElement.clientWidth);
-
-    if (isVisible && !load.current) {
-      load.current = true;
-      run({ project_id: projectId, current: current + 1 });
-    }
-  };
-
-  // 监听滚动事件
-  useEffect(() => {
-    window.addEventListener('scroll', handleScroll);
-    return () => {
-      window.removeEventListener('scroll', handleScroll);
-    };
-  }, [loading]);
-
   return (
     <PageContent closeable={false}>
       <PageTitle children="门禁日志" returnable />
 
-      <Table
+      <ScrollLoading
         loading={loading}
-        style={{ marginTop: '30px' }}
-        dataSource={list}
-        columns={columns}
-        pagination={false}
-      />
-      <div
-        ref={bottomAreaOfList}
-        style={{
-          height: '1px',
-        }}
-      />
-      <div />
+        totalLength={list?.length}
+        pagination={curPagination}
+        handleLoadData={(current) => run({ project_id: projectId, current })}
+      >
+        <Table
+          loading={loading}
+          style={{ marginTop: '30px' }}
+          dataSource={list}
+          columns={columns}
+          pagination={false}
+        />
+      </ScrollLoading>
     </PageContent>
   );
 };

+ 19 - 57
src/pages/TaskManage/Detail/TaskList/TaskList.tsx

@@ -18,8 +18,9 @@ import TopFilter from '@/pages/TaskManage/components/TopFilter';
 import { IMandateType } from '@/pages/TaskManage/index.types';
 import { useNavigate } from '@@/exports';
 import { DownOutlined } from '@ant-design/icons';
-import { Col, Collapse, CollapseProps, Divider, List, Row, Spin } from 'antd';
+import { Col, Collapse, CollapseProps, Divider, List, Row } from 'antd';
 
+import ScrollLoading from '@/components/ScrollLoading';
 import { getMandateList } from '@/services/TaskManage';
 import dayjs from 'dayjs';
 import { useEffect, useRef, useState } from 'react';
@@ -45,6 +46,7 @@ const TaskList: React.FC<IPropsType> = (props) => {
     currentPage: 1,
   });
   const [isLoadAll, setIsLoadAll] = useState(false);
+  const [pagination, setPagination] = useState({ current: 1, total: 0 });
 
   const bottomAreaOfList = useRef<HTMLDivElement>(null);
 
@@ -63,34 +65,10 @@ const TaskList: React.FC<IPropsType> = (props) => {
           setMandateList([...mandateList, ...result.data.list]);
         }
       }
-      if (pageInfo.current * pageInfo.pageSize >= pageInfo.total) {
-        setIsLoadAll(true);
-      }
-      pageInfo.current += 1;
-      setCurrentParams({
-        ...currentParams,
-        currentPage: pageInfo.current,
-      });
+      setPagination(pageInfo);
     },
   });
 
-  const handleScroll = () => {
-    if (bottomAreaOfList.current === null) {
-      return;
-    }
-    const rect = bottomAreaOfList.current.getBoundingClientRect();
-    const isVisible =
-      rect.top >= 0 &&
-      rect.left >= 0 &&
-      rect.bottom <=
-        (window.innerHeight || document.documentElement.clientHeight) &&
-      rect.right <= (window.innerWidth || document.documentElement.clientWidth);
-
-    if (isVisible) {
-      getList(currentParams);
-    }
-  };
-
   // 获取用户
   useEffect(() => {
     if (userList.length === 0) {
@@ -101,16 +79,6 @@ const TaskList: React.FC<IPropsType> = (props) => {
     }
   }, []);
 
-  // 监听滚动事件
-  useEffect(() => {
-    // 组件挂载时添加滚动事件监听
-    window.addEventListener('scroll', handleScroll);
-    // 组件卸载时移除滚动事件监听
-    return () => {
-      window.removeEventListener('scroll', handleScroll);
-    };
-  }, [loadData, currentParams]);
-
   // 配置顶部下拉过滤器
   useEffect(() => {
     const filters: ITopFilter[] = [];
@@ -166,16 +134,6 @@ const TaskList: React.FC<IPropsType> = (props) => {
     getList(params);
   };
 
-  const loadMoreMandate =
-    !isLoadAll && !loadData ? (
-      <div
-        ref={bottomAreaOfList}
-        style={{
-          height: '1px',
-        }}
-      />
-    ) : null;
-
   const goTaskDetail = (mandate: IMandateType) => {
     navigate(
       `/task-manage/list/detail?project_id=${project_id}&mandate_id=${mandate.Id}`,
@@ -332,22 +290,26 @@ const TaskList: React.FC<IPropsType> = (props) => {
 
   return (
     <PageContent closeable={false}>
-      <div className={styles.topContainer}>
-        <div className={styles.fixedTop}>
-          <PageTitle returnable>
-            {MandateType.find((item) => item.value === mandateType)?.label}
-          </PageTitle>
-          <TopFilter filters={topFiltersConfig} onChange={onTopFilterChange} />
-        </div>
-      </div>
-      <Spin spinning={loading || loadData}>
+      <PageTitle returnable>
+        {MandateType.find((item) => item.value === mandateType)?.label}
+      </PageTitle>
+      <TopFilter filters={topFiltersConfig} onChange={onTopFilterChange} />
+
+      <ScrollLoading
+        height={180}
+        loading={loading || loadData}
+        totalLength={mandateList?.length}
+        pagination={pagination}
+        handleLoadData={(current: number) =>
+          getList({ ...currentParams, currentPage: current })
+        }
+      >
         <List
           itemLayout="horizontal"
           dataSource={mandateList}
           renderItem={buildTaskList}
-          loadMore={loadMoreMandate}
         />
-      </Spin>
+      </ScrollLoading>
     </PageContent>
   );
 };

+ 1 - 1
src/pages/TaskManage/Detail/TaskList/taskList.less

@@ -55,7 +55,7 @@
 }
 
 .topContainer {
-  height: 120px;
+  // height: 120px;
   .fixedTop {
     position: fixed;
     top: 0;

+ 1 - 2
src/pages/TaskManage/components/TopFilter.tsx

@@ -1,5 +1,4 @@
 import { ITopFilter } from '@/pages/TaskManage/Detail/TaskList/taskList.types';
-import { CaretDownFilled, CloseCircleFilled } from '@ant-design/icons';
 import { Col, Row, Select } from 'antd';
 
 import { useState } from 'react';
@@ -16,7 +15,7 @@ const TopFilter: React.FC<IProps> = ({ filters, onChange }) => {
   );
 
   return (
-    <Row justify="space-around" style={{ marginTop: '30px' }}>
+    <Row justify="space-around" style={{ margin: '30px 0 20px' }}>
       {filters.map((item, index) => {
         return (
           <Col