refactor: oss下载 重构为浏览器原生下载(非阻塞)

This commit is contained in:
dap
2025-08-13 10:07:38 +08:00
parent 9eb9fef430
commit a17618423c
3 changed files with 63 additions and 24 deletions

View File

@@ -16,6 +16,7 @@
- Modal/Drawer中使用VxeTable tooltip需要设置更高的z-index 防止被遮挡 - Modal/Drawer中使用VxeTable tooltip需要设置更高的z-index 防止被遮挡
- 字典(DictTag)使用tsx写法重构 - 字典(DictTag)使用tsx写法重构
- 请假申请 按钮区域重构 - 请假申请 按钮区域重构
- oss下载 重构为浏览器原生下载(非阻塞)
**OTHERS** **OTHERS**

View File

@@ -65,6 +65,20 @@ export function ossDownload(
}); });
} }
/**
* 在使用浏览器原生下载前检测是否登录
* 这里的方案为请求一次接口 如果登录超时会走到response的401逻辑
* 如果没有listByIds的权限 也不会弹出无权限提示
* 仅仅是为了检测token是否有效使用
*
* @returns void
*/
export function checkLoginBeforeDownload() {
return requestClient.get<OssFile[]>(`${Api.ossInfo}/1`, {
errorMessageMode: 'none',
});
}
/** /**
* 删除文件 * 删除文件
* @param ossIds id数组 * @param ossIds id数组

View File

@@ -9,12 +9,14 @@ import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui'; import { Page, useVbenModal } from '@vben/common-ui';
import { useAppConfig } from '@vben/hooks';
import { $t } from '@vben/locales'; import { $t } from '@vben/locales';
import { stringify } from '@vben/request';
import { useAccessStore } from '@vben/stores';
import { getVxePopupContainer } from '@vben/utils'; import { getVxePopupContainer } from '@vben/utils';
import { import {
Image, Image,
message,
Modal, Modal,
Popconfirm, Popconfirm,
Space, Space,
@@ -29,9 +31,8 @@ import {
vxeCheckboxChecked, vxeCheckboxChecked,
} from '#/adapter/vxe-table'; } from '#/adapter/vxe-table';
import { configInfoByKey } from '#/api/system/config'; import { configInfoByKey } from '#/api/system/config';
import { ossDownload, ossList, ossRemove } from '#/api/system/oss'; import { checkLoginBeforeDownload, ossList, ossRemove } from '#/api/system/oss';
import { calculateFileSize } from '#/utils/file'; import { downloadByUrl } from '#/utils/file/download';
import { downloadByData } from '#/utils/file/download';
import { supportImageList } from './constant'; import { supportImageList } from './constant';
import { columns, querySchema } from './data'; import { columns, querySchema } from './data';
@@ -112,27 +113,50 @@ const [BasicTable, tableApi] = useVbenVxeGrid({
}, },
}); });
// async function handleDownload(row: OssFile) {
// const downloadSize = ref($t('pages.common.downloadLoading'));
// const hideLoading = message.loading({
// content: () => downloadSize.value,
// duration: 0,
// });
// try {
// const data = await ossDownload(row.ossId, (e) => {
// // 计算下载进度
// const percent = Math.floor((e.loaded / e.total!) * 100);
// // 已经下载
// const current = calculateFileSize(e.loaded);
// // 总大小
// const total = calculateFileSize(e.total!);
// downloadSize.value = `已下载: ${current}/${total} (${percent}%)`;
// });
// downloadByData(data, row.originalName);
// message.success('下载完成');
// } finally {
// hideLoading();
// }
// }
const { apiURL, clientId } = useAppConfig(
import.meta.env,
import.meta.env.PROD,
);
const accessStore = useAccessStore();
/**
* 浏览器直接接管下载 相较于axios请求 不会阻塞
* @param row oss信息
*/
async function handleDownload(row: OssFile) { async function handleDownload(row: OssFile) {
const downloadSize = ref($t('pages.common.downloadLoading')); await checkLoginBeforeDownload();
const hideLoading = message.loading({
content: () => downloadSize.value, const params = {
duration: 0, clientid: clientId,
}); Authorization: `Bearer ${accessStore.accessToken}`,
try { };
const data = await ossDownload(row.ossId, (e) => {
// 计算下载进度 const downloadLink = `${apiURL}/resource/oss/download/${row.ossId}?${stringify(params)}`;
const percent = Math.floor((e.loaded / e.total!) * 100); // fileName不设置也行 默认会取header里的名称
// 已经下载 downloadByUrl({ fileName: row.fileName, url: downloadLink });
const current = calculateFileSize(e.loaded);
// 总大小
const total = calculateFileSize(e.total!);
downloadSize.value = `已下载: ${current}/${total} (${percent}%)`;
});
downloadByData(data, row.originalName);
message.success('下载完成');
} finally {
hideLoading();
}
} }
async function handleDelete(row: OssFile) { async function handleDelete(row: OssFile) {