上传下载传输列表进度条展示

目录

一、store全局存储

二、上传下载公共方法

三、取消传输

四、html展示


一、store全局存储

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)

四、html展示

表格插槽 展示

<!-- 进度 -->
<template #fileName="{ row }">
  <div class="schedule">
    <div class="scheduletitle">
      <el-icon v-if="row.type == 'upload'"><Upload /></el-icon>
      <el-icon v-if="row.type == 'download'"><Download /></el-icon>
      {{ row.fileName }}
      <span v-if="row.progressEvent.status == '准备中'">(准备中)</span>
    </div>
    <el-progress
      :key="row.workId"
      :percentage="Number((row.progressEvent.loaded/row.progressEvent.total*100).toFixed(2))"
      :status="
        row.progressEvent.status == '传输失败'
          ? 'exception'
          : row.progressEvent.status == '传输完成'
          ? 'success'
          : ''
      "
    />
  </div>
</template>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天高任鸟飞dyz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值