From 1f73f483e03cb84c10719895e3e326b54efd2cae Mon Sep 17 00:00:00 2001 From: hongchao <3228015117@qq.com> Date: Mon, 20 Oct 2025 19:59:45 +0800 Subject: [PATCH] =?UTF-8?q?=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../costPush/expendableExpensePush/index.vue | 163 ++++++++++++++-- .../costPush/leaseExpensePush/index.vue | 182 ++++++++++++++++-- .../material/costPush/pushReview/index.vue | 9 +- 3 files changed, 320 insertions(+), 34 deletions(-) diff --git a/src/views/material/costPush/expendableExpensePush/index.vue b/src/views/material/costPush/expendableExpensePush/index.vue index 2b1f840f..319ae82c 100644 --- a/src/views/material/costPush/expendableExpensePush/index.vue +++ b/src/views/material/costPush/expendableExpensePush/index.vue @@ -102,7 +102,6 @@ 未推送 已推送 已退回 - 进行中 @@ -160,7 +159,7 @@ import { getProjectList, getUnitList, getAgreementInfoById } from '@/api/back/in import { getConsumPushCheckList, getConsumPushCheckListCount, submitPushSafetyConsumeCosts,getConsumeDetailsListApi } from '@/api/costPush/costPush' import TreeSelect from '@riophae/vue-treeselect' import '@riophae/vue-treeselect/dist/vue-treeselect.css' - +import ExcelJS from 'exceljs'; export default { components: { TreeSelect }, data() { @@ -189,13 +188,12 @@ export default { { label: '未推送', value: '0' }, { label: '已推送', value: '1' }, { label: '已退回', value: '2' }, - { label: '进行中', value: '3' } ], // 工程状态 total: 0, // 总条数 // 表头 tableColumns: [ + { label: '协议编号', prop: 'agreementCode' }, { label: '单位名称', prop: 'unitName' }, - { label: 'i8工程编号', prop: 'pc_no' }, { label: '工程名称', prop: 'projectName' }, { label: '推送月份', prop: 'month' }, { label: '消耗品费用', prop: 'leaseMoney' }, @@ -359,18 +357,151 @@ export default { const seconds = String(date.getSeconds()).padStart(2, '0') return `${year}${month}${day}_${hours}${minutes}${seconds}` }, - // 导出数据 - handleExport() { - try { - let fileName = `安全工器具费用推送_${this.formatTime(new Date())}.xLsx` - let url = '/material/backstage/costPush/exportConsPushCheck' - const params = { ...this.queryParams } - console.log('🚀 ~ 导出 ~ params:', params) - this.download(url, params, fileName) - } catch (error) { - console.log('导出数据失败', error) - } - }, + + /** 外层导出 */ + async handleExport() { + if (!this.tableList || this.tableList.length === 0) { + this.$modal.msgWarning('没有可导出的数据'); + return; + } + + try { + // 创建工作簿 + const workbook = new ExcelJS.Workbook(); + const worksheet = workbook.addWorksheet('消耗性费用推送审核记录'); + + // 定义列配置 + const columns = [ + { header: '序号', key: 'index', width: 8 }, + { header: '协议编号', key: 'agreementCode', width: 18 }, + { header: '单位名称', key: 'unitName', width: 20 }, + { header: '工程名称', key: 'projectName', width: 20 }, + { header: '推送月份', key: 'month', width: 12 }, + { header: '消耗品费用(元)', key: 'leaseMoney', width: 12 }, + { header: '推送状态', key: 'pushStatus', width: 12 }, + { header: '推送备注', key: 'pushRemark', width: 12 }, + ]; + + worksheet.columns = columns; + + // 定义表头样式 + const headerStyle = { + font: { bold: true, color: { argb: 'FFFFFFFF' }, size: 11 }, + fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF4472C4' } }, + alignment: { horizontal: 'center', vertical: 'center', wrapText: true }, + border: { + top: { style: 'thin', color: { argb: 'FF000000' } }, + bottom: { style: 'thin', color: { argb: 'FF000000' } }, + left: { style: 'thin', color: { argb: 'FF000000' } }, + right: { style: 'thin', color: { argb: 'FF000000' } } + } + }; + + // 定义数据行样式 + const dataStyle = { + alignment: { horizontal: 'center', vertical: 'center' }, + border: { + top: { style: 'thin', color: { argb: 'FF000000' } }, + bottom: { style: 'thin', color: { argb: 'FF000000' } }, + left: { style: 'thin', color: { argb: 'FF000000' } }, + right: { style: 'thin', color: { argb: 'FF000000' } } + } + }; + + // 定义合计行样式 + const totalStyle = { + font: { bold: true, size: 11 }, + fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFF8F8F9' } }, + alignment: { horizontal: 'center', vertical: 'center' }, + border: { + top: { style: 'thin', color: { argb: 'FF000000' } }, + bottom: { style: 'thin', color: { argb: 'FF000000' } }, + left: { style: 'thin', color: { argb: 'FF000000' } }, + right: { style: 'thin', color: { argb: 'FF000000' } } + } + }; + + // 设置表头样式 + worksheet.getRow(1).eachCell((cell) => { + cell.style = headerStyle; + }); + + // 添加数据行(排除最后一行合计行) + const dataRows = this.tableList; + dataRows.forEach((row, index) => { + const dataRow = { + index: index + 1, + agreementCode: row.agreementCode || '', + unitName: row.unitName || '', + projectName: row.projectName || '', + month: this.originalMonthTrue || row.month || '', + leaseMoney: row.leaseMoney ? parseFloat(row.leaseMoney) : 0, + pushStatus: row.pushStatus == 1 ? '已推送' : row.pushStatus == 0 ? '未推送' : '已退回', + pushRemark: row.pushRemark || '', + }; + + const newRow = worksheet.addRow(dataRow); + + // 设置数据行样式 + newRow.eachCell((cell) => { + cell.style = dataStyle; + }); + + // 设置费用列的数字格式(2位小数) + newRow.getCell(6).numFmt = '0.00'; // 合计费用 + }); + + // 添加合计行 + const totalRow = this.tableList[this.tableList.length - 1]; + const totalDataRow = { + index: '合计', + agreementCode: '', + unitName: '', + projectName: '', + month: '', + leaseMoney: this.totalCost ? parseFloat(this.totalCost) : 0, + pushStatus: '', + pushRemark: '' + }; + + const newTotalRow = worksheet.addRow(totalDataRow); + + // 设置合计行样式 + newTotalRow.eachCell((cell) => { + cell.style = totalStyle; + }); + + // 设置合计行费用列的数字格式 + newTotalRow.getCell(6).numFmt = '0.00'; // 租赁费用 + + // 生成文件名 + const fileName = `消耗性费用推送审核记录_${new Date().toISOString().slice(0, 10)}.xlsx`; + + // 生成Excel文件并下载 + const buffer = await workbook.xlsx.writeBuffer(); + const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); + + // 创建下载链接 + const link = document.createElement('a'); + const url = URL.createObjectURL(blob); + link.setAttribute('href', url); + link.setAttribute('download', fileName); + link.style.visibility = 'hidden'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + // 清理URL对象 + URL.revokeObjectURL(url); + + this.$modal.msgSuccess('Excel导出成功'); + } catch (error) { + console.error('导出Excel失败:', error); + this.$modal.msgError('导出Excel失败,请稍后重试'); + } + }, + + submit() { this.ids = this.ids.filter(id => id != null) console.log("xxxxxxxxxxxxxxx",this.ids) diff --git a/src/views/material/costPush/leaseExpensePush/index.vue b/src/views/material/costPush/leaseExpensePush/index.vue index 5ea4ea33..50ba3cf7 100644 --- a/src/views/material/costPush/leaseExpensePush/index.vue +++ b/src/views/material/costPush/leaseExpensePush/index.vue @@ -109,7 +109,6 @@ 未推送 已推送 已退回 - 进行中 @@ -190,7 +189,7 @@ import { getProjectList, getUnitList, getAgreementInfoById } from '@/api/back/in import { getCostPushCheckList, getCostPushCheckListCount, submitPushSafetyCosts,getCostPushLeaseListApi } from '@/api/costPush/costPush' import TreeSelect from '@riophae/vue-treeselect' import '@riophae/vue-treeselect/dist/vue-treeselect.css' - +import ExcelJS from 'exceljs'; export default { components: { TreeSelect }, data() { @@ -219,13 +218,12 @@ export default { { label: '未推送', value: '0' }, { label: '已推送', value: '1' }, { label: '已退回', value: '2' }, - { label: '进行中', value: '3' } ], // 工程状态 total: 0, // 总条数 // 表头 tableColumns: [ + { label: '协议编号', prop: 'agreementCode' }, { label: '单位名称', prop: 'unitName' }, - { label: 'i8工程编号', prop: 'pc_no' }, { label: '工程名称', prop: 'projectName' }, { label: '推送月份', prop: 'month' }, { label: '租赁费用', prop: 'leaseMoney' }, @@ -439,17 +437,171 @@ export default { return `${year}${month}${day}_${hours}${minutes}${seconds}` }, // 导出数据 - handleExport() { - try { - let fileName = `机具费用推送_${this.formatTime(new Date())}.xLsx` - let url = '/material/backstage/costPush/exportPushCheck' - const params = { ...this.queryParams } - console.log('🚀 ~ 导出 ~ params:', params) - this.download(url, params, fileName) - } catch (error) { - console.log('导出数据失败', error) - } - }, + // handleExport() { + // try { + // let fileName = `机具费用推送_${this.formatTime(new Date())}.xLsx` + // let url = '/material/backstage/costPush/exportPushCheck' + // const params = { ...this.queryParams } + // console.log('🚀 ~ 导出 ~ params:', params) + // this.download(url, params, fileName) + // } catch (error) { + // console.log('导出数据失败', error) + // } + // }, + + + /** 外层导出 */ + async handleExport() { + if (!this.tableList || this.tableList.length === 0) { + this.$modal.msgWarning('没有可导出的数据'); + return; + } + + try { + // 创建工作簿 + const workbook = new ExcelJS.Workbook(); + const worksheet = workbook.addWorksheet('消耗性费用推送审核记录'); + + // 定义列配置 + const columns = [ + { header: '序号', key: 'index', width: 8 }, + { header: '协议编号', key: 'agreementCode', width: 18 }, + { header: '单位名称', key: 'unitName', width: 20 }, + { header: '工程名称', key: 'projectName', width: 20 }, + { header: '推送月份', key: 'month', width: 12 }, + { header: '租赁费用(元)', key: 'leaseMoney', width: 18 }, + { header: '报废费用(元)', key: 'scrapMoney', width: 18 }, + { header: '丢失费用(元)', key: 'lostMoney', width: 18 }, + { header: '合计费用(元)', key: 'money', width: 18 }, + { header: '推送状态', key: 'pushStatus', width: 12 }, + { header: '推送备注', key: 'pushRemark', width: 12 }, + ]; + + worksheet.columns = columns; + + // 定义表头样式 + const headerStyle = { + font: { bold: true, color: { argb: 'FFFFFFFF' }, size: 11 }, + fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF4472C4' } }, + alignment: { horizontal: 'center', vertical: 'center', wrapText: true }, + border: { + top: { style: 'thin', color: { argb: 'FF000000' } }, + bottom: { style: 'thin', color: { argb: 'FF000000' } }, + left: { style: 'thin', color: { argb: 'FF000000' } }, + right: { style: 'thin', color: { argb: 'FF000000' } } + } + }; + + // 定义数据行样式 + const dataStyle = { + alignment: { horizontal: 'center', vertical: 'center' }, + border: { + top: { style: 'thin', color: { argb: 'FF000000' } }, + bottom: { style: 'thin', color: { argb: 'FF000000' } }, + left: { style: 'thin', color: { argb: 'FF000000' } }, + right: { style: 'thin', color: { argb: 'FF000000' } } + } + }; + + // 定义合计行样式 + const totalStyle = { + font: { bold: true, size: 11 }, + fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFF8F8F9' } }, + alignment: { horizontal: 'center', vertical: 'center' }, + border: { + top: { style: 'thin', color: { argb: 'FF000000' } }, + bottom: { style: 'thin', color: { argb: 'FF000000' } }, + left: { style: 'thin', color: { argb: 'FF000000' } }, + right: { style: 'thin', color: { argb: 'FF000000' } } + } + }; + + // 设置表头样式 + worksheet.getRow(1).eachCell((cell) => { + cell.style = headerStyle; + }); + + // 添加数据行(排除最后一行合计行) + const dataRows = this.tableList; + dataRows.forEach((row, index) => { + const dataRow = { + index: index + 1, + agreementCode: row.agreementCode || '', + unitName: row.unitName || '', + projectName: row.projectName || '', + month: this.originalMonthTrue || row.month || '', + leaseMoney: row.leaseMoney ? parseFloat(row.leaseMoney) : 0, + scrapMoney: row.scrapMoney? parseFloat(row.scrapMoney) : 0, + lostMoney: row.lostMoney? parseFloat(row.lostMoney) : 0, + money: row.money? parseFloat(row.money) : 0, + pushStatus: row.pushStatus == 1 ? '已推送' : row.pushStatus == 0 ? '未推送' : '已退回', + pushRemark: row.pushRemark || '', + }; + + const newRow = worksheet.addRow(dataRow); + + // 设置数据行样式 + newRow.eachCell((cell) => { + cell.style = dataStyle; + }); + + // 设置费用列的数字格式(2位小数) + newRow.getCell(6).numFmt = '0.00'; // 合计费用 + }); + + // 添加合计行 + const totalDataRow = { + index: '合计', + agreementCode: '', + unitName: '', + projectName: '', + month: '', + leaseMoney: this.totalData.leaseMoney? parseFloat(this.totalData.leaseMoney) : 0, + scrapMoney: this.totalData.scrapMoney? parseFloat(this.totalData.scrapMoney) : 0, + lostMoney: this.totalData.lostMoney? parseFloat(this.totalData.lostMoney) : 0, + money: this.totalData.money ? parseFloat(this.totalData.money) : 0, + pushStatus: '', + pushRemark: '' + }; + + const newTotalRow = worksheet.addRow(totalDataRow); + + // 设置合计行样式 + newTotalRow.eachCell((cell) => { + cell.style = totalStyle; + }); + + // 设置合计行费用列的数字格式 + newTotalRow.getCell(6).numFmt = '0.00'; // 租赁费用 + + // 生成文件名 + const fileName = `租赁费用推送审核记录_${new Date().toISOString().slice(0, 10)}.xlsx`; + + // 生成Excel文件并下载 + const buffer = await workbook.xlsx.writeBuffer(); + const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); + + // 创建下载链接 + const link = document.createElement('a'); + const url = URL.createObjectURL(blob); + link.setAttribute('href', url); + link.setAttribute('download', fileName); + link.style.visibility = 'hidden'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + // 清理URL对象 + URL.revokeObjectURL(url); + + this.$modal.msgSuccess('Excel导出成功'); + } catch (error) { + console.error('导出Excel失败:', error); + this.$modal.msgError('导出Excel失败,请稍后重试'); + } + }, + + submit() { this.ids = this.ids.filter(id => id != null) console.log("xxxxxxxxxxxxxxx",this.ids) diff --git a/src/views/material/costPush/pushReview/index.vue b/src/views/material/costPush/pushReview/index.vue index 78fdf043..ec96ceb0 100644 --- a/src/views/material/costPush/pushReview/index.vue +++ b/src/views/material/costPush/pushReview/index.vue @@ -960,7 +960,8 @@ export default { { header: '丢失费用(元)', key: 'lostMoney', width: 18 }, { header: '合计费用(元)', key: 'money', width: 18 }, { header: '是否结算', key: 'isSettlement', width: 12 }, - { header: '是否审核', key: 'checkStatus', width: 12 } + { header: '推送状态', key: 'pushStatus', width: 12 }, + { header: '推送备注', key: 'pushRemark', width: 12 }, ]; worksheet.columns = columns; @@ -1023,7 +1024,8 @@ export default { lostMoney: row.lostMoney ? parseFloat(row.lostMoney) : 0, money: row.money ? parseFloat(row.money) : 0, isSettlement: row.isSettlement === 1 || row.isSettlement === 2 ? '已结算' : '未结算', - checkStatus: row.checkStatus === 1 ? '已审核' : '未审核' + pushStatus: row.pushStatus == 1 ? '已推送' : row.pushStatus == 0 ? '未推送' : '已退回', + pushRemark: row.pushRemark || '', }; const newRow = worksheet.addRow(dataRow); @@ -1056,7 +1058,8 @@ export default { lostMoney: totalRow.lostMoney ? parseFloat(totalRow.lostMoney) : 0, money: totalRow.money ? parseFloat(totalRow.money) : 0, isSettlement: '', - checkStatus: '' + pushStatus: '', + pushRemark: '' }; const newTotalRow = worksheet.addRow(totalDataRow);