xyh 3 лет назад
Родитель
Сommit
f8aef039f1

+ 3 - 2
cypress/e2e/role.cy.ts

@@ -98,14 +98,15 @@ describe('角色管理', function() {
           : expect(res.hasClass('ant-tree-treenode-checkbox-checked')).to.false;
       }).should('have.length', 9);
 
+    cy.getTestId('role_tree_modal').find('form').submit();
+
     validateModalBtnGroup('role_tree_modal');
-    cy.getTestId('modal_btn_group').find('.ant-btn-loading').should('exist');
 
     cy.get('.ant-message-notice-content').should('include.text', '设置成功');
     cy.getTestId('role_tree_modal').should('not.exist');
   });
 
-  it.only('设置pda权限', function() {
+  it('设置pda权限', function() {
     tableBtnClick(TABLE_NAME, 3);
 
     cy.get('.ant-transfer-list').eq(0).find('.ant-transfer-list-content')

+ 1 - 0
packages/app/src/hooks/index.ts

@@ -1,3 +1,4 @@
 export * from './usePageContext';
 export * from './useContextSection';
 export * from './useExportFile';
+export {useQueryList as useQueryTableList} from './useQueryList';

+ 64 - 0
packages/app/src/hooks/useQueryList/index.ts

@@ -0,0 +1,64 @@
+import {createPageContext, usePage} from '@hooks';
+import {BaseListResult, ListParams} from '@models';
+import {useQuery} from '@tanstack/react-query';
+import {jumpToPrevPage} from '@utils';
+import {useState} from 'react';
+
+type UseQueryListResult<D> = [
+  {
+    count: number,
+    data: D[],
+    isFetching: boolean,
+  },
+  {refetch: () => void}
+];
+
+type UseQueryListOptions<P extends ListParams, R> = {
+  queryFn: (params: P) => BaseListResult<R>,
+  params: Omit<P, 'page' | 'limit'>,
+  pageContext: ReturnType<typeof createPageContext>,
+};
+
+export function useQueryList<
+  P extends ListParams,
+  R
+>(
+  {queryFn, params, pageContext}: UseQueryListOptions< P, R>,
+): UseQueryListResult<R> {
+  const [count, setCount] = useState(0);
+  const [{page, pageSize}, {onCurrentPageChange}] = usePage(pageContext);
+
+  const {data, isFetching, refetch} = useQuery<R[]>(
+    [queryFn.name, page, pageSize, ...Object.values(params)],
+    async function() {
+      const data = await queryFn({
+        ...params,
+        page: page.toString(),
+        limit: pageSize.toString(),
+      } as P);
+
+      if (data.msg === '200') {
+        // 当页面只有一个数据的时候 删除了页码改为前一个 但是数据请求还是当前页码
+        // 需要判断当前页码是否无数据并且大于1 满足时跳转到前一个页面
+        jumpToPrevPage({data: data.data.list, current: page, onPageChange: onCurrentPageChange});
+
+        setCount(data.data.total);
+
+        return data.data.list;
+      }
+
+      return [];
+    },
+    {
+      initialData: [],
+    },
+  );
+
+  return [{
+    count,
+    data,
+    isFetching,
+  },
+  {refetch},
+  ];
+}

+ 1 - 1
packages/app/src/models/response/index.tsx

@@ -22,7 +22,7 @@ export type BaseListData<T> = {
   navigateFirstPage: number;
   navigateLastPage: number;
 };
-export type BaseListResult<T> = BaseResult<BaseListData<T>>;
+export type BaseListResult<T = any> = BaseResult<BaseListData<T>>;
 
 export * from './user';
 export * from './department';

+ 11 - 25
packages/app/src/pages/department/table/hooks.tsx

@@ -1,4 +1,4 @@
-import {useMutation, useQuery} from '@tanstack/react-query';
+import {useMutation} from '@tanstack/react-query';
 import {context, pageContext} from '../context';
 import {deleteDepartment, getDepartmentList} from '@apis';
 import {useEffect, useState} from 'react';
@@ -6,40 +6,26 @@ import {ColumnsType} from 'antd/es/table';
 import {DepartmentListData} from '@models';
 import {useBoolean} from 'ahooks';
 import {Button, message} from 'antd';
-import {useContext, usePage} from '@hooks';
+import {useContext, useQueryTableList} from '@hooks';
 import {deleteConfirm} from '@utils';
 
 export function useList() {
-  const [count, setCount] = useState(0);
-  const [{page, pageSize}, {onPageChange}] = usePage(pageContext);
   const [{name, code}, dispatch] = useContext(context);
-  const {data, isFetching, refetch} = useQuery(
-    [name, code, page, pageSize, getDepartmentList.name],
-    async function() {
-      const data = await getDepartmentList({
-        departmentName: name,
-        code,
-        page: page.toString(),
-        limit: pageSize.toString(),
-      });
-
-      if (data.msg === '200') {
-        setCount(Number(data.data.total));
-        return data.data.list;
-      }
-
-      return [];
+  const [{data, count, isFetching}, {refetch}]
+  = useQueryTableList({
+    queryFn: getDepartmentList,
+    pageContext,
+    params: {
+      departmentName: name,
+      code,
     },
-    {
-      initialData: [],
-    },
-  );
+  });
 
   useEffect(function() {
     dispatch({type: 'CHANGE_SEARCH_STATE', payload: isFetching});
   }, [dispatch, isFetching]);
 
-  return [{count, data, isFetching, page, pageSize}, {onPageChange, refetch}] as const;
+  return [{count, data, isFetching}, {refetch}] as const;
 }
 
 export function useHandle(refetch: () => void) {

+ 5 - 2
packages/app/src/pages/department/table/index.tsx

@@ -4,16 +4,19 @@ import {useHandle, useList} from './hooks';
 import Modal from './modal';
 import {PAGE_SIZE_LIST} from '@utils';
 import {TableTools} from '@components';
+import {usePage} from '@hooks';
+import {pageContext} from '../context';
 
 const TableList: FC = function() {
   const [
-    {count, data, isFetching, page, pageSize},
-    {onPageChange, refetch},
+    {count, data, isFetching},
+    {refetch},
   ] = useList();
   const [
     {modalVisible, columns, editState},
     {onAdd, setFalse},
   ] = useHandle(refetch);
+  const [{page, pageSize}, {onPageChange}] = usePage(pageContext);
 
   return (
     <>

+ 7 - 23
packages/app/src/pages/goods/table/hooks.tsx

@@ -1,8 +1,8 @@
-import {useContext, usePage} from '@hooks';
+import {useContext, useQueryTableList} from '@hooks';
 import {useBoolean} from 'ahooks';
 import {useEffect, useState} from 'react';
 import {context, pageContext} from '../context';
-import {useMutation, useQuery} from '@tanstack/react-query';
+import {useMutation} from '@tanstack/react-query';
 import {deleteGoods, getGoodsList} from '@apis';
 import {ColumnsType} from 'antd/es/table';
 import {GoodsListData} from '@models';
@@ -11,28 +11,12 @@ import {deleteConfirm} from '@utils';
 
 export function useList() {
   const [{number}, dispatch] = useContext(context);
-  const [{page, pageSize}] = usePage(pageContext);
-  const [count, setCount] = useState(0);
 
-  const {data, refetch, isFetching} = useQuery<GoodsListData[]>(
-    [getGoodsList.name, number, page, pageSize],
-    async function() {
-      const data = await getGoodsList({
-        page: String(page),
-        limit: String(pageSize),
-        itemNumber: number,
-      });
-
-      if (data.msg === '200') {
-        setCount(data.data.total);
-
-        return data.data.list;
-      }
-
-      return [];
-    },
-    {initialData: []},
-  );
+  const [{data, isFetching, count}, {refetch}] = useQueryTableList({
+    queryFn: getGoodsList,
+    params: {itemNumber: number},
+    pageContext,
+  });
 
   useEffect(function() {
     dispatch({type: 'CHANGE_SEARCH_STATE', payload: isFetching});

+ 8 - 27
packages/app/src/pages/menu-id/table/hooks.tsx

@@ -1,48 +1,29 @@
 import {useBoolean} from 'ahooks';
 import {context, pIdContext, pageContext} from '../context';
 import {useEffect, useState} from 'react';
-import {useMutation, useQuery} from '@tanstack/react-query';
+import {useMutation} from '@tanstack/react-query';
 import {deleteMenu, getMenuList} from '@apis';
 import {MenuListData} from '@models';
 import {Button, message} from 'antd';
 import {ColumnsType} from 'antd/es/table';
-import {useContext, useContextSection, usePage} from '@hooks';
+import {useContext, useContextSection, useQueryTableList} from '@hooks';
 import {deleteConfirm} from '@utils';
 
 export function useList() {
-  const [{page, pageSize}, {onPageChange}] = usePage(pageContext);
   const [{name}, dispatch] = useContext(context);
-  const [count, setCount] = useState(0);
   const pid = useContextSection(pIdContext, ([pid]) => pid);
 
-  const {data, isFetching, refetch} = useQuery(
-    [getMenuList.name, pid, page, pageSize, name],
-    async function() {
-      const data = await getMenuList({
-        pId: pid,
-        page: page.toString(),
-        limit: pageSize.toString(),
-        name,
-      });
-
-      if (data.msg === '200') {
-        setCount(data.data.total);
-        return data.data.list;
-      }
-
-      return [] as MenuListData[];
-    },
-    {
-      initialData: [],
-      enabled: pid !== '0',
-    },
-  );
+  const [{isFetching, data, count}, {refetch}] = useQueryTableList({
+    queryFn: getMenuList,
+    params: {pId: pid, name},
+    pageContext,
+  });
 
   useEffect(function() {
     dispatch({type: 'CHANGE_SEARCH_STATE', payload: isFetching});
   }, [dispatch, isFetching]);
 
-  return [{count, isFetching, data, page, pageSize}, {refetch, onPageChange}] as const;
+  return [{count, isFetching, data}, {refetch}] as const;
 }
 
 export function useHandle(data: MenuListData[], refetch: () => void) {

+ 4 - 3
packages/app/src/pages/menu-id/table/index.tsx

@@ -3,14 +3,15 @@ import {FC} from 'react';
 import MenuModal from './modal';
 import {useHandle, useList} from './hooks';
 import {PAGE_SIZE_LIST} from '@utils';
-import {useContextSection} from '@hooks';
-import {context} from '../context';
+import {useContextSection, usePage} from '@hooks';
+import {context, pageContext} from '../context';
 import {TableTools} from '@components';
 
 const TableList: FC = function() {
-  const [{isFetching, data, page, pageSize, count}, {refetch, onPageChange}] = useList();
+  const [{isFetching, data, count}, {refetch}] = useList();
   const [{columns, visible, editId}, {onModalClose, onAdd}] = useHandle(data, refetch);
   const onClose = useContextSection(context, ([{onClose}]) => onClose);
+  const [{page, pageSize}, {onPageChange}] = usePage(pageContext);
 
   return (
     <>

+ 8 - 26
packages/app/src/pages/menu/table/hooks.tsx

@@ -1,46 +1,28 @@
 import {useBoolean} from 'ahooks';
 import {context, pageContext} from '../context';
 import {useEffect, useState} from 'react';
-import {useMutation, useQuery} from '@tanstack/react-query';
+import {useMutation} from '@tanstack/react-query';
 import {deleteMenu, getMenuList} from '@apis';
 import {MenuListData} from '@models';
 import {Button, message} from 'antd';
 import {ColumnsType} from 'antd/es/table';
-import {useContext, usePage} from '@hooks';
+import {useContext, useQueryTableList} from '@hooks';
 import {deleteConfirm} from '@utils';
 
 export function useList() {
-  const [{page, pageSize}, {onPageChange}] = usePage(pageContext);
   const [{name}, dispatch] = useContext(context);
-  const [count, setCount] = useState(0);
 
-  const {data, isFetching, refetch} = useQuery<MenuListData[]>(
-    [getMenuList.name, page, pageSize, name],
-    async function() {
-      const data = await getMenuList({
-        pId: '0',
-        page: page.toString(),
-        limit: pageSize.toString(),
-        name,
-      });
-
-      if (data.msg === '200') {
-        setCount(data.data.total);
-        return data.data.list;
-      }
-
-      return [] as MenuListData[];
-    },
-    {
-      initialData: [],
-    },
-  );
+  const [{data, isFetching, count}, {refetch}] = useQueryTableList({
+    queryFn: getMenuList,
+    params: {pId: '0', name},
+    pageContext,
+  });
 
   useEffect(function() {
     dispatch({type: 'CHANGE_SEARCH_STATE', payload: isFetching});
   }, [dispatch, isFetching]);
 
-  return [{count, isFetching, data, page, pageSize}, {refetch, onPageChange}] as const;
+  return [{count, isFetching, data}, {refetch}] as const;
 }
 
 export function useHandle(refetch: () => void) {

+ 4 - 1
packages/app/src/pages/menu/table/index.tsx

@@ -5,13 +5,16 @@ import {useHandle, useList} from './hooks';
 import {PAGE_SIZE_LIST} from '@utils';
 import ChildMenuModal from '../child-menu';
 import {TableTools} from '@components';
+import {pageContext} from '../context';
+import {usePage} from '@hooks';
 
 const TableList: FC = function() {
-  const [{isFetching, data, page, pageSize, count}, {refetch, onPageChange}] = useList();
+  const [{isFetching, data, count}, {refetch}] = useList();
   const [
     {columns, visible, editId, pid, childVisible},
     {onModalClose, onAdd, closeChildModal},
   ] = useHandle(refetch);
+  const [{page, pageSize}, {onPageChange}] = usePage(pageContext);
 
   return (
     <>

+ 8 - 26
packages/app/src/pages/pda-menu/table/hooks.tsx

@@ -1,46 +1,28 @@
 import {useBoolean} from 'ahooks';
 import {context, pageContext} from '../context';
 import {useEffect, useState} from 'react';
-import {useMutation, useQuery} from '@tanstack/react-query';
+import {useMutation} from '@tanstack/react-query';
 import {deleteMenu, getPDAMenuList} from '@apis';
 import {MenuListData} from '@models';
 import {Button, message} from 'antd';
 import {ColumnsType} from 'antd/es/table';
-import {useContext, usePage} from '@hooks';
+import {useContext, useQueryTableList} from '@hooks';
 import {deleteConfirm} from '@utils';
 
 export function useList() {
-  const [{page, pageSize}, {onPageChange}] = usePage(pageContext);
   const [{name}, dispatch] = useContext(context);
-  const [count, setCount] = useState(0);
 
-  const {data, isFetching, refetch} = useQuery<MenuListData[]>(
-    [getPDAMenuList.name, page, pageSize, name],
-    async function() {
-      const data = await getPDAMenuList({
-        pId: '0',
-        page: page.toString(),
-        limit: pageSize.toString(),
-        name,
-      });
-
-      if (data.msg === '200') {
-        setCount(data.data.total);
-        return data.data.list;
-      }
-
-      return [] as MenuListData[];
-    },
-    {
-      initialData: [],
-    },
-  );
+  const [{data, count, isFetching}, {refetch}] = useQueryTableList({
+    queryFn: getPDAMenuList,
+    params: {pId: '0', name},
+    pageContext,
+  });
 
   useEffect(function() {
     dispatch({type: 'CHANGE_SEARCH_STATE', payload: isFetching});
   }, [dispatch, isFetching]);
 
-  return [{count, isFetching, data, page, pageSize}, {refetch, onPageChange}] as const;
+  return [{count, isFetching, data}, {refetch}] as const;
 }
 
 export function useHandle(refetch: () => void) {

+ 4 - 1
packages/app/src/pages/pda-menu/table/index.tsx

@@ -4,13 +4,16 @@ import MenuModal from './modal';
 import {useHandle, useList} from './hooks';
 import {PAGE_SIZE_LIST} from '@utils';
 import {TableTools} from '@components';
+import {usePage} from '@hooks';
+import {pageContext} from '../context';
 
 const TableList: FC = function() {
-  const [{isFetching, data, page, pageSize, count}, {refetch, onPageChange}] = useList();
+  const [{isFetching, data, count}, {refetch}] = useList();
   const [
     {columns, visible, editId},
     {onModalClose, onAdd},
   ] = useHandle(refetch);
+  const [{page, pageSize}, {onPageChange}] = usePage(pageContext);
 
   return (
     <>

+ 7 - 24
packages/app/src/pages/role/table/hooks.tsx

@@ -1,6 +1,6 @@
-import {useContext, usePage} from '@hooks';
+import {useContext, useQueryTableList} from '@hooks';
 import {context, pageContext} from '../context';
-import {useMutation, useQuery} from '@tanstack/react-query';
+import {useMutation} from '@tanstack/react-query';
 import {deleteRole, getRoleList} from '@apis';
 import {useEffect, useState} from 'react';
 import {ColumnsType} from 'antd/es/table';
@@ -10,30 +10,13 @@ import {useBoolean} from 'ahooks';
 import {deleteConfirm} from '@utils';
 
 export function useList() {
-  const [{page, pageSize}] = usePage(pageContext);
-  const [count, setCount] = useState(0);
   const [{name}, dispatch] = useContext(context);
 
-  const {data, isFetching, refetch} = useQuery(
-    [getRoleList.name, page, pageSize, name],
-    async function() {
-      const data = await getRoleList({
-        roleName: name,
-        page: page.toString(),
-        limit: pageSize.toString(),
-      });
-
-      if (data.msg === '200') {
-        setCount(data.data.total);
-        return data.data.list;
-      }
-
-      return [] as RoleListData[];
-    },
-    {
-      initialData: [],
-    },
-  );
+  const [{data, isFetching, count}, {refetch}] = useQueryTableList({
+    queryFn: getRoleList,
+    params: {roleName: name},
+    pageContext,
+  });
 
   useEffect(function() {
     dispatch({type: 'CHANGE_SEARCH_STATE', payload: isFetching});

+ 11 - 25
packages/app/src/pages/storage/table/hooks.tsx

@@ -1,5 +1,5 @@
-import {useContext, usePage} from '@hooks';
-import {useMutation, useQuery} from '@tanstack/react-query';
+import {useContext, useQueryTableList} from '@hooks';
+import {useMutation} from '@tanstack/react-query';
 import {context, pageContext} from '../context';
 import {deleteStorage, getStorageList} from '@apis';
 import {useEffect, useState} from 'react';
@@ -10,34 +10,20 @@ import {useBoolean} from 'ahooks';
 import {deleteConfirm} from '@utils';
 
 export function useList() {
-  const [{pageSize, page}] = usePage(pageContext);
   const [{name, code, isNotDisable, type}, dispatch] = useContext(
     context,
   );
-  const [count, setCount] = useState(0);
 
-  const {isFetching, data, refetch} = useQuery(
-    [getStorageList.name, page, pageSize, name, code, isNotDisable, type],
-    async function() {
-      const data = await getStorageList({
-        storageLocationName: name,
-        storageLocationType: type,
-        storageLocationCode: code,
-        isNotDisable,
-        page: String(page),
-        limit: String(pageSize),
-      });
-
-      if (data.msg === '200') {
-        setCount(data.data.total);
-
-        return data.data.list;
-      }
-
-      return [];
+  const [{data, isFetching, count}, {refetch}] = useQueryTableList({
+    queryFn: getStorageList,
+    params: {
+      storageLocationName: name,
+      storageLocationType: type,
+      storageLocationCode: code,
+      isNotDisable,
     },
-    {initialData: []},
-  );
+    pageContext,
+  });
 
   useEffect(function() {
     dispatch({type: 'CHANGE_SEARCH_STATE', payload: isFetching});

+ 7 - 25
packages/app/src/pages/user/table/hooks.tsx

@@ -1,5 +1,5 @@
-import {useContext, usePage} from '@hooks';
-import {useMutation, useQuery} from '@tanstack/react-query';
+import {useContext, useQueryTableList} from '@hooks';
+import {useMutation} from '@tanstack/react-query';
 import {context, pageContext} from '../context';
 import {deleteUser, getUserList} from '@apis';
 import {UserListData} from '@models';
@@ -9,33 +9,15 @@ import {Button, Modal, message} from 'antd';
 import {useBoolean} from 'ahooks';
 
 export function useList() {
-  const [{page, pageSize}] = usePage(pageContext);
   const [{name, code}, disaptch] = useContext(
     context,
   );
-  const [count, setCount] = useState(0);
 
-  const {isFetching, data, refetch} = useQuery<UserListData[]>(
-    [getUserList.name, page, pageSize, name, code],
-    async function() {
-      const data = await getUserList({
-        limit: pageSize.toString(),
-        page: page.toString(),
-        userName: name,
-        code,
-      });
-
-      if (data.msg === '200') {
-        setCount(data.data.total);
-        return data.data.list;
-      }
-
-      return [];
-    },
-    {
-      initialData: [],
-    },
-  );
+  const [{data, isFetching, count}, {refetch}] = useQueryTableList({
+    queryFn: getUserList,
+    params: {userName: name, code},
+    pageContext,
+  });
 
   useEffect(function() {
     disaptch({type: 'CHAGNE_SEARCH_STATE', payload: isFetching});

+ 1 - 1
packages/app/src/utils/constants.ts

@@ -1,7 +1,7 @@
 /** 用户session token */
 export const USER_TOKEN_STORAGE = 'user_token';
 /** 页码列表 */
-export const PAGE_SIZE_LIST = ['10', '30', '50', '80', '100'];
+export const PAGE_SIZE_LIST = ['5', '10', '30', '50', '80', '100'];
 /** 请求域名 */
 export const NETWORK_URL = 'http://192.168.0.118:9560';
 export const E2E_NETWORK_URL = 'http://e2e.test.cn';

+ 1 - 0
packages/app/src/utils/index.ts

@@ -5,3 +5,4 @@ export * from './clearHistoryState';
 export * from './types';
 export * from './sortMenu';
 export * from './deleteConfirm';
+export * from './jumpToPrevPage';

+ 31 - 0
packages/app/src/utils/jumpToPrevPage/index.test.ts

@@ -0,0 +1,31 @@
+import {jumpToPrevPage} from '.';
+
+const fn = jest.fn();
+
+function onPageChange(page: number) {
+  fn();
+}
+
+describe('jumpToPrevPage', function() {
+  beforeEach(function() {
+    fn.mockClear();
+  });
+
+  it('有数据并且page大于1', function() {
+    jumpToPrevPage({current: 2, data: [1, 2, 3], onPageChange});
+
+    expect(fn).not.toBeCalled();
+  });
+
+  it('无数据并且page大于1', function() {
+    jumpToPrevPage({current: 2, data: [], onPageChange});
+
+    expect(fn).toBeCalled();
+  });
+
+  it('无数据并且page为1', function() {
+    jumpToPrevPage({current: 1, data: [], onPageChange});
+
+    expect(fn).not.toBeCalled();
+  });
+});

+ 12 - 0
packages/app/src/utils/jumpToPrevPage/index.ts

@@ -0,0 +1,12 @@
+
+type Options = {
+  data: any[],
+  current: number,
+  onPageChange: (page: number) => void,
+};
+
+export function jumpToPrevPage({data, current, onPageChange}: Options) {
+  if (current <= 1) return;
+
+  data.length === 0 && onPageChange(current - 1);
+}