sidebar.tsx 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import { useEffect, useState } from 'react';
  2. import { Badge, Layout, Menu } from 'antd';
  3. import { AdminRouterItem, routes } from '../../router';
  4. import { useLocation, useNavigate } from 'react-router-dom';
  5. import useMessagesHook from '@src/hooks/messages';
  6. const { Sider } = Layout;
  7. const getMenuItems = (routes: AdminRouterItem[], notReadMessageCount: number): any[] => {
  8. return routes.map(itm => {
  9. if (!itm.meta) return null
  10. let children: any[] = []
  11. if (itm.children) children = getMenuItems(itm.children, notReadMessageCount)
  12. const menuItem = children.length > 0 ? {
  13. ...itm.meta,
  14. children
  15. } : {
  16. ...itm.meta,
  17. path: itm.path,
  18. }
  19. // 为消息菜单添加未读数量徽章
  20. if (menuItem.key === '/messages' && notReadMessageCount > 0) {
  21. menuItem.extra = <Badge count={notReadMessageCount} />
  22. }
  23. return menuItem
  24. }).filter(itm => !!itm)
  25. }
  26. /**
  27. * PageSidebar
  28. * @param props {autoCollapse?: boolean} automatic collapes menu when click another menu
  29. * @returns
  30. */
  31. const PageSidebar = (props: {
  32. autoCollapse?: boolean
  33. }) => {
  34. const { notReadMessageCount } = useMessagesHook()
  35. const [menuItems, setMenuItems] = useState<any[]>([])
  36. useEffect(() => {
  37. const _menuItems = getMenuItems(routes, notReadMessageCount)
  38. console.log('menuItems', _menuItems)
  39. setMenuItems(_menuItems)
  40. }, [notReadMessageCount])
  41. const { autoCollapse = true } = props
  42. const navigate = useNavigate()
  43. const [selectedKeys, setSelectedKeys] = useState<string[]>([])
  44. const [lastOpenedMenu, setLastOpenedMenu] = useState<string[]>([])
  45. const location = useLocation()
  46. const onSwitchMenu = ({ key, keyPath }: { key: string; keyPath: string[] }) => {
  47. if (autoCollapse && keyPath.slice(1)) setLastOpenedMenu(keyPath.slice(1))
  48. navigate(key)
  49. }
  50. const onOpenChange = (openKeys: string[]) => {
  51. setLastOpenedMenu(openKeys)
  52. }
  53. useEffect(() => {
  54. setSelectedKeys([`${location.pathname}`])
  55. const lastOpenedMenu = location.pathname.split('/')?.[1]
  56. if (lastOpenedMenu) {
  57. setLastOpenedMenu([`/${lastOpenedMenu}`])
  58. }
  59. navigate(location.pathname)
  60. }, [location.pathname, navigate])
  61. return (
  62. <Sider theme='light'>
  63. <Menu openKeys={lastOpenedMenu} onOpenChange={onOpenChange} selectedKeys={selectedKeys} mode="inline" items={menuItems} onClick={onSwitchMenu} />
  64. </Sider>
  65. )
  66. }
  67. export default PageSidebar