Bonus-AI-LargeScreen/src/utils/request.js

216 lines
7.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import axios from 'axios'
import { Loading, Message, MessageBox, Notification } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { blobValidate, tansParams } from '@/utils/bonus'
import cache from '@/plugins/cache'
import { saveAs } from 'file-saver'
import { decryptCBC, encryptCBC } from '@/utils/aescbc'
import { hashWithSM3AndSalt } from '@/utils/sm' // 导入SM3哈希函数
let downloadLoadingInstance
export let isRelogin = { show: false }
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 10000
})
// 请求拦截器
service.interceptors.request.use(
(config) => {
const isToken = (config.headers || {}).isToken === false
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
// 如果需要token且存在token则设置Authorization头
if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken()
}
// 处理GET请求参数并加密
if (config.params) {
let param = tansParams(config.params)
if (param) {
param = param.slice(0, -1)
param = encryptCBC(param)
config.headers['Params-Hash'] = hashWithSM3AndSalt(param)
}
config.url = `${config.url}?${param}`
config.params = {}
}
// 防止重复提交
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
const requestObj = {
url: config.url,
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
time: new Date().getTime()
}
const requestSize = Object.keys(JSON.stringify(requestObj)).length
const limitSize = 5 * 1024 * 1024 // 限制请求数据大小为5M
if (requestSize >= limitSize) {
console.warn(`[${config.url}]: 请求数据大小超出允许的5M限制无法进行防重复提交验证。`)
return config
}
const sessionObj = cache.session.getJSON('sessionObj')
if (!sessionObj) {
cache.session.setJSON('sessionObj', requestObj)
} else {
const { url, data, time } = sessionObj
const interval = 0 // 间隔时间(ms),小于此时间视为重复提交
if (data === requestObj.data && requestObj.time - time < interval && url === requestObj.url) {
const message = '数据正在处理,请勿重复提交'
console.warn(`[${url}]: ${message}`)
return Promise.reject(new Error(message))
} else {
cache.session.setJSON('sessionObj', requestObj)
}
}
}
// 如果Content-Type为application/json且数据为对象则加密数据
if (config.headers['Content-Type'] === 'application/json;charset=utf-8' && typeof config.data === 'object') {
config.data = encryptCBC(JSON.stringify(config.data))
config.headers['Content-Type'] = 'application/json'
console.log(config.data)
config.headers['Params-Hash'] = hashWithSM3AndSalt(config.data) // 添加数据哈希到请求头
}
// 对下载请求进行数据参数拦截加密
if (config.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
if (typeof config.data === 'object') {
let formData = tansParams(config.data)
if (formData) {
formData = formData.slice(0, -1)
const encryptedData = encryptCBC(formData)
config.data = { formData: encryptedData }
config.headers['Params-Hash'] = hashWithSM3AndSalt(config.data) // 添加参数哈希到请求头
}
} else {
const encryptedData = encryptCBC(JSON.stringify(config.data))
config.data = `formData=${encryptedData}`
config.headers['Params-Hash'] = hashWithSM3AndSalt(config.data) // 添加参数哈希到请求头
}
}
// 如果Content-Type为空则设置为application/json
if (!config.headers['Content-Type']) {
config.headers['Content-Type'] = 'application/json'
console.warn('请求类型为空')
}
return config
},
(error) => {
console.log(error)
return Promise.reject(error)
}
)
// 响应拦截器
service.interceptors.response.use(
(res) => {
// 自动解密响应数据
if (res.data.decrypt) {
res.data = JSON.parse(decryptCBC(res.data.data))
} else if (typeof res.data.code === 'undefined') {
res.data = res.data.data
}
// 获取状态码
const code = res.data.code || 200
const msg = errorCode[code] || res.data.msg || errorCode['default']
// 处理二进制数据直接返回
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
return res.data
}
if (code === 401) {
if (!isRelogin.show) {
isRelogin.show = true
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
isRelogin.show = false
store.dispatch('LogOut').then(() => {
location.href = '/index'
})
}).catch(() => {
isRelogin.show = false
})
}
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code === 500) {
Message({ message: msg, type: 'error' })
return Promise.reject(new Error(msg))
} else if (code === 601) {
Message({ message: msg, type: 'warning' })
return Promise.reject('error')
} else if (code !== 200) {
Notification.error({ title: msg })
return Promise.reject('error')
} else {
return res.data
}
},
(error) => {
console.log('err' + error)
let { message } = error
if (message === 'Network Error') {
message = '后端接口连接异常'
} else if (message.includes('timeout')) {
message = '系统接口请求超时'
} else if (message.includes('Request failed with status code')) {
message = `系统接口${message.substr(message.length - 3)}异常`
}
Message({ message, type: 'error', duration: 5 * 1000 })
return Promise.reject(error)
}
)
// 通用下载方法
export function download(url, params, filename, config) {
downloadLoadingInstance = Loading.service({
text: '正在下载数据,请稍候',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
return service.post(url, params, {
transformRequest: [(params) => tansParams(params)],
headers: { 'Content-Type': 'application/x-www-form-urlencoded', encryption: 'encryption' },
responseType: 'blob',
...config
}).then(async(data) => {
const isBlob = blobValidate(data)
if (isBlob) {
const blob = new Blob([data])
saveAs(blob, filename)
} else {
const resText = await data.text()
const rspObj = JSON.parse(resText)
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
Message.error(errMsg)
}
downloadLoadingInstance.close()
}).catch((r) => {
console.error(r)
Message.error('下载文件出现错误,请联系管理员!')
downloadLoadingInstance.close()
})
}
export default service