From d7f7b85783767cd0c43a01d772d8decedf555fc6 Mon Sep 17 00:00:00 2001
From: hongchao <3228015117@qq.com>
Date: Fri, 21 Nov 2025 15:07:52 +0800
Subject: [PATCH] =?UTF-8?q?zip=E6=89=B9=E9=87=8F=E5=AF=BC=E5=87=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/utils/request.js | 66 ++---
.../material/cost/component/unreportHome.vue | 267 +++++++++++++++++-
.../stquery/deviceComparisonStatistical.vue | 4 +
3 files changed, 277 insertions(+), 60 deletions(-)
diff --git a/src/utils/request.js b/src/utils/request.js
index 42269568..6ae46169 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -228,49 +228,27 @@ export function downloadJson(url, params, filename, config) {
// 通用下载方法
export function downloadZip(url, params, filename, config) {
- const backgroundMode = config && config.background === true
- const showLoading = !(config && config.showLoading === false) && !backgroundMode
- const finalAxiosConfig = {
- transformRequest: [
- (params) => {
- return params
- },
- ],
- headers: { 'Content-Type': 'application/json', encryptResponse: false },
- responseType: 'blob',
- // if background mode and no explicit timeout, extend to 10 minutes
- timeout: backgroundMode && !(config && typeof config.timeout === 'number') ? 600000 : undefined,
- ...config,
- }
-
- if (showLoading) {
- downloadLoadingInstance = Loading.service({
- text: '正在下载数据,请稍候',
- spinner: 'el-icon-loading',
- background: 'rgba(0, 0, 0, 0.7)',
- })
- } else if (backgroundMode) {
- Notification.info({
- title: '已开始生成',
- message: '批量导出任务已在后台执行,准备就绪后将自动下载。',
- duration: 4000,
- })
- }
-
+ downloadLoadingInstance = Loading.service({
+ text: '正在下载数据,请稍候',
+ spinner: 'el-icon-loading',
+ background: 'rgba(0, 0, 0, 0.7)',
+ })
return service
- .post(url, params, finalAxiosConfig)
+ .post(url, params, {
+ transformRequest: [
+ (params) => {
+ return params
+ },
+ ],
+ headers: { 'Content-Type': 'application/json',encryptResponse: false },
+ responseType: 'blob',
+ ...config,
+ })
.then(async (data) => {
const isBlob = blobValidate(data)
if (isBlob) {
const blob = new Blob([data])
saveAs(blob, filename)
- if (backgroundMode) {
- Notification.success({
- title: '导出完成',
- message: 'ZIP 文件已准备好,正在开始下载。',
- duration: 3000,
- })
- }
} else {
const resText = await data.text()
const rspObj = JSON.parse(resText)
@@ -278,20 +256,12 @@ export function downloadZip(url, params, filename, config) {
errorCode[rspObj.code] || rspObj.msg || errorCode['default']
Message.error(errMsg)
}
- if (showLoading && downloadLoadingInstance) {
- downloadLoadingInstance.close()
- }
+ downloadLoadingInstance.close()
})
.catch((r) => {
console.error(r)
- if (r && r.message && r.message.includes('timeout')) {
- Message.error('导出超时,请减少选择数量或稍后重试')
- } else {
- Message.error('下载文件出现错误,请联系管理员!')
- }
- if (showLoading && downloadLoadingInstance) {
- downloadLoadingInstance.close()
- }
+ Message.error('下载文件出现错误,请联系管理员!')
+ downloadLoadingInstance.close()
})
}
export default service
diff --git a/src/views/material/cost/component/unreportHome.vue b/src/views/material/cost/component/unreportHome.vue
index c67bf32a..8392e2f5 100644
--- a/src/views/material/cost/component/unreportHome.vue
+++ b/src/views/material/cost/component/unreportHome.vue
@@ -37,8 +37,15 @@
查询
重置
导出Excel
- 批量导出ZIP
查看历史报表
+ {{ exporting ? '导出中...' : '批量导出ZIP' }}
+
+
+
{{ progress }}% ({{ current }}/{{ totalZip }})
+
{{ statusText }}
+
@@ -568,6 +575,9 @@ import vueEasyPrint from "vue-easy-print";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import * as XLSX from 'xlsx';
+import request from '@/utils/request'
+
+
export default {
name: 'UnreportHome',
dicts: ['cost_status'],
@@ -664,7 +674,18 @@ export default {
proStatus:[
{ id: 0, name: '未竣工' },
{ id: 1, name: '已竣工' },
- ]
+ ],
+
+
+ //导出zip相关参数
+ exporting: false,
+ exportFlag: false,
+ progress: 0,
+ current: 0,
+ totalZip: 0,
+ statusText: '',
+ taskId: null,
+ pollInterval: null
}
},
created() {
@@ -815,8 +836,32 @@ export default {
this.aform = { status: '2' };
},
+
+ //********************************************************************** */
//批量导出zip
- exportZip() {
+ // exportZip() {
+ // if (!this.ids.length) {
+ // this.$message.error('请选择要导出的记录')
+ // return false
+ // }
+ // let param = []
+ // this.ids.map(item => {
+ // param.push({ agreementId: item.agreementId,settlementType:item.settlementType })
+ // })
+ // // exportLeaseAll(this.exportParams).then(res => {
+ // // downloadFile({ fileName: `月结明细_${new Date().getTime()}.zip`, fileData: res, fileType: 'application/zip;charset=utf-8' })
+ // // })
+ // this.downloadZip(
+ // 'material/slt_agreement_info/exportUnsettled',
+ // JSON.stringify(param),
+ // `未结算批量明细导出_${new Date().getTime()}.zip`,
+ // { background: true, showLoading: false, timeout: 600000 }
+ // )
+
+ // this.$refs.tableRef.clearSelection()
+ // },
+
+ async exportZip() {
if (!this.ids.length) {
this.$message.error('请选择要导出的记录')
return false
@@ -825,19 +870,92 @@ export default {
this.ids.map(item => {
param.push({ agreementId: item.agreementId,settlementType:item.settlementType })
})
- // exportLeaseAll(this.exportParams).then(res => {
- // downloadFile({ fileName: `月结明细_${new Date().getTime()}.zip`, fileData: res, fileType: 'application/zip;charset=utf-8' })
- // })
- this.downloadZip(
- 'material/slt_agreement_info/exportUnsettled',
- JSON.stringify(param),
- `未结算批量明细导出_${new Date().getTime()}.zip`,
- { background: true, showLoading: false, timeout: 600000 }
- )
+ try {
+ this.exporting = true
+ this.progress = 0
+ this.current = 0
+ this.totalZip = 0
+ this.statusText = '开始导出...'
+
+
+ const response = await request({
+ url: '/material/slt_agreement_info/exportUnsettled',
+ method: 'post',
+ data: JSON.stringify(param),
+ timeout: 60000 // 设置10分钟超时
+ })
+ const result = response
+ this.taskId = result.taskId
+ this.totalZip = result.total
+ this.statusText = '导出任务已开始...'
+ this.exportFlag = true
+ // 开始轮询进度
+ this.startPolling()
+ } catch (error) {
+ console.error('导出请求失败', error)
+ this.statusText = '导出请求失败'
+ this.exporting = false
+ }
this.$refs.tableRef.clearSelection()
},
+ startPolling() {
+ this.pollInterval = setInterval(async () => {
+ try {
+ const response = await request({
+ url: `/material/slt_agreement_info/exportProgress/${this.taskId}`,
+ method: 'get'
+ })
+ const progress = response
+
+ this.progress = progress.percentage
+ this.current = progress.current
+
+ if (progress.status === 'completed') {
+ this.statusText = '导出完成,开始下载...'
+ clearInterval(this.pollInterval)
+ this.downloadFile()
+ this.exporting = false
+ this.exportFlag = false
+ } else if (progress.status === 'error') {
+ this.statusText = `导出失败: ${progress.errorMsg}`
+ clearInterval(this.pollInterval)
+ this.exporting = false
+ } else {
+ this.statusText = `处理中: ${progress.percentage}%`
+ }
+ } catch (error) {
+ console.error('查询进度失败', error)
+ this.statusText = '查询进度失败'
+ this.exportFlag = false
+ }
+ }, 1000)
+ },
+
+ downloadFile() {
+ if (this.taskId) {
+ console.log("xxxxxxxxxxtaskId",this.taskId)
+ const param = { taskId: this.taskId }
+ this.downloadZip(
+ 'material/slt_agreement_info/downloadExport',
+ JSON.stringify(param),
+ `未结算批量明细导出_${new Date().getTime()}.zip`,
+ )
+ }
+
+ },
+
+ beforeUnmount() {
+ if (this.pollInterval) {
+ clearInterval(this.pollInterval)
+ }
+ },
+
+
+
+ //********************************************************************** */
+
openPrintDialog(row){
this.openPrint = true
@@ -1593,4 +1711,129 @@ export default {
text-align: center;
border-left: 1px solid #9c9c9c;
}
+
+//导出zip
+.progress-container {
+ margin-top: 20px;
+ padding: 15px;
+ border: 1px solid #e0e0e0;
+ border-radius: 4px;
+}
+
+.progress-bar {
+ width: 100%;
+ height: 20px;
+ background-color: #f0f0f0;
+ border-radius: 10px;
+ overflow: hidden;
+}
+
+.progress-fill {
+ height: 100%;
+ background-color: #4CAF50;
+ transition: width 0.3s ease;
+}
+
+.progress-text {
+ margin-top: 8px;
+ text-align: center;
+ font-size: 14px;
+ color: #666;
+}
+
+.status-text {
+ margin-top: 5px;
+ text-align: center;
+ font-size: 12px;
+ color: #999;
+}
+
+button:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+//
+
+
+
+
\ No newline at end of file
diff --git a/src/views/material/stquery/deviceComparisonStatistical.vue b/src/views/material/stquery/deviceComparisonStatistical.vue
index b21fc72d..d8512c86 100644
--- a/src/views/material/stquery/deviceComparisonStatistical.vue
+++ b/src/views/material/stquery/deviceComparisonStatistical.vue
@@ -250,6 +250,8 @@ export default {
keyWord: undefined,
proId: undefined,
jijuType: undefined,
+ startTime: undefined,
+ endTime: undefined
},
deviceRecordList: [], // 二级列表数据
dialogDeviceTotal: 0, // 二级总条数
@@ -353,6 +355,8 @@ export default {
this.dialogDeviceQuery.keyWord = ''
this.dialogDeviceQuery.pageNum = 1
this.dialogDeviceQuery.pageSize = 10
+ this.dialogDeviceQuery.startTime = this.queryParams.startTime
+ this.dialogDeviceQuery.endTime = this.queryParams.endTime
this.deviceRecordList = []
this.getDeviceRecords()
},