import { queryCurrentUser, queryPermData } from './services/user' import { history, createSearchParams } from '@umijs/max' import RightContent from '@/components/RightContent' import { message, notification } from 'antd' import logo from '../public/logo.svg' import { getToken } from '@/utils/auth' import { tryChangeWorkStatus } from './components/RightContent/Book' import { getAuthCache, setAuthCache } from './utils/auth' import { LAYOUT_COLLAPSED_KEY } from './utils/cache/cacheEnum' import consts from './consts' import ModalStore from './components/ModalStore' import MessageDetail from './pages/Hr/Notification/components/MessageDetail' import defaultSettings from '../config/defaultSettings' import type { ErrorShowType, RequestConfig } from '@umijs/max' const loginPath = '/user/login' export async function getInitialState() { // 如果是登录页面,不执行 const fetchUserInfo = async () => { try { const res = await queryCurrentUser() return res.data } catch (error) { history.push(loginPath) } return undefined } const fetchPermData = async () => { try { const res = await queryPermData() return res.data } catch (error) { message.error('获取数据权限失败,请联系管理员') } return {} } // 如果是登录页面,不执行 if (history.location.pathname !== loginPath) { const userInfo = (await fetchUserInfo()) || {} const permData = (await fetchPermData()) || {} const collapsed = getAuthCache(LAYOUT_COLLAPSED_KEY) || false return { fetchUserInfo, fetchPermData, permData, ...userInfo, settings: { ...defaultSettings, collapsed, defaultCollapsed: collapsed } } } return { fetchUserInfo, fetchPermData, settings: { ...defaultSettings } } } export const layout = ({ initialState, setInitialState }) => { const onCollapse = collapsed => { setInitialState({ ...initialState, settings: { ...initialState.settings, collapsed } }) setAuthCache(LAYOUT_COLLAPSED_KEY, collapsed) } return { logo, rightContentRender: () => ( ), disableContentMargin: false, waterMarkProps: initialState.currentUser && { fontColor: 'rgba(0,0,0,.1)', offsetTop: 200, content: `${initialState.currentUser?.username} ${initialState.currentUser?.telephone.slice(-4)}` }, onPageChange: async location => { // 如果没有登录,重定向到 login if (!initialState?.currentUser?.staffId && location.pathname !== loginPath) { history.replace({ pathname: loginPath, search: createSearchParams({ redirect: window.location.pathname }).toString() }) } else { location.pathname !== loginPath && tryChangeWorkStatus(initialState?.currentUser?.staffId, location.pathname) } }, childrenRender: children => {children}, ...initialState?.settings, breakpoint: false, onCollapse } } let notificationLimit = 0 // 最大1 const errorHandler = (error: any, opts: any) => { if (opts?.skipErrorHandler) throw error if (error.name === 'BizError') { const errorInfo = error.info if (errorInfo) { if (notificationLimit >= 1) { return } const { errorMessage = '请求失败', showType, errorCode } = info if (consts.TOKEN_INVALID_CODE.includes(errorCode) && window.location.pathname !== loginPath) { history.replace({ pathname: loginPath, search: createSearchParams({ redirect: window.location.pathname }).toString() }) } switch (showType) { case ErrorShowType.ERROR_MESSAGE: message.error(errorMessage) break case ErrorShowType.WARN_MESSAGE: message.warn(errorMessage) break case ErrorShowType.NOTIFICATION: if (!notificationLimit) { const title = consts.TOKEN_INVALID_CODE.includes(errorCode) ? '用户信息过期' : '请求失败' notification.error({ message: title, description: errorMessage }) notificationLimit++ } break default: break } } else if (error.response) { // Axios 的错误 // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围 notification.error({ description: `状态码为${error.response.status}, 请联系管理员进行处理`, message: '请求异常' }) } else { // 请求已经成功发起,但没有收到响应 // 或请求根本没有发送出去 notification.error({ description: '您的网络发生异常,无法连接服务器', message: '网络异常' }) } } } const authHeaderInterceptor = (options: any) => { const token = getToken() if (token) { // 在白名单里的请求放过 if (consts.TOKEN_WHITE_LIST.includes(options.url)) { return options } options.headers[consts.TOKEN_HEADER] = `bearer ${token}` } return options } export const request: RequestConfig = { errorConfig: { // 错误抛出 errorThrower: (res: ResponseStructure) => { const { data, code, msg, showType } = res if (code !== consts.RET_CODE.SUCCESS) { const error: any = new Error(errorMessage) error.name = 'BizError' error.info = { errorCode: code, errorMessage: msg, showType, data } throw error // 抛出自制的错误 } }, errorHandler }, baseURL: consts.PREFIX_URL, requestInterceptors: [authHeaderInterceptor], responseInterceptors: [ response => { // 处理notificationLimit,请求成功应重置 if ( notificationLimit >= 1 && response.status === 200 && response.data?.code === consts.RET_CODE.SUCCESS ) { notificationLimit = 0 } const { code = -1 } = response?.data || {} if (code !== consts.RET_CODE.SUCCESS) { return Promise.reject(response?.data) } return Promise.resolve(response) } ] }