request.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  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. import useSettingsStore from '@/store/modules/settings'
  10. import Notification from '../plugins/notification'
  11. // import emitter from '../eventBus'
  12. // import { getCurrentInstance } from 'vue';
  13. // import { reject } from 'lodash-es'
  14. const beforeNotification = ['\/ezhizao-dms-sys\/getInfo', '\/ezhizao-dms-sys\/getRouters', '\/ezhizao-dms-sys\/system\/config\/configKey\/']
  15. const checkBeforeUrl = (url) => {
  16. let checked = false
  17. // console.log(url)
  18. beforeNotification.forEach(t => {
  19. let reg = new RegExp('^' + t)
  20. // console.log(t, reg.test(url))
  21. checked = checked || reg.test(url)
  22. })
  23. // console.log(checked)
  24. return checked
  25. }
  26. let downloadLoadingInstance
  27. // 是否显示重新登录
  28. export let isRelogin = { show: false }
  29. axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
  30. const preService = axios.create({
  31. baseURL: '',
  32. timeout: 1000,
  33. })
  34. // 创建axios实例
  35. const service = axios.create({
  36. // axios中请求配置有baseURL选项,表示请求URL公共部分
  37. // 因为对应了多个后端服务,这里不要统一定义前缀
  38. baseURL: '', //import.meta.env.VITE_APP_BASE_API
  39. // 超时
  40. timeout: 1000000,
  41. })
  42. // request拦截器
  43. service.interceptors.request.use(
  44. async (config) => {
  45. // 是否需要设置 token
  46. const isToken = (config.headers || {}).isToken === false
  47. // 是否需要防止数据重复提交
  48. const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
  49. if (getToken() && !isToken) {
  50. config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
  51. }
  52. const tenantInfo = getTenant()
  53. if (tenantInfo) {
  54. config.headers['tenantId'] = tenantInfo.tenantId
  55. }
  56. // appKey 根据该值,获取菜单,不要修改
  57. config.headers['appKey'] = 'ezhizao-identity'
  58. let requestable = true
  59. let notifications = []
  60. // 当登录状态为已登录时才可以获取公告
  61. // console.log(config)
  62. // console.log(checkBeforeUrl(config.url))
  63. if (getToken() && !isToken && tenantInfo && !checkBeforeUrl(config.url)) {
  64. // 所有条件都具备的情况下需先请求公告
  65. let url = import.meta.env.VITE_APP_BASE_API + '/business/notification/getUnshowedNotification'
  66. const showNotification = useSettingsStore().showNotification
  67. console.log('是否显示公告', showNotification)
  68. if (showNotification) {
  69. const res = await axios({
  70. url: url,
  71. method: 'get',
  72. headers: {
  73. Authorization: 'Bearer ' + getToken(),
  74. tenantId: getTenant().tenantId,
  75. appKey: 'ezhizao-identity'
  76. }
  77. })
  78. if (res.data.code == 200) {
  79. } else if (res.data.code == 202) {
  80. notifications = res.data.data
  81. requestable = false
  82. // showDialog()
  83. }
  84. }
  85. //
  86. }
  87. // get请求映射params参数
  88. if (config.method === 'get' && config.params) {
  89. let url = config.url + '?' + tansParams(config.params)
  90. url = url.slice(0, -1)
  91. config.params = {}
  92. config.url = url
  93. }
  94. if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
  95. const requestObj = {
  96. url: config.url,
  97. data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
  98. time: new Date().getTime()
  99. }
  100. const sessionObj = cache.session.getJSON('sessionObj')
  101. if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
  102. cache.session.setJSON('sessionObj', requestObj)
  103. } else {
  104. const s_url = sessionObj.url // 请求地址
  105. const s_data = sessionObj.data // 请求数据
  106. const s_time = sessionObj.time // 请求时间
  107. const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交
  108. if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
  109. const message = '数据正在处理,请勿重复提交'
  110. console.warn(`[${s_url}]: ` + message)
  111. return Promise.reject(new Error(message))
  112. } else {
  113. cache.session.setJSON('sessionObj', requestObj)
  114. }
  115. }
  116. }
  117. return requestable ? config : Promise.reject({ message: 'SHOW NOTIFICATION', data: notifications })
  118. },
  119. (error) => {
  120. console.log(error)
  121. Promise.reject(error)
  122. }
  123. )
  124. // 响应拦截器
  125. service.interceptors.response.use(
  126. (res) => {
  127. // 未设置状态码则默认成功状态
  128. const code = res.data.code || 200
  129. // 获取错误信息
  130. const msg = errorCode[code] || res.data.msg || errorCode['default']
  131. // 二进制数据则直接返回
  132. if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
  133. return res.data
  134. }
  135. if (code === 401) {
  136. if (!isRelogin.show) {
  137. isRelogin.show = true
  138. ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
  139. confirmButtonText: '重新登录',
  140. cancelButtonText: '取消',
  141. type: 'warning'
  142. })
  143. .then(() => {
  144. isRelogin.show = false
  145. useUserStore()
  146. .logOut()
  147. .then(() => {
  148. location.href = '/index'
  149. })
  150. })
  151. .catch(() => {
  152. isRelogin.show = false
  153. })
  154. }
  155. return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
  156. } else if (code === 500) {
  157. ElMessage({ message: msg, type: 'error' })
  158. return Promise.reject(new Error(msg))
  159. } else if (code === 601) {
  160. ElMessage({ message: msg, type: 'warning' })
  161. return Promise.reject(new Error(msg))
  162. } else if (code !== 200) {
  163. ElNotification.error({ title: msg })
  164. return Promise.reject('error')
  165. } else {
  166. return Promise.resolve(res.data)
  167. }
  168. },
  169. (error) => {
  170. // console.log(error)
  171. // console.log('err' + error)
  172. let { message, data } = error
  173. if (message == 'Network Error') {
  174. message = '后端接口连接异常'
  175. ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
  176. } else if (message.includes('timeout')) {
  177. message = '数据过多查询超时'
  178. ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
  179. } else if (message.includes('Request failed with status code')) {
  180. message = '系统接口' + message.substr(message.length - 3) + '异常'
  181. ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
  182. } else if (message.includes('SHOW NOTIFICATION')) {
  183. // showDialog(data)
  184. Notification(data[0])
  185. } else {
  186. ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
  187. }
  188. return Promise.reject(error)
  189. }
  190. )
  191. // 通用下载方法
  192. export function download(url, params, filename, config) {
  193. downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' })
  194. return service
  195. .post(url, params, {
  196. transformRequest: [
  197. (params) => {
  198. return tansParams(params)
  199. }
  200. ],
  201. headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  202. responseType: 'blob',
  203. ...config
  204. })
  205. .then(async (data) => {
  206. const isLogin = await blobValidate(data)
  207. if (isLogin) {
  208. const blob = new Blob([data])
  209. saveAs(blob, filename)
  210. } else {
  211. const resText = await data.text()
  212. const rspObj = JSON.parse(resText)
  213. const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
  214. ElMessage.error(errMsg)
  215. }
  216. downloadLoadingInstance.close()
  217. })
  218. .catch((r) => {
  219. console.error(r)
  220. ElMessage.error('下载文件出现错误,请联系管理员!')
  221. downloadLoadingInstance.close()
  222. })
  223. }
  224. // 通用pdf打印方法
  225. export function downloadPdf(url, params, filename, config) {
  226. downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)", })
  227. return service.post(url, params, {
  228. transformRequest: [(params) => { return tansParams(params) }],
  229. headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  230. responseType: 'blob',
  231. ...config
  232. }).then(async (data) => {
  233. const isLogin = await blobValidate(data);
  234. if (isLogin) {
  235. const blob = new Blob([data], { type: 'application/pdf' })
  236. var url = URL.createObjectURL(blob);
  237. window.open(url, 'filename');
  238. } else {
  239. const resText = await data.text();
  240. const rspObj = JSON.parse(resText);
  241. const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
  242. ElMessage.error(errMsg);
  243. throw new Error(errMsg);
  244. }
  245. downloadLoadingInstance.close();
  246. }).catch((r) => {
  247. console.error(r)
  248. ElMessage.error('下载文件出现错误,请联系管理员!')
  249. downloadLoadingInstance.close();
  250. throw new Error(r);
  251. })
  252. }
  253. function showDialog(message) {
  254. // console.log(message, emitter)
  255. // emitter.emit('show-dialog', message)
  256. console.log(emitter)
  257. // const instance = getCurrentInstance();
  258. // console.log(instance)
  259. // if (instance && instance.proxy && instance.proxy.showNotification) {
  260. // instance.proxy.showNotification(message);
  261. // } else {
  262. // console.error('Cannot show dialog: current instance is null or $showDialog is not available.');
  263. // }
  264. }
  265. export default service