190 lines
4.6 KiB
TypeScript
190 lines
4.6 KiB
TypeScript
// 运行时配置
|
||
|
||
// 全局初始化数据配置,用于 Layout 用户信息和权限初始化
|
||
// 更多信息见文档:https://umijs.org/docs/api/runtime-config#getinitialstate
|
||
import auth from '@/services/auth';
|
||
import { getRedirectUrl } from '@/utils/getRedirectUrl';
|
||
import { RunTimeLayoutConfig } from '@@/plugin-layout/types';
|
||
import { RequestConfig } from '@@/plugin-request/request';
|
||
import { history } from '@umijs/max';
|
||
import { message, notification } from 'antd';
|
||
import './global.less';
|
||
|
||
interface InitialState {
|
||
channel?: AuthAPI.ChannelVO;
|
||
homePagePath?: string;
|
||
tip?: {
|
||
show: boolean;
|
||
message: string;
|
||
};
|
||
}
|
||
|
||
export async function getInitialState(): Promise<InitialState> {
|
||
await getRedirectUrl();
|
||
|
||
const { data: channel } = await auth.channel.selectChannelByDomain({
|
||
domain: window.location.host,
|
||
});
|
||
|
||
return {
|
||
channel,
|
||
tip: {
|
||
show: false,
|
||
message: '',
|
||
},
|
||
};
|
||
}
|
||
|
||
export const layout: RunTimeLayoutConfig = ({ initialState }) => {
|
||
const link =
|
||
document.querySelector("link[rel*='icon']") ||
|
||
document.createElement('link');
|
||
link.type = 'image/x-icon';
|
||
link.rel = 'shortcut icon';
|
||
link.href = initialState?.channel?.logo;
|
||
document.getElementsByTagName('head')[0].appendChild(link);
|
||
|
||
return {
|
||
title: initialState?.channel?.title,
|
||
subTitle: initialState?.channel?.subTitle,
|
||
logo: initialState?.channel?.logo,
|
||
};
|
||
};
|
||
|
||
// 错误处理方案: 错误类型
|
||
enum ErrorShowType {
|
||
SILENT = 0,
|
||
WARN_MESSAGE = 1,
|
||
ERROR_MESSAGE = 2,
|
||
NOTIFICATION = 3,
|
||
REDIRECT = 9,
|
||
}
|
||
|
||
// 与后端约定的响应数据格式
|
||
interface ResponseStructure {
|
||
success: boolean;
|
||
data: any;
|
||
errCode?: string;
|
||
errMessage?: string;
|
||
showType?: ErrorShowType;
|
||
}
|
||
|
||
// 运行时配置
|
||
export const request: RequestConfig = {
|
||
// 统一的请求设定
|
||
timeout: 60000,
|
||
headers: {
|
||
'X-Requested-With': 'XMLHttpRequest',
|
||
'Xh-Platform-Id': '1769220738064285698',
|
||
},
|
||
|
||
// 错误处理: umi@3 的错误处理方案。
|
||
errorConfig: {
|
||
// 错误抛出
|
||
errorThrower: (res: ResponseStructure) => {
|
||
const { success, data, errCode, errMessage, showType } = res;
|
||
if (!success) {
|
||
if (errCode === '401' || errCode === '403') {
|
||
// 未登录,跳转到登录页面
|
||
history.push('/login');
|
||
return;
|
||
}
|
||
|
||
if (errCode === '400') {
|
||
message.error(errMessage);
|
||
return;
|
||
}
|
||
|
||
if (errCode === 'UNKNOWN_ERROR') {
|
||
message.error('未知的错误');
|
||
return;
|
||
}
|
||
|
||
if (errCode === 'USER_AUTH_NOT_LOGIN') {
|
||
return;
|
||
}
|
||
|
||
if (errCode === 'USER_AUTH_NO_APP_PERMISSION') {
|
||
message.error(errMessage);
|
||
return;
|
||
}
|
||
|
||
const error: any = new Error(errMessage || errCode);
|
||
error.name = 'BizError';
|
||
error.info = { errCode, errMessage, showType, data };
|
||
throw error; // 抛出自制的错误
|
||
}
|
||
},
|
||
// 错误接收及处理
|
||
errorHandler: (error: any, opts: any) => {
|
||
if (opts?.skipErrorHandler) throw error;
|
||
// 我们的 errorThrower 抛出的错误。
|
||
if (error.name === 'BizError') {
|
||
const errorInfo: ResponseStructure | undefined = error.info;
|
||
if (errorInfo) {
|
||
const { errMessage, errCode } = errorInfo;
|
||
switch (errorInfo.showType) {
|
||
case ErrorShowType.SILENT:
|
||
// do nothing
|
||
break;
|
||
case ErrorShowType.WARN_MESSAGE:
|
||
message.warning(errMessage);
|
||
break;
|
||
case ErrorShowType.ERROR_MESSAGE:
|
||
message.error(errMessage);
|
||
break;
|
||
case ErrorShowType.NOTIFICATION:
|
||
notification.open({
|
||
description: errMessage,
|
||
message: errCode,
|
||
});
|
||
break;
|
||
case ErrorShowType.REDIRECT:
|
||
// TODO: redirect
|
||
break;
|
||
default:
|
||
message.error(errMessage);
|
||
}
|
||
}
|
||
} else if (error.response) {
|
||
// Axios 的错误
|
||
// 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
|
||
message.error(`Response status:${error.response.status}`);
|
||
} else if (error.request) {
|
||
// 请求已经成功发起,但没有收到响应
|
||
// \`error.request\` 在浏览器中是 XMLHttpRequest 的实例,
|
||
// 而在node.js中是 http.ClientRequest 的实例
|
||
message.error('None response! Please retry.1');
|
||
} else {
|
||
// 发送请求时出了点问题
|
||
message.error('Request error, please retry.2');
|
||
}
|
||
},
|
||
},
|
||
|
||
// 请求拦截器
|
||
requestInterceptors: [
|
||
(
|
||
url: any,
|
||
options: {
|
||
headers: any;
|
||
},
|
||
) => {
|
||
console.log('请求拦截器', url, options);
|
||
const apiUrl = '/api' + url;
|
||
return {
|
||
url: apiUrl,
|
||
options,
|
||
};
|
||
},
|
||
],
|
||
|
||
// 响应拦截器
|
||
responseInterceptors: [
|
||
(response: ResponseStructure) => {
|
||
// 拦截响应数据,进行个性化处理
|
||
return response;
|
||
},
|
||
],
|
||
} as any;
|