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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// @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
}
]
}