app.tsx 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. import { AvatarDropdown, AvatarName, Question } from '@/components';
  2. import type { Settings as LayoutSettings } from '@ant-design/pro-components';
  3. import { SettingDrawer } from '@ant-design/pro-components';
  4. import type { RequestConfig, RunTimeLayoutConfig } from '@umijs/max';
  5. import { history, useModel } from '@umijs/max';
  6. import { message } from 'antd';
  7. import defaultSettings from '../config/defaultSettings';
  8. import { scriptUrl } from './global';
  9. import { errorConfig, ResponseStructure } from './requestErrorConfig';
  10. import { getMenu } from './services/global';
  11. import { getUserInfo } from './services/login';
  12. import { flattenRoutes } from './utils/generateNewLocalMenu';
  13. const isDev = process.env.NODE_ENV === 'development';
  14. const loginPath = '/user/login';
  15. /**
  16. * @see https://umijs.org/zh-CN/plugins/plugin-initial-state
  17. * */
  18. export async function getInitialState(): Promise<{
  19. settings?: Partial<LayoutSettings>;
  20. currentUser?: any;
  21. loading?: boolean;
  22. menuType?: 'distributor' | 'miniApp';
  23. navTheme?: '2' | '3';
  24. token?: any;
  25. menu?: any;
  26. }> {
  27. // 如果不是登录页面,执行
  28. const { location } = history;
  29. let menuType = (sessionStorage.getItem('menuType') as 'distributor' | 'miniApp') || 'distributor';
  30. let navTheme: any = localStorage.getItem('navTheme') || '2'; //主题色 2白 3黑
  31. if (location.pathname !== loginPath && localStorage.getItem('Admin-Token')) {
  32. const res = await getUserInfo();
  33. if (res.data) {
  34. return {
  35. token: res.data.token,
  36. currentUser: res.data.userInfo,
  37. menuType,
  38. settings: defaultSettings as Partial<LayoutSettings>,
  39. navTheme,
  40. };
  41. }
  42. }
  43. return {
  44. token: '',
  45. menuType: 'distributor',
  46. navTheme,
  47. settings: defaultSettings as Partial<LayoutSettings>,
  48. };
  49. }
  50. // ProLayout 支持的api https://procomponents.ant.design/components/layout
  51. export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
  52. return {
  53. // 动态管理菜单
  54. splitMenus: true, //切割菜单
  55. menu: {
  56. locale: false, //关闭国际化
  57. params: {
  58. //token变化重新获取
  59. token: initialState?.token,
  60. },
  61. request: async () => {
  62. //需要在routes.tsx中配置一份完整的路由
  63. let menu = await getMenu(['book']); //线上获取路由
  64. let flatMenu = flattenRoutes(menu);
  65. setInitialState({ ...initialState, menu: flatMenu });
  66. history.push(flatMenu[flatMenu['/'].redirect].redirect); //获取到本地路由后跳转到有权限的页面
  67. return menu;
  68. },
  69. },
  70. iconfontUrl: scriptUrl,
  71. actionsRender: () => [<Question key="doc" />],
  72. avatarProps: {
  73. src:
  74. initialState?.currentUser?.avatar ||
  75. 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png',
  76. title: <AvatarName />,
  77. render: (_, avatarChildren) => {
  78. return <AvatarDropdown>{avatarChildren}</AvatarDropdown>;
  79. },
  80. },
  81. waterMarkProps: {
  82. content: initialState?.currentUser?.name,
  83. },
  84. // footerRender: () => <Footer />,//页脚
  85. onPageChange: (location: any) => {
  86. //页面发生变化触发
  87. hasHandledCode300 = false;
  88. let obj = initialState?.menu || {};
  89. if (obj[location.pathname] && obj[location.pathname].redirect) {
  90. //强制调整到正确的路由地址
  91. history.push(obj[location.pathname].redirect);
  92. }
  93. // // 在小程序页面禁止用户点击回退按钮返回分享页面
  94. // if (sessionStorage.getItem("menuType") == 'miniApp' && location?.pathname?.match(/^\/distributor/)) {
  95. // console.log("miniApp", location)
  96. // history.replace('/miniApp');
  97. // }
  98. // // 在分销平台首页禁止用户点击回退按钮返回到小程序页面
  99. // if (sessionStorage.getItem("menuType") == 'distributor' && location?.pathname?.match(/^\/miniApp/)) {
  100. // console.log("distributor", location)
  101. // history.replace('/distributor');
  102. // }
  103. // // 如果没有登录,重定向到 login
  104. if (!localStorage.getItem('Admin-Token') && location?.pathname !== loginPath) {
  105. history.push(loginPath);
  106. }
  107. },
  108. bgLayoutImgList: [
  109. {
  110. src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/D2LWSqNny4sAAAAAAAAAAAAAFl94AQBr',
  111. left: 85,
  112. bottom: 100,
  113. height: '303px',
  114. },
  115. {
  116. src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/C2TWRpJpiC0AAAAAAAAAAAAAFl94AQBr',
  117. bottom: -68,
  118. right: -45,
  119. height: '303px',
  120. },
  121. {
  122. src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/F6vSTbj8KpYAAAAAAAAAAAAAFl94AQBr',
  123. bottom: 0,
  124. left: 0,
  125. width: '331px',
  126. },
  127. ],
  128. // links: initialState?.menuType === 'miniApp' ? [] : [],
  129. // menuHeaderRender: (logo, title, props) => {
  130. // if (props?.collapsed) {
  131. // return false
  132. // } else if (initialState?.selectApp) {
  133. // return <Space>
  134. // <MyIcon type={initialState?.selectApp?.appType === 1 ? "icon-weixin" : "icon-douyinzhanghao"} style={{ fontSize: 30 }} />
  135. // <strong style={{ fontSize: 18 }}>{initialState?.selectApp?.appName}</strong>
  136. // </Space>
  137. // } else {
  138. // return false
  139. // }
  140. // },
  141. // 自定义 403 页面
  142. // unAccessible: <div>unAccessible</div>,
  143. // 增加一个 loading 的状态
  144. childrenRender: (children: any) => {
  145. // if (initialState?.loading) return <PageLoading />;
  146. const { init, state } = useModel('global', (ret) => ({
  147. init: ret.init,
  148. state: ret.state,
  149. }));
  150. if (!state?.enumList && localStorage.getItem('Admin-Token')) {
  151. init(); //初始全局
  152. }
  153. return (
  154. <>
  155. {children}
  156. {isDev && (
  157. <SettingDrawer
  158. disableUrlParams
  159. enableDarkTheme
  160. settings={initialState?.settings}
  161. onSettingChange={(settings) => {
  162. setInitialState((preInitialState) => ({
  163. ...preInitialState,
  164. menuType: preInitialState?.menuType || 'distributor',
  165. settings,
  166. token: preInitialState?.token || '',
  167. // menu: preInitialState?.menu || [],
  168. }));
  169. }}
  170. />
  171. )}
  172. </>
  173. );
  174. },
  175. ...initialState?.settings,
  176. navTheme: initialState?.navTheme === '2' ? 'light' : 'realDark',
  177. // title:<span style={{fontSize:24,fontFamily:'cursive'}}>{defaultSettings?.title}</span>
  178. // title:initialState?.selectApp ? defaultSettings?.title + '--'+initialState?.selectApp?.appName : defaultSettings?.title //标题修改
  179. };
  180. };
  181. /**
  182. * @name request 配置,可以配置错误处理
  183. * 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。
  184. * @doc https://umijs.org/docs/max/request#配置
  185. */
  186. let hasHandledCode300 = false;
  187. export const request: RequestConfig = {
  188. ...errorConfig,
  189. // 响应拦截器
  190. responseInterceptors: [
  191. (response) => {
  192. // 拦截响应数据,进行个性化处理
  193. const { data } = response as unknown as ResponseStructure;
  194. switch (data.code) {
  195. case 310:
  196. if (!hasHandledCode300) {
  197. hasHandledCode300 = true; // 设置标志位,表示已经处理过
  198. message.error(data.msg);
  199. localStorage.removeItem('Admin-Token');
  200. sessionStorage.removeItem('menuType');
  201. sessionStorage.removeItem('selectApp');
  202. history.push(loginPath);
  203. }
  204. break;
  205. // case 500:
  206. // message.error(data.msg)
  207. // break
  208. }
  209. return response;
  210. },
  211. ],
  212. };