From d07dc9a90b55dd40bbdc56f81b48173cc814d4a3 Mon Sep 17 00:00:00 2001 From: jiayang yue Date: Fri, 16 May 2025 01:50:19 +0800 Subject: [PATCH] =?UTF-8?q?2025.05.15=20=E7=89=A9=E6=96=99=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E8=AE=BE=E7=BD=AE=20=E5=AF=BC=E5=87=BA=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20=E5=AF=BC=E5=87=BA=E6=89=80=E6=9C=89=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/qc/qc.js | 13 +++ src/views/modules/qc/qcPartAttribute.vue | 126 +++++++++++++++-------- 2 files changed, 98 insertions(+), 41 deletions(-) diff --git a/src/api/qc/qc.js b/src/api/qc/qc.js index f8fa76f..aa2dafe 100644 --- a/src/api/qc/qc.js +++ b/src/api/qc/qc.js @@ -74,6 +74,19 @@ export const getPlanLists = data => createAPI(`/pms/qc/getPlanLists`,'post',data // ===================================== 物料属性设置 ===================================== export const qcPartAttributeSearch = data => createAPI(`/pms/qc/qcPartAttributeSearch`,'post',data) +export const qcPartAttributeExport = data => + createAPI( + `/pms/qc/exportPartAttribute`, + 'post', + data, + 'download' // 关键:告诉 axios 要拿二进制流 + ); +export const qcPartAttributeExportAsync = data => + createAPI(`/pms/qce/exportPartAttributeAsync`, 'post', data); +export const getExportStatus = params => + createAPI(`/pms/qce/exportStatus`, 'get', params); +export const downloadExportFile = params => + createAPI(`/pms/qce/download`, 'get', params, 'download'); export const qcPartAttributeSave = data => createAPI(`/pms/qc/qcPartAttributeSave`,'post',data) export const qcPartAttributeDelete = data => createAPI(`/pms/qc/qcPartAttributeDelete`,'post',data) export const searchPartAttributeDetails = data => createAPI(`/pms/qc/searchPartAttributeDetails`,'post',data) diff --git a/src/views/modules/qc/qcPartAttribute.vue b/src/views/modules/qc/qcPartAttribute.vue index 6ca7899..11c2b94 100644 --- a/src/views/modules/qc/qcPartAttribute.vue +++ b/src/views/modules/qc/qcPartAttribute.vue @@ -35,20 +35,13 @@ 导入 - - {{ "导出" }} - + + 导出全部 + @@ -833,6 +826,12 @@ import {deleteObjectFile} from '@/api/eam/eam.js' import qcUpload from "./qc_upload" import qcSOPUploadFile from "./qc_SOP_upload_file" + import { + downloadExportFile, + getExportStatus, + qcPartAttributeExport, + qcPartAttributeExportAsync + } from "../../../api/qc/qc"; export default { components: { qcSOPUploadFile, @@ -851,6 +850,8 @@ exportList: [], // 导出 end tagNo: '', + importLoading: false, + pollTimer: null, searchData: { site: '', userName: this.$store.state.user.name, @@ -1681,6 +1682,10 @@ } }, + beforeDestroy() { + if (this.pollTimer) clearInterval(this.pollTimer); + }, + methods: { // 获取用户的bu getSiteAndBuByUserName () { @@ -2183,34 +2188,73 @@ } }, - //导出excel - async createExportData() { - this.searchData.limit = -1 - this.searchData.page = 1 - this.searchData.importFlag = true - await qcPartAttributeSearch(this.searchData).then(({data}) => { - this.exportList= data.page.list - }) - this.searchData.importFlag = false - return this.exportList - }, - - startDownload() {}, - - finishDownload() {}, + async handleAsyncExport() { + // 1. 一开始打开 loading + this.importLoading = true; + + let jobId; + try { + // 2. 启动导出,拿到 jobId + const initRes = await qcPartAttributeExportAsync(this.searchData); + jobId = initRes.data; // 或 initRes.data.jobId + + // 3. 开始轮询 + this.pollTimer = setInterval(async () => { + try { + const statusRes = await getExportStatus({ jobId }); + const { status } = statusRes.data; + + if (status === 'SUCCESS') { + clearInterval(this.pollTimer); + + // 4. 下载文件 + const fileRes = await downloadExportFile({ jobId }); + const blob = new Blob([fileRes.data], { + type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + }); + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + + // 获取当前时间东8到秒,转为字符串 + const date = new Date(); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + const seconds = String(date.getSeconds()).padStart(2, '0'); + a.download = '物料属性设置导出' + year + month + day + hours + minutes + seconds + '.xlsx'; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + + // **在下载完成后** 再关 loading + this.importLoading = false; + + } else if (status === 'FAILED') { + clearInterval(this.pollTimer); + this.$message.error('导出任务失败'); + // **任务失败时** 也关 loading + this.importLoading = false; + } + // 若还是 PROCESSING,就继续等 + } catch (err) { + clearInterval(this.pollTimer); + console.error(err); + this.$message.error('轮询状态出错'); + // 出错时也关 loading + this.importLoading = false; + } + }, 2000); - fields () { - let json = "{" - this.columnList1.forEach((item, index) => { - if (index == this.columnList1.length - 1) { - json += "\"" + item.columnLabel + "\"" + ":" + "\"" + item.columnProp + "\"" - } else { - json += "\"" + item.columnLabel + "\"" + ":" + "\"" + item.columnProp + "\"" + "," - } - }) - json += "}" - let s = eval("(" + json + ")") - return s + } catch (e) { + console.error('启动异步导出失败:', e); + this.$message.error('启动导出失败,请稍后重试'); + // 启动失败时直接关 loading + this.importLoading = false; + } }, // 导入