|  | @@ -1,22 +1,13 @@
 | 
	
		
			
				|  |  |  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 type { RequestConfig, RunTimeLayoutConfig } from '@umijs/max'
 | 
	
		
			
				|  |  | +import { getIntl, getLocale, history } from '@umijs/max'
 | 
	
		
			
				|  |  |  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'
 | 
	
		
			
				|  |  | +import defaultSettings from '../config/defaultSettings'
 | 
	
		
			
				|  |  |  const loginPath = '/user/login'
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/** 获取用户信息比较慢的时候会展示一个 loading */
 | 
	
		
			
				|  |  | -export const initialStateConfig = {
 | 
	
		
			
				|  |  | -  loading: <PageLoading />
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  |   * @see  https://umijs.org/zh-CN/plugins/plugin-initial-state
 | 
	
		
			
				|  |  |   * */
 | 
	
	
		
			
				|  | @@ -53,118 +44,81 @@ export async function getInitialState(): Promise<{
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -const authHeaderInterceptor = (url: string, options: RequestOptionsInit) => {
 | 
	
		
			
				|  |  | -  const token = window.localStorage.getItem('TOKEN_ID')
 | 
	
		
			
				|  |  | +const authHeaderInterceptor = options => {
 | 
	
		
			
				|  |  | +  const token = JSON.parse(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 }
 | 
	
		
			
				|  |  | +  if (token) {
 | 
	
		
			
				|  |  | +    // 在白名单里的请求放过
 | 
	
		
			
				|  |  | +    if (consts.TOKEN_WHITE_LIST.includes(options.url)) {
 | 
	
		
			
				|  |  | +      return options
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    options.headers[consts.TOKEN_HEADER] = 'bearer ' + token
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +  return options
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/**
 | 
	
		
			
				|  |  | - * 异常处理程序
 | 
	
		
			
				|  |  | - 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
 | 
	
		
			
				|  |  | +const errorHandler = (error: any, opts: any) => {
 | 
	
		
			
				|  |  | +  if (opts?.skipErrorHandler) return
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    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
 | 
	
		
			
				|  |  | +  const errorInfo = error.info
 | 
	
		
			
				|  |  | +  if (errorInfo) {
 | 
	
		
			
				|  |  | +    const { errorMessage = '请求失败', errorCode } = errorInfo
 | 
	
		
			
				|  |  | +    if (consts.TOKEN_INVALID_CODE.includes(errorCode) && window.location.pathname !== consts.loginPath) {
 | 
	
		
			
				|  |  |        notification.error({
 | 
	
		
			
				|  |  | -        message: errorMessage,
 | 
	
		
			
				|  |  | -        description: errorDescription
 | 
	
		
			
				|  |  | +        message: '用户信息过期',
 | 
	
		
			
				|  |  | +        description: '请重新登录'
 | 
	
		
			
				|  |  |        })
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (!response) {
 | 
	
		
			
				|  |  | -      notification.error({
 | 
	
		
			
				|  |  | -        description: '您的网络发生异常,无法连接服务器',
 | 
	
		
			
				|  |  | -        message: '网络异常'
 | 
	
		
			
				|  |  | +      history.replace({
 | 
	
		
			
				|  |  | +        pathname: consts.loginPath,
 | 
	
		
			
				|  |  | +        search: createSearchParams({
 | 
	
		
			
				|  |  | +          redirect: window.location.pathname
 | 
	
		
			
				|  |  | +        }).toString()
 | 
	
		
			
				|  |  |        })
 | 
	
		
			
				|  |  | +      return
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    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',
 | 
	
		
			
				|  |  | +    notification.error({
 | 
	
		
			
				|  |  | +      message: '请求失败',
 | 
	
		
			
				|  |  | +      description: errorMessage
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +  } else if (error.response) {
 | 
	
		
			
				|  |  | +    // Axios 的错误
 | 
	
		
			
				|  |  | +    // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
 | 
	
		
			
				|  |  | +    notification.error({
 | 
	
		
			
				|  |  | +      description: `状态码为${error.status}, 请联系管理员进行处理`,
 | 
	
		
			
				|  |  | +      message: '请求异常'
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +  } else if (error.request) {
 | 
	
		
			
				|  |  | +    // 请求已经成功发起,但没有收到响应
 | 
	
		
			
				|  |  | +    // 或请求根本没有发送出去
 | 
	
		
			
				|  |  | +    notification.error({
 | 
	
		
			
				|  |  | +      description: '您的网络请求已经发起,但没有收到响应',
 | 
	
		
			
				|  |  | +      message: '响应超时'
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    notification.error({
 | 
	
		
			
				|  |  | +      description: '您的网络发生异常,无法连接服务器',
 | 
	
		
			
				|  |  | +      message: '网络异常'
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +export const request: RequestConfig = {
 | 
	
		
			
				|  |  | +  baseURL: consts.PREFIX_URL,
 | 
	
		
			
				|  |  |    errorConfig: {
 | 
	
		
			
				|  |  | -    adaptor: resData => {
 | 
	
		
			
				|  |  | -      return {
 | 
	
		
			
				|  |  | -        // success: resData.code === consts.RET_CODE.SUCCESS,
 | 
	
		
			
				|  |  | -        data: resData.data,
 | 
	
		
			
				|  |  | -        errorCode: resData.code,
 | 
	
		
			
				|  |  | -        errorMessage: resData.msg
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +    errorHandler
 | 
	
		
			
				|  |  |    },
 | 
	
		
			
				|  |  |    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
 | 
	
		
			
				|  |  | +    async response => {
 | 
	
		
			
				|  |  | +      const { data, code: errorCode, msg: errorMessage } = response.data
 | 
	
		
			
				|  |  | +      if (!errorCode || errorCode !== consts.RET_CODE.SUCCESS) {
 | 
	
		
			
				|  |  | +        if (errorCode !== consts.RET_CODE.SUCCESS) {
 | 
	
		
			
				|  |  | +          const error: any = new Error(errorMessage)
 | 
	
		
			
				|  |  | +          error.name = 'BizError'
 | 
	
		
			
				|  |  | +          error.info = { errorCode, errorMessage, data }
 | 
	
		
			
				|  |  | +          throw error
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  | -      return response
 | 
	
		
			
				|  |  | +      return Promise.resolve(response)
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    ],
 | 
	
		
			
				|  |  |    requestInterceptors: [authHeaderInterceptor]
 | 
	
	
		
			
				|  | @@ -178,12 +132,8 @@ export const layout: RunTimeLayoutConfig = ({ initialState }) => {
 | 
	
		
			
				|  |  |      waterMarkProps: initialState.currentUser && {
 | 
	
		
			
				|  |  |        fontColor: 'rgba(0,0,0,.1)',
 | 
	
		
			
				|  |  |        offsetTop: 200,
 | 
	
		
			
				|  |  | -      content: `${initialState.currentUser?.username}  ${initialState.currentUser?.telephone.slice(
 | 
	
		
			
				|  |  | -        -4
 | 
	
		
			
				|  |  | -      )}`
 | 
	
		
			
				|  |  | +      content: `${initialState.currentUser?.username}  ${initialState.currentUser?.telephone.slice(-4)}`
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    footerRender: () => <Footer />,
 | 
	
		
			
				|  |  |      onPageChange: () => {
 | 
	
		
			
				|  |  |        const { location } = history
 | 
	
		
			
				|  |  |        // 如果没有登录,重定向到 login
 | 
	
	
		
			
				|  | @@ -191,21 +141,9 @@ export const layout: RunTimeLayoutConfig = ({ initialState }) => {
 | 
	
		
			
				|  |  |          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
 | 
	
		
			
				|  |  | +    ...defaultSettings
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 |