no message

main
HUOJIN\92525 2025-05-09 21:54:41 +08:00
parent ba2c7f819b
commit 316d40908d
3 changed files with 125 additions and 15 deletions

View File

@ -62,8 +62,8 @@ export const itemApi = {
/** /**
* @author hj * @author hj
*/ */
exportItems: () => { exportItems: (taskId: string) => {
return getDownload('/item/exportItems',{}); return getDownload(`/item/exportItems/${taskId}`,{});
} }
}; };

View File

@ -56,6 +56,7 @@
</template> </template>
导入 导入
</a-button> </a-button>
<a-modal <a-modal
v-model:open="open" v-model:open="open"
@cancel="onClose" @cancel="onClose"
@ -69,7 +70,7 @@
<template #title> <template #title>
<span style="display: inline-flex; align-items: center"> <span style="display: inline-flex; align-items: center">
<LoadingOutlined style="margin-right: 8px"/> <LoadingOutlined style="margin-right: 8px"/>
{{progressTitle}} {{ progressTitle }}
</span> </span>
</template> </template>
<template #footer> <template #footer>
@ -193,7 +194,7 @@
<script setup lang="ts"> <script setup lang="ts">
import {reactive, ref, onMounted} from 'vue'; import {reactive, ref, onMounted} from 'vue';
import {message, Modal, UploadFile} from 'ant-design-vue'; import {message, Modal, UploadFile} from 'ant-design-vue';
import { LoadingOutlined } from '@ant-design/icons-vue'; import {LoadingOutlined} from '@ant-design/icons-vue';
import {SmartLoading} from '/@/components/framework/smart-loading'; import {SmartLoading} from '/@/components/framework/smart-loading';
import {addressApi} from '/@/api/business/wms/base/address/address-api'; import {addressApi} from '/@/api/business/wms/base/address/address-api';
import {PAGE_SIZE_OPTIONS} from '/@/constants/common-const'; import {PAGE_SIZE_OPTIONS} from '/@/constants/common-const';
@ -449,6 +450,7 @@ const currentTaskId = ref('');//当前任务ID
const open = ref<boolean>(false);// const open = ref<boolean>(false);//
const onExportAddress = async () => { const onExportAddress = async () => {
try { try {
open.value = true; open.value = true;
//ID //ID
@ -456,17 +458,12 @@ const onExportAddress = async () => {
currentTaskId.value = taskId; currentTaskId.value = taskId;
progressStatus.value = 'active'; progressStatus.value = 'active';
// //
addressApi.exportAddress(currentTaskId.value); await addressApi.exportAddress(currentTaskId.value);
// //
const timer = setInterval(async () => { const timer = setInterval(async () => {
try { try {
// //
const {data: progress} = await addressApi.getExportProgress(currentTaskId.value); const {data: progress} = await addressApi.getExportProgress(currentTaskId.value);
if (progress === -1) {
clearInterval(timer);
progressStatus.value = 'exception';
return;
}
progressPercent.value = progress; progressPercent.value = progress;
if (progress >= 100) { if (progress >= 100) {
clearInterval(timer); clearInterval(timer);

View File

@ -13,7 +13,8 @@
<ItemSelect v-model:value="queryForm.itemId" :disabledFlag="true" @change="onSearch"/> <ItemSelect v-model:value="queryForm.itemId" :disabledFlag="true" @change="onSearch"/>
</a-form-item> </a-form-item>
<a-form-item label="是否启用" class="smart-query-form-item"> <a-form-item label="是否启用" class="smart-query-form-item">
<a-select style="width: 200px" v-model:value="queryForm.disabledFlag" allowClear placeholder="请选择" @change="onSearch"> <a-select style="width: 200px" v-model:value="queryForm.disabledFlag" allowClear placeholder="请选择"
@change="onSearch">
<a-select-option :value="true">启用</a-select-option> <a-select-option :value="true">启用</a-select-option>
<a-select-option :value="false">禁用</a-select-option> <a-select-option :value="false">禁用</a-select-option>
</a-select> </a-select>
@ -62,6 +63,28 @@
导入 导入
</a-button> </a-button>
<a-modal
v-model:open="open"
@cancel="onClose"
:closable="false"
:maskClosable="false"
:destroyOnClose="true">
<a-progress
:percent="progressPercent"
:status="progressStatus"
/>
<template #title>
<span style="display: inline-flex; align-items: center">
<LoadingOutlined style="margin-right: 8px"/>
{{ progressTitle }}
</span>
</template>
<template #footer>
<a-space>
<a-button @click="onClose"></a-button>
</a-space>
</template>
</a-modal>
<a-button @click="onExportItems" type="primary" v-privilege="'item:exportItems'"> <a-button @click="onExportItems" type="primary" v-privilege="'item:exportItems'">
<template #icon> <template #icon>
<ExportOutlined/> <ExportOutlined/>
@ -190,6 +213,8 @@ import ItemSelect from "/@/views/business/wms/base/item/item-select.vue";
import {UploadFile} from 'ant-design-vue'; import {UploadFile} from 'ant-design-vue';
import {fileApi} from "/@/api/support/file-api"; import {fileApi} from "/@/api/support/file-api";
import DictLabel from "/@/components/support/dict-label/index.vue"; import DictLabel from "/@/components/support/dict-label/index.vue";
import {addressApi} from "/@/api/business/wms/base/address/address-api";
import {LoadingOutlined} from "@ant-design/icons-vue";
// ---------------------------- ---------------------------- // ---------------------------- ----------------------------
let columns = ref([ let columns = ref([
{ {
@ -473,9 +498,97 @@ async function onImportItems() {
} }
// //
function onExportItems() { const progressTitle = ref('文件下载中,请稍等...');
itemApi.exportItems(); const progressPercent = ref(0);
} const progressStatus = ref('active');
const currentTaskId = ref('');
const open = ref(false);
const pollTimer = ref<NodeJS.Timeout>(); // 使ref
//
const resetProgress = () => {
progressPercent.value = 0;
progressStatus.value = 'active';
progressTitle.value = '文件下载中,请稍等...';
};
//
const startProgressPolling = async (taskId: string) => {
try {
// 1
pollTimer.value = setInterval(async () => {
try {
const { data: progress } = await addressApi.getExportProgress(taskId);
progressPercent.value = progress;
if (progress >= 100) {
handleComplete();
clearInterval(pollTimer.value);
}
} catch (error) {
handlePollingError();
clearInterval(pollTimer.value);
}
}, 200); // 1
} catch (error) {
handlePollingError();
}
};
//
const handleComplete = () => {
progressStatus.value = 'success';
progressTitle.value = '文件下载完成';
// 使
open.value = false;
resetProgress();
};
//
const handlePollingError = () => {
progressStatus.value = 'exception';
progressPercent.value = 0;
progressTitle.value = '获取进度失败';
};
const onExportItems = async () => {
try {
//
if (pollTimer.value) clearInterval(pollTimer.value);
// ID
resetProgress();
currentTaskId.value = '';
open.value = true;
// ID
const { data: taskId } = await addressApi.createExportTask();
currentTaskId.value = taskId;
//
await Promise.race([
itemApi.exportItems(taskId),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('导出超时')), 30_000)
)
]);
//
await startProgressPolling(taskId);
} catch (error: any) {
open.value = false;
message.error('导出失败: ' + error.message);
//
if (pollTimer.value) clearInterval(pollTimer.value);
resetProgress();
}
};
const onClose = () => {
resetProgress();
};
onMounted(queryData); onMounted(queryData);
</script> </script>