request.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. import axios from 'axios'
  2. import store from '@/store'
  3. import {
  4. MessageBox
  5. } from 'element-ui'
  6. import {
  7. getToken
  8. } from '@/utils/token'
  9. import {
  10. DES3
  11. } from '@/utils/3des'
  12. import {
  13. parseTime
  14. } from '@/utils/index'
  15. import router from '@/router/index'
  16. import {
  17. ElMessage
  18. } from '../utils/message.js'
  19. const Message = new ElMessage()
  20. const requestList = [] // 请求列表
  21. const CancelToken = axios.CancelToken
  22. const sources = {}
  23. const successCode = '000000000' | '0000000' // 成功编码
  24. // axios配置
  25. // 全局的 axios 默认值:指定将被用在各个请求的配置默认值
  26. axios.defaults.timeout = 20000 // 设置超时时间
  27. axios.defaults.baseURL = process.env.VUE_APP_BASE_API // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
  28. // axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;//根据项目需要配置
  29. axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded' // 设置请求头的类型
  30. // 添加请求拦截器
  31. axios.interceptors.request.use(config => {
  32. const request = JSON.stringify(config.url) + (config.data ? JSON.stringify(config.data) : JSON.stringify(config.params))
  33. config.cancelToken = new CancelToken((cancel) => {
  34. sources[request] = cancel
  35. })
  36. // 判断请求是否已存在请求列表,避免重复请求,将当前请求添加进请求列表数组;
  37. // if (requestList.includes(request)) {
  38. // console.log(request)
  39. // sources[request]('取消重复请求')
  40. // requestList.splice(requestList.findIndex(item => item === request), 1)
  41. // } else {
  42. // requestList.push(request)
  43. // }
  44. // 因本项目部分请求需要重复获取所以不用去重
  45. requestList.push(request)
  46. // 登录控制中根据本地是否存在token判断用户的登录情况,
  47. // 但即使token存在,也有可能token是过期的,所以在每次的请求头中携带token,
  48. // 后台根据携带的token判断用户的登录情况,并返回给我们对应的状态码,
  49. // 而后我们可以在响应拦截器中,根据状态码进行一些统一的操作。
  50. // 本项目不用请求头判断而是在报文体中发送token
  51. // let token = store.getters.token || getToken();
  52. // token && (config.headers.Authorization = token);
  53. return config
  54. }, error => Promise.reject(error))
  55. // 添加响应拦截器
  56. axios.interceptors.response.use(res => {
  57. const request = JSON.stringify(res.config.url) + (res.config.data ? JSON.stringify(res.config.data) : JSON.stringify(res.config.params))
  58. requestList.splice(requestList.findIndex(item => item === request), 1)
  59. if (res.status == 200) {
  60. const {
  61. data
  62. } = res
  63. if (data.returnCode == successCode) {
  64. return Promise.resolve(data)
  65. } else {
  66. if (data.returnMsg === '系统没有登录或会话超时!') {
  67. store.dispatch('user/changeState', {
  68. key: 'token',
  69. value: ''
  70. })
  71. store.dispatch('user/changeState', {
  72. key: 'name',
  73. value: ''
  74. })
  75. store.dispatch('user/changeState', {
  76. key: 'userId',
  77. value: ''
  78. })
  79. store.dispatch('user/changeState', {
  80. key: 'loginStatus',
  81. value: false
  82. })
  83. MessageBox.confirm('系统没有登录或会话超时, 是否登录?', '提示', {
  84. confirmButtonText: '登录',
  85. cancelButtonText: '取消',
  86. center: true,
  87. closeOnClickModal: false,
  88. type: 'warning'
  89. })
  90. .then(() => {
  91. MessageBox.close()
  92. router.replace(`/indexLayout/home?type=reLogin`)
  93. })
  94. .catch(() => {
  95. Message.info('已取消!')
  96. MessageBox.close()
  97. })
  98. }
  99. return Promise.reject(data)
  100. }
  101. } else {
  102. return Promise.reject(res)
  103. }
  104. }, err => {
  105. const {
  106. res
  107. } = err
  108. if (res) {
  109. // 请求已发出,但是不在2xx的范围
  110. requestList.length = 0
  111. errorHandle(res.status, res.data.message)
  112. return Promise.reject(res)
  113. } else {
  114. console.log(err)
  115. if (err.message === '取消上传') {
  116. return Promise.reject('cancel')
  117. }
  118. // 处理断网的情况
  119. // eg:请求超时或断网时,更新network状态,可在app.vue中控制着一个全局的断网提示组件的显示隐藏
  120. if (err.message === '取消重复请求') {
  121. // console.log(err)
  122. } else {
  123. const error = err.message.indexOf('timeout') != -1 ? {
  124. returnMsg: '请求超时'
  125. } : {
  126. returnMsg: '网络通讯异常'
  127. }
  128. requestList.splice(requestList.findIndex(item => item === request), 1)
  129. return Promise.reject(error)
  130. }
  131. }
  132. })
  133. // 完善请求url
  134. function getUrl(channelNo = 'service') {
  135. let url = ''
  136. if (channelNo === 'service') {
  137. url = '/TransServlet'
  138. } else if (channelNo === 'manager') {
  139. url = '/managersvr/TransServlet'
  140. }
  141. return url
  142. }
  143. // 配置上行报文公共包头
  144. function getParams(params, channelNo) {
  145. params['clientToken'] = store.getters.token || getToken()
  146. const userId = store.getters.userId
  147. if (userId) {
  148. params['userId'] = userId
  149. }
  150. params['transTime'] = parseTime(new Date().getTime(), '{y}-{m}-{d} {h}:{i}:{s} {t}')
  151. params['channelNo'] = channelNo
  152. return params
  153. }
  154. // 请求
  155. const request = (params, channelNo = 'service', method = 'post') => {
  156. const url = getUrl(channelNo) // 完善请求url
  157. params = getParams(params, channelNo) // 配置上行报文公共包头
  158. return new Promise((resolve, reject) => {
  159. if (method === 'post') {
  160. axios.post(url, params).then(res => {
  161. resolve(res)
  162. }).catch(err => {
  163. Message.error(err.returnMsg)
  164. reject(err)
  165. })
  166. } else if (method === 'get') {
  167. axios.get(url, {
  168. params
  169. }).then(res => {
  170. resolve(res)
  171. }).catch(err => {
  172. Message.error(err.returnMsg)
  173. reject(err)
  174. })
  175. }
  176. })
  177. }
  178. // 文件上传
  179. const uploadFile = (params, channelNo = 'service', callback1) => {
  180. const config = {
  181. timeout: 60000,
  182. headers: {
  183. 'Content-Type': 'multipart/form-data'
  184. },
  185. onUploadProgress: progressEvent => {
  186. // 属性lengthComputable主要表明总共需要完成的工作量和已经完成的工作是否可以被测量,如果lengthComputable为false,就获取不到progress.total和progress.loaded
  187. if (progressEvent.lengthComputable) {
  188. const loaded = progressEvent.loaded
  189. const total = progressEvent.total
  190. const progress = Math.floor((loaded / total) * 100) > 1 ? Math.floor((loaded / total) * 100) : 1
  191. // console.log('上传进度 ' + progress + '%');
  192. // callback1(progress)
  193. }
  194. }
  195. }
  196. const url = getUrl(channelNo) // 完善请求url
  197. params.append('clientToken', store.getters.token || getToken())
  198. params.append('userId', store.getters.userId)
  199. params.append('transTime', parseTime(new Date().getTime(), '{y}-{m}-{d} {h}:{i}:{s} {t}'))
  200. params.append('channelNo', channelNo) // 配置上行报文公共包头
  201. return new Promise((resolve, reject) => {
  202. axios.post(url, params, config).then(res => {
  203. resolve(res)
  204. }).catch(err => {
  205. if (err !== 'cancel') {
  206. Message.error(err.returnMsg)
  207. }
  208. reject(err)
  209. })
  210. })
  211. }
  212. // 获取图片验证码
  213. const getCode = (channelNo = 'service') => {
  214. const rand = Math.random()
  215. const token = store.getters.token || getToken()
  216. return process.env.VUE_APP_BASE_API + getUrl(channelNo) + '?transCode=HM0000&randomKey=' + rand + '&clientToken=' + token
  217. }
  218. // 获取图片Url
  219. const getImage = (id, channelNo = 'service') => {
  220. const token = store.getters.token || getToken()
  221. return process.env.VUE_APP_BASE_API + getUrl(channelNo) + '?transCode=B00022&clientToken=' + token + '&id=' + id
  222. }
  223. //download
  224. const download = (params, channelNo = 'service') => {
  225. let url = process.env.VUE_APP_BASE_API + getUrl(channelNo) + "?";
  226. Object.getOwnPropertyNames(params).forEach((key) => {
  227. url += '&' + key + '=' + params[key]
  228. })
  229. let link = document.createElement('a');
  230. link.style.display = 'none';
  231. link.href = url;
  232. link.target = '_blank';
  233. document.body.appendChild(link);
  234. link.click();
  235. document.body.removeChild(link);
  236. }
  237. // 加密密码
  238. const enPassword = (password) => {
  239. const token = store.getters.token || getToken()
  240. return DES3.encrypt(token, password)
  241. }
  242. // 解密密码
  243. const dePassword = (password) => {
  244. const token = store.getters.token || getToken()
  245. return DES3.decrypt(token, password)
  246. }
  247. export {
  248. request,
  249. uploadFile,
  250. getCode,
  251. getImage,
  252. download,
  253. enPassword,
  254. dePassword,
  255. sources
  256. }