123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- 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: <PageLoading />
- }
- /**
- * @see https://umijs.org/zh-CN/plugins/plugin-initial-state
- * */
- export async function getInitialState(): Promise<{
- settings?: Partial<LayoutSettings>
- currentUser?: API.CurrentUser
- menuList?: API.MenuListItem[]
- fetchUserInfo?: () => Promise<API.CurrentUser | undefined>
- }> {
- // 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: () => <RightContent />,
- disableContentMargin: false,
- waterMarkProps: {
- content: initialState?.currentUser?.username
- },
- footerRender: () => <Footer />,
- onPageChange: () => {
- const { location } = history
- // 如果没有登录,重定向到 login
- if (!initialState?.currentUser && location.pathname !== loginPath) {
- history.push(loginPath)
- }
- },
- links: isDev
- ? [
- // <Link to="/umi/plugin/openapi" target="_blank">
- // <LinkOutlined />
- // <span>openAPI 文档</span>
- // </Link>,
- // <Link to="/~docs">
- // <BookOutlined />
- // <span>业务组件文档</span>
- // </Link>
- ]
- : [],
- menuHeaderRender: undefined,
- // 自定义 403 页面
- // unAccessible: <div>unAccessible</div>,
- ...initialState?.settings
- }
- }
|