Files
vic-user-react/src/utils/http.ts
2019-09-29 19:36:43 +08:00

129 lines
3.3 KiB
TypeScript

import axios, { AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios';
import { formatMessage } from 'umi-plugin-locale';
import _ from 'lodash';
import md5 from 'md5';
import { globalState } from '@/services/common';
import { isDev, dispatch } from './utils';
import config from '@/config';
export interface AppResp<T = any> {
ok: boolean,
code: number;
msg: string;
data?: T;
}
const successLabel = 'color:white;background-color:green;padding: 1px 2px';
const failureLabel = 'color:white;background-color:red;padding: 1px 2px';
const originLabel = 'color:unset;background-color:unset;padding:unset';
const errorMap = {
404: 'common.404',
403: 'common.403',
};
const { baseURL } = config;
const instance = axios.create({
baseURL,
});
function replaceId(obj: any) {
if (obj instanceof Array) {
obj.forEach(replaceId);
} else if (typeof obj === 'object') {
const id = obj['_id'];
if (id) {
delete obj['_id'];
obj.id = id;
}
_.entries(obj).forEach(([_, value]) => {
if (typeof value === 'object') {
replaceId(value);
}
});
}
}
async function filter<T>(
method: keyof AxiosInstance,
url: string,
...args: any[]
): Promise<AppResp<T>> {
let ret;
try {
const { user } = globalState().user;
if (user && user.token) {
instance.defaults.headers = {
...(instance.defaults.headers || {}),
token: user.token,
};
} else {
instance.defaults.headers = _.omit(instance.defaults.headers, 'token');
}
const matches = url.match(/(?:[/\da-zA-Z]+)/) || [''];
const timestamp = Date.now();
instance.defaults.headers.ts = `${timestamp}`;
instance.defaults.headers.sig = md5(`${timestamp}${matches[0]}LimitSaltLOL8080`);
const { status, data, headers } =
await (instance[method] as (...args: any[]) => Promise<AxiosResponse<AppResp>>)(url, ...args);
replaceId(data);
if (headers && headers.token) {
dispatch({ type: 'user/updateToken', payload: headers.token });
}
ret = {
ok: status >= 200 && status < 300 && data && data.code === 0,
code: data && data.code,
msg: data && data.msg,
data: data && data.data,
};
} catch (e) {
let code = 404;
let msg = 'network.error';
if (e.response) {
code = e.response.status;
msg = (errorMap as any)[code] || 'network.error';
if (code === 403 || code === 401) {
dispatch({ type: 'user/logout' });
}
}
ret = {
ok: false,
msg: formatMessage({ id: msg }),
code,
};
}
if (isDev) {
/* tslint:disable */
console.group(`%c${method.toUpperCase()}%c: ${baseURL}${args[0]}`, ret.ok ? successLabel : failureLabel, originLabel);
console.log(ret);
console.groupEnd();
/* tslint:enable */
}
return ret;
}
function groupUrl(url: string, params?: any): string {
const postfix = _.keys(params || {})
.map(key => `${key}=${encodeURIComponent(params[key] || '') || ''}`)
.join('&');
if (!postfix) return url;
return `${url}?${postfix}`;
}
function get<T = any>(url: string, params?: any, config?: AxiosRequestConfig) {
return filter<T>('get', groupUrl(url, params), config);
}
function post<T = any>(url: string, data?: any, config?: AxiosRequestConfig) {
return filter<T>('post', url, data, config);
}
export default {
get,
post,
};
export {
get,
post,
};