|
@@ -1,7 +1,7 @@
|
|
|
/*
|
|
|
* @Author: your name
|
|
|
* @Date: 2022-01-06 15:25:39
|
|
|
- * @LastEditTime: 2024-07-18 16:59:59
|
|
|
+ * @LastEditTime: 2024-08-21 17:39:43
|
|
|
* @LastEditors: code4eat awesomedema@gmail.com
|
|
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
|
|
* @FilePath: /KC-MiddlePlatform/src/pages/platform/_layout.tsx
|
|
@@ -14,7 +14,7 @@ import { getPlatformMenu, getSpecifyMenuDetail } from '@/service/menu';
|
|
|
import './index.less';
|
|
|
import { TreeItemType } from '@/utils';
|
|
|
import { SpacicalPageParamsType } from '@/typings';
|
|
|
-import { Key, useEffect, useState } from 'react';
|
|
|
+import { Key, useEffect, useRef, useState } from 'react';
|
|
|
|
|
|
import Icon, { FileOutlined, FolderOutlined, createFromIconfontCN } from '@ant-design/icons';
|
|
|
import { getAllParams } from '@/service';
|
|
@@ -83,6 +83,48 @@ const findItemByKey: any = (tree: any[], key: string, keyName: string) => {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+// 权限检查函数
|
|
|
+function checkAccess(menu: any[], pathname: string) {
|
|
|
+ const matchPath = (path: any, target: string) => {
|
|
|
+ // 如果路径以 /platform 开头,则需要完整匹配
|
|
|
+ if (target.startsWith('/platform')) {
|
|
|
+ return path === target; // 完整匹配
|
|
|
+ }
|
|
|
+
|
|
|
+ // 否则,执行前缀匹配逻辑
|
|
|
+ return target.startsWith(path);
|
|
|
+ };
|
|
|
+
|
|
|
+ for (const item of menu) {
|
|
|
+ // 如果匹配成功,则立即返回 true
|
|
|
+ if (matchPath(item.path, pathname)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 递归检查 item.child 的情况
|
|
|
+ if (item.child) {
|
|
|
+ const hasAccess = checkAccess(item.child, pathname);
|
|
|
+ if (hasAccess) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 递归检查 item.children 的情况
|
|
|
+ if (item.children) {
|
|
|
+ const hasAccess = checkAccess(item.children, pathname);
|
|
|
+ if (hasAccess) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果所有匹配都失败,返回 false
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
export default function Layout({ children, location, route, history, match, ...rest }: IRouteComponentProps) {
|
|
|
const { initialState, setInitialState } = useModel('@@initialState');
|
|
|
const [openKeys, set_openKeys] = useState<string[]>([]);
|
|
@@ -101,6 +143,10 @@ export default function Layout({ children, location, route, history, match, ...r
|
|
|
const moreConfig: { menuRender?: any } = (isShowPageMenu && noMenu != 'true') ? {} : { menuRender: false }
|
|
|
|
|
|
const { pathname } = location;
|
|
|
+ const isMenuClickRef = useRef(false);
|
|
|
+
|
|
|
+ const [loading, setLoading] = useState(true);
|
|
|
+ const [dataLoaded, setDataLoaded] = useState(false);
|
|
|
|
|
|
const setEmptyPageContent = async (menuId: Key) => {
|
|
|
const menuItem = await getSpecifyMenuDetail(menuId);
|
|
@@ -110,6 +156,18 @@ export default function Layout({ children, location, route, history, match, ...r
|
|
|
set_emptyPageContent(menuItem.description);
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+ const checkPermission = (path: any) => {
|
|
|
+ const { navData = [], menuData = [] } = initialState || {};
|
|
|
+
|
|
|
+ // 检查访问权限
|
|
|
+ const hasAccess = checkAccess([...navData, ...menuData], path);
|
|
|
+
|
|
|
+ return hasAccess;
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
useEffect(() => {
|
|
|
const isShowMenu = localStorage.getItem('isChildShowMenu');
|
|
|
set_isShowPageMenu(isShowMenu == 'true');
|
|
@@ -240,6 +298,42 @@ export default function Layout({ children, location, route, history, match, ...r
|
|
|
return <>{pageUrl && <iframe id={'bi_iframe'} style={{ width: '100%', height: '100%', border: 'none' }} src={pageUrl} onLoad={() => adjustIframe()}></iframe>};</>;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+ // useEffect(() => {
|
|
|
+ // if (!dataLoaded && initialState) {
|
|
|
+ // const navData = initialState.navData || [];
|
|
|
+ // const menuData = initialState.menuData || [];
|
|
|
+
|
|
|
+ // if (navData.length > 0 || menuData.length > 0) {
|
|
|
+ // setDataLoaded(true);
|
|
|
+
|
|
|
+ // const { pathname } = history.location;
|
|
|
+ // const hasAccess = checkPermission(pathname);
|
|
|
+ // if (!hasAccess) {
|
|
|
+ // if (!pathname.includes('/platform')) {
|
|
|
+ // history.push('/noAccess');
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // setLoading(false);
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }, [initialState, dataLoaded]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ return history.listen((location) => {
|
|
|
+ if (!isMenuClickRef.current && dataLoaded) {
|
|
|
+ const hasPermission = checkPermission(location.pathname);
|
|
|
+ if (!hasPermission) {
|
|
|
+ history.push('/noAccess');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ isMenuClickRef.current = false; // 重置状态
|
|
|
+ });
|
|
|
+ }, [dataLoaded, initialState]);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
return (
|
|
|
<ProLayout
|
|
|
style={{
|
|
@@ -280,6 +374,7 @@ export default function Layout({ children, location, route, history, match, ...r
|
|
|
return (
|
|
|
<a
|
|
|
onClick={() => {
|
|
|
+ isMenuClickRef.current = true; // 标记为菜单点击
|
|
|
history.push(`${item.path}${item.contentType == '4' ? `?isEmpty=true&menuId=${item.key}` : ''}` || '/');
|
|
|
}}
|
|
|
>
|
|
@@ -455,10 +550,10 @@ export default function Layout({ children, location, route, history, match, ...r
|
|
|
<IconFont style={{ display: 'inline-block',fontSize:24 }} className="menuCollapseIcon" type={collapsed ? 'icon-celanzhankai' : 'icon-celanshouqi'} />
|
|
|
</div>
|
|
|
</div>
|
|
|
-
|
|
|
+
|
|
|
</ResizableContainer>
|
|
|
</div>
|
|
|
-
|
|
|
+
|
|
|
);
|
|
|
}}
|
|
|
onPageChange={(location) => { }}
|