import deepMerge from "../function/deepMerge"; 
 | 
import validate from "../function/test"; 
 | 
class Request { 
 | 
    // 设置全局默认配置 
 | 
    setConfig(customConfig) { 
 | 
        // 深度合并对象,否则会造成对象深层属性丢失 
 | 
        this.config = deepMerge(this.config, customConfig); 
 | 
    } 
 | 
  
 | 
    // 主要请求部分 
 | 
    request(options = {}) { 
 | 
        // 检查请求拦截 
 | 
        if (this.interceptor.request && typeof this.interceptor.request === 'function') { 
 | 
            let tmpConfig = {}; 
 | 
            let interceptorRequest = this.interceptor.request(options); 
 | 
            if (interceptorRequest === false) { 
 | 
                // 返回一个处于pending状态中的Promise,来取消原promise,避免进入then()回调 
 | 
                return new Promise(()=>{}); 
 | 
            } 
 | 
            this.options = interceptorRequest; 
 | 
        } 
 | 
        options.dataType = options.dataType || this.config.dataType; 
 | 
        options.responseType = options.responseType || this.config.responseType; 
 | 
        options.url = options.url || ''; 
 | 
        options.params = options.params || {}; 
 | 
        options.header = Object.assign({}, this.config.header, options.header); 
 | 
        options.method = options.method || this.config.method; 
 | 
  
 | 
        return new Promise((resolve, reject) => { 
 | 
            options.complete = (response) => { 
 | 
                // 请求返回后,隐藏loading(如果请求返回快的话,可能会没有loading) 
 | 
                uni.hideLoading(); 
 | 
                // 清除定时器,如果请求回来了,就无需loading 
 | 
                clearTimeout(this.config.timer); 
 | 
                this.config.timer = null; 
 | 
                // 判断用户对拦截返回数据的要求,如果originalData为true,返回所有的数据(response)到拦截器,否则只返回response.data 
 | 
                if(this.config.originalData) { 
 | 
                    // 判断是否存在拦截器 
 | 
                    if (this.interceptor.response && typeof this.interceptor.response === 'function') { 
 | 
                        let resInterceptors = this.interceptor.response(response); 
 | 
                        // 如果拦截器不返回false,就将拦截器返回的内容给this.$u.post的then回调 
 | 
                        if (resInterceptors !== false) { 
 | 
                            resolve(resInterceptors); 
 | 
                        } else { 
 | 
                            // 如果拦截器返回false,意味着拦截器定义者认为返回有问题,直接接入catch回调 
 | 
                            reject(response); 
 | 
                        } 
 | 
                    } else { 
 | 
                        // 如果要求返回原始数据,就算没有拦截器,也返回最原始的数据 
 | 
                        resolve(response); 
 | 
                    } 
 | 
                } else { 
 | 
                    if (response.statusCode == 200) { 
 | 
                        if (this.interceptor.response && typeof this.interceptor.response === 'function') { 
 | 
                            let resInterceptors = this.interceptor.response(response.data); 
 | 
                            if (resInterceptors !== false) { 
 | 
                                resolve(resInterceptors); 
 | 
                            } else { 
 | 
                                reject(response.data); 
 | 
                            } 
 | 
                        } else { 
 | 
                            // 如果不是返回原始数据(originalData=false),且没有拦截器的情况下,返回纯数据给then回调 
 | 
                            resolve(response.data); 
 | 
                        } 
 | 
                    } else { 
 | 
                        // 不返回原始数据的情况下,服务器状态码不为200,modal弹框提示 
 | 
                        // if(response.errMsg) { 
 | 
                        //     uni.showModal({ 
 | 
                        //         title: response.errMsg 
 | 
                        //     }); 
 | 
                        // } 
 | 
                        reject(response) 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
  
 | 
            // 判断用户传递的URL是否/开头,如果不是,加上/,这里使用了uView的test.js验证库的url()方法 
 | 
            options.url = validate.url(options.url) ? options.url : (this.config.baseUrl + (options.url.indexOf('/') == 0 ? 
 | 
                options.url : '/' + options.url)); 
 | 
             
 | 
            // 是否显示loading 
 | 
            // 加一个是否已有timer定时器的判断,否则有两个同时请求的时候,后者会清除前者的定时器id 
 | 
            // 而没有清除前者的定时器,导致前者超时,一直显示loading 
 | 
            if(this.config.showLoading && !this.config.timer) { 
 | 
                this.config.timer = setTimeout(() => { 
 | 
                    uni.showLoading({ 
 | 
                        title: this.config.loadingText, 
 | 
                        mask: this.config.loadingMask 
 | 
                    }) 
 | 
                    this.config.timer = null; 
 | 
                }, this.config.loadingTime); 
 | 
            } 
 | 
            uni.request(options); 
 | 
        }) 
 | 
        // .catch(res => { 
 | 
        //     // 如果返回reject(),不让其进入this.$u.post().then().catch()后面的catct() 
 | 
        //     // 因为很多人都会忘了写后面的catch(),导致报错捕获不到catch 
 | 
        //     return new Promise(()=>{}); 
 | 
        // }) 
 | 
    } 
 | 
  
 | 
    constructor() { 
 | 
        this.config = { 
 | 
            baseUrl: '', // 请求的根域名 
 | 
            // 默认的请求头 
 | 
            header: {}, 
 | 
            method: 'POST', 
 | 
            // 设置为json,返回后uni.request会对数据进行一次JSON.parse 
 | 
            dataType: 'json', 
 | 
            // 此参数无需处理,因为5+和支付宝小程序不支持,默认为text即可 
 | 
            responseType: 'text', 
 | 
            showLoading: true, // 是否显示请求中的loading 
 | 
            loadingText: '请求中...', 
 | 
            loadingTime: 800, // 在此时间内,请求还没回来的话,就显示加载中动画,单位ms 
 | 
            timer: null, // 定时器 
 | 
            originalData: false, // 是否在拦截器中返回服务端的原始数据,见文档说明 
 | 
            loadingMask: true, // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透 
 | 
        } 
 | 
     
 | 
        // 拦截器 
 | 
        this.interceptor = { 
 | 
            // 请求前的拦截 
 | 
            request: null, 
 | 
            // 请求后的拦截 
 | 
            response: null 
 | 
        } 
 | 
  
 | 
        // get请求 
 | 
        this.get = (url, data = {}, header = {}) => { 
 | 
            return this.request({ 
 | 
                method: 'GET', 
 | 
                url, 
 | 
                header, 
 | 
                data 
 | 
            }) 
 | 
        } 
 | 
  
 | 
        // post请求 
 | 
        this.post = (url, data = {}, header = {}) => { 
 | 
            return this.request({ 
 | 
                url, 
 | 
                method: 'POST', 
 | 
                header, 
 | 
                data 
 | 
            }) 
 | 
        } 
 | 
         
 | 
        // put请求,不支持支付宝小程序(HX2.6.15) 
 | 
        this.put = (url, data = {}, header = {}) => { 
 | 
            return this.request({ 
 | 
                url, 
 | 
                method: 'PUT', 
 | 
                header, 
 | 
                data 
 | 
            }) 
 | 
        } 
 | 
         
 | 
        // delete请求,不支持支付宝和头条小程序(HX2.6.15) 
 | 
        this.delete = (url, data = {}, header = {}) => { 
 | 
            return this.request({ 
 | 
                url, 
 | 
                method: 'DELETE', 
 | 
                header, 
 | 
                data 
 | 
            }) 
 | 
        } 
 | 
    } 
 | 
} 
 | 
export default new Request 
 |