|
|
|
@ -0,0 +1,442 @@
|
|
|
|
|
// import { fetch } from 'dva';
|
|
|
|
|
import { Modal, notification } from 'antd';
|
|
|
|
|
import hash from 'hash.js';
|
|
|
|
|
import { getDvaApp, history } from 'umi';
|
|
|
|
|
import ENV from './env/dev';
|
|
|
|
|
import { setHeader } from '.';
|
|
|
|
|
let modalConfirm: any;
|
|
|
|
|
const codeMessage: any = {
|
|
|
|
|
200: '服务器成功返回请求的数据。',
|
|
|
|
|
201: '新建或修改数据成功。',
|
|
|
|
|
202: '一个请求已经进入后台排队(异步任务)。',
|
|
|
|
|
204: '删除数据成功。',
|
|
|
|
|
400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
|
|
|
|
|
401: '用户没有权限(令牌、用户名、密码错误)。',
|
|
|
|
|
403: '用户得到授权,但是访问是被禁止的。',
|
|
|
|
|
404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
|
|
|
|
|
406: '请求的格式不可得。',
|
|
|
|
|
410: '请求的资源被永久删除,且不会再得到的。',
|
|
|
|
|
422: '当创建一个对象时,发生一个验证错误。',
|
|
|
|
|
500: '服务器发生错误,请检查服务器。',
|
|
|
|
|
502: '网关错误。',
|
|
|
|
|
503: '服务不可用,服务器暂时过载或维护。',
|
|
|
|
|
504: '网关超时。',
|
|
|
|
|
};
|
|
|
|
|
interface Response {
|
|
|
|
|
status: number;
|
|
|
|
|
statusText: string;
|
|
|
|
|
json: any;
|
|
|
|
|
message: string;
|
|
|
|
|
}
|
|
|
|
|
interface Params {
|
|
|
|
|
[key: string]: any;
|
|
|
|
|
}
|
|
|
|
|
const checkStatus = async (response: Response, responseData: any) => {
|
|
|
|
|
if (response.status >= 200 && response.status < 300) {
|
|
|
|
|
return response;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// debugger;
|
|
|
|
|
const errortext = codeMessage[response.status] || response.statusText;
|
|
|
|
|
let text;
|
|
|
|
|
var resJson = response.json();
|
|
|
|
|
|
|
|
|
|
await resJson.then((resolve: any, reject: any) => {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
let app = getDvaApp();
|
|
|
|
|
// reportData(ENV.REPORT_SERVER + "/report/error", {
|
|
|
|
|
// code: resolve.code,
|
|
|
|
|
// status: response.status,
|
|
|
|
|
// message: resolve.message,
|
|
|
|
|
// requestData: { ...responseData, cookie: document.cookie },
|
|
|
|
|
// responseData: { ...response, ...resolve },
|
|
|
|
|
// user: app._store.getState().user.userInfo
|
|
|
|
|
// })
|
|
|
|
|
}, 400);
|
|
|
|
|
text = resolve.message;
|
|
|
|
|
notification.error({
|
|
|
|
|
style: { wordBreak: 'break-all' },
|
|
|
|
|
// duration: null,
|
|
|
|
|
message: resolve.message || `请求错误 ${response.status}: ${response.message}`,
|
|
|
|
|
description: resolve.message ? '' : errortext,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const error: any = new Error(errortext);
|
|
|
|
|
error.name = response.status;
|
|
|
|
|
error.response = response;
|
|
|
|
|
throw {
|
|
|
|
|
data: response,
|
|
|
|
|
code: response.status,
|
|
|
|
|
message: text || errortext,
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const cachedSave = (response: any, hashcode: any) => {
|
|
|
|
|
const contentType = response.headers.get('Content-Type');
|
|
|
|
|
if (contentType && contentType.match(/application\/json/i)) {
|
|
|
|
|
response
|
|
|
|
|
.clone()
|
|
|
|
|
.text()
|
|
|
|
|
.then(() => {
|
|
|
|
|
// sessionStorage.setItem(hashcode, content)
|
|
|
|
|
// sessionStorage.setItem(`${hashcode}:timestamp`, Date.now())
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return response;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const parseParams = (param: Params) => {
|
|
|
|
|
param = param || {};
|
|
|
|
|
// param.domain = window.location.host
|
|
|
|
|
let paramStr = '';
|
|
|
|
|
for (let key in param) {
|
|
|
|
|
if (typeof param[key] === 'object') {
|
|
|
|
|
if (Array.isArray(param[key])) {
|
|
|
|
|
param[key].forEach((element: string, k: number) => {
|
|
|
|
|
paramStr += '&' + key + `[]=` + element;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// if ((param[key]) || param[key] === 0)
|
|
|
|
|
paramStr += '&' + key + '=' + param[key];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return paramStr.substr(1);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default function request(url: string, option: any, flag?: boolean, ismin?: boolean) {
|
|
|
|
|
!option.method ? (option.method = 'get') : '';
|
|
|
|
|
option.method = option.method.toUpperCase();
|
|
|
|
|
option.mode = 'cors';
|
|
|
|
|
|
|
|
|
|
const options = {
|
|
|
|
|
...option,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (options.body) {
|
|
|
|
|
options.body.is_test = 1;
|
|
|
|
|
options.body.is_admin = true;
|
|
|
|
|
} else if (options.params) {
|
|
|
|
|
options.params.is_test = 1;
|
|
|
|
|
options.params.is_admin = true;
|
|
|
|
|
} else {
|
|
|
|
|
options.params = { is_test: 1, is_admin: true };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// options.domain = window.location.host
|
|
|
|
|
|
|
|
|
|
const fingerprint = url + (options.body ? JSON.stringify(options.body) : '');
|
|
|
|
|
const hashcode = hash.sha256().update(fingerprint).digest('hex');
|
|
|
|
|
|
|
|
|
|
const defaultOptions = {
|
|
|
|
|
credentials: 'include',
|
|
|
|
|
withCredentials: true,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let newOptions = { ...defaultOptions, ...options };
|
|
|
|
|
if (
|
|
|
|
|
newOptions.method === 'POST' ||
|
|
|
|
|
newOptions.method === 'PUT' ||
|
|
|
|
|
newOptions.method === 'PATCH' ||
|
|
|
|
|
newOptions.method === 'DELETE'
|
|
|
|
|
) {
|
|
|
|
|
if (!flag) {
|
|
|
|
|
newOptions.headers = {
|
|
|
|
|
Accept: 'application/json',
|
|
|
|
|
'Content-Type': 'application/json; charset=utf-8',
|
|
|
|
|
...newOptions.headers,
|
|
|
|
|
};
|
|
|
|
|
newOptions.body = JSON.stringify(options.body);
|
|
|
|
|
} else {
|
|
|
|
|
newOptions.headers = {
|
|
|
|
|
...newOptions.headers,
|
|
|
|
|
};
|
|
|
|
|
newOptions.body = options.body;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (newOptions.method == 'GET' || newOptions.method == 'DELETE') {
|
|
|
|
|
newOptions.headers = {
|
|
|
|
|
Accept: 'application/json',
|
|
|
|
|
'Content-Type': 'application/json; charset=utf-8',
|
|
|
|
|
...newOptions.headers,
|
|
|
|
|
};
|
|
|
|
|
if (options.params) url += '?' + parseParams(options.params);
|
|
|
|
|
}
|
|
|
|
|
// newOptions.headers.withCredentials=true;
|
|
|
|
|
// newOptions.headers.Authorization =
|
|
|
|
|
// 'Bearer 09cb06de7874a0cfae0608ba5126b3b30dcb5d2a'
|
|
|
|
|
// if (localStorage.getItem('xhr-user-info')) {
|
|
|
|
|
// const token = JSON.parse(localStorage.getItem('xhr-user-info')).apiToken
|
|
|
|
|
// newOptions.headers.Authorization = 'Bearer ' + token
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
const expirys = options.expirys && 60;
|
|
|
|
|
/**
|
|
|
|
|
* @description: 枚举出请求数据格式类型
|
|
|
|
|
* @param {type} 枚举类型
|
|
|
|
|
* @return:
|
|
|
|
|
*/
|
|
|
|
|
enum ContentType {
|
|
|
|
|
json = 'application/json;charset=UTF-8',
|
|
|
|
|
form = 'application/x-www-form-urlencoded; charset=UTF-8',
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @description: 枚举request请求的method方法
|
|
|
|
|
* @param {type} 枚举类型
|
|
|
|
|
* @return:
|
|
|
|
|
*/
|
|
|
|
|
enum HttpMethod {
|
|
|
|
|
get = 'GET',
|
|
|
|
|
post = 'POST',
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @description: 声明请求头header的类型
|
|
|
|
|
* @param {type}
|
|
|
|
|
* @return:
|
|
|
|
|
*/
|
|
|
|
|
interface IHeader {
|
|
|
|
|
Accept?: string;
|
|
|
|
|
'Content-Type': string;
|
|
|
|
|
[propName: string]: any;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @description: 声明fetch请求参数配置
|
|
|
|
|
* @param {type}
|
|
|
|
|
* @return:
|
|
|
|
|
*/
|
|
|
|
|
interface IReqConfig {
|
|
|
|
|
method?: string;
|
|
|
|
|
credentials?: string;
|
|
|
|
|
headers?: IHeader;
|
|
|
|
|
body?: any;
|
|
|
|
|
}
|
|
|
|
|
interface IHttp {
|
|
|
|
|
getFetch<R, P = {}>(url: string, params?: P, options?: RequestInit): Promise<R>;
|
|
|
|
|
// getFetchJsonp<R,P>(url: string, params?:P, options?:RequestInit): Promise<R>;
|
|
|
|
|
postFetch<R, P = {}>(url: string, params?: P): Promise<R>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if (options.expirys !== false) {
|
|
|
|
|
// const cached = sessionStorage.getItem(hashcode)
|
|
|
|
|
// const whenCached = sessionStorage.getItem(`${hashcode}:timestamp`)
|
|
|
|
|
// if (cached !== null && whenCached !== null) {
|
|
|
|
|
// const age = (Date.now() - whenCached) / 1000
|
|
|
|
|
// if (age < expirys) {
|
|
|
|
|
// const response = new Response(new Blob([cached]))
|
|
|
|
|
// return response.json()
|
|
|
|
|
// }
|
|
|
|
|
// sessionStorage.removeItem(hashcode)
|
|
|
|
|
// sessionStorage.removeItem(`${hashcode}:timestamp`)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
const downloadFile = async (response: any) => {
|
|
|
|
|
const d = await response.arrayBuffer();
|
|
|
|
|
let fileName: any;
|
|
|
|
|
const blob = new Blob([d]);
|
|
|
|
|
try {
|
|
|
|
|
fileName = response.headers
|
|
|
|
|
.get('Content-Disposition')
|
|
|
|
|
.split(';')[1]
|
|
|
|
|
.replace('filename=', '')
|
|
|
|
|
.replace(/[\s+,\',\",\‘,\’,\“,\”,\<,\>,\《,\》]/g, '');
|
|
|
|
|
} catch (e) {
|
|
|
|
|
fileName = 'userfiles.zip';
|
|
|
|
|
}
|
|
|
|
|
const a = document.createElement('a');
|
|
|
|
|
const url = window.URL.createObjectURL(blob);
|
|
|
|
|
const filename = fileName;
|
|
|
|
|
a.href = url;
|
|
|
|
|
a.download = filename;
|
|
|
|
|
a.click();
|
|
|
|
|
window.URL.revokeObjectURL(url);
|
|
|
|
|
return d;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// const timenow = Date.now();
|
|
|
|
|
// const stringToSign =
|
|
|
|
|
// "method=" + newOptions.method + "&"+
|
|
|
|
|
// (newOptions.params ? parseParamsStr(newOptions.params) + "&" : "") +
|
|
|
|
|
// (newOptions.body ? parseParamsStr(newOptions.body) : "") +
|
|
|
|
|
// "ak=e83900ca9be33747397cc81a8f68ac11" + "&sk=6de3a75ae5718cde1e0907a593afd01f&time=" + timenow;
|
|
|
|
|
|
|
|
|
|
// newOptions.headers["X-EDU-Timestamp"] = timenow;
|
|
|
|
|
// newOptions.headers["X-EDU-Signature"] = md5(Base64.encode(stringToSign));
|
|
|
|
|
setHeader(newOptions, url);
|
|
|
|
|
|
|
|
|
|
let prefixUrl = ENV.PROXY_SERVER;
|
|
|
|
|
if ((window as any).ENV === 'dev' || url.startsWith('http')) prefixUrl = '';
|
|
|
|
|
if (ismin) prefixUrl = '';
|
|
|
|
|
return fetch(prefixUrl + url, newOptions)
|
|
|
|
|
.then((response: any) => checkStatus(response, { url: ENV.PROXY_SERVER + url, ...newOptions }))
|
|
|
|
|
.then((response: any) => cachedSave(response, hashcode))
|
|
|
|
|
.then(async (response: any) => {
|
|
|
|
|
if (response.status === 204) {
|
|
|
|
|
return response.text();
|
|
|
|
|
}
|
|
|
|
|
let d;
|
|
|
|
|
if (response.headers.get('content-type').indexOf('application/json') > -1) {
|
|
|
|
|
d = await response.json();
|
|
|
|
|
} else if (newOptions.headers['Content-Type'] === 'application/xml') {
|
|
|
|
|
d = await response.text();
|
|
|
|
|
} else if (options.body?.autoDownload || options.params?.autoDownload) {
|
|
|
|
|
d = await downloadFile(response);
|
|
|
|
|
} else {
|
|
|
|
|
d = await response.arrayBuffer();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (
|
|
|
|
|
d.status === 401 &&
|
|
|
|
|
(!newOptions.params?.hidePopLogin || !newOptions.body?.hidePopLogin)
|
|
|
|
|
) {
|
|
|
|
|
getDvaApp()._store.dispatch({
|
|
|
|
|
type: 'user/showPopLogin',
|
|
|
|
|
payload: {
|
|
|
|
|
showPopLogin: true,
|
|
|
|
|
showClosable: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (d.status === 402) {
|
|
|
|
|
if (localStorage.getItem('addinfo') === '2') {
|
|
|
|
|
//弹窗 填充信息
|
|
|
|
|
getDvaApp()._store.dispatch({
|
|
|
|
|
type: 'shixunHomeworks/setActionTabs',
|
|
|
|
|
payload: {
|
|
|
|
|
key: '填充信息弹窗',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
modalConfirm =
|
|
|
|
|
modalConfirm ||
|
|
|
|
|
Modal.confirm({
|
|
|
|
|
centered: true,
|
|
|
|
|
visible: false,
|
|
|
|
|
okText: '确定',
|
|
|
|
|
cancelText: '取消',
|
|
|
|
|
});
|
|
|
|
|
modalConfirm.update({
|
|
|
|
|
centered: true,
|
|
|
|
|
visible: true,
|
|
|
|
|
title: '提示',
|
|
|
|
|
content: '您需要去完善您的个人资料,才能使用此功能',
|
|
|
|
|
okText: '立即完善',
|
|
|
|
|
cancelText: '稍后完善',
|
|
|
|
|
onOk: () => {
|
|
|
|
|
history.push('/account/profile/edit');
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
handleHttpStatus(d, url);
|
|
|
|
|
return d;
|
|
|
|
|
})
|
|
|
|
|
.catch((e: any, a: any, b: any) => {
|
|
|
|
|
try {
|
|
|
|
|
const status = e.code;
|
|
|
|
|
if (status) {
|
|
|
|
|
if (status === 401) {
|
|
|
|
|
getDvaApp()._store.dispatch({
|
|
|
|
|
type: 'user/showPopLogin',
|
|
|
|
|
payload: {
|
|
|
|
|
showPopLogin: true,
|
|
|
|
|
showClosable: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
handleHttpStatus(e, url);
|
|
|
|
|
} else {
|
|
|
|
|
if (url.includes('/file/filePatchMerge')) {
|
|
|
|
|
getDvaApp()._store.dispatch({
|
|
|
|
|
type: 'shixunHomeworks/setActionTabs',
|
|
|
|
|
payload: {
|
|
|
|
|
key: '分片专用504',
|
|
|
|
|
params: newOptions.body,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
notification.warning({
|
|
|
|
|
style: { wordBreak: 'break-all' },
|
|
|
|
|
duration: null,
|
|
|
|
|
message: `您的网络可能出现了问题,请稍后再试`,
|
|
|
|
|
// description: url,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return e;
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let historyFlag = false;
|
|
|
|
|
let errorFlag = false;
|
|
|
|
|
const handleHttpStatus = (e: { status: number; message: string }, url?: string) => {
|
|
|
|
|
if ((e.status == -1 || e.status == -2 || e.status > 400) && e.status != 403 && !errorFlag) {
|
|
|
|
|
errorFlag = true;
|
|
|
|
|
setTimeout(() => (errorFlag = false), 500);
|
|
|
|
|
// message.warn({ content: e.message, key: 'message-key' });
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const mapping: { [key: number]: string } = {
|
|
|
|
|
403: '/403',
|
|
|
|
|
404: '/404',
|
|
|
|
|
500: '/500',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (mapping[e.status] && !historyFlag) {
|
|
|
|
|
const { user }: any = getDvaApp()._store.getState();
|
|
|
|
|
const { userInfo }: any = user;
|
|
|
|
|
if (
|
|
|
|
|
window.location.pathname.indexOf('/users') > -1 &&
|
|
|
|
|
document.domain === 'kepukehuan.educoder.net'
|
|
|
|
|
)
|
|
|
|
|
alert(e.status + ':' + userInfo?.id + '---' + url);
|
|
|
|
|
historyFlag = true;
|
|
|
|
|
setTimeout(() => (historyFlag = false), 500);
|
|
|
|
|
if (e.status === 403) {
|
|
|
|
|
history.replace(mapping[e.status]);
|
|
|
|
|
} else {
|
|
|
|
|
history.replace(mapping[e.status]);
|
|
|
|
|
}
|
|
|
|
|
sessionStorage.setItem('errorStatus', JSON.stringify(e));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export function get(url: string, params?: Object) {
|
|
|
|
|
return request(`/api/${url}`, {
|
|
|
|
|
method: 'Get',
|
|
|
|
|
params: params || {},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
export function getqq(url: string, params?: Object) {
|
|
|
|
|
return request(`/${url}`, {
|
|
|
|
|
method: 'Get',
|
|
|
|
|
params,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function post(url: string, params?: Object) {
|
|
|
|
|
return request(`/api/${url}`, {
|
|
|
|
|
method: 'Post',
|
|
|
|
|
body: { ...params },
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function put(url: string, params?: Object) {
|
|
|
|
|
return request(`/api/${url}`, {
|
|
|
|
|
method: 'Put',
|
|
|
|
|
body: { ...params },
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function del(url: string) {
|
|
|
|
|
return request(`/api/${url}`, { method: 'delete' });
|
|
|
|
|
}
|