generator-hcy-system
Version:
hcy system layout and pages
209 lines (190 loc) • 6.03 kB
text/typescript
import { TOKEN } from '@/utils/constant';
import type { RequestOptions } from '@@/plugin-request/request';
import type { RequestConfig} from '@umijs/max';
import { getLocale } from '@umijs/max';
import { OPERATION_SUCCESS } from '@/services/common/constant';
import { message } from 'antd';
let isLogout = false;
// 错误处理方案: 错误类型
enum ErrorShowType {
// 请求数据格式错误
INVALID_PARAM_FORMAT= 400,
// 无权限
INVALID_TOKEN = 401,
// token 过期
NO_ACCESS = 403,
//未找到
NOT_FOUND=404,
// 请求方式错误
INVALID_TYPE = 405,
// 服务器错误
SERVER_ERROR = 500,
}
// 与后端约定的响应数据格式
interface ResponseStructure {
code: string;
msg: string;
data?: any;
status:boolean;
}
//cookie中获取token,失败跳转到登录页面
const getToken = () => {
return localStorage.getItem(TOKEN) ||
(window.location.pathname.includes('/login') ? ''
: window.location.replace('/login')
);
};
// 获取菜单ID
const getMenuId = (menuTree?: [{
privilegeUrl: string,
id: string,
children?: Array<{
privilegeUrl: string,
id: string
}>
}] | undefined): string => {
if (menuTree) {
// console.log(menuTree, 'menuTree');
const l = window.location.pathname.split('/');
// console.log(l, 'l');
if (l.length < 2||l[1]==='') {
return '';
}
const pID = menuTree.find(({ privilegeUrl }) => privilegeUrl.includes(l[1].toString()));
// console.log(pID, 'pID');
if (pID) {
if (pID.children && pID.children.length > 0) {
const cID = pID.children.find(({ privilegeUrl }) =>privilegeUrl.includes(l[2]));
if (cID) {
return cID.id;
}
}
return pID.id;
}
}
return '';
};
const headerConfig = (type?: string) => {
const menuTree = JSON.parse(localStorage.getItem('currentMenu') || '[]');
const menuId = getMenuId(menuTree || []);
return {
menuId,
lang: getLocale(),
Authorization: getToken() as string,
'Content-Type': type || 'application/json',
};
};
/**
* @name 错误处理
* pro 自带的错误处理, 可以在这里做自己的改动
* @doc https://umijs.org/docs/max/request#配置
*/
export const errorConfig: RequestConfig = {
// 错误处理: umi@3 的错误处理方案。
errorConfig: {
// 业务错误抛出
errorThrower: (res) => {
const { code, msg } = res as unknown as ResponseStructure;
if (code.toString() !== OPERATION_SUCCESS) {
const error: any = new Error(`${code}/${msg}`);
error.name = 'BizError';
error.info = { code, msg };
try{
throw error;
}catch(e){
throw error.toString();
};
}
},
// 错误接收及处理
errorHandler: (error: any, opts: any) => {
const newError = typeof error === 'string'?{
name: error.split(':')[0],
info: {
code: parseInt(error.split(':')[1].split('/')[0]),
msg: error.split(':')[1].split('/')[1],
},
}:error;
if (opts?.skipErrorHandler) throw newError;
// 我们的业务抛出的错误。
if (newError.name === 'BizError') {
const errorInfo: ResponseStructure = newError.info;
const { msg } = errorInfo;
// console.log(msg, code, 'errorInfo');
message.error(msg);
// 返回错误
throw errorInfo;
} else if (newError.response) {
// 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
// console.log('接口非200 返回');
// console.log(newError.response, 'newError.response');
const { statusText, status } = newError.response;
switch (status) {
case ErrorShowType.INVALID_TOKEN: {
message.error(statusText);
if (!isLogout) {
isLogout = true;
setTimeout(() => {
isLogout = false;
}, 1000);
if (!window.location.pathname.includes('/login')) {
window.location.replace('/login');
}
}
break;
}
case ErrorShowType.NO_ACCESS: {
message.error(statusText);
break;
}
case ErrorShowType.INVALID_TYPE: {
message.error(statusText);
break;
}
case ErrorShowType.NOT_FOUND: {
message.error(statusText);
break;
}
case ErrorShowType.SERVER_ERROR: {
message.error(statusText);
break;
}
default:
message.error(statusText);
break;
}
// message.error(`Response status:${error.response.statusText}`);
} else if (newError.request) {
// 请求已经成功发起,但没有收到响应
// \`error.request\` 在浏览器中是 XMLHttpRequest 的实例,
// 而在node.js中是 http.ClientRequest 的实例
message.error('Request error, please retry.');
console.log('请求已经成功发起,但没有收到响应');
} else {
// console.log(newError, 'error.request');
// 发送请求时出了点问题
// console.log(errorInfo, '接口错误');
console.log('发送请求时出了点问题');
message.error('Request error, please retry.');
}
},
},
// 请求拦截器
requestInterceptors: [
(config: RequestOptions) => {
// 拦截请求配置,进行个性化处理。
const url = config?.url;
const headers = headerConfig(config?.type);
return { ...config, url, headers };
},
],
// 响应拦截器
responseInterceptors: [
(response) => {
// 拦截响应数据,进行个性化处理
const { data } = response as unknown as ResponseStructure;
data.success = data?.code === '0000';
return response;
},
],
};