97 lines
2.4 KiB
TypeScript
97 lines
2.4 KiB
TypeScript
import { setCurrentMenu, setHeadMenus } from '@/app/common';
|
||
import { useAppDispatch } from '@/app/hooks';
|
||
import SuspenseLayout from '@/components/suspense-layout';
|
||
import {
|
||
findFirstSubMenu,
|
||
findHeadMenuByHeadKey,
|
||
findHeadMenuBySideKey,
|
||
menuItems,
|
||
} from '@/utils/menu';
|
||
import { MenuProps } from '@df/toco-ui';
|
||
import { useCallback, useEffect } from 'react';
|
||
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
|
||
import Layout from './HeaderAndSider';
|
||
// import Layout from './HeaderAndFooter';
|
||
|
||
export type LayoutProps = {
|
||
children?: React.ReactNode;
|
||
onHeadMenuSelect?: MenuProps['onSelect'];
|
||
onSideMenuSelect?: MenuProps['onSelect'];
|
||
};
|
||
|
||
const LayoutRoot = () => {
|
||
const dispatch = useAppDispatch();
|
||
const location = useLocation();
|
||
const navigate = useNavigate();
|
||
|
||
// 设置head菜单
|
||
useEffect(() => {
|
||
dispatch(setHeadMenus(menuItems));
|
||
}, [dispatch]);
|
||
|
||
// 监听路由变化
|
||
useEffect(() => {
|
||
const key = location.pathname.replace(/^\//, '').replace(/\/$/, '');
|
||
const headMenu = findHeadMenuByHeadKey(key);
|
||
if (headMenu) {
|
||
// 一级页面
|
||
dispatch(
|
||
setCurrentMenu({
|
||
headKey: headMenu.key,
|
||
}),
|
||
);
|
||
} else {
|
||
// 非一级页面
|
||
const headMenu = findHeadMenuBySideKey(key);
|
||
dispatch(
|
||
setCurrentMenu({
|
||
headKey: headMenu?.key ?? '',
|
||
sideKey: key,
|
||
}),
|
||
);
|
||
}
|
||
}, [dispatch, location]);
|
||
|
||
const handleHeadMenuSelect: MenuProps['onSelect'] = useCallback(
|
||
({ item, key, keyPath, domEvent }) => {
|
||
const headMenu = findHeadMenuByHeadKey(key);
|
||
|
||
if (!headMenu) {
|
||
// 顶部嵌套的菜单(即实际点击的sideMenu)
|
||
navigate(key);
|
||
return;
|
||
}
|
||
|
||
if (!headMenu.children?.length) {
|
||
// 一级页面
|
||
navigate(key);
|
||
} else {
|
||
// 非一级页面点击一级菜单,主动跳转第一个子页面
|
||
const subMenu = findFirstSubMenu(headMenu);
|
||
if (subMenu) {
|
||
navigate(subMenu.key);
|
||
}
|
||
}
|
||
},
|
||
[navigate],
|
||
);
|
||
const handleSideMenuSelect: MenuProps['onSelect'] = useCallback(
|
||
({ item, key, keyPath, domEvent }) => {
|
||
navigate(key);
|
||
},
|
||
[navigate],
|
||
);
|
||
|
||
return (
|
||
<Layout
|
||
onHeadMenuSelect={handleHeadMenuSelect}
|
||
onSideMenuSelect={handleSideMenuSelect}
|
||
>
|
||
<SuspenseLayout>
|
||
<Outlet />
|
||
</SuspenseLayout>
|
||
</Layout>
|
||
);
|
||
};
|
||
export default LayoutRoot;
|