Skip to content

Commit

Permalink
fix: error in role page
Browse files Browse the repository at this point in the history
  • Loading branch information
condorheroblog committed Dec 28, 2024
1 parent c9d9e96 commit 3f8b5d5
Show file tree
Hide file tree
Showing 7 changed files with 240 additions and 54 deletions.
123 changes: 118 additions & 5 deletions fake/system.fake.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { resultSuccess } from "./utils";
const systemMenu = [
// 系统管理
{
parentId: 0,
id: system,
menuType: 0, // 菜单类型(0 代表菜单、1 代表 iframe、2 代表外链、3 代表按钮)
title: "common.menu.system",
Expand Down Expand Up @@ -39,19 +38,19 @@ const systemMenu = [
parentId: system + 4,
id: system + 4 + 1,
menuType: 3,
title: "新增",
title: "common.add",
},
{
parentId: system + 4,
id: system + 4 + 2,
menuType: 3,
title: "编辑",
title: "common.edit",
},
{
parentId: system + 4,
id: system + 4 + 3,
menuType: 3,
title: "删除",
title: "common.delete",
},
];

Expand Down Expand Up @@ -85,7 +84,7 @@ export default defineFakeRoute([
list = list.filter(item =>
item.name.includes(body?.name ?? "")
&& String(item.status).includes(String(body?.status ?? ""))
&& (!body.code || item.code === body.code),
&& (!body?.code || item.code === body?.code),
);
return resultSuccess({
list,
Expand Down Expand Up @@ -141,4 +140,118 @@ export default defineFakeRoute([
return resultSuccess([]);
},
},
// 菜单管理
{
url: "/menu-list",
method: "get",
response: () => {
const menuList = [
// 系统管理
{
parentId: "", // 上级菜单 id
id: system, // 菜单 id
menuType: 0, // 菜单类型(0 代表菜单、1 代表 iframe、2 代表外链、3 代表按钮)
title: "common.menu.system", // 菜单名称
path: "/system", // 路由路径
component: "/system", // 组件路径
order: system, // 菜单顺序
icon: "SettingOutlined", // 菜单图标
currentActiveMenu: "", // 激活路径
iframeLink: "", // iframe 链接
keepAlive: true, // 是否缓存页面
externalLink: "", // 外链地址
hideInMenu: false, // 是否隐藏菜单
ignoreAccess: false, // 是否忽略权限
},
{
parentId: system,
id: system + 1,
menuType: 0,
title: "common.menu.system.user",
path: "/system/user", // 路由路径
component: "/system/user", // 组件路径
order: undefined, // 菜单顺序
icon: "UserOutlined", // 菜单图标
currentActiveMenu: "", // 激活路径
iframeLink: "", // iframe 链接
keepAlive: true, // 是否缓存页面
externalLink: "", // 外链地址
hideInMenu: false, // 是否隐藏菜单
ignoreAccess: false, // 是否忽略权限
},
{
parentId: system,
id: system + 2,
menuType: 0,
title: "common.menu.system.role",
path: "/system/role", // 路由路径
component: "/system/role", // 组件路径
order: undefined, // 菜单顺序
icon: "TeamOutlined", // 菜单图标
currentActiveMenu: "", // 激活路径
iframeLink: "", // iframe 链接
keepAlive: true, // 是否缓存页面
externalLink: "", // 外链地址
hideInMenu: false, // 是否隐藏菜单
ignoreAccess: false, // 是否忽略权限
},
{
parentId: system,
id: system + 3,
menuType: 0,
title: "common.menu.system.menu",
path: "/system/menu", // 路由路径
component: "/system/menu", // 组件路径
order: undefined, // 菜单顺序
icon: "MenuOutlined", // 菜单图标
currentActiveMenu: "", // 激活路径
iframeLink: "", // iframe 链接
keepAlive: true, // 是否缓存页面
externalLink: "", // 外链地址
hideInMenu: false, // 是否隐藏菜单
ignoreAccess: false, // 是否忽略权限
},
{
parentId: system,
id: system + 4,
menuType: 0,
title: "common.menu.system.dept",
path: "/system/dept", // 路由路径
component: "/system/dept", // 组件路径
order: undefined, // 菜单顺序
icon: "ApartmentOutlined", // 菜单图标
currentActiveMenu: "", // 激活路径
iframeLink: "", // iframe 链接
keepAlive: true, // 是否缓存页面
externalLink: "", // 外链地址
hideInMenu: false, // 是否隐藏菜单
ignoreAccess: false, // 是否忽略权限
},
{
parentId: system + 4,
id: system + 4 + 1,
menuType: 3,
title: "common.add",
},
{
parentId: system + 4,
id: system + 4 + 2,
menuType: 3,
title: "common.edit",
},
{
parentId: system + 4,
id: system + 4 + 3,
menuType: 3,
title: "common.delete",
},
];
return resultSuccess({
list: menuList,
total: menuList.length, // 总条目数
pageSize: 10, // 每页显示条目个数
current: 1, // 当前页数
});
},
},
]);
2 changes: 2 additions & 0 deletions src/components/basic-table/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// 添加到 table 的 classname
export const BASIC_TABLE_ROOT_CLASS_NAME = "basic-table";
104 changes: 82 additions & 22 deletions src/components/basic-table/index.tsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,127 @@
import type { ParamsType, ProTableProps } from "@ant-design/pro-components";

import { cn } from "#src/utils/cn";

import { LoadingOutlined } from "@ant-design/icons";
import { ProTable } from "@ant-design/pro-components";
import { useSize } from "ahooks";
import { useEffect, useRef } from "react";
import { useEffect, useRef, useState } from "react";

export interface BasicTableProps<D, U, V> extends ProTableProps<D, U, V> {
import { BASIC_TABLE_ROOT_CLASS_NAME } from "./constants";
import { useStyles } from "./styles";

export interface BasicTableProps<D, U, V> extends ProTableProps<D, U, V> {
/**
* @description 是否填充父元素
* @default true
*/
autoHeight?: boolean
/**
* @description 表格底部的偏移量
* @default 0
*/
offsetBottom?: number
}

// 添加到 table 的 classname
export const ROOT_CLASS_NAME = "basic-table";

/**
* 当表格始终处于屏幕内时,表格高度是自适应的
* 如果表格在屏幕内可能不可见或者不位于 main 布局标签内,请设置 autoHeight 为 false,避免表格出现抖动,参考下面的 warning 部分
*/
export function BasicTable<
DataType extends Record<string, any>,
Params extends ParamsType = ParamsType,
ValueType = "text",
>(
props: BasicTableProps<DataType, Params, ValueType>,
) {
const classes = useStyles();
const { autoHeight = true, offsetBottom } = props;
const tableWrapperRef = useRef<HTMLDivElement>(null);
const size = useSize(tableWrapperRef);
const [scrollY, setScrollY] = useState(autoHeight ? 0 : undefined);

/**
* @description 表格高度自适应
* 这是一个 hook 方法,等待 antd 修复
* @see https://github.com/ant-design/ant-design/issues/23974
*/
useEffect(() => {
if (tableWrapperRef.current && size?.height) {
const isPaginationDisabled = props.pagination === false;
if (autoHeight && tableWrapperRef.current && size?.height) {
const tableWrapperHeight = size.height;
const basicTable = tableWrapperRef.current.getElementsByClassName(ROOT_CLASS_NAME)[0];
const basicTable = tableWrapperRef.current.getElementsByClassName(BASIC_TABLE_ROOT_CLASS_NAME)[0];

if (!basicTable)
return;

// const antPagination = basicTable.getElementsByClassName("ant-pagination")[0];
const tableWrapperRect = tableWrapperRef.current.getBoundingClientRect();

// 如果表格超出屏幕高度,不进行高度自适应
if (tableWrapperRect.top > window.innerHeight) {
setScrollY(undefined);
return;
}

const tableBody = basicTable.querySelector("div.ant-table-body");

if (!tableBody)
return;

// 获取元素的边界框
const tableBodyRect = tableBody.getBoundingClientRect();
const tableWrapperRect = tableWrapperRef.current.getBoundingClientRect();
// const antPaginationRect = antPagination?.getBoundingClientRect?.() || 0;
// 上边距
const distanceTop = tableBodyRect.top - tableWrapperRect.top;
// 下边距
// const distanceBottom = tableBodyRect.bottom - antPaginationRect?.bottom;
/* pagination 的高度 24,上边距 16,main 标签的 padding-bottom 16 */
const distanceBottom = 24 + 16 + 16;
// 表格表头的高度
const tableHeaderHeight = tableBodyRect.top - tableWrapperRect.top;
/**
* 表格分页的高度
*
* @warning 表格必须是 main 标签的子元素,因为 main 标签的 padding-bottom(16) 会影响表格的高度
* pagination 的高度 24,上边距 16,main 标签的 padding-bottom 16
*
* 无法通过获取分页器 DOM 来计算分页器距离屏幕底部高度的原因:
* 1. 分页器的 DOM 可能是 undefined,可能因为分页器是在表格渲染完成后才会渲染
* 2. 没有设置 table body 的高度,无法确保分页器位于正确的位置,导致高度计算不准确
*
*/
const paginationHeight = isPaginationDisabled ? 16 : 24 + 16 + 16;
const realOffsetBottom = offsetBottom || paginationHeight;

const bodyHeight = Math.max(200, tableWrapperHeight - distanceTop - distanceBottom);
tableBody.setAttribute("style", `overflow-y: scroll;height: ${bodyHeight}px;max-height: ${bodyHeight}px;`);
const bodyHeight = Math.max(400, tableWrapperHeight - tableHeaderHeight - realOffsetBottom);
if (bodyHeight - tableBodyRect.height <= 10) {
return;
}
tableBody.setAttribute("style", `overflow-y: auto;min-height: ${bodyHeight}px;max-height: ${bodyHeight}px;`);
}
}, [size, autoHeight, offsetBottom, props.pagination]);

const getLoadingProps = () => {
if (props.loading === false) {
return false;
}
if (props.loading === true) {
return true;
}
}, [size]);
return {
indicator: <LoadingOutlined spin />,
...props.loading,
};
};

return (
<div className="h-full" ref={tableWrapperRef}>
<ProTable
cardBordered
rowKey="id"
dateFormatter="string"
{...props}
rootClassName={ROOT_CLASS_NAME}
// 可提供任意值,高度自适应逻辑会默认覆盖此值
scroll={{ y: "0" }}
options={{
fullScreen: true,
...props.options,
}}
rootClassName={cn(BASIC_TABLE_ROOT_CLASS_NAME, props.rootClassName)}
className={cn(classes.basicTable, props.className)}
// 设置 y 为 0,保证 tableBodyRect.height 小于 bodyHeight
scroll={{ y: scrollY, ...props.scroll }}
loading={getLoadingProps()}
/>
</div>
);
Expand Down
17 changes: 17 additions & 0 deletions src/components/basic-table/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { createUseStyles } from "react-jss";

export const useStyles = createUseStyles(({ prefixCls, isDark }) => {
return {
basicTable: {
[`& .${prefixCls}-table`]: {
[`& .${prefixCls}-table-container`]: {
[`& .${prefixCls}-table-content, & .${prefixCls}-table-body`]: {
"scrollbar-width": "thin",
"scrollbar-color": isDark ? "#909399 transparent" : "#eaeaea transparent",
"scrollbar-gutter": "stable",
},
},
},
},
};
});
8 changes: 6 additions & 2 deletions src/components/jss-theme-provider/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import type { ReactNode } from "react";

import { usePreferences } from "#src/hooks";

import { theme } from "antd";
import { ConfigProvider, theme } from "antd";
import { useContext } from "react";
import { ThemeProvider } from "react-jss";

/**
Expand Down Expand Up @@ -32,11 +34,13 @@ const { useToken } = theme;
* @returns {JSX.Element} 返回的JSX元素
*/
export function JSSThemeProvider({ children }: JSSThemeProviderProps) {
const antdContext = useContext(ConfigProvider.ConfigContext);
const prefixCls = antdContext.getPrefixCls();
const { token } = useToken();
const { theme, isDark, isLight } = usePreferences();

return (
<ThemeProvider theme={{ token, theme, isDark, isLight }}>
<ThemeProvider theme={{ token, theme, isDark, isLight, prefixCls }}>
{children}
</ThemeProvider>
);
Expand Down
Loading

0 comments on commit 3f8b5d5

Please sign in to comment.