app.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. import bg1Layout from '@/assets/images/lay-bg1.webp';
  2. import bg2Layout from '@/assets/images/lay-bg2.webp';
  3. import bg3Layout from '@/assets/images/lay-bg3.webp';
  4. import { AvatarDropdown, AvatarName, Footer, Icon, SelectLang } from '@/components';
  5. import { Settings as LayoutSettings } from '@ant-design/pro-components';
  6. import mcLogoSvg from '@svgs/multi-color/mc-logo.svg';
  7. import type { RequestConfig, RuntimeConfig, RunTimeLayoutConfig } from '@umijs/max';
  8. import { history } from '@umijs/max';
  9. import { App } from 'antd';
  10. import dayjs from 'dayjs';
  11. import utc from 'dayjs/plugin/utc';
  12. import React from 'react';
  13. import defaultSettings from '../config/defaultSettings';
  14. import VersionChecker from './components/VersionChecker';
  15. import { requestConfig } from './requestConfig';
  16. import { AntdAppInstanceCapture } from './utils/antdAppInstance';
  17. import { userKey } from './utils/authUtils';
  18. import { createLocalTools } from './utils/localUtils';
  19. import { loginPath, toLoginPage } from './utils/routerUtils';
  20. dayjs.extend(utc);
  21. const isDev = process.env.NODE_ENV === 'development';
  22. const appEnv = process.env.REACT_APP_ENV;
  23. const VersionCheckComponent: React.FC = () => {
  24. if (appEnv !== 'prod' && appEnv !== 'test' && appEnv !== 'dev') {
  25. return null;
  26. }
  27. const currentBuildTime = process.env.REACT_APP_BUILD_TIME;
  28. if (!currentBuildTime) {
  29. return null;
  30. }
  31. return (
  32. <VersionChecker
  33. currentBuildTime={currentBuildTime}
  34. checkInterval={60 * 1000}
  35. notificationCooldown={5 * 60 * 1000}
  36. />
  37. );
  38. };
  39. let title = `${process.env.REACT_APP_NAME}`;
  40. let waterMarkContent = '';
  41. if (isDev) {
  42. waterMarkContent = `${process.env.REACT_APP_NAME} - 本地环境`;
  43. } else if (appEnv === 'dev') {
  44. waterMarkContent = `${process.env.REACT_APP_NAME} - 开发环境`;
  45. } else if (appEnv === 'test') {
  46. waterMarkContent = `${process.env.REACT_APP_NAME} - 测试环境`;
  47. }
  48. if (waterMarkContent !== '') {
  49. title = waterMarkContent;
  50. }
  51. const defSettings = {
  52. ...defaultSettings,
  53. title,
  54. logo: <Icon icon={mcLogoSvg} width="44px" height="44px" />,
  55. };
  56. export async function getInitialState(): Promise<{
  57. settings?: Partial<LayoutSettings>;
  58. currentUser?: API.UserInfo | null;
  59. fetchUserInfo?: () => Promise<API.UserInfo | null>;
  60. }> {
  61. const fetchUserInfo = () => {
  62. return new Promise<API.UserInfo | null>((resolve) => {
  63. const userInfo = createLocalTools().getLocal<API.UserInfo>(userKey);
  64. resolve(userInfo);
  65. });
  66. };
  67. const { location } = history;
  68. if (location.pathname !== loginPath) {
  69. const currentUser = await fetchUserInfo();
  70. return {
  71. fetchUserInfo,
  72. currentUser,
  73. settings: defSettings as Partial<LayoutSettings>,
  74. };
  75. }
  76. return {
  77. fetchUserInfo,
  78. settings: defSettings as Partial<LayoutSettings>,
  79. };
  80. }
  81. export const layout: RunTimeLayoutConfig = ({ initialState }) => {
  82. return {
  83. stylish: {
  84. sider: (token) => ({
  85. backgroundColor: token.colorBgLayout,
  86. }),
  87. },
  88. pageTitleRender: false,
  89. menu: {
  90. defaultOpenAll: true,
  91. ignoreFlatMenu: true,
  92. autoClose: false,
  93. },
  94. menuProps: {
  95. mode: 'inline',
  96. inlineIndent: 24,
  97. },
  98. actionsRender: () => [<SelectLang key="SelectLang" />],
  99. avatarProps: {
  100. size: 24,
  101. src: initialState?.currentUser?.avatar,
  102. title: <AvatarName />,
  103. render: (_, avatarChildren) => {
  104. return <AvatarDropdown menu>{avatarChildren}</AvatarDropdown>;
  105. },
  106. },
  107. waterMarkProps: {
  108. content: waterMarkContent,
  109. },
  110. footerRender: () => <Footer />,
  111. onPageChange: () => {
  112. const { location } = history;
  113. if (!initialState?.currentUser?.username && location.pathname !== loginPath) {
  114. toLoginPage();
  115. }
  116. },
  117. disableMobile: true,
  118. bgLayoutImgList: [
  119. {
  120. src: bg1Layout,
  121. left: 85,
  122. bottom: 100,
  123. height: '303px',
  124. },
  125. {
  126. src: bg2Layout,
  127. bottom: -68,
  128. right: -45,
  129. height: '303px',
  130. },
  131. {
  132. src: bg3Layout,
  133. bottom: 0,
  134. left: 0,
  135. width: '331px',
  136. },
  137. ],
  138. childrenRender: (children) => {
  139. return (
  140. <>
  141. {children}
  142. <VersionCheckComponent />
  143. </>
  144. );
  145. },
  146. ...initialState?.settings,
  147. };
  148. };
  149. export const request: RequestConfig = requestConfig;
  150. export const locale: RuntimeConfig['locale'] = {
  151. onError: (err: string) => {
  152. if (err.includes('using message id as fallback')) return;
  153. if (err.includes('Missing message')) return;
  154. console.error(err);
  155. },
  156. };
  157. export function rootContainer(container: React.ReactNode) {
  158. return (
  159. <App>
  160. <AntdAppInstanceCapture />
  161. {container}
  162. </App>
  163. );
  164. }