目录
一、store全局存储
二、上传下载公共方法
三、取消传输
四、html展示
import { defineStore } from 'pinia'
// state 类型定义
interface AppState {
sourceData: any
}
export const transmissionStore = defineStore({
id: 'transmissionStore', // 唯一
state: (): AppState => ({
sourceData: [], // 更新传输数据 workId, axiosSource
}),
getters: {},
actions: {
// 更新传输数据
setSourceData(type: any, data: any) {
if (type == 'update') {
let sourceDataRow = this.sourceData.find((e: any) => e.workId == data.workId)
if (!sourceDataRow) {
this.sourceData.push(data) // 添加新的传输
}else{
if(data.type == 'upload'){
let ratio = Number((data.progressEvent.loaded/data.progressEvent.total*100).toFixed(2))
if(ratio < 99.9) sourceDataRow.progressEvent = data.progressEvent // 更新进度
}else{
sourceDataRow.progressEvent = data.progressEvent // 更新进度
// 传输完成列表删除
// if(data.progressEvent.loaded == data.progressEvent.total){
// this.sourceData = this.sourceData.filter(
// (e: any) => e.workId != data.workId
// )
// }
}
}
} else if (type == 'delete') {
this.sourceData = this.sourceData.filter(
(e: any) => e.workId != data.workId
)
} else if (type == 'allDelete') {
this.sourceData = []
}
// console.log('axios上传中记录', this.sourceData)
},
},
persist: {
enabled: false, // 开启数据缓存
},
})
import axios from 'axios'
import { transmissionStore } from '@/store/transmissionStore.ts'
import lodash from 'lodash' // lodash库
import { v4 as uuidv4 } from 'uuid'
/**
* 推送存储
*/
const lodashdebounce = lodash.throttle(
(uid, progressEvent, source, fileName, type) => {
transmissionStore().setSourceData('update', {
workId: uid,
type: type,
fileName: fileName,
progressEvent: {
loaded: progressEvent.loaded,
total: progressEvent.total,
status: progressEvent.status ||
(progressEvent.loaded < progressEvent.total ? '传输中' : '传输完成'),
},
axiosSource: source,
hash: window.location.hash,
})
},
0,
{
leading: true, //指定在延迟开始前调用
trailing: true, //延迟结束后是否调用
}
)
/**
* 上传
*/
export const uploadFile = (method, url, params, fileName, then) => {
const uid = uuidv4()
const CancelToken = axios.CancelToken
let source = CancelToken.source()
axios({
url: url,
method: method,
data: params,
headers: {
workId: uid,
},
cancelToken: source.token,
onUploadProgress: function (progressEvent) {
lodashdebounce(uid, progressEvent, source, fileName, 'upload') //节流推送
},
})
.then((res) => {
then(res)
transmissionStore().setSourceData('delete', {
workId: uid,
})
})
.catch((error) => {
console.log(error, '上传接口中断')
})
}
/**
* 下载
*/
export const downloadFile = (method, url, params, fileName) => {
const uid = uuidv4()
const CancelToken = axios.CancelToken
let source = CancelToken.source()
lodashdebounce(uid, {loaded:0, total: 99999, status: '准备中'}, source, fileName, 'download') //准备中 后端压缩文件时间停留
axios({
url: url,
method: method,
params: params,
responseType: 'blob',
headers: {
'Content-Type': 'application/json; charset=utf-8',
workId: uid,
},
cancelToken: source.token,
onDownloadProgress: function (progressEvent) {
lodashdebounce(uid, progressEvent, source, fileName, 'download') //节流推送
},
})
.then((res) => {
const blob = new Blob([res.data], {
type: 'application/octet-stream',
})
const url = window.URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = fileName
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
window.URL.revokeObjectURL(url)
transmissionStore().setSourceData('delete', {
workId: uid,
})
})
.catch((error) => {
console.log(error, '下载接口中断')
})
}
let axiosSource = sourceData.value.find((e) => e.workId == row.workId)?.axiosSource
//中断下载接口
if(axiosSource?.cancel){
axiosSource.cancel(`取消下载${row.workId}`)
}
//删除axios记录
setTimeout(() => {
transmissionStore().setSourceData('delete', {
workId: row.workId,
})
}, 500)
表格插槽 展示
{{ row.fileName }}
(准备中)