mh-sms-web/src/layout/Sider.js
2024-04-01 15:15:42 +08:00

382 lines
13 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 [mainSilder, setMainSilder] = useState(1);
const clickMainMenu = (index) => {
setMainSilder(index);
};
/** 子菜单路由 */
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 [MenuShow, setMenuShow] = useState(false);
const toggleCollapsed = () => {
setCollapsed(!collapsed);
};
useEffect(() => {
if (MenuShow == true) {
setMenuShow(false);
}
}, [props.repost]);
const menuCUR = topMenus.menus[mainSilder - 2];
/** 登录页隐藏 */
if (props.matchLogin) return null;
return (
<div className={`sider ${"shortMenuShow"}`}>
<div>
<div className={`sider ${"shortMenuShow_overflow"}`}>
<div className={`sider ${"shortMenuShow_overflowb"}`}>
<div
className="sider__shortMenuShowoverca"
onClick={() => {
clickMainMenu(1);
navToHome();
setMenuShow(false);
}}
>
<Icon
type="home"
className={
mainSilder == 1
? "sider__shortMenuShowoverca-overcd"
: "sider__shortMenuShowoverca-overc"
}
></Icon>
<div className="sider__shortMenuShowoverca-title">首页</div>
</div>
{/* <div
className="sider__shortMenuShowoverca"
onClick={() => {
clickMainMenu(2);
setMenuShow(true);
}}
>
<Icon
type="profile"
title="常用菜单"
className={
mainSilder == 2
? "sider__shortMenuShowoverca-overcd"
: "sider__shortMenuShowoverca-overc"
}
></Icon>
</div> */}
<div>
{topMenus.menus.map((menu, index) => {
return (
<div
className="sider__shortMenuShowoverca"
onClick={() => {
clickMainMenu(index + 2);
setCurrMenu(menu.Node);
clickMenu();
setMenuShow(true);
}}
>
<Icon
type={menu.Node.ICON ? menu.Node.ICON : "reconciliation"}
title={menu.Node.NAME}
className={
mainSilder == index + 2
? "sider__shortMenuShowoverca-overcd"
: "sider__shortMenuShowoverca-overc"
}
></Icon>
<div className="sider__shortMenuShowoverca-title">
{menu.Node.NAME}
</div>
</div>
);
})}
</div>
<div className="sider__outButton">
<div
className="sider__shortMenuShowovercae"
onClick={() => {
setMenuShow(!MenuShow);
if (mainSilder == 1) {
//禁止mainsilder为1--首页状态
setMainSilder(2);
}
// if (MenuShow) {
// setMainSilder(1);
// } else {
// setMainSilder(2);
// }
}}
>
{MenuShow == true ? (
<Icon
type="import"
className="sider__shortMenuShowoverca-overcd"
></Icon>
) : (
<Icon
type="import"
className="sider__shortMenuShowoverca-overcd"
 style={{transform:'scaleX(-1)'}}
></Icon>
)}
</div>
</div>
</div>
<div
className={
MenuShow
? `sider ${"shortMenuShow_overflowc"}`
: `sider ${"shortMenuShow_overflowcExpand"}`
}
>
{/* <img
src={require("././../assets/logo-slider.jpg")}
style={{
height: "80px",
width: "auto",
objectFit: "contain",
marginTop: "10px",
}}
></img> */}
<div className={`sider ${"__shortMenuShowChild"}`}>
{/* {mainSilder == 2 ? (
<div className={`sider ${"shortMenuShow_ChildPadding"}`}>
{favorMenus.map((menu2, index2) => {
return (
<div
// key={`${menu2.ID}_${index2}`}
onClick={() => handleActiveMenu(menu2)}
className="sider__shortMenuShowChild"
>
<Icon
type={menu2.ICON ? menu2.ICON : "file-text"}
className="sider__shortMenuShowChild-iconone"
/>
<span className="sider__shortMenuShowChild-name">
{menu2.NAME}
</span>
</div>
);
})}
</div>
) : ( */}
<div className={`sider ${"shortMenuShow_ChildPadding"}`}>
{menuCUR &&
menuCUR.Children.map((menu2, index2) => {
return (
<div
// key={`${menu2.ID}_${index2}`}
className="sider__shortMenuShowFlex"
>
<div className="sider__shortMenuShowChildTwo">
<Icon
type={"caret-right"}
className="sider__shortMenuShowChildTwo-iconri"
/>
<Icon
type={
menu2.Node.ICON ? menu2.Node.ICON : "file-text"
}
className="sider__shortMenuShowChildTwo-icon"
/>
<span className="sider__shortMenuShowChildTwo-name">
{menu2.Node.NAME}
</span>
</div>
<div className="sider__shortMenuShowGrid">
{menu2.Children.map((menu3, index3) => {
return (
<div
key={`${menu3.Node.ID}_${index3}`}
onClick={() => {
handleActiveMenu(menu3.Node);
}}
title={menu3.Node.NAME}
>
<div className="sider__shortMenuShowChild">
{/* <Icon
type={"caret-right"}
className="sider__shortMenuShowChild-iconritwo"
/> */}
<Icon
type={
menu3.Node.ICON
? menu3.Node.ICON
: "file-text"
}
className="sider__shortMenuShowChild-icontwo"
/>
<span className="sider__shortMenuShowChild-nametwo">
{menu3.Node.NAME}
</span>
</div>
</div>
);
})}
</div>
</div>
);
})}
</div>
{/* // )} */}
</div>
</div>
</div>
</div>
</div>
);
};
export default withRouter(connect(({ login }) => ({ login }))(Sider));