From 090c10fb81eb38fe71c768b6dfe5efe802df73d4 Mon Sep 17 00:00:00 2001
From: rain <1679827795@qq.com>
Date: Tue, 04 Mar 2025 17:11:43 +0800
Subject: [PATCH] 媒体文件单个下载

---
 src/views/resource/media.vue |  190 ++++++++++++++++++++--------------------------
 1 files changed, 83 insertions(+), 107 deletions(-)

diff --git a/src/views/resource/media.vue b/src/views/resource/media.vue
index a09389e..ca24c27 100644
--- a/src/views/resource/media.vue
+++ b/src/views/resource/media.vue
@@ -8,6 +8,9 @@
         <el-button type="primary" text icon="el-icon-view" v-if="permission.attach_delete"
           @click="handleRowView(scope.row)">查看
         </el-button>
+        <el-button type="success" text icon="el-icon-download" v-if="permission.attach_delete"
+          @click="handleRowDownload(scope.row)">下载
+        </el-button>
         <el-button type="danger" text icon="el-icon-delete" v-if="permission.attach_delete"
           @click="handleRowDelete(scope.row)">删除
         </el-button>
@@ -28,18 +31,14 @@
 
 export default {
   data() {
-    // 计算默认的开始和结束日期
-    const endDate = new Date(); // 当前日期
-    const startDate = new Date(); // 一个月前的日期
+    const endDate = new Date();
+    const startDate = new Date();
     startDate.setMonth(startDate.getMonth() - 1);
-
-    // 格式化为 YYYY-MM-DD 字符串,与 valueFormat 一致
     const defaultStartDate = `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, '0')}-${String(startDate.getDate()).padStart(2, '0')}`;
     const defaultEndDate = `${endDate.getFullYear()}-${String(endDate.getMonth() + 1).padStart(2, '0')}-${String(endDate.getDate()).padStart(2, '0')}`;
 
     return {
       form: {},
-      // 初始化 query,设置默认时间范围
       query: {
         daterange: [defaultStartDate, defaultEndDate]
       },
@@ -72,10 +71,7 @@
             search: true,
             searchSpan: 5,
             dicData: [],
-            props: {
-              label: 'nickname',
-              value: 'nickname',
-            },
+            props: { label: 'nickname', value: 'nickname' },
             hide: true,
           },
           {
@@ -91,7 +87,7 @@
             endPlaceholder: '结束时间',
             viewDisplay: false,
             hide: true,
-            searchValue: [defaultStartDate, defaultEndDate] // 设置搜索表单默认值,确保显示
+            searchValue: [defaultStartDate, defaultEndDate]
           },
           { label: '任务名称', prop: 'job_name' },
           { label: '文件名称', prop: 'file_name' },
@@ -113,9 +109,7 @@
             drag: true,
             loadText: '任务上传中,请稍等',
             span: 24,
-            propsHttp: {
-              res: 'data',
-            },
+            propsHttp: { res: 'data' },
             action: '/blade-resource/oss/endpoint/put-file-task',
           },
         ],
@@ -137,16 +131,11 @@
       };
     },
     ids() {
-      let ids = [];
-      this.selectionList.forEach(ele => {
-        ids.push(ele.id);
-      });
-      return ids.join(',');
+      return this.selectionList.map(ele => ele.id).join(',');
     },
   },
   mounted() {
     this.loadAirportList();
-    // 初始化时强制设置搜索表单默认值并加载数据
     this.$refs.crud.setSearch({ daterange: this.query.daterange });
     this.onLoad(this.page, this.query);
   },
@@ -173,28 +162,49 @@
       this.refreshChange();
       done();
     },
+    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'; // 设置下载文件名
+        document.body.appendChild(link);
+        link.click();
+        document.body.removeChild(link);
+        window.URL.revokeObjectURL(url); // 释放 URL 对象
+
+        this.$message({
+          type: 'success',
+          message: '文件下载成功: ' + row.file_name
+        });
+      } catch (error) {
+        console.error('下载文件时出错:', error);
+        this.$message({
+          type: 'error',
+          message: '下载失败: ' + error.message
+        });
+      }
+    },
     handleRowDelete(row) {
       this.$confirm('确定删除此文件?', {
         confirmButtonText: '确定',
         cancelButtonText: '取消',
         type: 'warning',
       })
-        .then(() => {
-          return deleteAllFile(row.id);
-        })
+        .then(() => deleteAllFile(row.id))
         .then(() => {
           this.onLoad(this.page);
-          this.$message({
-            type: 'success',
-            message: '删除成功!',
-          });
+          this.$message({ type: 'success', message: '删除成功!' });
         })
         .catch(error => {
           console.error('删除文件时出错:', error);
-          this.$message({
-            type: 'error',
-            message: '删除失败,请稍后重试!',
-          });
+          this.$message({ type: 'error', message: '删除失败,请稍后重试!' });
         });
     },
     rowDel(row) {
@@ -203,40 +213,29 @@
         cancelButtonText: '取消',
         type: 'warning',
       })
-        .then(() => {
-          return deleteAllFile(row.id);
-        })
+        .then(() => deleteAllFile(row.id))
         .then(() => {
           this.onLoad(this.page);
-          this.$message({
-            type: 'success',
-            message: '操作成功!',
-          });
+          this.$message({ type: 'success', message: '操作成功!' });
         });
     },
     searchReset() {
-      // 重置时恢复默认值
       const endDate = new Date();
       const startDate = new Date();
       startDate.setMonth(startDate.getMonth() - 1);
       const defaultStartDate = `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, '0')}-${String(startDate.getDate()).padStart(2, '0')}`;
       const defaultEndDate = `${endDate.getFullYear()}-${String(endDate.getMonth() + 1).padStart(2, '0')}-${String(endDate.getDate()).padStart(2, '0')}`;
-      this.query = {
-        daterange: [defaultStartDate, defaultEndDate]
-      };
+      this.query = { daterange: [defaultStartDate, defaultEndDate] };
       this.selectedWorkspaceId = null;
-      // 更新搜索表单显示
       this.$refs.crud.setSearch({ daterange: this.query.daterange });
       this.onLoad(this.page, this.query);
     },
     searchChange(params, done) {
       this.query = params;
       this.page.currentPage = 1;
-
       const airportColumn = this.option.column.find(col => col.prop === 'airportNickname');
       const selectedAirport = airportColumn.dicData.find(item => item.nickname === params.airportNickname);
       this.selectedWorkspaceId = selectedAirport ? selectedAirport.workspace_id : null;
-
       this.onLoad(this.page, params);
       done();
     },
@@ -261,7 +260,7 @@
     onLoad(page, params = {}) {
       this.loading = true;
       const { daterange } = params;
-      let create_time = null; // 修改为 null,避免未定义变量引用
+      let create_time = null;
       let end_time = null;
 
       if (daterange && Array.isArray(daterange) && daterange.length === 2) {
@@ -275,54 +274,41 @@
         }
       }
 
-      let values = {
-        ...params,
-        ...this.query,
-      };
-      if (daterange) {
-        values.daterange = null;
-      }
+      let values = { ...params, ...this.query };
+      if (daterange) values.daterange = null;
 
-      getMedia(
-        page.currentPage,
-        page.pageSize,
-        this.selectedWorkspaceId || null,
-        create_time,
-        end_time
-      ).then(res => {
-        const data = res.data;
-        if (data && data.data && data.data.list) {
-          this.page.total = data.data.pagination.total;
-          this.data = data.data.list.map(item => ({
-            job_name: item.job_name,
-            file_name: item.file_name,
-            create_time: this.formatCreateTime(item.create_time),
-            object_key: item.object_key,
-            payload: item.payload,
-            airportNickname: item.airportNickname,
-            id: item.id,
-          }));
-          this.domainUrl = data.data.list.length > 0 ? data.data.list[0].domain_url : 'http://localhost:2888/manage/resource';
-        } else {
-          this.data = [];
-        }
-        this.loading = false;
-        this.selectionClear();
-        this.$refs.crud.refreshTable();
-      }).catch(error => {
-        this.loading = false;
-        console.error('加载媒体数据时出错:', error);
-      });
+      getMedia(page.currentPage, page.pageSize, this.selectedWorkspaceId || null, create_time, end_time)
+        .then(res => {
+          const data = res.data;
+          if (data && data.data && data.data.list) {
+            this.page.total = data.data.pagination.total;
+            this.data = data.data.list.map(item => ({
+              job_name: item.job_name,
+              file_name: item.file_name,
+              create_time: this.formatCreateTime(item.create_time),
+              object_key: item.object_key,
+              payload: item.payload,
+              airportNickname: item.airportNickname,
+              id: item.id,
+            }));
+            this.domainUrl = data.data.list.length > 0 ? data.data.list[0].domain_url : 'http://localhost:2888/manage/resource';
+          } else {
+            this.data = [];
+          }
+          this.loading = false;
+          this.selectionClear();
+          this.$refs.crud.refreshTable();
+        })
+        .catch(error => {
+          this.loading = false;
+          console.error('加载媒体数据时出错:', error);
+        });
     },
     formatCreateTime(createTime) {
-      if (typeof createTime !== 'number' || isNaN(createTime)) {
-        return '';
-      }
+      if (typeof createTime !== 'number' || isNaN(createTime)) return '';
       const timestamp = createTime < 10000000000 ? createTime * 1000 : createTime;
       const date = new Date(timestamp);
-      if (isNaN(date.getTime())) {
-        return '';
-      }
+      if (isNaN(date.getTime())) return '';
       const year = date.getFullYear();
       const month = String(date.getMonth() + 1).padStart(2, '0');
       const day = String(date.getDate()).padStart(2, '0');
@@ -334,27 +320,19 @@
     handleRowView(row) {
       const mediaUrl = this.domainUrl + row.object_key;
       const mediaType = this.getMediaType(row.object_key);
-
-      if (mediaType === 'image') {
-        window.open(mediaUrl, '_blank');
-      } else if (mediaType === 'video') {
-        window.open(mediaUrl, '_blank');
+      if (mediaType === 'image' || mediaType === 'video') {
+        window.open(mediaUrl, '_blank'); // 查看功能,打开新窗口
       }
     },
     getMediaType(objectKey) {
       const extension = objectKey.split('.').pop().toLowerCase();
-      if (['jpg', 'jpeg', 'png', 'gif'].includes(extension)) {
-        return 'image';
-      } else if (['mp4', 'avi', 'mov'].includes(extension)) {
-        return 'video';
-      }
+      if (['jpg', 'jpeg', 'png', 'gif'].includes(extension)) return 'image';
+      if (['mp4', 'avi', 'mov'].includes(extension)) return 'video';
       return 'unknown';
     },
     showVideo(url) {
       this.taskBox = true;
-      this.taskForm = {
-        videoUrl: url,
-      };
+      this.taskForm = { videoUrl: url };
       this.taskOption = {
         submitBtn: false,
         emptyBtn: false,
@@ -364,10 +342,7 @@
             prop: 'videoUrl',
             type: 'video',
             span: 24,
-            props: {
-              controls: true,
-              autoplay: false,
-            },
+            props: { controls: true, autoplay: false },
           },
         ],
       };
@@ -379,4 +354,5 @@
 };
 </script>
 
-<style></style>
\ No newline at end of file
+<style>
+</style>
\ No newline at end of file

--
Gitblit v1.9.3