demo-sps-web/src/layout/Sider.js
2024-12-16 13:42:31 +08:00

332 lines
9.7 KiB
JavaScript

import React, { useState, useEffect, useMemo, useRef } from "react";
import {
AppstoreOutlined,
CalendarOutlined,
LinkOutlined,
MailOutlined,
SettingOutlined,
MenuUnfoldOutlined,
MenuFoldOutlined,
} from "@ant-design/icons";
import { Divider, Menu, Switch, Icon, Button } from "antd";
import { connect } from "dva";
import { withRouter, matchPath } from "dva/router";
import { Scrollbars } from "react-custom-scrollbars";
import EnergyIcon from "../utils/energyIcon";
import { $consts } from "../plugins";
import "./sider.less";
import MenuItem from "antd/lib/menu/MenuItem";
import SubMenu from "antd/lib/menu/SubMenu";
const Sider = (props) => {
/** 菜单页展开与收起 */
const timer = useRef(-1);
const handleExpandMenuShow = () => {
clearTimeout(timer.current);
setExpandMenuShow(true);
};
const handleExpandMenuHide = () => {
clearTimeout(timer.current);
timer.current = setTimeout(() => {
setExpandMenuShow(false);
}, 200);
};
/** 控制三级菜单收缩和展开 */
const [menuShrink, setMenuShrink] = useState({});
const handleMenuShrink = (menuId) => {
const data = Object.assign({}, menuShrink);
data[menuId] ? (data[menuId] = "") : (data[menuId] = menuId);
setMenuShrink(data);
};
/** 回到首页 */
const navToHome = () => {
setActiveMenu(null);
props.history.push({ pathname: "/home" });
};
const clickMenu = ()=>{
collapsed===true?setCollapsed(false):setCollapsed(false)
}
/** 子菜单路由 */
const navToMenu = (menu) => {
props.history.push({ pathname: `/main/${menu.ID}` });
};
/** 后台设置:四级菜单 */
const navToBackend = (menu) => {
props.history.push({ pathname: `/backend/${menu.ID}` });
};
/** 一级菜单显示菜单 */
const [currMenu, setCurrMenu] = useState(null);
useEffect(() => {
const menus = props.login.loginInfo?.Menus || [];
menus.length && !currMenu && setCurrMenu(menus[0].Node);
}, [props.login.loginInfo?.Menus]);
/** 已激活菜单 */
const [activeMenu, setActiveMenu] = useState(null);
const handleActiveMenu = (menu) => {
setActiveMenu(menu);
navToMenu(menu);
};
/** 页面刷新时候,更新菜单的选中状态 */
useEffect(() => {
const { pathname } = props.location;
const mathHome = matchPath(pathname, {
path: $consts["ROUTE/HOME"],
exact: true,
strict: true,
});
if (mathHome) {
activeMenu && setActiveMenu(null);
}
const mathMain = matchPath(pathname, {
path: $consts["ROUTE/MAIN"],
exact: true,
strict: true,
});
if (mathMain) {
const { flatMenus } = props.login;
const { menuId } = mathMain.params;
const find = flatMenus.find((item) => item.ID === menuId);
if (find) {
props.dispatch({
type: "app/updateActivatedMenu",
payload: {
currActivatedTab: find.ID,
currActivatedMenu: find,
},
});
!activeMenu && setActiveMenu(find);
}
}
}, [props.location.pathname, props.login.flatMenus, activeMenu]);
/** 常用菜单 */
const favorMenus = useMemo(() => {
const { flatMenus } = props.login;
return flatMenus.filter((menu) => menu.IS_RESIDENT);
}, [props.login.flatMenus]);
/** 一级菜单 */
const topMenus = useMemo(() => {
const menus = props.login.loginInfo?.Menus || [];
// 菜单宽度 82 + margin 40
const menuWidth = menus.length
? menus.length * 82 + (menus.length - 1) * 40
: 0;
// 叶子菜单需要换行展示个数
const leafMenuSections =
menus.length < 3 ? 1 : menus.length === 3 ? 2 : menus.length - 2;
return {
menus,
width: menuWidth < 120 ? 120 : menuWidth,
leafMenuSections,
};
}, [props.login.loginInfo?.Menus]);
/** 二三级子菜单 */
const subMenus = useMemo(() => {
const { menus } = topMenus;
const find = menus.find((menu) => menu.Node.ID === currMenu?.ID);
return find?.Children || [];
}, [currMenu, topMenus]);
/** 三级子菜单默认收缩与展开 */
const { IS_MENU_SHRINK = false } = props.login.baseConfig;
useEffect(() => {
// IS_MENU_SHRINK为true时, 收缩所有三级菜单
if (IS_MENU_SHRINK) {
const { menus } = topMenus;
const data = {};
menus.forEach(
(menu) =>
menu.Children &&
menu.Children.forEach(
(child) => (data[child.Node.ID] = child.Node.ID)
)
);
setMenuShrink(data);
}
}, [IS_MENU_SHRINK]);
const [collapsed, setCollapsed] = useState(true);
const toggleCollapsed = () => {
setCollapsed(!collapsed);
};
useEffect(()=>{
if(collapsed == false) {
setCollapsed(true);
}
},[props.repost])
// console.log(props.repost,'21312313213213123')
/** 登录页隐藏 */
if (props.matchLogin) return null;
return (
<div className={`sider ${"shortMenuShow"}`}>
<div className={`sider ${"shortMenuShow_overflow"}`}>
<Menu
mode="inline"
inlineCollapsed={collapsed}
style={{
// marginTop: 24,
// paddingRight: 10,
paddingTop:'21px'
}}
// defaultOpenKeys={['sub1']}
inlineIndent="16"
onClick={clickMenu}
>
<MenuItem key="1" onClick={navToHome} title={'工作台'}>
{/* <img
src={require("../assets/layout/menu-all.png")}
alt=""
className="sider__menuAll-icon"
/> */}
<Icon type="home"></Icon>
<span>工作台</span>
</MenuItem>
<SubMenu
key="sub1"
title={
<span>
<Icon type="profile" title="常用菜单"></Icon>
<span>常用菜单</span>
</span>
}
onTitleClick={clickMenu}
>
{favorMenus.map((menu2, index2) => {
return (
<MenuItem
key={`${menu2.ID}_${index2}`}
onClick={() => handleActiveMenu(menu2)}
title={menu2.NAME}
>
<Icon type={menu2.ICON ? menu2.ICON : "file-text"} />
<span>{menu2.NAME}</span>
</MenuItem>
);
})}
</SubMenu>
{topMenus.menus.map((menu, index) => {
return (
// <div
// key={`${menu.Node.ID}_${index}`}
// // onMouseEnter={() => {
// // setCurrMenu(menu.Node);
// // setActiveKeepMenu(menu.Node);
// // }}
// onClick={() =>{handleActiveMenu(menu.Node);setCurrMenu(menu.Node);
// setActiveKeepMenu(menu.Node);} }
// className={wrapClass}
// >
// <div className="sider__menuExpand-menu--item">
// <Icon
// type={menu.Node.ICON ? menu.ICON : "file-text"}
// className={iconClass}
// />
// <div className={fontClass}>{menu.Node.NAME}</div>
// </div>
// <div className={indicatorClass} />
// </div>
<SubMenu
key={`${menu.Node.ID}_${index}`}
title={
<span>
<Icon type= {menu.Node.ICON ? menu.Node.ICON : "reconciliation"} title={menu.Node.NAME}></Icon>
<span>{menu.Node.NAME}</span>
</span>
}
onTitleClick={() => {
setCurrMenu(menu.Node);
clickMenu()
}}
>
{/* 二级 */}
{menu.Children.map((menu1, index1) => {
const isLevel4Menu = menu1.Children?.find(
(mc) => mc.Children?.length
);
const childMenus = isLevel4Menu
? [menu]
: menu.Children || [];
return (
<SubMenu
key={`${menu1.Node.ID}_${index1}`}
title={
<span>
<Icon type={menu1.Node.ICON ? menu1.Node.ICON : "reconciliation"}></Icon>
<span>{ menu1.Node.NAME}</span>
</span>
}
>
{/* 三级 */}
{menu1.Children.map((menu3, index3) => {
return (
<MenuItem key={`${menu3.Node.ID}_${index3}`} onClick={() =>
isLevel4Menu
? navToBackend(menu3.Node)
: handleActiveMenu(menu3.Node)
}
title={menu3.Node.NAME}
>
<Icon type={menu3.Node.ICON ? menu3.Node.ICON : "file-text"} />
<span>{menu3.Node.NAME}</span>
</MenuItem>
);
})}
</SubMenu>
);
})}
</SubMenu>
);
})}
</Menu>
</div>
<div onClick={toggleCollapsed}
style={{
marginBottom: 16,
display:'flex',
alignItems:'center',
position:'absolute',
right:0,
top:'40%',
padding:'40px 0px',
backgroundColor:'#DEE0E8',
borderRadius:'6px',
margin:'0px 0px 0px 0px',
}}>
<Icon type={collapsed ? 'right' : 'left'} style={{
fontSize:'12px',
display:'flex',
// alignItems:'right',
// justifyContent:'flex-end'
}} />
</div>
</div>
);
};
export default withRouter(connect(({ login }) => ({ login }))(Sider));