import type { Settings as LayoutSettings } from '@ant-design/pro-layout'
import { PageLoading } from '@ant-design/pro-layout'
import { notification } from 'antd'
import type { RequestConfig, RunTimeLayoutConfig } from 'umi'
import { getIntl, getLocale, history } from 'umi'
import RightContent from '@/components/RightContent'
import Footer from '@/components/Footer'
import type { RequestOptionsInit, ResponseError } from 'umi-request'
import { currentUser as queryCurrentUser } from './services/user/api'
import consts from './utils/consts'
const isDev = process.env.NODE_ENV === 'development'
const loginPath = '/user/login'
/** 获取用户信息比较慢的时候会展示一个 loading */
export const initialStateConfig = {
loading:
}
/**
* @see https://umijs.org/zh-CN/plugins/plugin-initial-state
* */
export async function getInitialState(): Promise<{
settings?: Partial
currentUser?: API.CurrentUser
menuList?: API.MenuListItem[]
fetchUserInfo?: () => Promise
}> {
// eslint-disable-next-line react-hooks/rules-of-hooks
// 获取用户信息
const fetchUserInfo = async () => {
const currentUser = await queryCurrentUser()
return currentUser
}
// 如果是登录页面,不执行
if (history.location.pathname !== loginPath) {
try {
const { data: currentUser } = await fetchUserInfo()
return {
fetchUserInfo,
menuList: currentUser.menus,
currentUser: currentUser.staff,
settings: {}
}
} catch (error) {
history.push(loginPath)
}
return undefined
}
return {
settings: {}
}
}
const authHeaderInterceptor = (url: string, options: RequestOptionsInit) => {
const token = window.localStorage.getItem('TOKEN_ID')
// 如果是登录页面,不执行
if (!token && history.location.pathname !== loginPath) {
return history.push(loginPath)
}
const authHeader = { Authorization: `Bearer ${JSON.parse(token)}` }
return {
url: `${url}`,
options: { ...options, interceptors: true, headers: authHeader }
}
}
/**
* 异常处理程序
const codeMessage = {
200: '服务器成功返回请求的数据。',
201: '新建或修改数据成功。',
202: '一个请求已经进入后台排队(异步任务)。',
204: '删除数据成功。',
400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
401: '用户没有权限(令牌、用户名、密码错误)。',
403: '用户得到授权,但是访问是被禁止的。',
404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
405: '请求方法不被允许。',
406: '请求的格式不可得。',
410: '请求的资源被永久删除,且不会再得到的。',
422: '当创建一个对象时,发生一个验证错误。',
500: '服务器发生错误,请检查服务器。',
502: '网关错误。',
503: '服务不可用,服务器暂时过载或维护。',
504: '网关超时。',
};
* @see https://beta-pro.ant.design/docs/request-cn
*/
export const request: RequestConfig = {
errorHandler: (error: ResponseError) => {
const { messages } = getIntl(getLocale())
const { response } = error
if (response && response.status) {
const { status, statusText, url } = response
const requestErrorMessage = messages['app.request.error']
const errorMessage = `${requestErrorMessage} ${status}: ${url}`
const errorDescription = messages[`app.request.${status}`] || statusText
notification.error({
message: errorMessage,
description: errorDescription
})
}
if (!response) {
notification.error({
description: '您的网络发生异常,无法连接服务器',
message: '网络异常'
})
}
throw error
},
middlewares: [
async (ctx, next) => {
await next()
const { req, res } = ctx
// @ts-ignore
if (req.options?.skipErrorHandler) {
return
}
const errorAdaptor = req.options?.errorConfig.adaptor || (resData => resData)
const { options } = req
const { getResponse } = options
const resData = getResponse ? res.data : res
const errorInfo = errorAdaptor(resData, ctx)
if (resData.code !== consts.RET_CODE.SUCCESS) {
// 抛出错误到 errorHandler 中处理
const error: ResponseError = new Error(errorInfo.errorMessage)
error.name = 'BizError'
error.data = resData
error.info = errorInfo
error.response = res
throw error
}
}
],
prefix: '/backstage',
errorConfig: {
adaptor: resData => {
return {
// success: resData.code === consts.RET_CODE.SUCCESS,
data: resData.data,
errorCode: resData.code,
errorMessage: resData.msg
}
}
},
responseInterceptors: [
async (response, options) => {
const errorAdaptor = options?.errorConfig.adaptor || (resData => resData)
const res = await response.clone().json()
const { getResponse } = options
const resData = getResponse ? res.data : res
const errorInfo = errorAdaptor(resData, { res: response, req: options })
if (res?.code !== consts.RET_CODE.SUCCESS) {
// 抛出错误到 errorHandler 中处理
const error: ResponseError = new Error(errorInfo.errorMessage)
error.name = 'BizError'
error.data = resData
error.info = errorInfo
error.response = res
throw error
}
return response
}
],
requestInterceptors: [authHeaderInterceptor]
}
// ProLayout 支持的api https://procomponents.ant.design/components/layout
export const layout: RunTimeLayoutConfig = ({ initialState }) => {
return {
rightContentRender: () => ,
disableContentMargin: false,
waterMarkProps: {
content: initialState?.currentUser?.username
},
footerRender: () => ,
onPageChange: () => {
const { location } = history
// 如果没有登录,重定向到 login
if (!initialState?.currentUser && location.pathname !== loginPath) {
history.push(loginPath)
}
},
links: isDev
? [
//
//
// openAPI 文档
// ,
//
//
// 业务组件文档
//
]
: [],
menuHeaderRender: undefined,
// 自定义 403 页面
// unAccessible: unAccessible
,
...initialState?.settings
}
}