绩效考核手机版
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
5.3 KiB

3 years ago
import extend from '../../utils/extend';
import getType from '../../utils/getType';
import getTypeValue from '../../utils/getTypeValue';
import mergePath from '../../utils/mergePath';
import toast from '../../utils/toast';
import noop from './../../utils/noop';
import createError from './createError';
import createSuccess from './createSuccess';
import defaultConfig from './defaultConfig';
import defaultInterceptors from './defaultInterceptors';
import failMap from './failMap';
import loading from './loading';
/**
* @description: 创建一个请求器
* @param {defaultConfig} config 默认参数
* @param {defaultInterceptors} interceptors 拦截器
* @return {function(defaultConfig)}
*/
export default function createRequest(config = {}, interceptors = {}) {
// 配置
config = extend(true, {}, defaultConfig, config);
// 拦截器
interceptors = Object.assign({}, defaultInterceptors, interceptors);
/**
* @description: 请求方法
* @param {defaultConfig} options
* @return {Promise}
*/
const request = function request(options = {}) {
options = extend(true, {}, config, options);
// 显示loading
if (options.showLoading && options.useDefaultLoading) {
loading.show(options.loadingText, options.loadingTime);
}
// 创建 promise
const promise = new Promise((resolve, reject) => {
// 执行请求前拦截器
Promise.resolve(interceptors.request(options)).then(newOptions => {
// 获取新的options
options = getTypeValue(newOptions, Object, options);
// method转大写
options.method = options.method.toUpperCase();
// 路径参数赋值
if (options.url && options.urlParams) {
options.url = options.url.replace(/{([^{}}]+)}/g, (_str, k) => options.urlParams[k]);
}
// 判断url是否携带域名,然后拼接域名
if (!/^(https|http|\/{2})/.test(options.url)) {
options.url = mergePath(options.baseURL, options.url);
}
// 去除无效参数
if (getType(options.data) === 'object') {
const data = JSON.parse(JSON.stringify(options.data));
const isUrlParams = ['GET', 'DELETE', 'PATCH'].includes(options.method);
Object.keys(data).forEach(k => {
const value = data[k];
if ([undefined, null].includes(value)) {
// 如果属性值为undefined或null,则直接移除属性
delete data[k];
} else if (isUrlParams && typeof value === 'string' && !value.trim()) {
// 如果是'GET', 'DELETE', 'PATCH'请求方式,则移除值为空字符串的属性
delete data[k];
}
});
options.data = data;
}
// 发起请求
const createTask = () => {
options.getTask = getTypeValue(options.getTask, Function, defaultConfig.getTask);
options.validateStatus = getTypeValue(options.validateStatus, Function, defaultConfig.validateStatus);
options.getTask(uni.request(Object.assign({}, options, {
success: noop,
fail: noop,
complete(res) {
// 判断请求状态
if (options.validateStatus(res, options)) {
resolve(res.data);
} else {
const { statusCode, errMsg } = res;
let msg = failMap[statusCode];
if (!msg) {
if (errMsg.indexOf('timeout') > -1) {
msg = '请求超时';
} else if (errMsg.indexOf('request:fail') > -1) {
msg = '请求异常';
} else {
msg = errMsg;
}
}
if (statusCode) msg = statusCode + ` ${msg}`;
reject(createError(msg, statusCode));
}
},
})));
};
// 判断是否延时发起请求
if (options.delayTime > 0) {
setTimeout(createTask, options.delayTime);
} else {
createTask();
}
}).catch(error => reject(createError(error)));
}).then(
data => {
// 执行请求成功拦截器
return interceptors.success({ options, data, createError, createSuccess });
},
error => {
if (options.showError && options.useDefaultToast) {
toast({ message: error.message, duration: options.toastTime });
}
// 执行请求失败拦截器
return interceptors.fail({ options, error, createError, createSuccess });
},
).finally(() => {
// 关闭loading
if (options.showLoading && options.useDefaultLoading) {
loading.hide();
}
});
// 执行参数上的回调方法
promise.then(res => {
typeof options.success === 'function' && options.success(res);
typeof options.complete === 'function' && options.complete(res);
}).catch(err => {
typeof options.fail === 'function' && options.fail(err);
typeof options.complete === 'function' && options.complete(err);
});
// 返回 promise
return promise;
};
// 增加属性方法
['get', 'post', 'put', 'delete', 'head', 'trace', 'options', 'connect'].map(method => {
request[method] = (url, data, options) => request({
method,
url,
data,
...options,
});
});
return request;
}