110 lines
3.5 KiB
JavaScript
110 lines
3.5 KiB
JavaScript
import axios from 'axios'
|
||
import { Loading, Message } from 'element-ui'
|
||
import { getToken } from '@/utils/auth'
|
||
import { blobValidate } from '@/utils/bonus'
|
||
import { saveAs } from 'file-saver'
|
||
|
||
// 下载blob文件
|
||
export const downloadFile = ({ fileData, fileType, fileName }) => {
|
||
const blob = new Blob([fileData], {
|
||
type: fileType
|
||
})
|
||
const link = document.createElement('a')
|
||
link.href = URL.createObjectURL(blob)
|
||
link.download = fileName
|
||
link.style.display = 'none'
|
||
document.body.appendChild(link)
|
||
link.click()
|
||
URL.revokeObjectURL(link.href)
|
||
document.body.removeChild(link)
|
||
}
|
||
|
||
// 通用a链接下载
|
||
export const downloadFileByUrl = (url) => {
|
||
const link = document.createElement('a')
|
||
link.href = url
|
||
link.setAttribute('download', '')
|
||
link.style.display = 'none'
|
||
document.body.appendChild(link)
|
||
link.click()
|
||
URL.revokeObjectURL(link.href)
|
||
document.body.removeChild(link)
|
||
}
|
||
|
||
/**
|
||
* 通用文件下载方法(带加载提示)
|
||
* @param {string} path - 下载路径
|
||
* @param {string} defaultFileName - 默认文件名(可选,如果响应头没有文件名则使用此名称)
|
||
* @param {string} loadingText - 加载提示文本(可选,默认为'正在下载文件,请稍候...')
|
||
* @returns {Promise} - 返回 Promise
|
||
*/
|
||
export const downloadFileWithLoading = (path, defaultFileName = '文件.xlsx', loadingText = '正在下载文件,请稍候...') => {
|
||
const baseURL = process.env.VUE_APP_BASE_API
|
||
const url = path.startsWith('http') ? path : `${baseURL}/${path}`
|
||
|
||
// 显示下载中提示(优化样式)
|
||
const downloadLoadingInstance = Loading.service({
|
||
lock: true, // 锁定屏幕,防止用户操作
|
||
text: loadingText,
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.1)', // 稍微降低透明度,更柔和
|
||
customClass: 'download-loading-mask' // 自定义样式类
|
||
})
|
||
|
||
return axios({
|
||
method: 'get',
|
||
url: url,
|
||
responseType: 'blob',
|
||
headers: {
|
||
'Authorization': 'Bearer ' + getToken(),
|
||
'encryptResponse':false
|
||
}
|
||
}).then((res) => {
|
||
console.log('res',res)
|
||
// 验证是否为blob格式
|
||
const isBlob = blobValidate(res.data)
|
||
if (isBlob) {
|
||
// 从响应头获取文件名,如果没有则使用默认名称
|
||
const fileName = res.headers['download-filename']
|
||
? decodeURIComponent(res.headers['download-filename'])
|
||
: defaultFileName
|
||
|
||
// 创建blob并下载
|
||
const blob = new Blob([res.data], {
|
||
type: res.data.type || 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||
})
|
||
saveAs(blob, fileName)
|
||
Message.success('文件下载成功')
|
||
return Promise.resolve(fileName)
|
||
} else {
|
||
// 如果不是blob,尝试解析错误信息
|
||
return printErrMsg(res.data)
|
||
}
|
||
}).catch((error) => {
|
||
console.error('文件下载失败:', error)
|
||
Message.error('文件下载失败,请稍后重试')
|
||
return Promise.reject(error)
|
||
}).finally(() => {
|
||
// 关闭加载提示
|
||
if (downloadLoadingInstance) {
|
||
downloadLoadingInstance.close()
|
||
}
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 打印错误信息
|
||
* @param {Blob} data - 错误响应的blob数据
|
||
*/
|
||
async function printErrMsg(data) {
|
||
try {
|
||
const resText = await data.text()
|
||
const rspObj = JSON.parse(resText)
|
||
Message.error(rspObj.msg || '下载失败,请稍后重试')
|
||
return Promise.reject(new Error(rspObj.msg || '下载失败'))
|
||
} catch (e) {
|
||
Message.error('下载失败,请稍后重试')
|
||
return Promise.reject(e)
|
||
}
|
||
}
|