no message
parent
ba2c7f819b
commit
316d40908d
|
|
@ -62,8 +62,8 @@ export const itemApi = {
|
|||
/**
|
||||
* 导出 @author hj
|
||||
*/
|
||||
exportItems: () => {
|
||||
return getDownload('/item/exportItems',{});
|
||||
exportItems: (taskId: string) => {
|
||||
return getDownload(`/item/exportItems/${taskId}`,{});
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
</template>
|
||||
导入
|
||||
</a-button>
|
||||
|
||||
<a-modal
|
||||
v-model:open="open"
|
||||
@cancel="onClose"
|
||||
|
|
@ -69,7 +70,7 @@
|
|||
<template #title>
|
||||
<span style="display: inline-flex; align-items: center">
|
||||
<LoadingOutlined style="margin-right: 8px"/>
|
||||
{{progressTitle}}
|
||||
{{ progressTitle }}
|
||||
</span>
|
||||
</template>
|
||||
<template #footer>
|
||||
|
|
@ -193,7 +194,7 @@
|
|||
<script setup lang="ts">
|
||||
import {reactive, ref, onMounted} from '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 {addressApi} from '/@/api/business/wms/base/address/address-api';
|
||||
import {PAGE_SIZE_OPTIONS} from '/@/constants/common-const';
|
||||
|
|
@ -449,6 +450,7 @@ const currentTaskId = ref('');//当前任务ID
|
|||
const open = ref<boolean>(false);//显示模态框
|
||||
|
||||
const onExportAddress = async () => {
|
||||
|
||||
try {
|
||||
open.value = true;
|
||||
//获取导出任务ID
|
||||
|
|
@ -456,17 +458,12 @@ const onExportAddress = async () => {
|
|||
currentTaskId.value = taskId;
|
||||
progressStatus.value = 'active';
|
||||
//导出
|
||||
addressApi.exportAddress(currentTaskId.value);
|
||||
await addressApi.exportAddress(currentTaskId.value);
|
||||
// 启动轮询
|
||||
const timer = setInterval(async () => {
|
||||
try {
|
||||
//获取当前任务的进度条
|
||||
const {data: progress} = await addressApi.getExportProgress(currentTaskId.value);
|
||||
if (progress === -1) {
|
||||
clearInterval(timer);
|
||||
progressStatus.value = 'exception';
|
||||
return;
|
||||
}
|
||||
progressPercent.value = progress;
|
||||
if (progress >= 100) {
|
||||
clearInterval(timer);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@
|
|||
<ItemSelect v-model:value="queryForm.itemId" :disabledFlag="true" @change="onSearch"/>
|
||||
</a-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="false">禁用</a-select-option>
|
||||
</a-select>
|
||||
|
|
@ -62,6 +63,28 @@
|
|||
导入
|
||||
</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'">
|
||||
<template #icon>
|
||||
<ExportOutlined/>
|
||||
|
|
@ -190,6 +213,8 @@ import ItemSelect from "/@/views/business/wms/base/item/item-select.vue";
|
|||
import {UploadFile} from 'ant-design-vue';
|
||||
import {fileApi} from "/@/api/support/file-api";
|
||||
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([
|
||||
{
|
||||
|
|
@ -473,9 +498,97 @@ async function onImportItems() {
|
|||
}
|
||||
|
||||
//导出
|
||||
function onExportItems() {
|
||||
itemApi.exportItems();
|
||||
}
|
||||
const progressTitle = ref('文件下载中,请稍等...');
|
||||
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);
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Reference in New Issue