feat: 批量下载任务

This commit is contained in:
rd
2025-07-21 15:10:26 +08:00
parent 4800d5fa99
commit e6798bf313
8 changed files with 103 additions and 20 deletions

View File

@ -3,10 +3,10 @@ import { ref, computed } from 'vue';
import { Input, Table, TableColumn, Checkbox, Pagination, Button, Tooltip, Notification } from '@arco-design/web-vue';
import { IconSearch, IconClose, IconQuestionCircle } from '@arco-design/web-vue/es/icon';
import NoData from '@/components/no-data';
import { getTask, postRedoTask } from '@/api/all/common';
import { getTask, postRedoTask, postBatchDownload, batchQueryTaskStatus } from '@/api/all/common';
import { INITIAL_FORM, TABLE_COLUMNS } from './constants';
import { EXPORT_TASK_STATUS, enumTaskStatus } from '../../constants';
import { formatTableField, exactFormatTime } from '@/utils/tools';
import { formatTableField, exactFormatTime, genRandomId } from '@/utils/tools';
import { useTableSelectionWithPagination } from '@/hooks/useTableSelectionWithPagination';
import { downloadByUrl } from '@/utils/tools';
import DeleteTaskModal from './delete-task-modal.vue';
@ -34,9 +34,11 @@ export default {
getData();
},
});
let queryTaskTimer = null;
const query = ref({ ...INITIAL_FORM });
const query = ref(cloneDeep(INITIAL_FORM));
const deleteTaskModalRef = ref(null);
const downloadTaskIds = ref([]);
const checkedAll = computed(() => selectedRows.value.length === dataSource.value.length);
const indeterminate = computed(
@ -44,11 +46,12 @@ export default {
);
const reset = () => {
query.value = { ...INITIAL_FORM };
pageInfo.value = { ...DEFAULT_PAGE_INFO };
query.value = cloneDeep(INITIAL_FORM);
pageInfo.value = cloneDeep(DEFAULT_PAGE_INFO);
selectedRowKeys.value = [];
selectedRows.value = [];
dataSource.value = [];
downloadTaskIds.value = [];
};
const init = () => {
@ -82,7 +85,7 @@ export default {
reload();
};
const handleCloseTip = () => {
const clearSelectedRows = () => {
selectedRows.value = [];
selectedRowKeys.value = [];
};
@ -98,8 +101,66 @@ export default {
record.file && downloadByUrl(record.file);
}
};
const handleBatchDownload = () => {
// 批量下载逻辑
const clearQueryTaskTimer = () => {
if (queryTaskTimer) {
clearInterval(queryTaskTimer);
queryTaskTimer = null;
}
};
const startBatchDownload = (id) => {
const randomId = genRandomId();
showExportNotification(
`正在批量下载“${selectedRows.value[0]?.name}”等${selectedRows.value.length}个文件,请稍后...`,
{
duration: 0,
id: randomId,
},
);
downloadTaskIds.value.push({
id,
randomId,
});
// getSyncTaskStatus(randomId);
if (!queryTaskTimer) {
queryTaskTimer = setInterval(() => getSyncTaskStatus(), 3000);
}
};
const handleBatchDownload = debounce(async () => {
const { code, data } = await postBatchDownload({ ids: selectedRowKeys.value });
if (code === 200) {
startBatchDownload(data.id);
}
}, 500);
const getSyncTaskStatus = async () => {
const { code, data } = await batchQueryTaskStatus({ ids: downloadTaskIds.value.map((v) => v.id) });
if (code === 200) {
let completeTaskNum = 0;
data.forEach((item) => {
const { status, file, id } = item;
if (status !== 0) {
completeTaskNum++;
const notificationId = downloadTaskIds.value.find((v) => v.id === id)?.randomId;
notificationId && Notification.remove(notificationId);
if (status === 1) {
AMessage.success('批量下载已完成,正在下载文件...');
downloadByUrl(file);
} else if (status === 2) {
AMessage.error('批量下载失败,请重新尝试下载');
}
}
});
// 全部完成了
if (completeTaskNum === data.length) {
clearQueryTaskTimer();
clearSelectedRows();
downloadTaskIds.value = [];
}
}
};
const handleDelete = (record) => {
@ -121,8 +182,14 @@ export default {
selectedRowKeys.value = [];
getData();
};
const unloadComp = () => {
clearQueryTaskTimer();
};
onUnmounted(() => {
clearQueryTaskTimer;
});
expose({ init, reset });
expose({ init, reset, unloadComp });
return () => (
<div class="export-task-wrap">
@ -187,7 +254,7 @@ export default {
</span>
</div>
</div>
<IconClose size={16} class="cursor-pointer color-#737478" onClick={handleCloseTip} />
<IconClose size={16} class="cursor-pointer color-#737478" onClick={clearSelectedRows} />
</div>
)}
@ -252,7 +319,7 @@ export default {
))}
<TableColumn
data-index="operation"
width={100}
width={110}
fixed="right"
title="操作"
v-slots={{

View File

@ -52,6 +52,7 @@ const onClose = () => {
activeTab.value = '0';
clearTimer();
componentRef.value?.unloadComp?.()
visible.value = false;
};
const clearTimer = () => {