first commit
This commit is contained in:
42
src/utils/EventDispatcher.js
Normal file
42
src/utils/EventDispatcher.js
Normal file
@@ -0,0 +1,42 @@
|
||||
export default class EventDispatcher {
|
||||
constructor() {
|
||||
this.listeners = {}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加事件监听器
|
||||
* @param {string} type - 事件类型
|
||||
* @param {Function} listener - 监听函数,当事件触发时会执行此函数
|
||||
*/
|
||||
addEventListener(type, listener) {
|
||||
if (!this.listeners[type]) {
|
||||
this.listeners[type] = []
|
||||
}
|
||||
// 检查监听函数是否已经存在于该事件类型的监听队列中,如果不存在则添加
|
||||
if (this.listeners[type].indexOf(listener) === -1) {
|
||||
this.listeners[type].push(listener)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据事件类型移除所有的事件监听器
|
||||
* @param {string} type - 事件类型
|
||||
*/
|
||||
removeEventListener(type) {
|
||||
this.listeners[type] = []
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发指定类型的事件,并向事件监听器传递数据
|
||||
* @param {string} type - 事件类型
|
||||
* @param {*} data - 要传递给事件监听器的数据
|
||||
*/
|
||||
dispatchEvent(type, data) {
|
||||
const listenerArray = this.listeners[type] || []
|
||||
if (listenerArray.length) {
|
||||
listenerArray.forEach((listener) => {
|
||||
listener.call(this, data)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
158
src/utils/WebSocketClient.js
Normal file
158
src/utils/WebSocketClient.js
Normal file
@@ -0,0 +1,158 @@
|
||||
import EventDispatcher from '@/utils/EventDispatcher'
|
||||
|
||||
export default class WebSocketClient extends EventDispatcher {
|
||||
url = '' // socket链接地址
|
||||
socket = null // socket实例
|
||||
reconnectCount = 0 // 重连次数
|
||||
maxReconnectCount = 5 // 最大重连次数
|
||||
reconnectTimer = null // 重连定时器
|
||||
reconnectInterval = 1000 * 10 // 重连时间间隔
|
||||
heartbeatInterval = 1000 * 30 // 心跳时间间隔
|
||||
heartbeatTimer = null // 定时器
|
||||
isStop = false // 是否停止
|
||||
|
||||
constructor(url) {
|
||||
super()
|
||||
this.url = url
|
||||
}
|
||||
|
||||
onopen(callback) {
|
||||
this.addEventListener('open', callback)
|
||||
}
|
||||
onmessage(callback) {
|
||||
this.addEventListener('message', callback)
|
||||
}
|
||||
onclose(callback) {
|
||||
this.addEventListener('close', callback)
|
||||
}
|
||||
onerror(callback) {
|
||||
this.addEventListener('error', callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息发送
|
||||
* @param {*} message
|
||||
*/
|
||||
send(message) {
|
||||
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
|
||||
this.socket.send(message)
|
||||
} else {
|
||||
console.error('[WebSocket] 未连接')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化连接
|
||||
*/
|
||||
connect() {
|
||||
if (this.reconnectCount === 0) {
|
||||
console.log('websocket', `初始化连接中...${this.url}`)
|
||||
}
|
||||
|
||||
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
|
||||
return
|
||||
}
|
||||
|
||||
this.socket = new WebSocket(this.url)
|
||||
|
||||
// 连接成功
|
||||
this.socket.onopen = (event) => {
|
||||
this.isStop = false
|
||||
// 重置重连次数
|
||||
this.reconnectCount = 0
|
||||
// 在连接成功时停止当前的心跳检测并重新启动
|
||||
this.startHeartbeat()
|
||||
console.log('WebSocket', `连接成功,等待服务端数据推送[onopen]...${this.url}`)
|
||||
this.dispatchEvent('open', event)
|
||||
}
|
||||
|
||||
this.socket.onmessage = (event) => {
|
||||
this.dispatchEvent('message', event)
|
||||
}
|
||||
|
||||
this.socket.onclose = (event) => {
|
||||
if (this.reconnectCount === 0) {
|
||||
console.log('websocket', `连接断开[onclose]...${this.url}`)
|
||||
}
|
||||
if (!this.isStop) {
|
||||
this.reconnect()
|
||||
}
|
||||
this.closeHeartbeat()
|
||||
this.dispatchEvent('close', event)
|
||||
}
|
||||
|
||||
this.socket.onerror = (event) => {
|
||||
if (this.reconnectCount === 0) {
|
||||
console.log('websocket', `连接异常[onclose]...${this.url}`)
|
||||
}
|
||||
this.closeHeartbeat()
|
||||
this.dispatchEvent('error', event)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新连接
|
||||
*/
|
||||
reconnect() {
|
||||
if (this.reconnectCount < this.maxReconnectCount) {
|
||||
this.reconnectCount++
|
||||
console.log('WebSocket', `尝试重连(${this.reconnectCount}/${this.maxReconnectCount})...${this.url}`)
|
||||
if(this.reconnectTimer) {
|
||||
clearTimeout(this.reconnectTimer)
|
||||
this.reconnectTimer = null
|
||||
}
|
||||
this.reconnectTimer = setTimeout(() => {
|
||||
this.connect()
|
||||
}, this.reconnectInterval)
|
||||
} else {
|
||||
this.closeHeartbeat()
|
||||
console.log('WebSocket', `最大重连失败,终止重连: ${this.url}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭连接
|
||||
*/
|
||||
close() {
|
||||
if (this.socket) {
|
||||
this.isStop = true
|
||||
this.socket.close()
|
||||
this.socket = null
|
||||
this.removeEventListener('open')
|
||||
this.removeEventListener('message')
|
||||
this.removeEventListener('close')
|
||||
this.removeEventListener('error')
|
||||
}
|
||||
if(this.reconnectTimer) {
|
||||
clearTimeout(this.reconnectTimer)
|
||||
this.reconnectTimer = null
|
||||
}
|
||||
this.closeHeartbeat()
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始心跳检测
|
||||
*/
|
||||
startHeartbeat() {
|
||||
this.closeHeartbeat()
|
||||
this.heartbeatTimer = setInterval(() => {
|
||||
if (this.socket) {
|
||||
// this.socket.send({ type: 'heartbeat', data: {} })
|
||||
// console.log('WebSocket', '发送心跳数据...')
|
||||
} else {
|
||||
console.log('WebSocket', '未连接')
|
||||
}
|
||||
}, this.heartbeatInterval)
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭心跳检测
|
||||
*/
|
||||
closeHeartbeat() {
|
||||
if (this.heartbeatTimer) {
|
||||
clearInterval(this.heartbeatTimer)
|
||||
this.heartbeatTimer = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
78
src/utils/cache.js
Normal file
78
src/utils/cache.js
Normal file
@@ -0,0 +1,78 @@
|
||||
// 缓存数据处理
|
||||
const sessionCache = {
|
||||
set (key, value) {
|
||||
if (!sessionStorage) {
|
||||
return
|
||||
}
|
||||
if (key != null && value != null) {
|
||||
sessionStorage.setItem(key, value)
|
||||
}
|
||||
},
|
||||
get (key) {
|
||||
if (!sessionStorage) {
|
||||
return null
|
||||
}
|
||||
if (key == null) {
|
||||
return null
|
||||
}
|
||||
return sessionStorage.getItem(key)
|
||||
},
|
||||
setJSON (key, jsonValue) {
|
||||
if (jsonValue != null) {
|
||||
this.set(key, JSON.stringify(jsonValue))
|
||||
}
|
||||
},
|
||||
getJSON (key) {
|
||||
const value = this.get(key)
|
||||
if (value != null) {
|
||||
return JSON.parse(value)
|
||||
}
|
||||
},
|
||||
remove (key) {
|
||||
sessionStorage.removeItem(key)
|
||||
}
|
||||
}
|
||||
const localCache = {
|
||||
set (key, value) {
|
||||
if (!localStorage) {
|
||||
return
|
||||
}
|
||||
if (key != null && value != null) {
|
||||
localStorage.setItem(key, value)
|
||||
}
|
||||
},
|
||||
get (key) {
|
||||
if (!localStorage) {
|
||||
return null
|
||||
}
|
||||
if (key == null) {
|
||||
return null
|
||||
}
|
||||
return localStorage.getItem(key)
|
||||
},
|
||||
setJSON (key, jsonValue) {
|
||||
if (jsonValue != null) {
|
||||
this.set(key, JSON.stringify(jsonValue))
|
||||
}
|
||||
},
|
||||
getJSON (key) {
|
||||
const value = this.get(key)
|
||||
if (value != null) {
|
||||
return JSON.parse(value)
|
||||
}
|
||||
},
|
||||
remove (key) {
|
||||
localStorage.removeItem(key)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
/**
|
||||
* 会话级缓存
|
||||
*/
|
||||
session: sessionCache,
|
||||
/**
|
||||
* 本地缓存
|
||||
*/
|
||||
local: localCache
|
||||
}
|
||||
208
src/utils/common.js
Normal file
208
src/utils/common.js
Normal file
@@ -0,0 +1,208 @@
|
||||
import { download } from '@/utils/request'
|
||||
/**
|
||||
* 获取assets文件夹下的静态图片资源
|
||||
* @param url // 文件路径
|
||||
*/
|
||||
export const getAssetsFile = (url) => new URL(`../assets/images/${url}`, import.meta.url).href
|
||||
|
||||
// 日期格式化
|
||||
export function parseTime(time, pattern) {
|
||||
if (arguments.length === 0 || !time) {
|
||||
return null
|
||||
}
|
||||
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
|
||||
let date
|
||||
if (typeof time === 'object') {
|
||||
date = time
|
||||
} else {
|
||||
if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
|
||||
time = parseInt(time)
|
||||
} else if (typeof time === 'string') {
|
||||
time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '')
|
||||
}
|
||||
if (typeof time === 'number' && time.toString().length === 10) {
|
||||
time *= 1000
|
||||
}
|
||||
date = new Date(time)
|
||||
}
|
||||
const formatObj = {
|
||||
y: date.getFullYear(),
|
||||
m: date.getMonth() + 1,
|
||||
d: date.getDate(),
|
||||
h: date.getHours(),
|
||||
i: date.getMinutes(),
|
||||
s: date.getSeconds(),
|
||||
a: date.getDay()
|
||||
}
|
||||
const timeStr = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
|
||||
let value = formatObj[key]
|
||||
// Note: getDay() returns 0 on Sunday
|
||||
if (key === 'a') {
|
||||
return [ '日', '一', '二', '三', '四', '五', '六' ][value]
|
||||
}
|
||||
if (result.length > 0 && value < 10) {
|
||||
value = `0${value}`
|
||||
}
|
||||
return value || 0
|
||||
})
|
||||
return timeStr
|
||||
}
|
||||
/**
|
||||
* 参数处理
|
||||
* @param {*} params 参数
|
||||
*/
|
||||
export const tansParams = (params) => {
|
||||
let result = ''
|
||||
for (const propName of Object.keys(params)) {
|
||||
const value = params[propName]
|
||||
let part = encodeURIComponent(propName) + '='
|
||||
if (value !== null && value !== '' && typeof value !== 'undefined') {
|
||||
if (typeof value === 'object') {
|
||||
for (const key of Object.keys(value)) {
|
||||
if (value[key] !== null && value[key] !== '' && typeof value[key] !== 'undefined') {
|
||||
let params = propName + '[' + key + ']'
|
||||
let subPart = encodeURIComponent(params) + '='
|
||||
result += subPart + encodeURIComponent(value[key]) + '&'
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result += part + encodeURIComponent(value) + '&'
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造树型结构数据
|
||||
* @param {*} data 数据源
|
||||
* @param {*} id id字段 默认 'id'
|
||||
* @param {*} parentId 父节点字段 默认 'parentId'
|
||||
* @param {*} children 孩子节点字段 默认 'children'
|
||||
*/
|
||||
export const handleTree = (data, id, parentId, children) => {
|
||||
let config = {
|
||||
id: id || 'id',
|
||||
parentId: parentId || 'parentId',
|
||||
childrenList: children || 'children'
|
||||
}
|
||||
|
||||
let childrenListMap = {}
|
||||
let nodeIds = {}
|
||||
let tree = []
|
||||
|
||||
for (let d of data) {
|
||||
let parentId = d[config.parentId]
|
||||
if (!childrenListMap[parentId]) {
|
||||
childrenListMap[parentId] = []
|
||||
}
|
||||
nodeIds[d[config.id]] = d
|
||||
|
||||
childrenListMap[parentId].push(d)
|
||||
}
|
||||
|
||||
for (let d of data) {
|
||||
let parentId = d[config.parentId]
|
||||
if (!nodeIds[parentId]) {
|
||||
tree.push(d)
|
||||
}
|
||||
}
|
||||
|
||||
for (let t of tree) {
|
||||
adaptToChildrenList(t)
|
||||
}
|
||||
|
||||
function adaptToChildrenList(o) {
|
||||
if (childrenListMap[o[config.id]] !== null) {
|
||||
o[config.childrenList] = childrenListMap[o[config.id]]
|
||||
}
|
||||
if (o[config.childrenList]) {
|
||||
for (let c of o[config.childrenList]) {
|
||||
adaptToChildrenList(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
return tree
|
||||
}
|
||||
|
||||
// 添加日期范围
|
||||
export const addDateRange = (params, dateRange, propName) => {
|
||||
let search = params
|
||||
search.params = typeof search.params === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {}
|
||||
dateRange = Array.isArray(dateRange) ? dateRange : []
|
||||
if (typeof propName === 'undefined') {
|
||||
search.params.beginTime = dateRange[0]
|
||||
search.params.endTime = dateRange[1]
|
||||
} else {
|
||||
search.params['begin' + propName] = dateRange[0]
|
||||
search.params['end' + propName] = dateRange[1]
|
||||
}
|
||||
return search
|
||||
}
|
||||
|
||||
// 验证是否为blob格式
|
||||
export function blobValidate(data) {
|
||||
return data.type !== 'application/json'
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断url是否是http或https
|
||||
* @param {string} url
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function isHttp(url) {
|
||||
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
|
||||
}
|
||||
|
||||
export function downloadFile(url, params, filename, config, method) {
|
||||
return download(url, params, filename, config, method)
|
||||
}
|
||||
|
||||
/**
|
||||
* 拖拽事件
|
||||
* 添加到元素上的mousedown事件 @mousedown
|
||||
*/
|
||||
export function dragEvent(e, className, moving, moveEnd) {
|
||||
if (e.target.nodeName === 'INPUT' || e.target.nodeName === 'TEXTAREA' || e.target.nodeName === 'svg' || e.target.nodeName === 'path') {
|
||||
return
|
||||
}
|
||||
if (className && !e.target.className.includes(className)) {
|
||||
return
|
||||
}
|
||||
|
||||
// if (className && className !== e.target.className) return
|
||||
const divDom = e.target // 获取目标元素
|
||||
const [ disX, disY ] = [ e.clientX - divDom.offsetLeft, e.clientY - divDom.offsetTop ]
|
||||
document.onmousemove = (e) => { // 鼠标按下并移动的事件//用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
|
||||
|
||||
const left = e.clientX - disX
|
||||
const top = e.clientY - disY
|
||||
divDom.style.left = `${left}px`
|
||||
divDom.style.top = `${top}px`
|
||||
if (moving) {
|
||||
moving()
|
||||
}
|
||||
}
|
||||
document.onmouseup = (e) => {
|
||||
document.onmousemove = null
|
||||
document.onmouseup = null
|
||||
if (moveEnd) {
|
||||
moveEnd()
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param value 将十进制转为度分秒
|
||||
* @returns { degrees: number, minutes: number, seconds: number } degrees:度 minutes:分 seconds:秒
|
||||
*/
|
||||
export const formatDecimalToDegrees = (value) => {
|
||||
const degrees = Math.floor(value)
|
||||
const minutes = Math.floor((value - degrees) * 60)
|
||||
const seconds = (value - degrees - minutes / 60) * 3600
|
||||
|
||||
return {
|
||||
degrees: degrees,
|
||||
minutes: minutes,
|
||||
seconds: seconds.toFixed(2)
|
||||
}
|
||||
}
|
||||
29
src/utils/directive/hasPermi.js
Normal file
29
src/utils/directive/hasPermi.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* v-hasPermi 操作权限处理
|
||||
* Copyright (c) 2019 ruoyi
|
||||
*/
|
||||
|
||||
import useUserStore from '@/store/modules/user'
|
||||
|
||||
export default {
|
||||
mounted(el, binding) {
|
||||
const { value } = binding
|
||||
const all_permission = '*:*:*'
|
||||
const permissions = useUserStore().permissions
|
||||
|
||||
if (value && value instanceof Array && value.length > 0) {
|
||||
const permissionFlag = value
|
||||
|
||||
const hasPermissions = permissions.some((permission) => {
|
||||
return (
|
||||
all_permission === permission || permissionFlag.includes(permission)
|
||||
)
|
||||
})
|
||||
if (!hasPermissions) {
|
||||
el.parentNode && el.parentNode.removeChild(el)
|
||||
}
|
||||
} else {
|
||||
// throw new Error('请设置操作权限标签值')
|
||||
}
|
||||
}
|
||||
}
|
||||
5
src/utils/directive/index.js
Normal file
5
src/utils/directive/index.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import hasPermi from './hasPermi'
|
||||
|
||||
export default function directive(app) {
|
||||
app.directive('hasPermi', hasPermi)
|
||||
}
|
||||
26
src/utils/encryption.js
Normal file
26
src/utils/encryption.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import * as CryptoSM4 from 'sm-crypto'
|
||||
|
||||
const pwdKey = stringToHex('egtEdgfrkasjsafr')
|
||||
const pwdIV = stringToHex('9475352547656596')
|
||||
|
||||
function stringToHex(str) {
|
||||
let hex = Array.prototype.map
|
||||
.call(str, (c) => {
|
||||
return c.charCodeAt(0).toString(16)
|
||||
})
|
||||
.join('')
|
||||
return hex
|
||||
}
|
||||
|
||||
function encryptedSM4(text) {
|
||||
const gmCryptConfigSet = {
|
||||
mode: 'cbc',
|
||||
iv: pwdIV,
|
||||
cipherType: 'base64'
|
||||
}
|
||||
return CryptoSM4.sm4.encrypt(text || '', pwdKey, gmCryptConfigSet)
|
||||
}
|
||||
|
||||
export {
|
||||
encryptedSM4
|
||||
}
|
||||
25832
src/utils/fakeData.js
Normal file
25832
src/utils/fakeData.js
Normal file
File diff suppressed because it is too large
Load Diff
179
src/utils/request.js
Normal file
179
src/utils/request.js
Normal file
@@ -0,0 +1,179 @@
|
||||
import axios from 'axios'
|
||||
import { ElNotification, ElMessage, ElLoading } from 'element-plus'
|
||||
import { tansParams, blobValidate } from '@/utils/common'
|
||||
import cache from '@/utils/cache'
|
||||
import { saveAs } from 'file-saver'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
// import {encryptedSM4} from '@/utils/encryption'
|
||||
|
||||
let downloadLoadingInstance
|
||||
|
||||
const errorCode = {
|
||||
'401': '认证失败,无法访问系统资源',
|
||||
'403': '当前操作没有权限',
|
||||
'404': '访问资源不存在',
|
||||
'default': '系统未知错误,请反馈给管理员'
|
||||
}
|
||||
|
||||
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
|
||||
// 创建axios实例
|
||||
const service = axios.create({
|
||||
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||
baseURL: import.meta.env.VITE_APP_BASE_URL,
|
||||
// 超时
|
||||
timeout: 10000
|
||||
})
|
||||
|
||||
// request拦截器
|
||||
service.interceptors.request.use(config => {
|
||||
// 是否需要设置 token
|
||||
const isToken = (config.headers || {}).isToken === false
|
||||
// 是否需要防止数据重复提交
|
||||
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
|
||||
const token = cache.local.get('token')
|
||||
|
||||
if (token && !isToken) {
|
||||
config.headers.Authorization = 'Bearer ' + token // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
}
|
||||
// get请求映射params参数
|
||||
if (config.method === 'get' && config.params) {
|
||||
let url = config.url + '?' + tansParams(config.params)
|
||||
url = url.slice(0, -1)
|
||||
config.params = {}
|
||||
config.url = url
|
||||
}
|
||||
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 sessionObj = cache.session.getJSON('sessionObj')
|
||||
if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
|
||||
cache.session.setJSON('sessionObj', requestObj)
|
||||
} else {
|
||||
const _url = sessionObj.url // 请求地址
|
||||
const _data = sessionObj.data // 请求数据
|
||||
const _time = sessionObj.time // 请求时间
|
||||
const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交
|
||||
if (_data === requestObj.data && requestObj.time - _time < interval && _url === requestObj.url) {
|
||||
const message = '数据正在处理,请勿重复提交'
|
||||
console.warn(`[${_url}]: ` + message)
|
||||
return Promise.reject(new Error(message))
|
||||
}
|
||||
cache.session.setJSON('sessionObj', requestObj)
|
||||
}
|
||||
}
|
||||
|
||||
// 数据加密(过密SM4)暂时注释
|
||||
// if (config.method === 'post' && config.data && !(config.data instanceof FormData)) {
|
||||
// const encryptedData = encryptedSM4(JSON.stringify(config.data)) // 将明文加密为十六进制字符串
|
||||
// let data = {
|
||||
// paramValue: encryptedData
|
||||
// }
|
||||
// config.data = data
|
||||
// }
|
||||
return config
|
||||
}, error => {
|
||||
console.log(error)
|
||||
Promise.reject(error)
|
||||
})
|
||||
|
||||
// 响应拦截器
|
||||
service.interceptors.response.use(res => {
|
||||
// 未设置状态码则默认成功状态
|
||||
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) {
|
||||
useUserStore().logout().then(() => {
|
||||
location.href = '/login'
|
||||
})
|
||||
// todo 退出登录跳转到登录页
|
||||
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
|
||||
} else if (code === 500) {
|
||||
ElMessage({ message: msg, type: 'error' })
|
||||
return Promise.reject(new Error(msg))
|
||||
} else if (code === 601) {
|
||||
ElMessage({ message: msg, type: 'warning' })
|
||||
return Promise.reject(new Error(msg))
|
||||
} else if (code !== 200) {
|
||||
ElNotification.error({ title: msg })
|
||||
return Promise.reject('error')
|
||||
}
|
||||
return Promise.resolve(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) + '异常'
|
||||
}
|
||||
ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
|
||||
return Promise.reject(error)
|
||||
})
|
||||
|
||||
// 通用下载方法
|
||||
export function download(url, params, filename, config, method = 'post') {
|
||||
downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' })
|
||||
const requestConfig = {
|
||||
...config,
|
||||
responseType: 'blob',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
|
||||
}
|
||||
if (method.toLowerCase() === 'post') {
|
||||
requestConfig.transformRequest = [ params => tansParams(params) ]
|
||||
return service.post(url, params, requestConfig).then(async (data) => {
|
||||
const isBlob = blobValidate(data)
|
||||
if (isBlob) {
|
||||
const blob = new Blob([ data ], { type: 'application/octet-stream' }) // 你可以根据实际需要设置MIME类型
|
||||
saveAs(blob, filename)
|
||||
} else {
|
||||
const resText = await data.text()
|
||||
const rspObj = JSON.parse(resText)
|
||||
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode.default
|
||||
ElMessage.error(errMsg)
|
||||
}
|
||||
downloadLoadingInstance.close()
|
||||
})
|
||||
.catch((r) => {
|
||||
console.error(r)
|
||||
ElMessage.error('下载文件出现错误,请联系管理员!')
|
||||
downloadLoadingInstance.close()
|
||||
})
|
||||
} else if (method.toLowerCase() === 'get') {
|
||||
// 如果是GET请求,需要将params附加到url上,并且不设置transformRequest
|
||||
const queryString = new URLSearchParams(params).toString()
|
||||
url += (url.includes('?') ? '&' : '?') + queryString
|
||||
return service.get(url, requestConfig).then(async (data) => {
|
||||
const isBlob = blobValidate(data)
|
||||
if (isBlob) {
|
||||
const blob = new Blob([ data ], { type: 'application/octet-stream' }) // 你可以根据实际需要设置MIME类型
|
||||
saveAs(blob, filename)
|
||||
} else {
|
||||
const resText = await data.text()
|
||||
const rspObj = JSON.parse(resText)
|
||||
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode.default
|
||||
ElMessage.error(errMsg)
|
||||
}
|
||||
downloadLoadingInstance.close()
|
||||
})
|
||||
.catch((r) => {
|
||||
console.error(r)
|
||||
ElMessage.error('下载文件出现错误,请联系管理员!')
|
||||
downloadLoadingInstance.close()
|
||||
})
|
||||
}
|
||||
throw new Error('Unsupported method: ' + method)
|
||||
|
||||
}
|
||||
export default service
|
||||
Reference in New Issue
Block a user