PageLayout.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import HeaderBar from './HeaderBar.js';
  2. import { Layout } from '@douyinfe/semi-ui';
  3. import SiderBar from './SiderBar.js';
  4. import App from '../App.js';
  5. import FooterBar from './Footer.js';
  6. import { ToastContainer } from 'react-toastify';
  7. import React, { useContext, useEffect } from 'react';
  8. import { StyleContext } from '../context/Style/index.js';
  9. import { useTranslation } from 'react-i18next';
  10. import { API, getLogo, getSystemName, showError } from '../helpers/index.js';
  11. import { setStatusData } from '../helpers/data.js';
  12. import { UserContext } from '../context/User/index.js';
  13. import { StatusContext } from '../context/Status/index.js';
  14. const { Sider, Content, Header, Footer } = Layout;
  15. const PageLayout = () => {
  16. const [userState, userDispatch] = useContext(UserContext);
  17. const [statusState, statusDispatch] = useContext(StatusContext);
  18. const [styleState, styleDispatch] = useContext(StyleContext);
  19. const { i18n } = useTranslation();
  20. const loadUser = () => {
  21. let user = localStorage.getItem('user');
  22. if (user) {
  23. let data = JSON.parse(user);
  24. userDispatch({ type: 'login', payload: data });
  25. }
  26. };
  27. const loadStatus = async () => {
  28. try {
  29. const res = await API.get('/api/status');
  30. const { success, data } = res.data;
  31. if (success) {
  32. statusDispatch({ type: 'set', payload: data });
  33. setStatusData(data);
  34. } else {
  35. showError('Unable to connect to server');
  36. }
  37. } catch (error) {
  38. showError('Failed to load status');
  39. }
  40. };
  41. useEffect(() => {
  42. loadUser();
  43. loadStatus().catch(console.error);
  44. let systemName = getSystemName();
  45. if (systemName) {
  46. document.title = systemName;
  47. }
  48. let logo = getLogo();
  49. if (logo) {
  50. let linkElement = document.querySelector("link[rel~='icon']");
  51. if (linkElement) {
  52. linkElement.href = logo;
  53. }
  54. }
  55. // 从localStorage获取上次使用的语言
  56. const savedLang = localStorage.getItem('i18nextLng');
  57. if (savedLang) {
  58. i18n.changeLanguage(savedLang);
  59. }
  60. // 默认显示侧边栏
  61. styleDispatch({ type: 'SET_SIDER', payload: true });
  62. }, [i18n]);
  63. // 获取侧边栏折叠状态
  64. const isSidebarCollapsed = localStorage.getItem('default_collapse_sidebar') === 'true';
  65. return (
  66. <Layout style={{ height: '100vh', display: 'flex', flexDirection: 'column' }}>
  67. <Header style={{
  68. padding: 0,
  69. height: 'auto',
  70. lineHeight: 'normal',
  71. position: 'fixed',
  72. width: '100%',
  73. top: 0,
  74. zIndex: 100,
  75. boxShadow: '0 1px 6px rgba(0, 0, 0, 0.08)'
  76. }}>
  77. <HeaderBar />
  78. </Header>
  79. <Layout style={{
  80. marginTop: '56px',
  81. height: 'calc(100vh - 56px)',
  82. overflow: styleState.isMobile ? 'auto' : 'hidden'
  83. }}>
  84. {styleState.showSider && (
  85. <Sider style={{
  86. height: 'calc(100vh - 56px)',
  87. position: 'fixed',
  88. left: 0,
  89. top: '56px',
  90. zIndex: 90,
  91. overflowY: 'auto',
  92. overflowX: 'hidden',
  93. width: 'auto',
  94. background: 'transparent',
  95. boxShadow: 'none',
  96. border: 'none',
  97. paddingRight: '5px'
  98. }}>
  99. <SiderBar />
  100. </Sider>
  101. )}
  102. <Layout style={{
  103. marginLeft: styleState.showSider ? (isSidebarCollapsed ? '60px' : '200px') : '0',
  104. transition: 'margin-left 0.3s ease',
  105. height: '100%',
  106. overflow: 'auto'
  107. }}>
  108. <Content
  109. style={{
  110. height: '100%',
  111. overflowY: 'auto',
  112. WebkitOverflowScrolling: 'touch',
  113. padding: styleState.shouldInnerPadding? '24px': '0',
  114. position: 'relative'
  115. }}
  116. >
  117. <App />
  118. </Content>
  119. <Layout.Footer>
  120. <FooterBar />
  121. </Layout.Footer>
  122. </Layout>
  123. </Layout>
  124. <ToastContainer />
  125. </Layout>
  126. )
  127. }
  128. export default PageLayout;