request.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import axios from 'axios'
  2. import { ElNotification, ElMessageBox, ElMessage, ElLoading } from 'element-plus'
  3. import { getToken, getTenant } from '@/utils/auth'
  4. import errorCode from '@/utils/errorCode'
  5. import { tansParams, blobValidate } from '@/utils/ruoyi'
  6. import cache from '@/plugins/cache'
  7. import { saveAs } from 'file-saver'
  8. import useUserStore from '@/store/modules/user'
  9. let downloadLoadingInstance
  10. // 是否显示重新登录
  11. export let isRelogin = { show: false }
  12. axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
  13. // 创建axios实例
  14. const service = axios.create({
  15. // axios中请求配置有baseURL选项,表示请求URL公共部分
  16. // 因为对应了多个后端服务,这里不要统一定义前缀
  17. baseURL: '', //import.meta.env.VITE_APP_BASE_API
  18. // 超时
  19. timeout: 100000
  20. })
  21. // request拦截器
  22. service.interceptors.request.use(
  23. (config) => {
  24. // 是否需要设置 token
  25. const isToken = (config.headers || {}).isToken === false
  26. // 是否需要防止数据重复提交
  27. const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
  28. if (getToken() && !isToken) {
  29. config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
  30. }
  31. const tenantInfo = getTenant()
  32. if (tenantInfo) {
  33. config.headers['tenantId'] = tenantInfo.tenantId
  34. }
  35. // appKey 根据该值,获取菜单,不要修改
  36. config.headers['appKey'] = 'ezhizao-identity'
  37. // get请求映射params参数
  38. if (config.method === 'get' && config.params) {
  39. let url = config.url + '?' + tansParams(config.params)
  40. url = url.slice(0, -1)
  41. config.params = {}
  42. config.url = url
  43. }
  44. if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
  45. const requestObj = {
  46. url: config.url,
  47. data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
  48. time: new Date().getTime()
  49. }
  50. const sessionObj = cache.session.getJSON('sessionObj')
  51. if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
  52. cache.session.setJSON('sessionObj', requestObj)
  53. } else {
  54. const s_url = sessionObj.url // 请求地址
  55. const s_data = sessionObj.data // 请求数据
  56. const s_time = sessionObj.time // 请求时间
  57. const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交
  58. if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
  59. const message = '数据正在处理,请勿重复提交'
  60. console.warn(`[${s_url}]: ` + message)
  61. return Promise.reject(new Error(message))
  62. } else {
  63. cache.session.setJSON('sessionObj', requestObj)
  64. }
  65. }
  66. }
  67. return config
  68. },
  69. (error) => {
  70. console.log(error)
  71. Promise.reject(error)
  72. }
  73. )
  74. // 响应拦截器
  75. service.interceptors.response.use(
  76. (res) => {
  77. // 未设置状态码则默认成功状态
  78. const code = res.data.code || 200
  79. // 获取错误信息
  80. const msg = errorCode[code] || res.data.msg || errorCode['default']
  81. // 二进制数据则直接返回
  82. if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
  83. return res.data
  84. }
  85. if (code === 401) {
  86. if (!isRelogin.show) {
  87. isRelogin.show = true
  88. ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
  89. confirmButtonText: '重新登录',
  90. cancelButtonText: '取消',
  91. type: 'warning'
  92. })
  93. .then(() => {
  94. isRelogin.show = false
  95. useUserStore()
  96. .logOut()
  97. .then(() => {
  98. location.href = '/index'
  99. })
  100. })
  101. .catch(() => {
  102. isRelogin.show = false
  103. })
  104. }
  105. return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
  106. } else if (code === 500) {
  107. ElMessage({ message: msg, type: 'error' })
  108. return Promise.reject(new Error(msg))
  109. } else if (code === 601) {
  110. ElMessage({ message: msg, type: 'warning' })
  111. return Promise.reject(new Error(msg))
  112. } else if (code !== 200) {
  113. ElNotification.error({ title: msg })
  114. return Promise.reject('error')
  115. } else {
  116. return Promise.resolve(res.data)
  117. }
  118. },
  119. (error) => {
  120. console.log('err' + error)
  121. let { message } = error
  122. if (message == 'Network Error') {
  123. message = '后端接口连接异常'
  124. } else if (message.includes('timeout')) {
  125. message = '系统接口请求超时'
  126. } else if (message.includes('Request failed with status code')) {
  127. message = '系统接口' + message.substr(message.length - 3) + '异常'
  128. }
  129. ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
  130. return Promise.reject(error)
  131. }
  132. )
  133. // 通用下载方法
  134. export function download(url, params, filename, config) {
  135. downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' })
  136. return service
  137. .post(url, params, {
  138. transformRequest: [
  139. (params) => {
  140. return tansParams(params)
  141. }
  142. ],
  143. headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  144. responseType: 'blob',
  145. ...config
  146. })
  147. .then(async (data) => {
  148. const isLogin = await blobValidate(data)
  149. if (isLogin) {
  150. const blob = new Blob([data])
  151. saveAs(blob, filename)
  152. } else {
  153. const resText = await data.text()
  154. const rspObj = JSON.parse(resText)
  155. const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
  156. ElMessage.error(errMsg)
  157. }
  158. downloadLoadingInstance.close()
  159. })
  160. .catch((r) => {
  161. console.error(r)
  162. ElMessage.error('下载文件出现错误,请联系管理员!')
  163. downloadLoadingInstance.close()
  164. })
  165. }
  166. // 通用pdf打印方法
  167. export function downloadPdf(url, params, filename, config) {
  168. downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)", })
  169. return service.post(url, params, {
  170. transformRequest: [(params) => { return tansParams(params) }],
  171. headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  172. responseType: 'blob',
  173. ...config
  174. }).then(async (data) => {
  175. const isLogin = await blobValidate(data);
  176. if (isLogin) {
  177. const blob = new Blob([data], { type: 'application/pdf' })
  178. var url = URL.createObjectURL(blob);
  179. window.open(url, 'filename');
  180. } else {
  181. const resText = await data.text();
  182. const rspObj = JSON.parse(resText);
  183. const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
  184. ElMessage.error(errMsg);
  185. }
  186. downloadLoadingInstance.close();
  187. }).catch((r) => {
  188. console.error(r)
  189. ElMessage.error('下载文件出现错误,请联系管理员!')
  190. downloadLoadingInstance.close();
  191. })
  192. }
  193. export default service