no message

main
HUOJIN\92525 2025-05-12 15:12:40 +08:00
parent fb50787fcd
commit 6bd3ddb555
6 changed files with 268 additions and 16 deletions

View File

@ -5,7 +5,7 @@
* @Date: 2024-11-18 14:17:31 * @Date: 2024-11-18 14:17:31
* @Copyright * @Copyright
*/ */
import {postRequest, getRequest, getDownload} from '/@/lib/axios'; import {postRequest, getRequest, postDownload2} from '/@/lib/axios';
export const locationApi = { export const locationApi = {
@ -76,7 +76,7 @@ export const locationApi = {
/** /**
* @author hj * @author hj
*/ */
exportLocations : () =>{ exportLocations: (taskId: string, param: any, signal?: AbortSignal) => {
return getDownload('/location/exportLocations',{}); return postDownload2(`/location/exportLocations/${taskId}`, param, signal);
} },
}; };

View File

@ -5,7 +5,7 @@
* @Date: 2024-11-26 11:37:48 * @Date: 2024-11-26 11:37:48
* @Copyright * @Copyright
*/ */
import {postRequest, getRequest,getDownload} from '/@/lib/axios'; import {postRequest, getRequest,postDownload2} from '/@/lib/axios';
export const stockApi = { export const stockApi = {
@ -61,9 +61,9 @@ export const stockApi = {
/** /**
* @author hj * @author hj
*/ */
exportStocks: () => { exportStocks: (taskId: string, param: any, signal?: AbortSignal) => {
return getDownload('/stock/exportStocks', {}); return postDownload2(`/stock/exportStocks/${taskId}`, param, signal);
} },
}; };

View File

@ -544,6 +544,7 @@ const onCancel = () => {
abortController.value.abort(); abortController.value.abort();
abortController.value = null; abortController.value = null;
} }
handleExportError();
}; };
onMounted(queryData); onMounted(queryData);

View File

@ -598,6 +598,7 @@ const onCancel = () => {
abortController.value.abort(); abortController.value.abort();
abortController.value = null; abortController.value = null;
} }
handleExportError();
}; };
onMounted(queryData); onMounted(queryData);

View File

@ -85,6 +85,28 @@
导入 导入
</a-button> </a-button>
<a-modal
v-model:open="open"
@cancel="onCancel"
: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="onCancel"></a-button>
</a-space>
</template>
</a-modal>
<a-button @click="onExportLocations" type="primary" v-privilege="'location:exportLocations'"> <a-button @click="onExportLocations" type="primary" v-privilege="'location:exportLocations'">
<template #icon> <template #icon>
<ExportOutlined/> <ExportOutlined/>
@ -226,6 +248,7 @@ import {reactive, ref, onMounted} from 'vue';
import {message, Modal} from 'ant-design-vue'; import {message, Modal} from 'ant-design-vue';
import {SmartLoading} from '/@/components/framework/smart-loading'; import {SmartLoading} from '/@/components/framework/smart-loading';
import {locationApi} from '/@/api/business/wms/base/location/location-api'; import {locationApi} from '/@/api/business/wms/base/location/location-api';
import {exportApi} from "/@/api/business/wms/export/export-api";
import {PAGE_SIZE_OPTIONS} from '/@/constants/common-const'; import {PAGE_SIZE_OPTIONS} from '/@/constants/common-const';
import {smartSentry} from '/@/lib/smart-sentry'; import {smartSentry} from '/@/lib/smart-sentry';
import TableOperator from '/@/components/support/table-operator/index.vue'; import TableOperator from '/@/components/support/table-operator/index.vue';
@ -239,6 +262,7 @@ import DictLabel from '/@/components/support/dict-label/index.vue';
import MultipleInsert from "/@/views/business/wms/base/location/multiple-insert.vue"; import MultipleInsert from "/@/views/business/wms/base/location/multiple-insert.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 {LoadingOutlined} from "@ant-design/icons-vue";
// ---------------------------- ---------------------------- // ---------------------------- ----------------------------
let columns = ref([ let columns = ref([
@ -554,9 +578,108 @@ async function onImportLocations() {
} }
// //
function onExportLocations() { const progressTitle = ref('文件下载中,请稍等...');//
locationApi.exportLocations(); const progressPercent = ref(0);//
} const progressStatus = ref('active');
const currentTaskId = ref('');//ID
const open = ref(false);//
const timerId = ref<NodeJS.Timeout | null>(null); //
const isExporting = ref(false); //
const abortController = ref<AbortController | null>(null);//
const onExportLocations = async () => {
if (isExporting.value) return;
try {
isExporting.value = true;
abortController.value = new AbortController(); //
open.value = true;
resetProgressState(); //
//
const {data: taskId} = await exportApi.createExportTask();
currentTaskId.value = taskId;
//
try {
locationApi.exportLocations(taskId, queryForm, abortController.value.signal)
} catch (error) {
handleExportError();
}
//
if (timerId.value) {
clearInterval(timerId.value);
}
//
timerId.value = setInterval(async () => {
try {
const {data: progress} = await exportApi.getExportProgress(currentTaskId.value);
if (progress == -1) {
handleExportError();
}
progressPercent.value = progress;
console.log('progress', progress);
if (progress >= 100) {
handleExportSuccess();
}
} catch (error) {
handleExportError();
}
}, 1000);
} catch (error) {
handleExportError();
} finally {
isExporting.value = false;
}
};
//
const handleExportSuccess = () => {
if (timerId.value) {
clearInterval(timerId.value);
}
progressStatus.value = 'success';
progressTitle.value = '文件下载完成';
setTimeout(() => {
open.value = false;
resetProgressState();
}, 1000);
};
//
const handleExportError = () => {
if (timerId.value) clearInterval(timerId.value);
progressStatus.value = 'exception';
progressPercent.value = 0;
open.value = false;
resetProgressState();
};
//
const resetProgressState = () => {
progressPercent.value = 0;
progressStatus.value = 'active';
progressTitle.value = '文件下载中,请稍等...';
currentTaskId.value = '';
};
//
const onCancel = () => {
//
open.value = false;
if (abortController.value) {
abortController.value.abort();
abortController.value = null;
}
handleExportError();
};
onMounted(queryData); onMounted(queryData);
</script> </script>

View File

@ -16,10 +16,12 @@
<LocationSelect v-model:value="queryForm.locationId" :disabledFlag="true" @change="onSearch"/> <LocationSelect v-model:value="queryForm.locationId" :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">
<SmartEnumSelect style="width: 200px" enum-name="USAGE_STATUS_ENUM" v-model:value="queryForm.status" @change="onSearch"/> <SmartEnumSelect style="width: 200px" enum-name="USAGE_STATUS_ENUM" v-model:value="queryForm.status"
@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>
@ -68,6 +70,28 @@
导入 导入
</a-button> </a-button>
<a-modal
v-model:open="open"
@cancel="onCancel"
: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="onCancel"></a-button>
</a-space>
</template>
</a-modal>
<a-button @click="onExportStocks" type="primary" v-privilege="'stock:exportStocks'"> <a-button @click="onExportStocks" type="primary" v-privilege="'stock:exportStocks'">
<template #icon> <template #icon>
<ExportOutlined/> <ExportOutlined/>
@ -200,6 +224,9 @@ import StockSelect from "/@/views/business/wms/base/stock/stock-select.vue";
import SmartEnumSelect from "/@/components/framework/smart-enum-select/index.vue"; import SmartEnumSelect from "/@/components/framework/smart-enum-select/index.vue";
import LocationSelect from "/@/views/business/wms/base/location/location-select.vue"; import LocationSelect from "/@/views/business/wms/base/location/location-select.vue";
import DictLabel from "/@/components/support/dict-label/index.vue"; import DictLabel from "/@/components/support/dict-label/index.vue";
import {LoadingOutlined} from "@ant-design/icons-vue";
import {exportApi} from "/@/api/business/wms/export/export-api";
import {itemApi} from "/@/api/business/wms/base/item/item-api";
// ---------------------------- ---------------------------- // ---------------------------- ----------------------------
let columns = ref([ let columns = ref([
@ -479,9 +506,109 @@ async function onImportStocks() {
} }
// //
function onExportStocks() { const progressTitle = ref('文件下载中,请稍等...');//
stockApi.exportStocks(); const progressPercent = ref(0);//
} const progressStatus = ref('active');
const currentTaskId = ref('');//ID
const open = ref(false);//
const timerId = ref<NodeJS.Timeout | null>(null); //
const isExporting = ref(false); //
const abortController = ref<AbortController | null>(null);//
const onExportStocks = async () => {
if (isExporting.value) return;
try {
isExporting.value = true;
abortController.value = new AbortController(); //
open.value = true;
resetProgressState(); //
//
const {data: taskId} = await exportApi.createExportTask();
currentTaskId.value = taskId;
//
try {
itemApi.exportItems(taskId, queryForm, abortController.value.signal)
} catch (error) {
handleExportError();
}
//
if (timerId.value) {
clearInterval(timerId.value);
}
//
timerId.value = setInterval(async () => {
try {
const {data: progress} = await exportApi.getExportProgress(currentTaskId.value);
if (progress == -1) {
handleExportError();
}
progressPercent.value = progress;
if (progress >= 100) {
handleExportSuccess();
}
} catch (error) {
handleExportError();
}
}, 1000);
} catch (error) {
handleExportError();
} finally {
isExporting.value = false;
}
};
//
const handleExportSuccess = () => {
if (timerId.value) {
clearInterval(timerId.value);
}
progressStatus.value = 'success';
progressTitle.value = '文件下载完成';
setTimeout(() => {
open.value = false;
resetProgressState();
}, 1000);
};
//
const handleExportError = () => {
if (timerId.value) clearInterval(timerId.value);
progressStatus.value = 'exception';
progressPercent.value = 0;
open.value = false;
resetProgressState();
};
//
const resetProgressState = () => {
progressPercent.value = 0;
progressStatus.value = 'active';
progressTitle.value = '文件下载中,请稍等...';
currentTaskId.value = '';
};
//
const onCancel = () => {
//
open.value = false;
if (abortController.value) {
abortController.value.abort();
abortController.value = null;
}
handleExportError();
};
onMounted(queryData); onMounted(queryData);
</script> </script>