You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
4.6 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. import Avatar from '@/components/avatar'
  2. import PageBreadcrumb from '@/components/breadcrumb'
  3. import ErrorPage from '@/components/error/error.tsx'
  4. import SelectLang from '@/components/select-lang'
  5. import { appAtom } from '@/store/system.ts'
  6. import { userMenuDataAtom } from '@/store/system/user.ts'
  7. import { MenuItem } from '@/global'
  8. import { ProConfigProvider, ProLayout, } from '@ant-design/pro-components'
  9. import { zhCNIntl, enUSIntl } from '@ant-design/pro-provider/es/intl'
  10. import { CatchBoundary, Link, Outlet } from '@tanstack/react-router'
  11. import { ConfigProvider } from '@/components/config-provider'
  12. import { useState } from 'react'
  13. import defaultProps from './_defaultProps'
  14. import { useAtomValue } from 'jotai'
  15. import { useStyle } from '@/layout/style.ts'
  16. import zh from 'antd/locale/zh_CN'
  17. import en from 'antd/locale/en_US'
  18. //根据menuData生成Breadcrumb所需的数据
  19. const getBreadcrumbData = (menuData: MenuItem[], pathname: string) => {
  20. const breadcrumbData: any[] = []
  21. const findItem = (menuData: any[], pathname: string) => {
  22. for (let i = 0; i < menuData.length; i++) {
  23. if (menuData[i].path === pathname) {
  24. breadcrumbData.push(menuData[i])
  25. return true
  26. }
  27. if (menuData[i].children) {
  28. if (findItem(menuData[i].children, pathname)) {
  29. breadcrumbData.push(menuData[i])
  30. return true
  31. }
  32. }
  33. }
  34. return false
  35. }
  36. findItem(menuData, pathname)
  37. return breadcrumbData.reverse()
  38. }
  39. export default () => {
  40. const { styles } = useStyle()
  41. const { data: menuData = [], isLoading } = useAtomValue(userMenuDataAtom)
  42. const { language } = useAtomValue(appAtom)
  43. const items = getBreadcrumbData(menuData, location.pathname)
  44. const [ pathname, setPathname ] = useState(location.pathname)
  45. return (
  46. <div
  47. className={styles.container}
  48. id="crazy-pro-layout"
  49. style={{
  50. height: '100vh',
  51. // overflow: 'auto',
  52. }}
  53. >
  54. <CatchBoundary
  55. getResetKey={() => 'reset-page'}
  56. errorComponent={ErrorPage}
  57. >
  58. <ProConfigProvider hashed={false} intl={language === 'zh-CN' ? zhCNIntl : enUSIntl}>
  59. <ConfigProvider
  60. locale={language === 'zh-CN' ? zh : en}
  61. getTargetContainer={() => {
  62. return document.getElementById('crazy-pro-layout') || document.body
  63. }}
  64. >
  65. <ProLayout
  66. headerContentRender={() => <PageBreadcrumb
  67. className={'top-breadcrumb'}
  68. showIcon={false}
  69. items={items}/>}
  70. title="Crazy Pro"
  71. {...defaultProps}
  72. route={{
  73. path: '/',
  74. routes: menuData
  75. }}
  76. location={{
  77. pathname,
  78. }}
  79. token={{
  80. header: {
  81. colorBgMenuItemSelected: 'rgba(0,0,0,0.04)',
  82. },
  83. }}
  84. menu={{
  85. collapsedShowGroupTitle: true,
  86. loading: isLoading,
  87. }}
  88. avatarProps={{
  89. // src: 'https://gw.alipayobjects.com/zos/antfincdn/efFD%24IOql2/weixintupian_20170331104822.jpg',
  90. render: () => {
  91. return (
  92. <Avatar/>
  93. )
  94. },
  95. }}
  96. actionsRender={(props) => {
  97. if (props.isMobile) return []
  98. if (typeof window === 'undefined') return []
  99. return [
  100. <SelectLang/>,
  101. ]
  102. }}
  103. menuProps={{
  104. className: styles.sideMenu,
  105. }}
  106. menuRender={(_, defaultDom) => (
  107. <span style={{ userSelect: 'none' }}>
  108. {defaultDom}
  109. </span>
  110. )}
  111. menuItemRender={(item, dom) => {
  112. return <span style={{ userSelect: 'none' }} onClick={() => {
  113. setPathname(item.path || '/dashboard')
  114. }}
  115. >
  116. <Link to={item.path} target={item.type === 'url' ? '_blank' : '_self'}>
  117. {dom}
  118. </Link>
  119. </span>
  120. }}
  121. {...{
  122. 'layout': 'mix',
  123. 'navTheme': 'light',
  124. 'contentWidth': 'Fluid',
  125. 'fixSiderbar': true,
  126. // 'colorPrimary': '#1677FF',
  127. 'siderMenuType': 'group',
  128. // layout: 'side',
  129. }}
  130. >
  131. <Outlet/>
  132. </ProLayout>
  133. </ConfigProvider>
  134. </ProConfigProvider>
  135. </CatchBoundary>
  136. </div>
  137. )
  138. }