You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
6.1 KiB
TypeScript

import { Footer, Question, SelectLang, AvatarDropdown, AvatarName } from '@/components';
import { LinkOutlined } from '@ant-design/icons';
import type { Settings as LayoutSettings } from '@ant-design/pro-components';
import { SettingDrawer } from '@ant-design/pro-components';
import type { RunTimeLayoutConfig } from '@umijs/max';
import { history, Link, getLocale } from '@umijs/max';
import defaultSettings from '../config/defaultSettings';
import { errorConfig } from './requestErrorConfig';
import React from 'react';
const isDev = process.env.NODE_ENV === 'development';
const loginPath = '/user/login';
import {RequestConfig} from 'umi';
// @ts-ignore
import cookie from 'react-cookies';
import {getUserGetUserInfo} from "@/services/system/User";
import {MenuDataItem} from "@ant-design/pro-layout";
import fixMenuItemIcon from "@/utils/FixMenuItemIcon";
import {postMenuGetMenu} from "@/services/system/Menu";
import {SelectRole} from "@/components/RightContent";
import {addLocale} from "@@/plugin-locale";
import zhCN from "@/locales/zh-CN";
import {getAllRouteNameTile} from "@/utils/common";
/**
* @see https://umijs.org/zh-CN/plugins/plugin-initial-state
* */
export async function getInitialState(): Promise<{
settings?: Partial<LayoutSettings>;
currentUser?: API.UserView;
loading?: boolean;
fetchUserInfo?: any;
menuData?: MenuDataItem[];
}> {
const fetchUserInfo = async () => {
try {
const msg = await getUserGetUserInfo();
return msg.data.userInfo;
} catch (error) {
history.push(loginPath);
}
return undefined;
};
// 如果不是登录页面,执行
const { location } = history;
if (location.pathname !== loginPath && localStorage.getItem('access')) {
const currentUser = await fetchUserInfo();
const menus = await postMenuGetMenu();
if (getLocale() === 'zh-CN') {
let localData = getAllRouteNameTile(menus.data.routes, '')
let localRes:any = {}
localData.forEach((v)=>{
localRes[`menu${v.name}`] = v.title
})
console.log(localRes)
addLocale("zh-CN", localRes,{
momentLocale: "zh-CN",
antd: zhCN
});
}
return {
fetchUserInfo,
currentUser,
settings: defaultSettings as Partial<LayoutSettings>,
menuData: menus.data.routes,
};
}
return {
fetchUserInfo,
settings: defaultSettings as Partial<LayoutSettings>,
};
}
// ProLayout 支持的api https://procomponents.ant.design/components/layout
export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
return {
actionsRender: () => [<SelectRole key="selectRole"/>, <Question key="doc" />, <SelectLang key="SelectLang" />],
avatarProps: {
src: SERVER_HOST + initialState?.currentUser?.avatarUrl,
title: <AvatarName />,
render: (_, avatarChildren) => {
return <AvatarDropdown>{avatarChildren}</AvatarDropdown>;
},
},
waterMarkProps: {
// content: initialState?.currentUser?.name,
},
menu: {
loading: initialState?.loading || false,
locale: true,
params: {
userId: initialState?.currentUser?.id,
},
request: async () => {
return initialState?.menuData || []
}
},
footerRender: () => <Footer />,
onPageChange: () => {
const { location } = history;
// 如果没有登录,重定向到 login
if (!initialState?.currentUser && location.pathname !== loginPath) {
history.push(loginPath);
}
},
menuDataRender: () => {
if (initialState?.menuData !== undefined) {
return fixMenuItemIcon(initialState?.menuData || [])
}
},
layoutBgImgList: [
{
src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/D2LWSqNny4sAAAAAAAAAAAAAFl94AQBr',
left: 85,
bottom: 100,
height: '303px',
},
{
src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/C2TWRpJpiC0AAAAAAAAAAAAAFl94AQBr',
bottom: -68,
right: -45,
height: '303px',
},
{
src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/F6vSTbj8KpYAAAAAAAAAAAAAFl94AQBr',
bottom: 0,
left: 0,
width: '331px',
},
],
links: isDev
? [
<Link key="openapi" to="/umi/plugin/openapi" target="_blank">
<LinkOutlined />
<span>OpenAPI </span>
</Link>,
]
: [],
menuHeaderRender: undefined,
// 自定义 403 页面
// unAccessible: <div>unAccessible</div>,
// 增加一个 loading 的状态
childrenRender: (children) => {
// if (initialState?.loading) return <PageLoading />;
return (
<>
{children}
{isDev && (
<SettingDrawer
disableUrlParams
enableDarkTheme
settings={initialState?.settings}
onSettingChange={(settings) => {
setInitialState((preInitialState) => ({
...preInitialState,
settings,
}));
}}
/>
)}
</>
);
},
...initialState?.settings,
};
};
const csrfAndJwtHeaderInterceptor = (url: string, options: RequestConfig) => {
const csrfHeader = { 'X-CSRFToken': cookie.load('csrftoken') };
let bearerToken = {}
const access = localStorage.getItem('access')
if (access) {
bearerToken = {'X-Token': `${access}`}
}
let locale = getLocale()
return {
url: `${url}`,
options: { ...options, interceptors: true, headers: {...csrfHeader, ...bearerToken, 'Accept-Language': locale} },
};
};
const responseHeaderInterceptor = (response: Response) => {
if ('new-token' in response.headers) {
localStorage.setItem('access', (response.headers['new-token'] || '') as string);
window.location.reload();
}
return response;
};
/**
* @name request 配置,可以配置错误处理
* 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。
* @doc https://umijs.org/docs/max/request#配置
*/
export const request = {
...errorConfig,
requestInterceptors: [csrfAndJwtHeaderInterceptor],
responseInterceptors: [responseHeaderInterceptor],
};