app.tsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. import Footer from '@/components/Footer';
  2. import RightContent from '@/components/RightContent';
  3. import type { Settings as LayoutSettings } from '@ant-design/pro-components';
  4. import { PageLoading, SettingDrawer } from '@ant-design/pro-components';
  5. import type { RunTimeLayoutConfig } from 'umi';
  6. import { history } from 'umi';
  7. import defaultSettings from '../config/defaultSettings';
  8. import { currentUser as queryCurrentUser } from './services/ant-design-pro/api';
  9. import { message } from 'antd';
  10. import { queryMenu } from '@/services/menu';
  11. import Icon from '@ant-design/icons';
  12. import * as icons from '@ant-design/icons';
  13. const loginPath = '/user/login';
  14. /** 获取用户信息比较慢的时候会展示一个 loading */
  15. export const initialStateConfig = {
  16. loading: <PageLoading />,
  17. };
  18. /**
  19. * @see https://umijs.org/zh-CN/plugins/plugin-initial-state
  20. * */
  21. export async function getInitialState(): Promise<{
  22. settings?: Partial<LayoutSettings>;
  23. currentUser?: API.CurrentUser;
  24. loading?: boolean;
  25. fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
  26. }> {
  27. const fetchUserInfo = async () => {
  28. try {
  29. const msg: any = await queryCurrentUser(localStorage.getItem('token'));
  30. return {
  31. name: msg.data.user_name,
  32. };
  33. } catch (error) {
  34. history.push(loginPath);
  35. }
  36. return undefined;
  37. };
  38. // 如果不是登录页面,执行
  39. if (history.location.pathname !== loginPath) {
  40. const currentUser = await fetchUserInfo();
  41. return {
  42. fetchUserInfo,
  43. currentUser,
  44. settings: defaultSettings,
  45. };
  46. }
  47. return {
  48. fetchUserInfo,
  49. settings: defaultSettings,
  50. };
  51. }
  52. /**
  53. * 映射菜单对应的图标
  54. * */
  55. const loopMenuItem: any = (menus: any[]) =>
  56. menus.map(({ icon, routes, ...item }) => ({
  57. ...item,
  58. icon: icon && <Icon component={icons[icon]} />,
  59. routes: routes && loopMenuItem(routes),
  60. }));
  61. const permissionsMenu = (routers: any[], data: any) => {
  62. data.forEach((item: any) => {
  63. let menu: any;
  64. if (item.children && item.children.length > 0) {
  65. // 还有下级
  66. menu = {
  67. path: item.router,
  68. routes: [],
  69. name: item.name,
  70. icon: item.icon,
  71. };
  72. } else {
  73. // 最后一级
  74. menu = {
  75. path: item.router,
  76. name: item.name,
  77. icon: item.icon,
  78. };
  79. }
  80. if (item.children) {
  81. permissionsMenu(menu.routes, item.children);
  82. }
  83. routers.push(menu);
  84. });
  85. };
  86. // ProLayout 支持的api https://procomponents.ant.design/components/layout
  87. export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
  88. return {
  89. rightContentRender: () => <RightContent />,
  90. disableContentMargin: false,
  91. waterMarkProps: {
  92. content: initialState?.currentUser?.name,
  93. },
  94. footerRender: () => <Footer />,
  95. onPageChange: () => {
  96. const { location } = history;
  97. if (location.pathname === '/DataBoard') {
  98. return;
  99. }
  100. // // 如果没有登录,重定向到 login
  101. // if (!initialState?.currentUser?.name && location.pathname !== loginPath) {
  102. // history.push(loginPath);
  103. // }
  104. },
  105. menu: {
  106. locale: false,
  107. params: initialState?.currentUser,
  108. request: async () => {
  109. const menuData = await queryMenu({ q: 'tree', query_all: 1 });
  110. const routers: any[] = [];
  111. permissionsMenu(routers, menuData.data.list);
  112. return loopMenuItem(routers);
  113. },
  114. },
  115. menuHeaderRender: undefined,
  116. // 自定义 403 页面
  117. // unAccessible: <div>unAccessible</div>,
  118. // 增加一个 loading 的状态
  119. childrenRender: (children: any, props: { location: { pathname: string | string[] } }) => {
  120. // if (initialState?.loading) return <PageLoading />;
  121. return (
  122. <>
  123. {children}
  124. {!props.location?.pathname?.includes('/login') && (
  125. <SettingDrawer
  126. disableUrlParams
  127. enableDarkTheme
  128. settings={initialState?.settings}
  129. onSettingChange={(settings) => {
  130. setInitialState((preInitialState: any) => ({
  131. ...preInitialState,
  132. settings,
  133. }));
  134. }}
  135. />
  136. )}
  137. </>
  138. );
  139. },
  140. ...initialState?.settings,
  141. };
  142. };
  143. const addToken = async (url: any, options: any) => {
  144. // 此处为拦截器,每次发送请求之前判断能否取到token
  145. if (localStorage.getItem('token')) {
  146. const headers = {
  147. Authorization: `${localStorage.getItem('token')}`,
  148. };
  149. return {
  150. url,
  151. options: { ...options, headers },
  152. };
  153. }
  154. return false;
  155. };
  156. const MainResponseInterceptors = (response: { status: number }) => {
  157. if (response.status === 401) {
  158. message.warn('帐号登录过期,请重新登录');
  159. history.push(loginPath);
  160. }
  161. return response;
  162. };
  163. export const request = {
  164. errorConfig: {
  165. adaptor: (resData: any) => {
  166. return {
  167. showType: resData.code ? 2 : 0,
  168. errorMessage: resData.message,
  169. };
  170. },
  171. },
  172. requestInterceptors: [addToken],
  173. responseInterceptors: [MainResponseInterceptors],
  174. };