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.

136 lines
3.6 KiB

2 years ago
  1. import React, { FC, useState, useEffect, useRef, Component } from 'react'
  2. import { useHistory, useLocation } from 'react-router-dom'
  3. import MenuView from '@/components/Menu'
  4. import classNames from 'classnames'
  5. import { Layout, BackTop } from 'antd'
  6. import { getKeyName, isAuthorized } from '@/assets/js/publicFunc'
  7. import Header from '@/components/Header'
  8. import TabPanes from '@/components/TabPanes'
  9. import { connect } from 'react-redux'
  10. import * as actions from '@/store/actions'
  11. import styles from './Home.module.less'
  12. const noNewTab = ['/login'] // 不需要新建 tab的页面
  13. const noCheckAuth = ['/', '/403'] // 不需要检查权限的页面
  14. // 检查权限
  15. const checkAuth = (newPathname: string): boolean => {
  16. // 不需要检查权限的
  17. // if (noCheckAuth.includes(newPathname)) {
  18. // return true
  19. // }
  20. // const { tabKey: currentKey } = getKeyName(newPathname)
  21. // return isAuthorized(currentKey)
  22. return true;
  23. }
  24. interface Props extends ReduxProps {}
  25. interface PanesItemProps {
  26. title: string;
  27. content: Component;
  28. key: string;
  29. closable: boolean;
  30. path: string;
  31. }
  32. const Home: FC<Props> = (props) => {
  33. const [tabActiveKey, setTabActiveKey] = useState<string>('home')
  34. const [panesItem, setPanesItem] = useState<PanesItemProps>({
  35. title: '',
  36. content: null,
  37. key: '',
  38. closable: false,
  39. path: ''
  40. })
  41. const pathRef: RefType = useRef<string>('')
  42. const history = useHistory()
  43. const { pathname, search } = useLocation()
  44. const {
  45. storeData: { collapsed, userInfo },
  46. setStoreData
  47. } = props
  48. const { token } = userInfo
  49. useEffect(() => {
  50. setStoreData('SET_COLLAPSED', document.body.clientWidth <= 1024)
  51. // 未登录
  52. if (!token && pathname !== '/login') {
  53. history.replace({ pathname: '/login' })
  54. return
  55. }
  56. const { tabKey, title, component: Content } = getKeyName(pathname)
  57. // 新tab已存在或不需要新建tab,return
  58. if (pathname === pathRef.current || noNewTab.includes(pathname)) {
  59. setTabActiveKey(tabKey)
  60. return
  61. }
  62. // 检查权限,比如直接从地址栏输入的,提示无权限
  63. const isHasAuth = checkAuth(pathname)
  64. if (!isHasAuth) {
  65. const errorUrl = '/403'
  66. const {
  67. tabKey: errorKey,
  68. title: errorTitle,
  69. component: errorContent
  70. } = getKeyName(errorUrl)
  71. setPanesItem({
  72. title: errorTitle,
  73. content: errorContent,
  74. key: errorKey,
  75. closable: true,
  76. path: errorUrl
  77. })
  78. pathRef.current = errorUrl
  79. setTabActiveKey(errorKey)
  80. history.replace(errorUrl)
  81. return
  82. }
  83. // 记录新的路径,用于下次更新比较
  84. const newPath = search ? pathname + search : pathname
  85. pathRef.current = newPath
  86. setPanesItem({
  87. title,
  88. content: Content,
  89. key: tabKey,
  90. closable: tabKey !== 'home',
  91. path: newPath
  92. })
  93. setTabActiveKey(tabKey)
  94. }, [history, pathname, search, setStoreData, token])
  95. return (
  96. <Layout
  97. className={styles.container}
  98. onContextMenu={(e) => e.preventDefault()}
  99. style={{ display: pathname.includes('/login') ? 'none' : 'flex' }}
  100. >
  101. <MenuView />
  102. <Layout
  103. className={classNames(styles.content, {
  104. [styles.collapsed]: collapsed
  105. })}
  106. >
  107. <Header />
  108. <Layout.Content>
  109. <TabPanes
  110. defaultActiveKey="home"
  111. panesItem={panesItem}
  112. tabActiveKey={tabActiveKey}
  113. />
  114. </Layout.Content>
  115. </Layout>
  116. <BackTop visibilityHeight={1080} />
  117. </Layout>
  118. )
  119. }
  120. export default connect(
  121. (state) => state,
  122. actions
  123. )(Home)