Преглед на файлове

reactor:大文件下载;

zhangchong преди 11 месеца
родител
ревизия
a6497e4b89
променени са 1 файла, в които са добавени 104 реда и са изтрити 1 реда
  1. 104 1
      src/components/ProTable/index.vue

+ 104 - 1
src/components/ProTable/index.vue

@@ -9,6 +9,12 @@
 			</div>
 			<div v-if="toolButton" class="header-button-ri">
 				<slot name="toolButton">
+            <el-progress :stroke-width="10" :percentage="downloadObj.percentage" v-if="downloadObj.downloading">
+              <template #default="{ percentage }">
+                <span class="font14">{{ percentage }}%</span>
+                <span class="font14">导出进度</span>
+              </template>
+            </el-progress>
 					<el-button v-if="showToolButton('refresh')" circle @click="onRefresh" title="刷新表格">
 						<SvgIcon name="ele-Refresh" />
 					</el-button>
@@ -21,7 +27,7 @@
 					<el-button v-if="showToolButton('exportAll') && columns.length" circle @click="exportAll" title="导出全部">
 						<SvgIcon name="iconfont icon-export" />
 					</el-button>
-				</slot>
+        </slot>
 			</div>
 		</div>
 		<!-- 表格主体 -->
@@ -328,6 +334,103 @@ watch(
 		clearSelection();
 	}
 );
+
+//下载逻辑
+const downloadObj = reactive({
+  fileName: '',
+  downloading: false,
+  range: 0,
+  fileBlob: [],
+  percentage: 0,
+})
+
+const download = async () => {
+  downloadObj.fileBlob = []
+  downloadObj.downloading = true
+  downloadObj.range = 0 //文件总大小
+  downloadObj.percentage = 0 //下载进度
+  const params = {
+    md5: '7343784583fsdufhusdfgsudfe8934',
+  }
+  const chunkSize = 5 * 1024 * 1024
+
+  //第一次调接口获取到响应头的content-range,文件总大小,用于计算下载切割
+  const config = {
+    headers: {
+      Range: `bytes=0-${chunkSize}`,
+    },
+  }
+
+  const data = await downLoadbyPiece(params, config)
+
+  //获取文件总大小
+  const arr = data.headers['content-range'].split('/')
+  downloadObj.range = Number(arr[1])
+  //存储每片文件流
+  downloadObj.fileBlob.push(data.data)
+  //获取文件名称
+  let fileName = ''
+  let cd = data.headers['content-disposition']
+  if (cd) {
+    let index = cd.lastIndexOf('=')
+    fileName = decodeURI(cd.substring(index + 1, cd.length))
+  }
+
+  await chunkUpload(params, fileName, chunkSize)
+}
+
+//拿到文件总大小downloadObj.range,计算分为多少都段下载
+const chunkUpload = async (params, fileName, chunkSize) => {
+  //获取分段下载的数组
+  let chunkList = []
+  function chunkPush(page = 1) {
+    chunkList.push((page - 1) * chunkSize)
+    if (page * chunkSize < downloadObj.range) {
+      chunkPush(page + 1)
+    }
+  }
+  chunkPush()
+
+  //加上文件大小在最后一位
+  chunkList.push(downloadObj.range)
+  console.log(chunkList, 'chunkList')
+  //分段组合传参格式处理 0-1024 1024-2048
+  let uploadRange = []
+  chunkList.forEach((item, i) => {
+    if (i == chunkList.length - 1) return
+
+    uploadRange.push(`${chunkList[i]}-${chunkList[i + 1]}`)
+  })
+  console.log(uploadRange, 'uploadRang')
+  for (let index = 0; index < uploadRange.length; index++) {
+    //第一次调接口已经传过了第一组,从第二位开始
+    if (index > 0) {
+      const config = {
+        headers: {
+          Range: `bytes=${uploadRange[index]}`,
+        },
+      }
+      const data = await downLoadbyPiece(params, config)
+      //计算下载进度
+      downloadObj.percentage = Math.floor(((index + 1) / uploadRange.length) * 100)
+      emit('getDownloadpercent', downloadObj.percentage)
+      //存储每一片文件流
+      downloadObj.fileBlob.push(data.data)
+    }
+  }
+  //合并
+  const blob = new Blob(downloadObj.fileBlob, {
+    type: downloadObj.fileBlob[0].type,
+  })
+  downloadObj.downloading = false
+  //下载
+  const link = document.createElement('a')
+  const URL = window.URL || window.webkitURL;
+  link.href = URL.createObjectURL(blob)
+  link.download = fileName
+  link.click()
+  URL.revokeObjectURL(link.href)
+}
 // 暴露给父组件的参数和方法 (外部需要什么,都可以从这里暴露出去)
 defineExpose({
 	element: tableRef,