// @ts-nocheck import React from 'react' import { history, RequestConfig, type AxiosResponse, matchPath } from '@umijs/max' import { notification } from 'antd' import NotificationTemplate from '@/components/NotificationTemplate' import { getTokenAuthority, setUserInfo } from '@/utils/globalCommon' import errorCode from '@/utils/errorCode' import { queryCurrent } from '@/services/user' import defaultSettings from '../config/defaultSettings' import { getAllForProMenuByUserId } from '@/services/system/api_promenu' import { getAllForProResourceActionByUserId } from '@/services/system/api_proresourceaction' import * as allIcons from '@ant-design/icons' import 'dayjs/locale/zh-cn' import dayjs from 'dayjs' import weekday from 'dayjs/plugin/weekday' import localeData from 'dayjs/plugin/localeData' import customParseFormat from 'dayjs/plugin/customParseFormat' import relativeTime from 'dayjs/plugin/relativeTime' dayjs.locale('zh-cn') dayjs.extend(weekday) dayjs.extend(localeData) dayjs.extend(customParseFormat) dayjs.extend(relativeTime) const loginPath = '/login' const { REACT_APP_ENV } = process.env let staticMapList = ['/', '/login', '/register', '/exception00', '/exception00/403', '/exception00/404', '/exception00/500', '/exception00/1403'] let tempMapList = [] //约定 src/app.tsx 为运行时配置 export async function getInitialState (type) { tempMapList = [] // 如果是登录页面,不执行 if (history.location.pathname !== loginPath || type === 'refresh') { try { history.replace({ pathname: "/topnavbar00/hrefficiency" }) // if (!localStorage.getItem('antd-token-authority')) { // history.replace({ // pathname: loginPath // }) // localStorage.clear() // throw new Error() // } // let response = await queryCurrent() // const { datarecord: { user: currentUser, roles } } = response // localStorage.setItem('antd-token-userid', currentUser.user_id ?? '') // localStorage.setItem('antd-token-username', currentUser.user_name ?? '') // localStorage.setItem('antd-token-poweruser', currentUser.poweruser ?? '') // localStorage.setItem('antd-pro-authority', roles ? JSON.stringify(roles) : '') // localStorage.setItem('antd-token-user', currentUser ? JSON.stringify(currentUser) : '') // setUserInfo() // let menuData = await getAllForProMenuByUserId({ // user_name: currentUser.user_name, // parentid: '000000000000', // systemid: '000000000000' // }) // let resourceData = await getAllForProResourceActionByUserId({ // systemid: '000000000000' // }) // localStorage.setItem('antd-pro-button', resourceData?.datarecord?.button ? JSON.stringify(resourceData?.datarecord?.button) : '') // const toHump = (name) => name.replace(/-(\w)/g, (all, letter) => letter.toUpperCase()) // let tempList = [] // let tempMap = [] // const formatter = (data, list) => { // data?.map(item => { // tempMap.push((item?.redirect === '' ? null : item?.redirect) ?? item?.key) // // if (item?.hideInMenu) return // if (item?.alias === 'ywmk') { // formatter(item?.children ?? [], tempList) // return // } // let tempObj = { // key: (item?.redirect === '' ? null : item?.redirect) ?? item?.key, // label: item?.label, // hideInMenu: item?.hideInMenu, // children: [] // } // if (item?.children || item?.routes) formatter(item?.children?.length > 0 ? item?.children : (item?.routes?.length > 0 ? item?.routes : []), tempObj.children) // tempObj.children.length === 0 && delete tempObj.children // if (item?.icon) { // const { icon } = item // const v4IconName = toHump(icon.replace(icon[0], icon[0].toUpperCase())) // const NewIcon = allIcons[icon] || allIcons[''.concat(v4IconName, 'Outlined')] // if (NewIcon) { // try { // tempObj.icon = React.createElement(NewIcon) // } catch (error) {} // } // } // list.push(tempObj) // }) // } // formatter(menuData.list ?? [], tempList) // menuData.list = tempList // tempMapList = tempMap // window.dynamicRoute = tempList return { // currentUser, settings: defaultSettings, // menu: menuData.list, // menuMap: tempMap } } catch (error) { notification.error({ message: '网络异常', description: '用户信息获取失败!' }) // history.replace({ // pathname: loginPath // }) } } return { currentUser: null, menu: null, settings: defaultSettings } } export function onRouteChange({ location }) { const locationName = location.pathname const menuMap = [...staticMapList, ...tempMapList] let foundFlag = menuMap?.some(item => !!matchPath(item, locationName)) //本地开发注释掉下面这一行 // !foundFlag && (window.location.href = '/exception00/404') } /** * 在控制台打印出对应的错误信息,方便定位问题 * @param error */ const printErrorInfo = (error: {}) => { const { code, message, status, timestamp, request = {} } = error || {} const { url, options } = request const { method, headers, params, data } = options const paramsKeys = Object.keys(params || {}) const tempParams = paramsKeys && paramsKeys.length ? params : data // 接口的参数有可能在 params 中也有可能在 data 里 const errorTagStyle = [ 'color: #ff4d4f', 'background: #fff2f0', 'padding: 2px 6px', 'font-size: 12px', 'border-radius: 2px', 'border: 1px solid #ff4d4f' ].join('') console.log('%c接口报错信息', errorTagStyle) console.log(` ------------- error-start ------------- 时间:${timestamp || new Date().toString()} HTTP Status:${status || 200} 接口路径:${url} 请求类型:${method} headers:${JSON.stringify(headers)} 参数:${JSON.stringify(tempParams || {})} code:${code} message:${message} ------------- error-end --------------- `) } export const dva = { config: { onError(e: { preventDefault: () => void }) { e.preventDefault() } } } /** * 统一异常处理程序 */ const errorHandler = (error: any) => { if (error && Object.keys(error).length > 0) { REACT_APP_ENV === 'dev' && printErrorInfo(error) const { status, success, message: msg } = error if (status === 203 || status === 401) { /*let duration = 4 let interval = setInterval(function(){ if(duration === 0) { // 跳转到登录页 记录是从哪个页面跳转到登录页的,登录后直接跳转到对应的页面 const redirect = window.location.pathname === '/' || window.location.pathname === '/topnavbar/home' ? {} : { redirect: window.location.href } history.replace({ pathname: loginPath, search: JSON.stringify(redirect) }) // 跳到登录页时需要将存储在本地的信息全部清除掉 localStorage.clear() clearInterval(interval) } else { duration-- notification.error({ key: 'notification_login', message: '未登录或登录已过期,请重新登录!', description: `${duration === 0 ? '即': duration + ' 秒之后'}将跳转到登录页面` }) } }, 1000)*/ } else if (status <= 504 && status >= 500) { history.push('/exception/500') //500 }/* else if (status === 403) { history.push('/exception/403') //403 } */else if (status >= 404 && status < 422) { history.push('/exception/404') //404 } else if (status === 1403) { history.replace({ pathname: '/exception/1403' }) //未授权 } else { // 获取错误信息 let errorText = errorCode[status] || msg || errorCode['default'] if (errorText == 'Network Error') { errorText = '后端接口连接异常' } else if (errorText.includes('timeout')) { errorText = '系统接口请求超时' } else if (errorText.includes('Request failed with status code')) { errorText = '系统接口请求异常' } notification.error({ message: `请求错误 ${errorText || ''}`, description: }) } } else { notification.config({ maxCount: 1 }) notification.error({ description: '您的网络发生异常,无法连接服务器', message: '网络异常' }) } // reject出去之后使用时才可通过.catch对异常情况进行处理 // return Promise.reject(error) } /** * 设置 headers */ const getHeaders = () => { // 统一的headers return { Authorization: getTokenAuthority() } } /** * request 请求 */ export const request: RequestConfig = { timeout: 20000, errorConfig: { errorHandler: errorHandler, // 默认错误处理 // errorThrower: printErrorInfo // 默认错误抛出 }, adaptor: (resData: any) => { return { ...resData, success: true, errorMessage: resData.message } }, credentials: 'include', // 默认请求是否带上cookie headers: getHeaders(), requestInterceptors: [ (url: any, options: any) => { let headers = getTokenAuthority() ? getHeaders() : {} return { url: url, options: { ...options, headers: headers } } } ], responseInterceptors: [ async (response: AxiosResponse) => { const responseClone = response || {} if(responseClone.status === 200) { // 二进制数据则直接返回 if(response.request.responseType === 'blob' || response.request.responseType === 'arraybuffer') { return response } const data = await responseClone?.data || {} let { success, message: msg, status } = data if (!success) { // msg = msg?.split('!')[0] || msg?.match(/[\u4e00-\u9fa5|\uff01|\uff0c|\u3002]/gi).join(') if(status) { // 注意:需要reject出去才会在请求不成功或返回错误的status时调用errorHandler // data.message = msg return Promise.reject(data) } else { // 只保留汉字 !,。 // message.error(msg) notification.error({ message: `${msg?.split('!')[0] || '请求错误'}: `, description: }) } } } else { return Promise.reject({ status: responseClone.status, statusText: responseClone.statusText }) } return response } ] }