You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

338 lines
12 KiB
TypeScript

2 months ago
// @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: <NotificationTemplate message={errorText || ''} />
})
}
} 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<T>) => {
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: <NotificationTemplate message={data.message || ''}/>
})
}
}
} else {
return Promise.reject({
status: responseClone.status,
statusText: responseClone.statusText
})
}
return response
}
]
}