long
2024-06-26 911e0ed72a790ba054385ffe594262e123948691
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
/**
 * Http 请求
 * * 小程序请使用增强编译
 *
 * 调用例子
 * Req.http.post({
 *     url: '',
 *     data: {},
 * })
 */
 
import Axios from '../libs/axios'
 
/* json转formdata(序列化),仅支持一级字面量和字面量数组 */
function jsonToFormData(json) {
  var arr = []
  var e = encodeURIComponent
  for (var key in json) {
    var item = json[key]
    var res
    if (item instanceof Array) {
      res = []
      item.map(function(o) {
        res.push(e(key) + '=' + e(o))
      })
      res = res.join('&')
    } else {
      res = e(key) + '=' + e(item)
    }
    arr.push(res)
  }
  return arr.join('&')
}
 
/**
 * Http 类
 * @param http_option {Object}
 * -@key {string}   baseUrl --请求链接前置
 * -@key {object}   getChangeRequestParameter --get请求参数
 * -@key {object}   postChangeRequestParameter --post请求参数
 * -@key {function} beforeRequest --请求前处理
 * -@key {function} beforeFlow --请求前流程
 * -@key {function} successChangeData --请求完成后,处理数据
 * -@key {function} httpEventCode --请求完成后,处理委托
 * -@key {function} afterFlow --请求完成后流程
 * -@key {function} afterRequest --请求后事件
 * -@key {function} afterMultiRequests --同时多次请求完成之后 
 */
function Http (http_option) {
    // 请求配置数组,标记是否批量请求
    var requestArr = []
    // 请求总线
    function Request (request_option) {
        // 默认 data 为对象
        request_option.data = request_option.data || {}
        // 请求配置加入数组
        requestArr.push(request_option)
 
        // 触发请求前事件
        if (http_option.beforeRequest) {
            http_option.beforeRequest({http_option, request_option})
        }
        // 使用 promise 完成请求
        return new Promise ((resolve, reject) => {
            // vue-cli中改用mockjs
            // mock假数据流程
            // 20210121 - 暂停使用mockjs
            if (http_option.mockFlow && http_option.ismock) {
                resolve(http_option.mockFlow({http_option, Request, request_option}))
                return 
            }
            // 请求前自定义流程
            if (http_option.beforeFlow && !request_option.skip_before_flow) {
                // skip 为 true 时,不仅如此此流程
                requestArr.splice(0, 1)
                resolve(http_option.beforeFlow({http_option, Request, request_option}))
                return
            }
            var url = request_option.url
            if (!url) {
                throw new Error('url不能为空')
            }
            // 不增加domain设定
            if (request_option.udData && request_option.udData.nodomain) {
                if (!/^https?:\/\//.test(url)) {
                    // 使用本项目域名
                    if (/^\//.test(url)) {
                        url = location.origin + url
                    } else {
                        // 修复访问本地json问题
                        url = location.origin + location.pathname.replace('index.html', '') + url
                    }
                }
            } else if (!/^https?:\/\//.test(url)) {
                url = http_option.baseUrl + url
            }
            // 定义请求配置
            var request_config = {
                method: request_option.method,
                url,
                data: request_option.data,
                header: request_option.header || {'Content-type':'application/x-www-form-urlencoded'},
                // 请求成功
                success (res) {
                    // 请求成功后,处理数据
                    if (http_option.successChangeData) {
                        res = http_option.successChangeData(res)
                    }
                    // 触发 code 委托事件
                    if (http_option.httpEventCode && http_option.httpEventCode['code'+res.status]) {
                        http_option.httpEventCode['code'+res.status](res);
                    }
                    // 请求后自定义流程
                    if (http_option.afterFlow) {
                        resolve(http_option.afterFlow({
                            res,
                            request_config,
                            request_option,
                            http_option,
                            Request,
                        }))
                    }
                    // 触发请求后事件
                    if (http_option.afterRequest) {
                        http_option.afterRequest({http_option, res})
                    }
 
                    if (request_option.udData) {
                        // 返回全部数据
                        if (request_option.udData.fullData === true) {
                            resolve(res)
                        }
                    }
                    resolve(res.data)
                },
 
                // 请求失败
                fail (err) {
                    // console.error(err)
                    var code = err.response && err.response.status
                    // 触发 code 委托事件
                    if (code && http_option.httpEventCode && http_option.httpEventCode['code'+code]) {
                        http_option.httpEventCode['code'+code](err, url)
                    }
                    // alert('请求失败,错误代号:'+code)
                    reject(err)
                },
 
                // 无论成功或者失败都会执行
                complete () {
                    requestArr.splice(0, 1)
                    if (requestArr.length === 0) {
                        // http_option.debug && console.log('触发 afterMultiRequests', request_config)
                        // 批量请求全部完成,触发事件
                        if (http_option.afterMultiRequests) {
                            http_option.afterMultiRequests(request_option)
                        }
                    }
                }
            };
 
            // get 方法时,去掉 data
            if (request_option.method === 'GET') {
                delete request_config.data
            }
 
            // 打印请求信息
            http_option.debug && console.log('请求', request_config)
            // 处理header和data的关系
            if (request_config.header['Content-type'] == 'application/x-www-form-urlencoded') {
                request_config.data = request_config.data ? jsonToFormData(request_config.data) : {}
            }
 
            // 开始请求
            // wx.request(request_config)
            Axios({
                method: request_config.method,
                headers: request_config.header,
                url: request_config.url,
                data: request_config.data
            }).then((res) => {
                // http_option.debug && console.log('成功回调', res)
                request_config.success(res)
                request_config.complete(res)
            }).catch((res) => {
                // http_option.debug && console.log('失败回调', res)
                request_config.fail(res)
                request_config.complete(res)
            })
        })
    }
 
    var obj = {
        // get请求
        // @param get_option {Object} 请求配置
        // -@key url {String} 请求路径
        // -@key params {Object} 请求参数
        // -@key udData {Object} 自定义扩展字段
 
        // @return {Promise}
        get (get_option) {
            // 请求前,统一处理请求参数
            if (http_option.getChangeRequestOption) {
                get_option = http_option.getChangeRequestOption(get_option)
            }
 
            // params对象序列化到url中
            if (get_option.params) {
                let arr = []
                for (let i in get_option.params) {
                    if (get_option.params.hasOwnProperty(i)) {
                        arr.push(encodeURIComponent(i) + '=' + encodeURIComponent(get_option.params[i]))
                    }
                }
                if (/\?/.test(get_option.url)) {
                    get_option.url += '&' + arr.join('&')
                } else {
                    get_option.url += '?' + arr.join('&')
                }
                
            }
 
            // 使用promise完成Request调用
            return new Promise ((resolve, reject) => {
                Request({
                    method: 'GET',
                    url: get_option.url,
                    udData: get_option.udData,
                    header: get_option.header,
                    mockData: get_option.mockData,
                }).then((data) => {
                    resolve(data)
                }).catch((res)=>{
                    // ↓↓↓↓↓↓↓↓↓↓ 临时处理失败
                    // var junPage = getApp().getCurPage()
                    // junPage = junPage && junPage.selectComponent('#junPage')
                    // if (junPage && junPage.fail) {
                    //     console.log('设置fail')
                    //     junPage.fail()
                    // }
                    // ↑↑↑↑↑↑↑↑↑↑ 临时处理失败
                    reject(res)
                })
            })
        },
 
        // post请求
        // @param post_option {Object} 请求配置
        // -@key url {String} 请求路径
        // -@key data {Object} 请求参数
        // -@key udData {Object} 自定义扩展字段
 
        // @return {Promise}
        post (post_option) {
            // 请求前,统一处理请求参数
            if (http_option.postChangeRequestOption) {
                post_option = http_option.postChangeRequestOption(post_option)
            }
            // 使用promise完成Request调用
            return new Promise ((resolve, reject) => {
                Request({
                    method: 'POST',
                    url: post_option.url,
                    data: post_option.data,
                    udData: post_option.udData,
                    header: post_option.header,
                    mockData: post_option.mockData,
                }).then((data) => {
                    resolve(data)
                }).catch((res)=>{
                    // ↓↓↓↓↓↓↓↓↓↓ 临时处理失败
                    // var junPage = getApp().getCurPage()
                    // junPage = junPage && junPage.selectComponent('#junPage')
                    // if (junPage && junPage.fail) {
                    //     console.log('设置fail')
                    //     junPage.fail()
                    // }
                    // ↑↑↑↑↑↑↑↑↑↑ 临时处理失败
                    reject(res)
                })
            })
        }
    }
    obj.getFN = obj.get
    obj.postFN = obj.post
    return obj;
}
 
export default Http