bonus-ui/src/views/material/costPush/expendableExpensePush/index.vue

608 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- 基础页面 -->
<div class="app-container">
<el-form v-show="showSearch" :model="queryParams" ref="queryForm" size="small" inline @submit.native.prevent>
<el-form-item label="选择单位" prop="unitId">
<TreeSelect
v-model="queryParams.unitId"
:options="unitList"
:normalizer="normalizer"
:show-count="true"
style="width: 215px"
:disable-branch-nodes="true"
noChildrenText="没有数据了"
noOptionsText="没有数据"
noResultsText="没有搜索结果"
placeholder="请选择单位"
@select="unitChange"
/>
</el-form-item>
<el-form-item label="选择工程" prop="projectId">
<TreeSelect
v-model="queryParams.projectId"
:options="proList"
:normalizer="normalizer"
:show-count="true"
style="width: 215px"
:disable-branch-nodes="true"
noChildrenText="没有数据了"
noOptionsText="没有数据"
noResultsText="没有搜索结果"
placeholder="请选择工程"
@select="proChange"
/>
</el-form-item>
<el-form-item label="推送月份" prop="month">
<el-date-picker
v-model="queryParams.month"
type="month"
:clearable="false"
placeholder="请选择月份"
value-format="yyyy-MM"
></el-date-picker>
</el-form-item>
<el-form-item label="提交状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 240px">
<el-option v-for="item in pushList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<!-- 表单按钮 -->
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
<el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">导出数据</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" size="mini" @click="submit">提 交</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table
:data="tableList"
fit
highlight-current-row
show-summary
ref="multipleTable"
row-key="id"
:summary-method="getSummaries"
style="width: 100%"
:max-height="650"
@selection-change="selectionChange"
>
<!-- 多选 -->
<el-table-column type="selection" width="65" align="center" :selectable="row => row.pushStatus != 1" />
<el-table-column
type="index"
width="55"
label="序号"
align="center"
:index="index => (queryParams.pageNum - 1) * queryParams.pageSize + index + 1"
/>
<el-table-column
v-for="(column, index) in tableColumns"
show-overflow-tooltip
:key="index"
:label="column.label"
:prop="column.prop"
align="center"
>
<!-- 插槽 -->
<template v-slot="{ row }" v-if="column.prop == 'leaseMoney'">
<span style="color: #409eff; cursor: pointer" @click="openDialog(row)">{{ row.leaseMoney }}</span>
</template>
<template v-slot="{ row }" v-else-if="column.prop == 'pushStatus'">
<span v-if="row.pushStatus == 0">未推送</span>
<span v-else-if="row.pushStatus == 1">已推送</span>
<span v-else-if="row.pushStatus == 2">已退回</span>
</template>
</el-table-column>
<!-- 操作 -->
</el-table>
<!-- 分页 -->
<!-- <pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/> -->
<!-- 弹框 -->
<el-dialog title="查看" :visible.sync="dialogVisible" width="70%">
<el-form ref="dialogForm" :model="dialogForm" label-width="80px" size="small" inline @submit.native.prevent>
<el-form-item label="" prop="name">
<el-input v-model="dialogForm.name" placeholder="请输入机具名称" clearable style="width: 240px" />
</el-form-item>
<el-form-item label="" prop="type">
<el-input v-model="dialogForm.type" placeholder="请输入规格型号" clearable style="width: 240px" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="getDiaList">查询</el-button>
<el-button icon="el-icon-refresh" @click="resetDialog">重置</el-button>
<el-button type="warning" icon="el-icon-download" @click="handleDiaExport">导出数据</el-button>
</el-form-item>
</el-form>
<el-table
:data="dialogTableList"
fit
highlight-current-row
show-summary
:summary-method="getDiaSummaries"
style="width: 100%"
>
<el-table-column type="index" width="55" label="序号" align="center" />
<el-table-column
v-for="(column, index) in dialogColumns"
show-overflow-tooltip
:key="index"
:label="column.label"
:prop="column.prop"
align="center"
></el-table-column>
</el-table>
</el-dialog>
</div>
</template>
<script>
import { getProjectList, getUnitList, getAgreementInfoById } from '@/api/back/index.js'
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() {
return {
showSearch: true,
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 多选框选中数据
ids: [],
taskId:[],
queryParams: {
pageNum: 1,
pageSize: 10,
unitId: null,
projectId: null,
agreementId: '',
agreementCode: '',
month: new Date().getFullYear() + '-' + String(new Date().getMonth() + 1).padStart(2, '0'),
isSend: null
},
unitList: [], // 单位
proList: [], // 工程
pushList: [
{ label: '未推送', value: '0' },
{ label: '已推送', value: '1' },
{ label: '已退回', value: '2' },
], // 工程状态
total: 0, // 总条数
// 表头
tableColumns: [
{ label: '协议编号', prop: 'agreementCode' },
{ label: '单位名称', prop: 'unitName' },
{ label: '工程名称', prop: 'projectName' },
{ label: '推送月份', prop: 'month' },
{ label: '消耗品费用', prop: 'leaseMoney' },
{ label: '推送状态', prop: 'pushStatus' },
{ label: '推送备注', prop: 'pushRemark' }
],
// 表格数据
tableList: [],
// 合计
totalCost: 0,
selectionList: [], // 选中行
// 弹窗数据
dialogVisible: false,
dialogForm: {
name: '',
type: ''
},
dialogTableList: [],
dialogColumns: [
{ label: '机具名称', prop: 'typeName' },
{ label: '规格型号', prop: 'modelName' },
{ label: '领料时间', prop: 'leaseDate' },
{ label: '消耗品数量', prop: 'num' },
{ label: '消耗品费用', prop: 'consMoney' }
]
}
},
created() {
this.GetUnitData()
this.GetProData()
this.getList()
},
methods: {
// 查询
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
// 重置
handleReset() {
this.queryParams.pageNum = 1
this.queryParams.pageSize = 10
this.$refs.queryForm.resetFields()
this.getList()
this.GetUnitData()
this.GetProData()
},
// 获取列表
async getList() {
console.log('列表-查询', this.queryParams)
const loading = this.$loading({ text: '加载中...' })
try {
const params = { ...this.queryParams }
const res = await getConsumPushCheckList(params)
console.log('🚀 ~ 获取列表 ~ res:', res)
this.tableList = res.rows
this.total = res.total
const res2 = await getConsumPushCheckListCount()
this.totalCost = res2.data.leaseMoney
loading.close()
} catch (error) {
console.log('🚀 ~ 获取列表 ~ error:', error)
this.tableList = []
this.total = 0
loading.close()
}
},
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children
}
return {
id: node.id,
label: node.name,
children: node.children
}
},
// 多选
selectionChange(selection) {
console.log("xxxxxxxxxxxxx",selection)
this.taskId = selection.map((item) => item.taskId).filter(id => id != null)
this.ids = selection.map((item) => item.agreementId).filter(id => id != null)
this.single = selection.length != 1
this.multiple = !selection.length
},
// 合计
getSummaries() {
const sums = []
sums[0] = '合计'
sums[6] = this.totalCost
return sums
},
// 获取 单位 列表数据
async GetUnitData() {
try {
const res = await getUnitList({})
this.unitList = res.data
this.getAgreementInfo()
} catch (error) {
console.log('🚀 ~ GetUnitData ~ error:', error)
}
},
unitChange(val) {
setTimeout(() => {
this.queryParams.projectId = null
this.queryParams.agreementId = null
this.queryParams.agreementCode = null
this.GetProData()
}, 300)
},
// 获取 工程名称 列表数据
async GetProData() {
const params = {
unitId: this.queryParams.unitId
}
try {
const res = await getProjectList(params)
this.proList = res.data
this.getAgreementInfo()
} catch (error) {
console.log('🚀 ~ GetProData ~ error:', error)
}
},
proChange(val) {
setTimeout(() => {
this.GetUnitData()
}, 500)
},
// 获取 协议id
async getAgreementInfo() {
if (this.queryParams.unitId && this.queryParams.projectId) {
const params = {
unitId: this.queryParams.unitId,
projectId: this.queryParams.projectId
}
try {
const res = await getAgreementInfoById(params)
console.log('🚀 ~ 协议id ~ res:', res)
if (res.data && res.data.agreementId) {
this.queryParams.agreementId = res.data.agreementId
this.queryParams.agreementCode = res.data.agreementCode
} else {
this.$message.error('当前单位和工程无协议!')
this.queryParams.unitId = null
this.queryParams.projectId = null
this.GetUnitData()
this.GetProData()
}
} catch (error) {
console.log('🚀 ~ getAgreementInfo ~ error:', error)
}
}
},
formatTime(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')
return `${year}${month}${day}_${hours}${minutes}${seconds}`
},
/** 外层导出 */
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)
if (this.ids.length == 0) {
this.$message({
type: 'warning',
message: '请选择数据',
})
return;
}
// 弹框确认
this.$confirm('是否确认提交?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
try {
let params = {
agreementIds: this.ids.filter(id => id != null),
taskId: this.taskId.filter(id => id!= null)[0]
}
submitPushSafetyConsumeCosts(params).then(res => {
// 确定
this.$message({
type: 'success',
message: '操作成功!'
})
this.getList()
})
} catch (error) {
console.log('🚀 ~ .then ~ error:', error)
}
})
.catch(() => {
// 取消
})
},
// 弹框
openDialog(row, type) {
this.dialogVisible = true
this.dialogForm.agreementId = row.agreementId
this.dialogForm.taskId = row.taskId
this.getDiaList()
},
// 弹框列表
async getDiaList() {
const params = { ...this.dialogForm }
try {
const res = await getConsumeDetailsListApi(params)
this.dialogTableList = res.rows
console.log("xxxxxxxxxxxx",this.dialogTableList)
// else if (this.costIndex === 2) {
// res = await
// } else if (this.costIndex === 3) {
// res = await
// }
} catch (error) {
console.log('🚀 ~ getDiaList ~ error:', error)
}
},
// 弹框重置
resetDialog() {
this.dialogForm = {
name: '',
type: ''
}
this.getDiaList()
},
// 弹框合计
getDiaSummaries(param) {
const { columns, data } = param
const sums = []
sums[0] = '合计'
let total = 0
data.forEach((column, index) => {
total += Number(column.consMoney)
})
sums[5] = total ==0 ? 0:total.toFixed(5)
return sums
},
// 弹框导出数据
handleDiaExport() {
// 提示
this.$message({
type: 'warning',
message: '导出功能开发中,敬请期待!'
})
try {
let fileName = `数据_${this.formatTime(new Date())}.xLsx`
let url = ''
const params = { ...this.dialogForm }
console.log('🚀 ~ 导出 ~ params:', params)
// this.download(url, params, fileName)
} catch (error) {
console.log('导出数据失败', error)
}
}
}
}
</script>
<style lang="scss" scoped></style>