feat: 管理后台文件列表支持下载文件,格式化过期时间

This commit is contained in:
Yanlongli
2024-03-29 17:55:18 +08:00
parent 7b37269dfb
commit e309e89379
24 changed files with 152 additions and 40 deletions
+5
View File
@@ -88,6 +88,11 @@ export default {
file_path: 'File Path',
action: 'Action',
delete: 'Delete',
delete_success: 'Delete successful',
forever: 'Forever',
unlimited_count: 'Unlimited',
download: 'Download',
download_fail: 'File save failed, please try again later~',
},
menu: {
fileManage: 'File Management',
+5
View File
@@ -88,6 +88,11 @@ export default {
file_path: '文件路径',
action: '操作',
delete: '删除',
delete_success: '删除成功',
forever: '永久有效',
unlimited_count: '不限次数',
download: '下载',
download_fail: '文件保存失败,请稍后再试~',
},
menu: {
fileManage: '文件管理',
+3
View File
@@ -14,6 +14,9 @@ instance.interceptors.request.use(
});
instance.interceptors.response.use(
(response:any) => {
if (response.status === 200 && response.config.url === '/admin/file/download') {
return response;
}
if (response.data.code === 200) {
return response.data;
} else {
+11
View File
@@ -0,0 +1,11 @@
export function formatTimestamp(timestamp: string): string {
const date = new Date(timestamp);
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
const seconds = date.getSeconds().toString().padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
+67 -3
View File
@@ -12,7 +12,7 @@
<el-table-column prop="used_count" :label="t('admin.fileView.used_count')" />
<el-table-column prop="expired_count" :label="t('admin.fileView.expired_count')">
<template #default="scope">
<span>{{ scope.row.expired_count > -1 ? scope.row.expired_count : '不限次数' }}</span>
<span>{{ scope.row.expired_count > -1 ? scope.row.expired_count : t('admin.fileView.unlimited_count') }}</span>
</template>
</el-table-column>
<el-table-column prop="size" :label="t('admin.fileView.size')">
@@ -22,7 +22,7 @@
</el-table-column>
<el-table-column prop="expired_at" :label="t('admin.fileView.expired_at')">
<template #default="scope">
<span>{{ scope.row.expired_at ? scope.row.expired_at : '永久有效' }}</span>
<span>{{ scope.row.expired_at ? formatTimestamp(scope.row.expired_at) : t('admin.fileView.forever') }}</span>
</template>
</el-table-column>
<el-table-column prop="file_path" :label="t('admin.fileView.file_path')" />
@@ -32,6 +32,7 @@
</template>
<template #default="scope">
<el-button type="danger" size="small" @click="deleteFile(scope.row.id)">{{ t('admin.fileView.delete') }}</el-button>
<el-button type="success" size="small" @click="downloadFile(scope.row.id)" v-if="scope.row.file_path">{{ t('admin.fileView.download') }}</el-button>
</template>
</el-table-column>
</el-table>
@@ -40,6 +41,7 @@
</template>
<script lang="ts" setup>
import { request } from "@/utils/request";
import { formatTimestamp } from "@/utils/timestamp-format"
import { ref } from "vue";
import { ElMessage } from "element-plus";
const tableData = ref([]);
@@ -64,10 +66,72 @@ const deleteFile = (id: number) => {
id,
},
}).then(() => {
ElMessage.success('删除成功');
ElMessage.success(t('admin.fileView.delete_success'));
refreshData();
});
};
const downloadFile = (id: number) => {
request({
url: '/admin/file/download',
method: 'get',
params: {
id,
},
responseType: 'blob'
}).then((response: any) => {
const contentDisposition = response.headers['content-disposition'];
let filename = 'file';
// 使用正则表达式来提取文件名
const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
if (filenameMatch != null && filenameMatch[1]) {
// 去除文件名周围的引号
filename = filenameMatch[1].replace(/['"]/g, '');
}
// @ts-ignore
if (window.showSaveFilePicker)
saveFileByWebApi(response.data, filename).catch(() => {
// ElMessage.error('文件保存函数不支持您的浏览器');
saveFileByElementA(response.data, filename).catch(() => {
ElMessage.error(t('admin.fileView.download_fail'));
})
})
else
saveFileByElementA(response.data, filename).catch(() => {
ElMessage.error(t('admin.fileView.download_fail'));
})
});
};
async function saveFileByElementA(fileBlob: Blob, filename: string) {
const downloadUrl = window.URL.createObjectURL(fileBlob);
const link = document.createElement('a');
link.href = downloadUrl;
link.download = filename; // 设置下载文件名
document.body.appendChild(link);
link.click();
// 清理并释放URL对象
window.URL.revokeObjectURL(downloadUrl);
document.body.removeChild(link);
}
async function saveFileByWebApi(fileBlob: Blob, filename: string) {
// 创建一个新句柄。
// @ts-ignore
const newHandle = await window.showSaveFilePicker({
suggestedName: filename,
});
// 创建一个 FileSystemWritableFileStream 用于写入。
const writableStream = await newHandle.createWritable();
// 写入我们的文件。
await writableStream.write(fileBlob);
// 关闭文件并将内容写入磁盘。
await writableStream.close();
}
const updatePageSize=(pageSize: number) => {
params.value.size = pageSize;
refreshData();