forgeplus-react/src/utils/fetch.ts

390 lines
11 KiB
TypeScript
Executable File

import { fetch } from 'dva';
import ENV from './env'
import { notification, message, Modal } from 'antd'
import hash from 'hash.js'
import { useDispatch, getDvaApp, history } from 'umi'
import { reportData } from 'monitor-error-ll'
import { getCookie } from './util';
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
}
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) {
!option.method ? (option.method = 'get') : ''
option.method = option.method.toUpperCase()
option.mode = 'cors'
const options = {
...option,
}
// 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.headers = {
Accept: 'application/json',
'Content-Type': 'application/json; charset=utf-8',
...newOptions.headers
}
url += '?' + parseParams(options.params)
}
if(url.indexOf("get_user_info") === -1 && getCookie("logintrustie")){
newOptions.headers={
...newOptions.headers,
Authorization:getCookie("logintrustie")
}
}
// 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-type').split(';')[1].replace('filename=', '');
} 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);
};
let prefixUrl = ENV.API_SERVER;
if (window.ENV === 'dev') prefixUrl = '';
return fetch(url.indexOf("https") > -1 ? url : prefixUrl + url, newOptions)
.then((response: any) => checkStatus(response, { url: url.indexOf("https") > -1 ? url : ENV.API_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 {
downloadFile(response);
d = await response.arrayBuffer();
}
try {
if (d.status === 401 && (!newOptions.params?.hidePopLogin || !newOptions.body?.hidePopLogin)) {
console.log("new:", newOptions)
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({ visible: false, okText: "确定", cancelText: "取消" });
modalConfirm.update({
centered: true,
visible: true,
title: "提示",
content: "您需要去完善您的个人资料,才能使用此功能",
okText: "立即完善",
cancelText: "稍后完善",
onOk: () => {
history.push('/account/profile/edit');
}
})
}
}
} catch (e) {
console.log("fetcherr", e)
}
handleHttpStatus(d, url)
return d
})
.catch((e: any) => {
try {
const status = e.code
if (status === 401) {
getDvaApp()._store.dispatch({
type: 'user/showPopLogin',
payload: {
showPopLogin: true,
showClosable: true
}
})
}
handleHttpStatus(e, 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" })
}
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))
}
}
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' })
}