Showing
4 changed files
with
213 additions
and
75 deletions
| ... | @@ -64,3 +64,29 @@ export function getCustomizeExcel(data) { | ... | @@ -64,3 +64,29 @@ export function getCustomizeExcel(data) { |
| 64 | data: data, | 64 | data: data, |
| 65 | }); | 65 | }); |
| 66 | } | 66 | } |
| 67 | + | ||
| 68 | +// 查询导出的任务ID | ||
| 69 | + | ||
| 70 | +// POST | ||
| 71 | +// /exportList/submitExportTask | ||
| 72 | +export function getSubmitExportTask(data) { | ||
| 73 | + return request({ | ||
| 74 | + url: "/bus-customer/exportList/submitExportTask", | ||
| 75 | + method: "post", | ||
| 76 | + data: data, | ||
| 77 | + }); | ||
| 78 | +} | ||
| 79 | +// /asyncExport/taskStatus/{taskId} | ||
| 80 | +export function getTaskStatus(data) { | ||
| 81 | + return request({ | ||
| 82 | + url: "/bus-customer/asyncExport/taskStatus/" + data.taskId, | ||
| 83 | + method: "get", | ||
| 84 | + }); | ||
| 85 | +} | ||
| 86 | +// /asyncExport/download/{taskId} | ||
| 87 | +export function getDownload(data) { | ||
| 88 | + return request({ | ||
| 89 | + url: "/bus-customer/asyncExport/download/" + data.taskId, | ||
| 90 | + method: "get", | ||
| 91 | + }); | ||
| 92 | +} | ... | ... |
| 1 | -import axios from 'axios' | 1 | +import axios from "axios"; |
| 2 | -import { MessageBox, Message } from 'element-ui' | 2 | +import { MessageBox, Message } from "element-ui"; |
| 3 | -import store from '@/store' | 3 | +import store from "@/store"; |
| 4 | -import { getToken, setTime, removeTime, removeToken } from '@/utils/auth' | 4 | +import { getToken, setTime, removeTime, removeToken } from "@/utils/auth"; |
| 5 | -import errorCode from '@/utils/errorCode' | 5 | +import errorCode from "@/utils/errorCode"; |
| 6 | -import i18n from '@/assets/languages' | 6 | +import i18n from "@/assets/languages"; |
| 7 | 7 | ||
| 8 | -axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' | 8 | +axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8"; |
| 9 | // 创建axios实例 | 9 | // 创建axios实例 |
| 10 | const service = axios.create({ | 10 | const service = axios.create({ |
| 11 | // axios中请求配置有baseURL选项,表示请求URL公共部分 | 11 | // axios中请求配置有baseURL选项,表示请求URL公共部分 |
| 12 | baseURL: process.env.VUE_APP_BASE_API, | 12 | baseURL: process.env.VUE_APP_BASE_API, |
| 13 | // 超时 | 13 | // 超时 |
| 14 | - timeout: 1800000 | 14 | + timeout: 180000000, |
| 15 | -}) | 15 | +}); |
| 16 | // request拦截器 | 16 | // request拦截器 |
| 17 | -service.interceptors.request.use(config => { | 17 | +service.interceptors.request.use( |
| 18 | + (config) => { | ||
| 18 | // 是否需要设置 token | 19 | // 是否需要设置 token |
| 19 | - const isToken = (config.headers || {}).isToken === false | 20 | + const isToken = (config.headers || {}).isToken === false; |
| 20 | // if (getToken() && !isToken) { | 21 | // if (getToken() && !isToken) { |
| 21 | - config.headers['Authorization'] = getToken() == null ? '1' : 'Bearer ' + getToken()// 让每个请求携带自定义token 请根据实际情况自行修改 | 22 | + config.headers["Authorization"] = |
| 23 | + getToken() == null ? "1" : "Bearer " + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改 | ||
| 22 | // } | 24 | // } |
| 23 | - config.headers['Lang'] = localStorage.getItem('iClearExpLang') ? localStorage.getItem('iClearExpLang') : '1' | 25 | + config.headers["Lang"] = localStorage.getItem("iClearExpLang") |
| 24 | - config.headers['Ver'] = process.env.VUE_APP_APIVERSION | 26 | + ? localStorage.getItem("iClearExpLang") |
| 27 | + : "1"; | ||
| 28 | + config.headers["Ver"] = process.env.VUE_APP_APIVERSION; | ||
| 25 | // get请求映射params参数 | 29 | // get请求映射params参数 |
| 26 | - if (config.method === 'get' && config.params) { | 30 | + if (config.method === "get" && config.params) { |
| 27 | - let url = config.url + '?'; | 31 | + let url = config.url + "?"; |
| 28 | for (const propName of Object.keys(config.params)) { | 32 | for (const propName of Object.keys(config.params)) { |
| 29 | const value = config.params[propName]; | 33 | const value = config.params[propName]; |
| 30 | var part = encodeURIComponent(propName) + "="; | 34 | var part = encodeURIComponent(propName) + "="; |
| 31 | - if (value !== null && typeof (value) !== "undefined") { | 35 | + if (value !== null && typeof value !== "undefined") { |
| 32 | - if (typeof value === 'object') { | 36 | + if (typeof value === "object") { |
| 33 | for (const key of Object.keys(value)) { | 37 | for (const key of Object.keys(value)) { |
| 34 | - let params = propName + '[' + key + ']'; | 38 | + let params = propName + "[" + key + "]"; |
| 35 | var subPart = encodeURIComponent(params) + "="; | 39 | var subPart = encodeURIComponent(params) + "="; |
| 36 | url += subPart + encodeURIComponent(value[key]) + "&"; | 40 | url += subPart + encodeURIComponent(value[key]) + "&"; |
| 37 | } | 41 | } |
| ... | @@ -58,78 +62,86 @@ service.interceptors.request.use(config => { | ... | @@ -58,78 +62,86 @@ service.interceptors.request.use(config => { |
| 58 | // }) | 62 | // }) |
| 59 | // return config | 63 | // return config |
| 60 | // } else { | 64 | // } else { |
| 61 | - return config | 65 | + return config; |
| 62 | // } | 66 | // } |
| 63 | -}, error => { | 67 | + }, |
| 64 | - console.log(error) | 68 | + (error) => { |
| 65 | - Promise.reject(error) | 69 | + console.log(error); |
| 66 | -}) | 70 | + Promise.reject(error); |
| 71 | + } | ||
| 72 | +); | ||
| 67 | 73 | ||
| 68 | // 响应拦截器 | 74 | // 响应拦截器 |
| 69 | -service.interceptors.response.use(res => { | 75 | +service.interceptors.response.use( |
| 70 | - if (res.config.url != '/manager-server/systemAddressInfoController/findSystemAddressInfoAll') { | 76 | + (res) => { |
| 71 | - setTime(new Date().getTime()) | 77 | + if ( |
| 78 | + res.config.url != | ||
| 79 | + "/manager-server/systemAddressInfoController/findSystemAddressInfoAll" | ||
| 80 | + ) { | ||
| 81 | + setTime(new Date().getTime()); | ||
| 72 | } | 82 | } |
| 73 | // 未设置状态码则默认成功状态 | 83 | // 未设置状态码则默认成功状态 |
| 74 | const code = Number(res.data.code) || 200; | 84 | const code = Number(res.data.code) || 200; |
| 75 | // 获取错误信息 | 85 | // 获取错误信息 |
| 76 | - const msg = errorCode[code] || res.data.message || errorCode['default'] | 86 | + const msg = errorCode[code] || res.data.message || errorCode["default"]; |
| 77 | if (code === 50000 || code === 530) { | 87 | if (code === 50000 || code === 530) { |
| 78 | - removeToken() | 88 | + removeToken(); |
| 79 | - MessageBox.alert(i18n.t('system.loginOut'), i18n.t('system.systemTip'), { | 89 | + MessageBox.alert(i18n.t("system.loginOut"), i18n.t("system.systemTip"), { |
| 80 | - confirmButtonText: i18n.t('system.relogin'), | 90 | + confirmButtonText: i18n.t("system.relogin"), |
| 81 | - cancelButtonText: i18n.t('system.close'), | 91 | + cancelButtonText: i18n.t("system.close"), |
| 82 | - type: 'warning' | 92 | + type: "warning", |
| 83 | - } | 93 | + }).finally(() => { |
| 84 | - ).finally(() => { | 94 | + store.dispatch("FedLogOut"); |
| 85 | - store.dispatch('FedLogOut') | 95 | + }); |
| 86 | - }) | ||
| 87 | } else if (code === 10005) { | 96 | } else if (code === 10005) { |
| 88 | - removeToken() | 97 | + removeToken(); |
| 89 | - MessageBox.alert('<span style="font-weight:700">系统版本已更新!</span><br/>当前版本非最新版,请退出系统后刷新您当前所使用的浏览器后,重新登录系统!</br> </br>常用浏览器的快速刷新页面操作方法有:</br>1、谷歌浏览器请按“F5键”或“Ctrl键 + R键”快速刷新页面</br>2、360浏览器跟EDGE浏览器请按“Ctrl键 + R键”快速刷新页面</br>3、IE浏览器请按“F5键”或“Ctrl键 + R键”快速刷新页面</br> </br>其它浏览器的刷新方式请根据浏览器的菜单进行操作!', i18n.t('system.systemTip'), { | 98 | + MessageBox.alert( |
| 90 | - confirmButtonText: i18n.t('system.relogin'), | 99 | + '<span style="font-weight:700">系统版本已更新!</span><br/>当前版本非最新版,请退出系统后刷新您当前所使用的浏览器后,重新登录系统!</br> </br>常用浏览器的快速刷新页面操作方法有:</br>1、谷歌浏览器请按“F5键”或“Ctrl键 + R键”快速刷新页面</br>2、360浏览器跟EDGE浏览器请按“Ctrl键 + R键”快速刷新页面</br>3、IE浏览器请按“F5键”或“Ctrl键 + R键”快速刷新页面</br> </br>其它浏览器的刷新方式请根据浏览器的菜单进行操作!', |
| 91 | - cancelButtonText: i18n.t('system.close'), | 100 | + i18n.t("system.systemTip"), |
| 92 | - type: 'warning', | 101 | + { |
| 93 | - customClass: 'systemVerError', | 102 | + confirmButtonText: i18n.t("system.relogin"), |
| 94 | - dangerouslyUseHTMLString: true | 103 | + cancelButtonText: i18n.t("system.close"), |
| 104 | + type: "warning", | ||
| 105 | + customClass: "systemVerError", | ||
| 106 | + dangerouslyUseHTMLString: true, | ||
| 95 | } | 107 | } |
| 96 | ).finally(() => { | 108 | ).finally(() => { |
| 97 | - store.dispatch('FedLogOut') | 109 | + store.dispatch("FedLogOut"); |
| 98 | - }) | 110 | + }); |
| 99 | } else if (code === 500) { | 111 | } else if (code === 500) { |
| 100 | - MessageBox.alert(msg, i18n.t('system.tipTitle2'), { | 112 | + MessageBox.alert(msg, i18n.t("system.tipTitle2"), { |
| 101 | - dangerouslyUseHTMLString: true | 113 | + dangerouslyUseHTMLString: true, |
| 102 | }); | 114 | }); |
| 103 | - return Promise.reject(new Error(msg)) | 115 | + return Promise.reject(new Error(msg)); |
| 104 | } else if (code !== 200) { | 116 | } else if (code !== 200) { |
| 105 | // MessageBox.alert(msg, '注意', { | 117 | // MessageBox.alert(msg, '注意', { |
| 106 | // dangerouslyUseHTMLString: true | 118 | // dangerouslyUseHTMLString: true |
| 107 | // }); | 119 | // }); |
| 108 | - return res.data | 120 | + return res.data; |
| 109 | } else { | 121 | } else { |
| 110 | - return res.data | 122 | + return res.data; |
| 111 | } | 123 | } |
| 112 | -}, | 124 | + }, |
| 113 | - error => { | 125 | + (error) => { |
| 114 | - removeTime() | 126 | + removeTime(); |
| 115 | - console.log('err' + error) | 127 | + console.log("err" + error); |
| 116 | let { message } = error; | 128 | let { message } = error; |
| 117 | if (message == "Network Error") { | 129 | if (message == "Network Error") { |
| 118 | - message = i18n.t('system.systemError1'); | 130 | + message = i18n.t("system.systemError1"); |
| 119 | - } | 131 | + } else if (message.includes("timeout")) { |
| 120 | - else if (message.includes("timeout")) { | 132 | + message = i18n.t("system.systemError2"); |
| 121 | - message = i18n.t('system.systemError2'); | 133 | + } else if (message.includes("Request failed with status code")) { |
| 122 | - } | 134 | + message = i18n.t("system.systemError3", { |
| 123 | - else if (message.includes("Request failed with status code")) { | 135 | + a: message.substr(message.length - 3), |
| 124 | - message = i18n.t('system.systemError3', { a: message.substr(message.length - 3) }); | 136 | + }); |
| 125 | } | 137 | } |
| 126 | Message({ | 138 | Message({ |
| 127 | message: message, | 139 | message: message, |
| 128 | - type: 'error', | 140 | + type: "error", |
| 129 | - duration: 5 * 1000 | 141 | + duration: 5 * 1000, |
| 130 | - }) | 142 | + }); |
| 131 | - return Promise.reject(error) | 143 | + return Promise.reject(error); |
| 132 | } | 144 | } |
| 133 | -) | 145 | +); |
| 134 | 146 | ||
| 135 | -export default service | 147 | +export default service; | ... | ... |
| ... | @@ -20,6 +20,8 @@ const apiUrl = { | ... | @@ -20,6 +20,8 @@ const apiUrl = { |
| 20 | declareDataModel: "/bus-customer/declareData/downloadTemplate", | 20 | declareDataModel: "/bus-customer/declareData/downloadTemplate", |
| 21 | // 清单查询下载 | 21 | // 清单查询下载 |
| 22 | listExport: "/bus-customer/exportList/listExport", | 22 | listExport: "/bus-customer/exportList/listExport", |
| 23 | + // 根据id导出 | ||
| 24 | + customDownloadXls: "/bus-customer/asyncExport/download", | ||
| 23 | }; | 25 | }; |
| 24 | 26 | ||
| 25 | const baseUrl = process.env.VUE_APP_BASE_API; | 27 | const baseUrl = process.env.VUE_APP_BASE_API; |
| ... | @@ -31,6 +33,8 @@ export function downLoadZip(urlStatus, str, filename, type, method, data) { | ... | @@ -31,6 +33,8 @@ export function downLoadZip(urlStatus, str, filename, type, method, data) { |
| 31 | url = baseUrl + apiUrl[str]; | 33 | url = baseUrl + apiUrl[str]; |
| 32 | } else if (urlStatus == "res") { | 34 | } else if (urlStatus == "res") { |
| 33 | url = str; | 35 | url = str; |
| 36 | + } else if (urlStatus == "task") { | ||
| 37 | + url = baseUrl + apiUrl[str] + "/" + data.taskId; | ||
| 34 | } | 38 | } |
| 35 | console.log(url); | 39 | console.log(url); |
| 36 | 40 | ... | ... |
| ... | @@ -215,6 +215,7 @@ | ... | @@ -215,6 +215,7 @@ |
| 215 | size="small" | 215 | size="small" |
| 216 | icon="el-icon-download" | 216 | icon="el-icon-download" |
| 217 | @click="downloadData" | 217 | @click="downloadData" |
| 218 | + :loading="isPolling || exportLoading" | ||
| 218 | > | 219 | > |
| 219 | 导出 | 220 | 导出 |
| 220 | </el-button> | 221 | </el-button> |
| ... | @@ -282,7 +283,12 @@ | ... | @@ -282,7 +283,12 @@ |
| 282 | </template> | 283 | </template> |
| 283 | 284 | ||
| 284 | <script> | 285 | <script> |
| 285 | -import { getAllexportList, getListReceiptData } from "@/api/exportList-api.js"; | 286 | +import { |
| 287 | + getAllexportList, | ||
| 288 | + getListReceiptData, | ||
| 289 | + getSubmitExportTask, | ||
| 290 | + getTaskStatus, | ||
| 291 | +} from "@/api/exportList-api.js"; | ||
| 286 | import CustomDialog from "./custom-dialog.vue"; | 292 | import CustomDialog from "./custom-dialog.vue"; |
| 287 | import { formatDateNew } from "../../utils"; | 293 | import { formatDateNew } from "../../utils"; |
| 288 | 294 | ||
| ... | @@ -415,6 +421,11 @@ export default { | ... | @@ -415,6 +421,11 @@ export default { |
| 415 | formItemconsignmentHeadCode: false, | 421 | formItemconsignmentHeadCode: false, |
| 416 | }, | 422 | }, |
| 417 | tableMaxheight: null, | 423 | tableMaxheight: null, |
| 424 | + exportLoading: false, | ||
| 425 | + pollTimer: null, // 定时器实例 | ||
| 426 | + pollInterval: 5000, // 轮询间隔(5秒) | ||
| 427 | + isPolling: false, // 轮询状态标识 | ||
| 428 | + currentTaskId: null, | ||
| 418 | }; | 429 | }; |
| 419 | }, | 430 | }, |
| 420 | created() { | 431 | created() { |
| ... | @@ -423,9 +434,13 @@ export default { | ... | @@ -423,9 +434,13 @@ export default { |
| 423 | mounted() { | 434 | mounted() { |
| 424 | this.tableMaxheight = window.innerHeight - 360; | 435 | this.tableMaxheight = window.innerHeight - 360; |
| 425 | }, | 436 | }, |
| 437 | + beforeDestroy() { | ||
| 438 | + this.stopPolling(); // 组件销毁前清理定时器 | ||
| 439 | + }, | ||
| 426 | watch: { | 440 | watch: { |
| 427 | $route() { | 441 | $route() { |
| 428 | this.popoverClose(); | 442 | this.popoverClose(); |
| 443 | + this.stopPolling(); // 组件销毁前清理定时器 | ||
| 429 | }, | 444 | }, |
| 430 | }, | 445 | }, |
| 431 | methods: { | 446 | methods: { |
| ... | @@ -496,6 +511,68 @@ export default { | ... | @@ -496,6 +511,68 @@ export default { |
| 496 | summaryApplicationStatus: "", | 511 | summaryApplicationStatus: "", |
| 497 | }; | 512 | }; |
| 498 | }, | 513 | }, |
| 514 | + | ||
| 515 | + // 查询成功后调用的其他接口 | ||
| 516 | + async callOtherApi() { | ||
| 517 | + try { | ||
| 518 | + const fileName = `${formatDateNew(new Date())}.xlsx`; | ||
| 519 | + this.fileDownload | ||
| 520 | + .downLoadZip("task", "customDownloadXls", fileName, "xlsx", "get", { | ||
| 521 | + taskId: this.currentTaskId, | ||
| 522 | + }) | ||
| 523 | + .finally(() => { | ||
| 524 | + // this.cancelDownload(); | ||
| 525 | + this.exportLoading = false; | ||
| 526 | + }); | ||
| 527 | + } catch (error) { | ||
| 528 | + console.error("后续接口调用失败:", error); | ||
| 529 | + } | ||
| 530 | + }, | ||
| 531 | + // 轮询查询状态 | ||
| 532 | + async pollStatus() { | ||
| 533 | + try { | ||
| 534 | + const result = await getTaskStatus({ taskId: this.currentTaskId }); | ||
| 535 | + | ||
| 536 | + if (+result.code === 200) { | ||
| 537 | + // PENDING, PROCESSING, COMPLETED, FAILED | ||
| 538 | + if (result.data.status === "COMPLETED") { | ||
| 539 | + this.stopPolling(); // 停止轮询 | ||
| 540 | + await this.callOtherApi(); // 调用其他接口 | ||
| 541 | + } else if (result.data.status === "FAILED") { | ||
| 542 | + this.stopPolling(); | ||
| 543 | + this.handleFailure(); | ||
| 544 | + this.alertWarningMsg(result.data.errorMessage); | ||
| 545 | + } else { | ||
| 546 | + this.startPolling(); // 启动轮询 | ||
| 547 | + } | ||
| 548 | + } else { | ||
| 549 | + this.stopPolling(); | ||
| 550 | + this.handleFailure(); | ||
| 551 | + } | ||
| 552 | + // 其他状态继续轮询 | ||
| 553 | + } catch (error) { | ||
| 554 | + console.error("轮询查询失败:", error); | ||
| 555 | + this.stopPolling(); | ||
| 556 | + } | ||
| 557 | + }, | ||
| 558 | + // 启动轮询 | ||
| 559 | + startPolling() { | ||
| 560 | + if (this.isPolling) return; | ||
| 561 | + | ||
| 562 | + this.isPolling = true; | ||
| 563 | + this.pollTimer = setInterval(() => { | ||
| 564 | + this.pollStatus(); | ||
| 565 | + }, this.pollInterval); | ||
| 566 | + }, | ||
| 567 | + // 停止轮询 | ||
| 568 | + stopPolling() { | ||
| 569 | + if (this.pollTimer) { | ||
| 570 | + clearInterval(this.pollTimer); | ||
| 571 | + this.pollTimer = null; | ||
| 572 | + } | ||
| 573 | + this.isPolling = false; | ||
| 574 | + this.exportLoading = false; | ||
| 575 | + }, | ||
| 499 | //导出 | 576 | //导出 |
| 500 | downloadData() { | 577 | downloadData() { |
| 501 | let obj = { ...this.sreachFormData }; | 578 | let obj = { ...this.sreachFormData }; |
| ... | @@ -527,13 +604,32 @@ export default { | ... | @@ -527,13 +604,32 @@ export default { |
| 527 | // // 2. 清单查询 | 604 | // // 2. 清单查询 |
| 528 | // console.log(res); | 605 | // console.log(res); |
| 529 | // }); | 606 | // }); |
| 530 | - const fileName = `${formatDateNew(new Date())}.xlsx`; | 607 | + this.exportLoading = true; |
| 531 | - this.fileDownload | 608 | + |
| 532 | - .downLoadZip("api", "listExport", fileName, "xlsx", "post", { | 609 | + this.$confirm(`正在导出中,请稍候!`, "提示", { |
| 533 | - ...obj, | 610 | + confirmButtonText: "确定", |
| 611 | + cancelButtonText: "取消", | ||
| 612 | + type: "warning", | ||
| 534 | }) | 613 | }) |
| 535 | - .finally(() => { | 614 | + .then(() => { |
| 536 | - this.cancelDownload(); | 615 | + getSubmitExportTask(obj).then((res) => { |
| 616 | + if (+res.code === 200) { | ||
| 617 | + console.log(res); | ||
| 618 | + this.currentTaskId = res.data; | ||
| 619 | + this.startPolling(); | ||
| 620 | + } | ||
| 621 | + }); | ||
| 622 | + // this.fileDownload | ||
| 623 | + // .downLoadZip("api", "listExport", fileName, "xlsx", "post", { | ||
| 624 | + // ...obj, | ||
| 625 | + // }) | ||
| 626 | + // .finally(() => { | ||
| 627 | + // // this.cancelDownload(); | ||
| 628 | + // this.exportLoading = false; | ||
| 629 | + // }); | ||
| 630 | + }) | ||
| 631 | + .catch(() => { | ||
| 632 | + this.exportLoading = false; | ||
| 537 | }); | 633 | }); |
| 538 | }, | 634 | }, |
| 539 | //查询详情 | 635 | //查询详情 | ... | ... |
-
Please register or login to post a comment