liweilong
2020-12-24 c95579f945a795138fc85a59246c97a21ce8a45e
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
const axios = require('axios')
import { Message } from 'element-ui'
import { getToken } from '@/utils/auth'
function isF() { return typeof arguments[0] === 'function' }
 
/* 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('&')
}
 
function Http(http_o) {
  // 返回值 Object
  // 参数说明
  // o.baseUrl 这个参数根据传入的基础路径会初始化http中的所有请求方法
  // ... 待扩展
  var requestArr = [] // 请求次数
  return {
    // 这个对象是包含全部所有的请求
    postFN(post_o, successCallBack, failCallBack) {
      // post 方法
      // 参数说明
      // post_o.url 指的是请求的路径
      // post_o.baseChgUrl 可动态切换的接口
      // params 接受 对象序列化 传参 即 将传入的 params(对象) 参数  序列化为 url 传参的方式如 xxx.com/api?id=1212&name=456
      // udData Object:即userDefined Data 用户自定义数据,这是一个扩展字段
      // mockData Object 测试数据
      Request({
        method: 'post',
        header: post_o.header,
        params: post_o.params || false,
        url: post_o.url,
        baseChgUrl: post_o.baseChgUrl, // 动态切换接口
        udData: post_o.udData, // 预留扩展字段
        mockData: post_o.mockData // 测试数据
      }).then(data => {
        console.log('请求:', post_o.url, data, post_o.params)
        // 登录失效
        if (Number(data.code) === 603) {
          Message({
            type: 'error',
            showClose: true,
            duration: 10000,
            message: data.msg
          })
          setTimeout(() => {
            sessionStorage.clear()
            // 未登录,刷新页面出发页面 checkLoginFN跳转登录页面
            location.reload()
          }, 800)
          return
        }
 
        // todo 无code时的报错
        if (Number(data.code) === 100) {
          // 请求成功
          isF(successCallBack) && successCallBack(data.data)
        } else {
          // 请求失败
          if (isF(failCallBack)) {
            failCallBack(data)
          } else {
            Message({
              type: 'error',
              showClose: true,
              duration: 10000,
              message: data.msg
            })
          }
        }
      })
    },
    getFN(get_o, successCallBack, failCallBack) {
      // get 方法
      // 参数说明
      // get_o.url 指的是请求的路径
      // get_o.baseChgUrl 可动态切换的接口
      // params 接受 对象序列化 传参 即 将传入的 params(对象) 参数  序列化为 url 传参的方式如 xxx.com/api?id=1212&name=456
      // udData Object:即userDefined Data 用户自定义数据,这是一个扩展字段
      // mockData Object 测试数据
      Request({
        method: 'get',
        header: get_o.header,
        params: get_o.params || false,
        url: get_o.url,
        baseChgUrl: get_o.baseChgUrl, // 动态切换接口
        udData: get_o.udData, // 预留扩展字段
        mockData: get_o.mockData // 测试数据
      }).then(data => {
        console.log('请求:', get_o.url, data, get_o.params)
        // 登录失效
        if (Number(data.code) === 603) {
          Message({
            type: 'error',
            showClose: true,
            duration: 10000,
            message: data.msg
          })
          setTimeout(() => {
            sessionStorage.clear()
            // 未登录,刷新页面出发页面 checkLoginFN跳转登录页面
            location.reload()
          }, 800)
          return
        }
 
        if (Number(data.code) === 100) {
          // 请求成功
          isF(successCallBack) && successCallBack(data.inf)
        } else {
          // 请求失败
          if (isF(failCallBack)) {
            failCallBack(data)
          } else {
            Message({
              type: 'error',
              showClose: true,
              duration: 10000,
              message: data.msg
            })
          }
        }
      })
    }
  }
 
  function Request(request_o) {
    // 总请求方法,这是一个被独立处理出来的方法,因为这个方法是一个比较特殊的方法,首先这个方法不应被暴露出来,
    // 然后因为根据项目的独特性,最底层的拦截、加密、权限的实现和代码都有所不同,这里应该独立处理,方便以后移植和复用
    // 这个方法是所有请求方法的底层方法,具有错误码拦截,权限管理(鉴权)等 拦截的功能
    // 返回值 Object
    // 参数说明
    // o.method 请求类型
    // o.url 请求路径
    // o.params 请求参数
    // o.baseUrl 基本路径
    // udData Object:即userDefined Data 用户自定义数据,这是一个扩展字段
    //              fullData 这个字段为真的话,将返回 服务端返回的所有数据,默认返回data
    requestArr.push(request_o) // 将请求加入数组
    if (http_o.startRequest) {
      http_o.startRequest(http_o, request_o) // 事件委托,请求之前
    }
    return new Promise((resolve, reject) => {
      // 添加切换调用接口域名功能 -- start
      var ajaxUrl
      if (request_o.baseChgUrl) {
        ajaxUrl = request_o.baseChgUrl + request_o.url
      } else {
        ajaxUrl = http_o.baseUrl + request_o.url
      }
      // 添加切换调用接口域名功能 -- end
 
      // 处理传参 -- start
      // 将token放到params里
      var noToken = request_o.udData && request_o.udData.noToken // noToken则不传token
      var adminToken = getToken()
      // 放到连接后得请求参数
 
      var urlEncodes = {}
      if (adminToken && !noToken) {
        urlEncodes = { adminToken: adminToken }
        // ...urlEncodes,
      }
      // // 将请求参数放到链接后面
      var paramsUrl = urlEncode(urlEncodes)
      if(!/\?/.test(ajaxUrl)) {
          paramsUrl = paramsUrl.replace('&', '?')
      }
      ajaxUrl = ajaxUrl + paramsUrl
 
      // console.log(ajaxUrl)
      // console.log(request_o.params)
      // 处理传参 -- end
 
      // request_o.params.adminToken = adminToken
 
      var requestConfig = {
        // 請求對象
        method: request_o.method,
        url: ajaxUrl,
        data: request_o.params,
        header: request_o.header || {
          'Content-type': 'application/x-www-form-urlencoded' // 默认值
        }
      }
 
      // 转formData
      if (requestConfig.header['Content-type'] === 'application/x-www-form-urlencoded') {
        requestConfig.data = requestConfig.data ? jsonToFormData(requestConfig.data) : {}
      }
 
      // 使用测试数据
      if (http_o.isMock) {
        console.log('开始模拟等待800ms')
        // 模拟请求
        if (http_o.httpEventCode && http_o.httpEventCode['code200']) {
          http_o.httpEventCode['code200'](request_o.mockData) // 事件委托,处理错误
        }
        if (http_o.endRequest) {
          http_o.endRequest({ ...http_o, ...request_o.mockData }) // 事件委托,请求之前
        }
        setTimeout(() => {
          console.log('结束模拟等待800ms')
          resolve(request_o.mockData)
 
          // 无论成功或者失败都会执行
          requestArr.splice(0, 1)
          if (requestArr.length === 0) {
            // 批量请求全部完成
            if (http_o.concurrentRequests) {
              http_o.concurrentRequests()
            }
          }
        }, 800)
        return
      }
 
      axios(requestConfig).then((res) => {
        if (http_o.httpEventCode && http_o.httpEventCode['code' + res.status]) {
          http_o.httpEventCode['code' + res.status](res) // 事件委托,处理错误
        }
        if (http_o.endRequest) {
          http_o.endRequest({ ...http_o, ...res }) // 事件委托,请求之前
        }
        if (http_o.defindFlow) {
          // 自定义流程
          resolve(http_o.defindFlow({ requestConfig: requestConfig, res: res, Request: Request }))
        }
        if (request_o.udData && request_o.udData.fullData === true) {
          // 如果这里的fullData 为真的话,将返回服务器返回的所有数据
          resolve(res)
        }
        resolve(res.data)
      }).catch((err) => {
        // console.log('异步报错:',err);
        var code
        err.response && (code = err.response.status) // 请求错误码
        if (http_o.httpEventCode && http_o.httpEventCode['code' + code]) {
          http_o.httpEventCode['code' + code](err) // 事件委托,处理错误
        }
        reject(err)
      }).finally(() => {
        // 无论成功或者失败都会执行
        requestArr.splice(0, 1)
        if (requestArr.length === 0) {
          // 批量请求全部完成
          if (http_o.concurrentRequests) {
            http_o.concurrentRequests()
          }
        }
      })
    })
  }
 
  // 对象转url参数
  function urlEncode(param, key, encode) {
    if (param == null) return ''
    var paramStr = ''
    var t = typeof (param)
    if (t === 'string' || t === 'number' || t === 'boolean') {
      paramStr += '&' + key + '=' + ((encode == null || encode) ? encodeURIComponent(param) : param)
    } else {
      for (var i in param) {
        var k = key == null ? i : key + (param instanceof Array ? '[' + i + ']' : '.' + i)
        paramStr += urlEncode(param[i], k, encode)
      }
    }screenLeft
    return paramStr
  }
}
export { Http }