From 40550ba188593fdec9358dcdd7fe9c4ccd27333a Mon Sep 17 00:00:00 2001
From: rain <1679827795@qq.com>
Date: Thu, 06 Mar 2025 18:56:01 +0800
Subject: [PATCH] 媒体文件打包下载
---
src/views/resource/media.vue | 141 ++++++++++++++++++++++------------------------
1 files changed, 67 insertions(+), 74 deletions(-)
diff --git a/src/views/resource/media.vue b/src/views/resource/media.vue
index ca24c27..6d5f575 100644
--- a/src/views/resource/media.vue
+++ b/src/views/resource/media.vue
@@ -4,6 +4,10 @@
v-model="form" ref="crud" @row-del="rowDel" @search-change="searchChange" @search-reset="searchReset"
@selection-change="selectionChange" @current-change="currentChange" @size-change="sizeChange"
@refresh-change="refreshChange" @on-load="onLoad">
+ <template #menu-left>
+ <el-button type="primary" icon="el-icon-download" plain :loading="isDownloading" @click="handleZipDownload">{{
+ isDownloading ? '压缩下载中...' : '压缩下载' }}</el-button>
+ </template>
<template #menu="scope">
<el-button type="primary" text icon="el-icon-view" v-if="permission.attach_delete"
@click="handleRowView(scope.row)">查看
@@ -24,6 +28,7 @@
</template>
<script>
+import JSZip from 'jszip';
import { getMedia, deleteAllFile } from '@/api/resource/media';
import { getAirportList } from '@/api/device/device';
import { mapGetters } from 'vuex';
@@ -64,31 +69,8 @@
dialogClickModal: false,
delBtn: false,
column: [
- {
- label: '机场选择',
- prop: 'airportNickname',
- type: 'select',
- search: true,
- searchSpan: 5,
- dicData: [],
- props: { label: 'nickname', value: 'nickname' },
- hide: true,
- },
- {
- label: '创建日期',
- prop: 'daterange',
- type: 'daterange',
- search: true,
- searchRange: true,
- searchSpan: 6,
- format: 'YYYY-MM-DD',
- valueFormat: 'YYYY-MM-DD',
- startPlaceholder: '开始时间',
- endPlaceholder: '结束时间',
- viewDisplay: false,
- hide: true,
- searchValue: [defaultStartDate, defaultEndDate]
- },
+ { label: '机场选择', prop: 'airportNickname', type: 'select', search: true, searchSpan: 5, dicData: [], props: { label: 'nickname', value: 'nickname' }, hide: true },
+ { label: '创建日期', prop: 'daterange', type: 'daterange', search: true, searchRange: true, searchSpan: 6, format: 'YYYY-MM-DD', valueFormat: 'YYYY-MM-DD', startPlaceholder: '开始时间', endPlaceholder: '结束时间', viewDisplay: false, hide: true, searchValue: [defaultStartDate, defaultEndDate] },
{ label: '任务名称', prop: 'job_name' },
{ label: '文件名称', prop: 'file_name' },
{ label: '拍摄时间', prop: 'create_time' },
@@ -102,25 +84,15 @@
submitBtn: false,
emptyBtn: false,
column: [
- {
- label: '任务上传',
- prop: 'taskFile',
- type: 'upload',
- drag: true,
- loadText: '任务上传中,请稍等',
- span: 24,
- propsHttp: { res: 'data' },
- action: '/blade-resource/oss/endpoint/put-file-task',
- },
+ { label: '任务上传', prop: 'taskFile', type: 'upload', drag: true, loadText: '任务上传中,请稍等', span: 24, propsHttp: { res: 'data' }, action: '/blade-resource/oss/endpoint/put-file-task' },
],
},
domainUrl: '',
+ isDownloading: false, // 控制按钮加载状态
};
},
computed: {
- func() {
- return func;
- },
+ func() { return func; },
...mapGetters(['permission']),
permissionList() {
return {
@@ -130,9 +102,7 @@
delBtn: this.validData(this.permission.attach_delete, false),
};
},
- ids() {
- return this.selectionList.map(ele => ele.id).join(',');
- },
+ ids() { return this.selectionList.map(ele => ele.id).join(','); },
},
mounted() {
this.loadAirportList();
@@ -165,38 +135,25 @@
async handleRowDownload(row) {
const mediaUrl = this.domainUrl + row.object_key;
try {
- // 使用 fetch 获取文件,确保触发下载而不是查看
const response = await fetch(mediaUrl);
if (!response.ok) throw new Error('文件下载失败');
-
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
- link.download = row.file_name || 'download'; // 设置下载文件名
+ link.download = row.file_name || 'download';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
- window.URL.revokeObjectURL(url); // 释放 URL 对象
-
- this.$message({
- type: 'success',
- message: '文件下载成功: ' + row.file_name
- });
+ window.URL.revokeObjectURL(url);
+ this.$message({ type: 'success', message: '文件下载成功: ' + row.file_name });
} catch (error) {
console.error('下载文件时出错:', error);
- this.$message({
- type: 'error',
- message: '下载失败: ' + error.message
- });
+ this.$message({ type: 'error', message: '下载失败: ' + error.message });
}
},
handleRowDelete(row) {
- this.$confirm('确定删除此文件?', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- })
+ this.$confirm('确定删除此文件?', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
.then(() => deleteAllFile(row.id))
.then(() => {
this.onLoad(this.page);
@@ -208,11 +165,7 @@
});
},
rowDel(row) {
- this.$confirm('确定将选择数据及对应的文件删除?', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- })
+ this.$confirm('确定将选择数据及对应的文件删除?', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
.then(() => deleteAllFile(row.id))
.then(() => {
this.onLoad(this.page);
@@ -321,7 +274,7 @@
const mediaUrl = this.domainUrl + row.object_key;
const mediaType = this.getMediaType(row.object_key);
if (mediaType === 'image' || mediaType === 'video') {
- window.open(mediaUrl, '_blank'); // 查看功能,打开新窗口
+ window.open(mediaUrl, '_blank');
}
},
getMediaType(objectKey) {
@@ -337,22 +290,62 @@
submitBtn: false,
emptyBtn: false,
column: [
- {
- label: '视频播放',
- prop: 'videoUrl',
- type: 'video',
- span: 24,
- props: { controls: true, autoplay: false },
- },
+ { label: '视频播放', prop: 'videoUrl', type: 'video', span: 24, props: { controls: true, autoplay: false } },
],
};
},
validData(val, def) {
return typeof val !== 'undefined' ? val : def;
},
+ async handleZipDownload() {
+ if (this.selectionList.length === 0) {
+ this.$message({ type: 'warning', message: '请先选择需要下载的文件' });
+ return;
+ }
+
+ this.isDownloading = true;
+
+ try {
+ const zip = new JSZip();
+ const files = this.selectionList.map(item => ({
+ url: this.domainUrl + item.object_key,
+ name: item.file_name
+ }));
+
+ const fetchPromises = files.map(async file => {
+ const response = await fetch(file.url, { cache: 'force-cache' });
+ if (!response.ok) throw new Error(`下载文件 ${file.name} 失败`);
+ const blob = await response.blob();
+ zip.file(file.name, blob);
+ });
+
+ await Promise.all(fetchPromises);
+
+ const content = await zip.generateAsync({
+ type: 'blob',
+ compression: 'DEFLATE',
+ compressionOptions: { level: 1 }
+ });
+
+ const url = window.URL.createObjectURL(content);
+ const link = document.createElement('a');
+ link.href = url;
+ link.download = `media_files_${new Date().toISOString().slice(0, 10)}_${new Date().getTime()}.zip`;
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ window.URL.revokeObjectURL(url);
+
+ this.$message({ type: 'success', message: `成功下载 ${this.selectionList.length} 个文件` });
+ } catch (error) {
+ console.error('压缩下载失败:', error);
+ this.$message({ type: 'error', message: '压缩下载失败: ' + error.message });
+ } finally {
+ this.isDownloading = false;
+ }
+ },
},
};
</script>
-<style>
-</style>
\ No newline at end of file
+<style></style>
\ No newline at end of file
--
Gitblit v1.9.3