608 lines
20 KiB
Vue
608 lines
20 KiB
Vue
<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>
|