bonus-ui/src/views/material/cost/component/unreportHome.vue

1021 lines
45 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" id="costApplyList">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
<el-form-item prop="unitIds">
<treeselect
v-model="queryParams.unitId"
:options="unitList" :normalizer="normalizer"
:show-count="true" style="width: 240px" :disable-branch-nodes="true"
noChildrenText="没有数据了" noOptionsText="没有数据" noResultsText="没有搜索结果"
placeholder="请选择结算单位" @select="unitChange"
/>
</el-form-item>
<el-form-item prop="projectIds">
<treeselect
v-model="queryParams.projectId"
:options="proList" :normalizer="normalizer"
:show-count="true" style="width: 240px" :disable-branch-nodes="true"
noChildrenText="没有数据了" noOptionsText="没有数据" noResultsText="没有搜索结果"
placeholder="请选择结算工程" @select="proChange"
/>
</el-form-item>
<el-form-item prop="agreementCode">
<el-input v-model="queryParams.agreementCode" placeholder="请输入协议号" clearable/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery" >查询</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery" >重置</el-button>
<el-button type="success" icon="el-icon-download" size="mini" @click="exportExcel" :disabled="tableList.length === 0">导出Excel</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="tableList" :max-height="650">
<el-table-column label="序号" align="center" type="index" width="60">
<template slot-scope="scope">
<span>{{
(queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1
}}</span>
</template>
</el-table-column>
<el-table-column label="协议号" align="center" prop="agreementCode" :show-overflow-tooltip="true"/>
<el-table-column label="结算单位" align="center" prop="unitName" />
<el-table-column label="结算工程" align="center" prop="projectName" />
<el-table-column label="结算类型" align="center" prop="sltStatus" :show-overflow-tooltip="true">
<template slot-scope="scope">
<el-tag v-if="scope.row.settlementType === 1" effect="plain">工器具</el-tag>
<el-tag type="warning" v-if="scope.row.settlementType === 2" effect="plain">安全工器具</el-tag>
<el-tag v-if="scope.row.settlementType == null || scope.row.settlementType === 0" effect="plain">总费用</el-tag>
</template>
</el-table-column>
<el-table-column label="租赁费用" align="center" prop="leaseCost" :show-overflow-tooltip="true">
<template slot-scope="scope">
<el-button
type="text"
@click="showCostDetail(scope.row, 'lease')"
:style="{color: scope.row.leaseCost > 0 ? '#409EFF' : '#606266'}"
:disabled="!(scope.row.leaseCost > 0)">
{{ scope.row.leaseCost || 0 }}
</el-button>
</template>
</el-table-column>
<el-table-column label="维修费用" align="center" prop="repairCost" width="80">
<template slot-scope="scope">
<el-button
type="text"
@click="showCostDetail(scope.row, 'repair')"
:style="{color: scope.row.repairCost > 0 ? '#409EFF' : '#606266'}"
:disabled="!(scope.row.repairCost > 0)">
{{ scope.row.repairCost || 0 }}
</el-button>
</template>
</el-table-column>
<el-table-column label="丢失费用" align="center" prop="loseCost" :show-overflow-tooltip="true">
<template slot-scope="scope">
<el-button
type="text"
@click="showCostDetail(scope.row, 'lose')"
:style="{color: scope.row.loseCost > 0 ? '#409EFF' : '#606266'}"
:disabled="!(scope.row.loseCost > 0)">
{{ scope.row.loseCost || 0 }}
</el-button>
</template>
</el-table-column>
<el-table-column label="报废费用" align="center" prop="scrapCost" width="80">
<template slot-scope="scope">
<el-button
type="text"
@click="showCostDetail(scope.row, 'scrap')"
:style="{color: scope.row.scrapCost > 0 ? '#409EFF' : '#606266'}"
:disabled="!(scope.row.scrapCost > 0)">
{{ scope.row.scrapCost || 0 }}
</el-button>
</template>
</el-table-column>
<el-table-column label="减免费用" align="center" prop="reductionCost" width="80">
<template slot-scope="scope">
<el-button
type="text"
@click="showCostDetail(scope.row, 'reduction')"
:style="{color: scope.row.reductionCost > 0 ? '#409EFF' : '#606266'}"
:disabled="!(scope.row.reductionCost > 0)">
{{ scope.row.reductionCost || 0 }}
</el-button>
</template>
</el-table-column>
<el-table-column label="合计费用(元)" align="center" prop="costs" :show-overflow-tooltip="true">
<template slot-scope="scope">
<span v-if="scope.row.costs != null && scope.row.costs != ''">
<el-button
type="text"
@click="showCostDetail(scope.row, 'total')"
:style="{color: calculateTotalCost(scope.row) > 0 ? '#409EFF' : '#606266'}"
:disabled="!(calculateTotalCost(scope.row) > 0)">
{{ calculateTotalCost(scope.row).toFixed(2) }}
</el-button>
</span>
<span v-else style="color: #909399;">
无待结算费用
</span>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
:page-sizes="[10, 50, 200, 500, 2000]"
@pagination="getList"
/>
<!-- 费用详情弹窗 -->
<el-dialog
:title="costDetailTitle"
:visible.sync="costDetailVisible"
width="80%"
top="5vh"
:close-on-click-modal="false">
<!-- 租赁费用详情表格 -->
<el-table
v-if="costDetailType === 'lease'"
v-loading="costDetailLoading"
:data="costDetailList"
border
stripe
height="500">
<el-table-column label="序号" align="center" type="index" width="60" />
<el-table-column label="名称" align="center" prop="name" :show-overflow-tooltip="true" />
<el-table-column label="型号" align="center" prop="model" :show-overflow-tooltip="true" />
<el-table-column label="单位" align="center" prop="unit" width="80" />
<el-table-column label="单价(元)" align="center" prop="unitPrice" width="100" />
<el-table-column label="数量" align="center" prop="quantity" width="80" />
<el-table-column label="归还数量" align="center" prop="returnQuantity" width="100" />
<el-table-column label="租赁日期" align="center" prop="leaseDate" width="120" />
<el-table-column label="退还日期" align="center" prop="returnDate" width="120" />
<el-table-column label="天数" align="center" prop="days" width="80" />
<el-table-column label="费用(元)" align="center" prop="cost" width="100">
<template slot-scope="scope">
{{ scope.row.cost ? scope.row.cost.toFixed(2) : '0.00' }}
</template>
</el-table-column>
</el-table>
<!-- 维修费用详情表格 -->
<el-table
v-if="costDetailType === 'repair'"
v-loading="costDetailLoading"
:data="costDetailList"
border
stripe
height="500">
<el-table-column label="序号" align="center" type="index" width="60" />
<el-table-column label="机具名称" align="center" prop="name" :show-overflow-tooltip="true" />
<el-table-column label="规格型号" align="center" prop="model" :show-overflow-tooltip="true" />
<el-table-column label="单位" align="center" prop="unit" width="80" />
<el-table-column label="维修数量" align="center" prop="repairQuantity" width="100" />
<el-table-column label="是否收费" align="center" prop="partType" width="100">
<template slot-scope="scope">
<span v-if="scope.row.partType === '收费'">收费</span>
<span v-else-if="scope.row.partType === '不收费'">不收费</span>
<span v-else>{{ scope.row.partType || '-' }}</span>
</template>
</el-table-column>
<el-table-column label="维修费用(元)" align="center" prop="cost" width="120">
<template slot-scope="scope">
{{ scope.row.cost ? scope.row.cost.toFixed(2) : '0.00' }}
</template>
</el-table-column>
</el-table>
<!-- 丢失费用详情表格 -->
<el-table
v-if="costDetailType === 'lose'"
v-loading="costDetailLoading"
:data="costDetailList"
border
stripe
height="500">
<el-table-column label="序号" align="center" type="index" width="60" />
<el-table-column label="机具名称" align="center" prop="name" :show-overflow-tooltip="true" />
<el-table-column label="规格型号" align="center" prop="model" :show-overflow-tooltip="true" />
<el-table-column label="单位" align="center" prop="unit" width="80" />
<el-table-column label="丢失数量" align="center" prop="loseQuantity" width="100" />
<el-table-column label="丢失费用(元)" align="center" prop="cost" width="120">
<template slot-scope="scope">
{{ scope.row.cost ? scope.row.cost.toFixed(2) : '0.00' }}
</template>
</el-table-column>
</el-table>
<!-- 报废费用详情表格 -->
<el-table
v-if="costDetailType === 'scrap'"
v-loading="costDetailLoading"
:data="costDetailList"
border
stripe
height="500">
<el-table-column label="序号" align="center" type="index" width="60" />
<el-table-column label="机具名称" align="center" prop="name" :show-overflow-tooltip="true" />
<el-table-column label="机具规格" align="center" prop="model" :show-overflow-tooltip="true" />
<el-table-column label="单位" align="center" prop="unit" width="80" />
<el-table-column label="报废数量" align="center" prop="scrapQuantity" width="100" />
<el-table-column label="报废费用(元)" align="center" prop="cost" width="120">
<template slot-scope="scope">
{{ scope.row.cost ? scope.row.cost.toFixed(2) : '0.00' }}
</template>
</el-table-column>
</el-table>
<!-- 减免费用详情表格 -->
<el-table
v-if="costDetailType === 'reduction'"
v-loading="costDetailLoading"
:data="costDetailList"
border
stripe
height="500">
<el-table-column label="序号" align="center" type="index" width="60" />
<el-table-column label="机具名称" align="center" prop="name" :show-overflow-tooltip="true" />
<el-table-column label="机具规格" align="center" prop="model" :show-overflow-tooltip="true" />
<el-table-column label="单位" align="center" prop="unit" width="80" />
<el-table-column label="减免数量" align="center" prop="reductionQuantity" width="100" />
<el-table-column label="减免费用(元)" align="center" prop="cost" width="120">
<template slot-scope="scope">
{{ scope.row.cost ? scope.row.cost.toFixed(2) : '0.00' }}
</template>
</el-table-column>
</el-table>
<!-- 合计费用详情表格 -->
<el-table
v-if="costDetailType === 'total'"
v-loading="costDetailLoading"
:data="costDetailList"
border
stripe
height="500">
<el-table-column label="序号" align="center" type="index" width="60" />
<el-table-column label="名称" align="center" prop="name" :show-overflow-tooltip="true" />
<el-table-column label="型号" align="center" prop="model" :show-overflow-tooltip="true" />
<el-table-column label="单位" align="center" prop="unit" width="80" />
<el-table-column label="单价(元)" align="center" prop="unitPrice" width="100">
<template slot-scope="scope">
<span v-if="scope.row.costType === 'lease'">{{ scope.row.unitPrice || 0 }}</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="数量" align="center" width="80">
<template slot-scope="scope">
<span v-if="scope.row.costType === 'lease'">{{ scope.row.quantity || 0 }}</span>
<span v-else-if="scope.row.costType === 'repair'">{{ scope.row.repairQuantity || 0 }}</span>
<span v-else-if="scope.row.costType === 'lose'">{{ scope.row.loseQuantity || 0 }}</span>
<span v-else-if="scope.row.costType === 'scrap'">{{ scope.row.scrapQuantity || 0 }}</span>
<span v-else-if="scope.row.costType === 'reduction'">{{ scope.row.reductionQuantity || 0 }}</span>
<span v-else>{{ scope.row.quantity || 0 }}</span>
</template>
</el-table-column>
<el-table-column label="归还数量" align="center" width="100">
<template slot-scope="scope">
<span v-if="scope.row.costType === 'lease'">{{ scope.row.returnQuantity || 0 }}</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="租赁日期" align="center" width="120">
<template slot-scope="scope">
<span v-if="scope.row.costType === 'lease'">{{ scope.row.leaseDate || '-' }}</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="退还日期" align="center" width="120">
<template slot-scope="scope">
<span v-if="scope.row.costType === 'lease'">{{ scope.row.returnDate || '-' }}</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="天数" align="center" width="80">
<template slot-scope="scope">
<span v-if="scope.row.costType === 'lease'">{{ scope.row.days || 0 }}</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="费用(元)" align="center" prop="cost" width="100">
<template slot-scope="scope">
{{ scope.row.cost ? scope.row.cost.toFixed(2) : '0.00' }}
</template>
</el-table-column>
<el-table-column label="费用类型" align="center" prop="costType" width="100">
<template slot-scope="scope">
<el-tag v-if="scope.row.costType === 'lease'" type="primary">租赁费用</el-tag>
<el-tag v-else-if="scope.row.costType === 'repair'" type="warning">维修费用</el-tag>
<el-tag v-else-if="scope.row.costType === 'lose'" type="danger">丢失费用</el-tag>
<el-tag v-else-if="scope.row.costType === 'scrap'" type="info">报废费用</el-tag>
<el-tag v-else-if="scope.row.costType === 'reduction'" type="success">减免费用</el-tag>
<el-tag v-else>未知</el-tag>
</template>
</el-table-column>
</el-table>
<div slot="footer" class="dialog-footer">
<el-button type="primary" icon="el-icon-download" @click="exportCostDetail">导出Excel</el-button>
<el-button @click="costDetailVisible = false">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
getProjectList,
getUnitList,
getAgreementInfoById, getUnitListFilterTeam,
} from '@/api/back/index.js'
import {getSltList, costExamine, getSltReportedList, getSltReportList} from '@/api/cost/cost'
import { toChineseAmount } from '@/utils/bonus.js'
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';
export default {
name: 'UnreportHome',
dicts: ['cost_status'],
components: { Treeselect, vueEasyPrint },
data() {
return {
// 遮罩层
loading: false,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 单位数据
unitList: [],
// 工程数据
proList: [],
unitIds: null,
projectIds: null,
selectTreeProps: {
children: 'children',
label: 'name',
value: 'id',
// multiple: true,//false
},
statusList: [
{ id: '1', name: '待审核' },
{ id: '2', name: '审核通过' },
{ id: '3', name: '审核驳回' },
], //集合
// 表格数据
tableList: [],
// 查询参数
queryParams: {
disabled: false,
pageNum: 1,
pageSize: 10,
keyWord: undefined,
sltStatus: '',
isCommit: '',
unitId: null,
projectId: null,
agreementId: null,
agreementCode: null,
},
openPrint: false,
// 审批弹窗
aform: { status: '2' },
//审批弹窗是否开启
applyVisible: false,
id: '',
agreementIdTemp: '',
// 协议书内容
agreementContent: {
agreementCode: '',
projectName: '',
unitName: '',
leaseCost: '', // 租赁费用
repairCost: '', // 维修费用
loseCost: '', // 丢失费用
scrapCost: '', // 报废费用
reductionCost: '', // 减免费用
costAll: '', // 合计费用
costAllUpper: '', // 合计费用大写
},
// 费用详情弹窗相关
costDetailVisible: false,
costDetailLoading: false,
costDetailTitle: '',
costDetailList: [],
costDetailType: '', // 当前查看的费用类型
}
},
created() {
this.GetUnitData()
this.GetProData()
this.getList()
},
methods: {
/** 转换菜单数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.id,
label: node.name,
children: node.children,
};
},
// 获取 来往单位 列表数据
async GetUnitData() {
const params = {
// projectId: this.queryParams.projectId /* */,
}
const res = await getUnitListFilterTeam(params)
this.unitList = res.data;
this.getAgreementInfo()
},
unitChange(val){
setTimeout(()=>{
this.queryParams.projectId=null
this.queryParams.agreementId = null
this.queryParams.agreementCode = null
this.GetProData()
},500)
},
// 获取 工程名称 列表数据
async GetProData() {
const params = {
unitId: this.queryParams.unitId,
}
const res = await getProjectList(params)
this.proList = res.data;
this.getAgreementInfo()
},
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,
}
const res = await getAgreementInfoById(params)
console.log(res)
if (!(res.data && res.data.agreementId)) {
this.$message.error('当前单位和工程无协议!')
this.queryParams.unitId = null
this.queryParams.projectId = null
this.GetUnitData()
this.GetProData()
} else {
this.queryParams.agreementId = res.data.agreementId
this.queryParams.agreementCode = res.data.agreementCode
}
}
},
/** 查询列表 */
getList() {
this.loading = true
getSltReportList(this.queryParams).then((response) => {
console.dir(response)
this.tableList = response.rows
this.total = response.total
this.loading = false
})
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.queryParams={
pageNum: 1,
pageSize: 10,
sltStatus: '',
isCommit:'',
unitId: null,
projectId: null,
agreementId: '',
agreementCode: '',
}
this.resetForm('queryForm')
this.handleQuery()
},
//结算审批查看
handleView(row) {
let arr = [];
arr.push(row);
this.$emit("goDetail",JSON.stringify(arr));
},
//结算审批
handleExame(row) {
this.id = row.id
this.agreementIdTemp = row.agreementId
this.applyVisible = true
},
//提交按钮
submitListForm() {
let param = {
id: this.id,
status: this.aform.status,
remark: this.aform.remark,
agreementId: this.agreementIdTemp,
}
costExamine(param).then((res) => {
if (res.code == 200) {
this.$modal.msgSuccess("审批成功");
this.getList();
this.applyVisible = false;
} else {
this.$modal.msgError(res.msg);
}
}).catch(() => {});
},
//取消按钮
cancel() {
this.applyVisible = false;
this.aform = { status: '2' };
},
openPrintDialog(row){
this.openPrint = true
try {
// 直接使用row中的数据不再调用接口
this.agreementContent = {
agreementCode: row.agreementCode,
projectName: row.projectName,
unitName: row.unitName,
leaseCost: row.leaseCost || 0,
repairCost: row.repairCost || 0,
loseCost: row.loseCost || 0,
scrapCost: row.scrapCost || 0,
reductionCost: row.reductionCost || 0
};
this.agreementContent.costAll = this.calculateTotalCost(row)
// costAllUpper 中文大写
this.agreementContent.costAllUpper = toChineseAmount(this.agreementContent.costAll.toFixed(2))
} catch (error) {
console.log('🚀 ~ openPrintDialog ~ error:', error)
}
},
//维修任务单打印
print() {
this.$refs.remarksPrintRef.print();
},
// 显示费用详情 - 直接使用外层数据,不再调用接口
showCostDetail(row, costType) {
const costTypeMap = {
'lease': '租赁费用',
'repair': '维修费用',
'lose': '丢失费用',
'scrap': '报废费用',
'reduction': '减免费用',
'total': '合计费用'
};
this.costDetailTitle = `${costTypeMap[costType]}详情 - ${row.agreementCode}`;
this.costDetailType = costType;
this.costDetailVisible = true;
this.costDetailLoading = false; // 直接使用数据,无需加载
this.costDetailList = [];
// 直接从row对象中获取已有的费用列表数据
let sourceList = [];
// 根据费用类型获取对应的数据列表
switch (costType) {
case 'lease':
sourceList = row.leaseList || [];
break;
case 'repair':
sourceList = row.repairList || [];
break;
case 'lose':
sourceList = row.loseList || [];
break;
case 'scrap':
sourceList = row.scrapList || [];
break;
case 'reduction':
sourceList = row.reductionList || [];
break;
case 'total':
// 合计费用显示所有类型的数据
const allLists = [
...(row.leaseList || []).map(item => ({...item, costType: 'lease'})),
...(row.repairList || []).map(item => ({...item, costType: 'repair'})),
...(row.loseList || []).map(item => ({...item, costType: 'lose'})),
...(row.scrapList || []).map(item => ({...item, costType: 'scrap'})),
...(row.reductionList || []).map(item => ({...item, costType: 'reduction'}))
];
sourceList = allLists;
break;
default:
sourceList = [];
}
// 根据不同费用类型处理数据
this.costDetailList = sourceList.map(item => {
const baseData = {
name: item.typeName || '',
model: item.modelName || '',
unit: item.mtUnitName || '',
cost: item.costs || 0,
costType: item.costType || costType
};
// 根据费用类型添加特定字段
if (costType === 'lease' || (costType === 'total' && item.costType === 'lease')) {
return {
...baseData,
unitPrice: item.leasePrice || 0,
quantity: item.num || 0,
returnQuantity: item.backNum || 0,
leaseDate: item.startTime || '',
returnDate: item.endTime || '',
days: item.leaseDays || 0
};
} else if (costType === 'repair' || (costType === 'total' && item.costType === 'repair')) {
return {
...baseData,
repairQuantity: item.num || 0,
partType: item.partType
};
} else if (costType === 'lose' || (costType === 'total' && item.costType === 'lose')) {
return {
...baseData,
loseQuantity: item.num || 0
};
} else if (costType === 'scrap' || (costType === 'total' && item.costType === 'scrap')) {
return {
...baseData,
scrapQuantity: item.num || 0
};
} else if (costType === 'reduction' || (costType === 'total' && item.costType === 'reduction')) {
return {
...baseData,
reductionQuantity: item.num || 0
};
}
return baseData;
});
},
// 导出主表格Excel
exportExcel() {
if (!this.tableList || this.tableList.length === 0) {
this.$modal.msgWarning('没有可导出的数据');
return;
}
try {
// 定义Excel列配置
const columns = [
{ key: 'index', title: '序号' },
{ key: 'agreementCode', title: '协议号' },
{ key: 'unitName', title: '结算单位' },
{ key: 'projectName', title: '结算工程' },
{ key: 'settlementType', title: '结算类型' },
{ key: 'leaseCost', title: '租赁费用' },
{ key: 'repairCost', title: '维修费用' },
{ key: 'loseCost', title: '丢失费用' },
{ key: 'scrapCost', title: '报废费用' },
{ key: 'reductionCost', title: '减免费用' },
{ key: 'costs', title: '合计费用(元)' }
];
// 准备Excel数据
const excelData = [];
// 添加表头
const headerRow = columns.map(col => col.title);
excelData.push(headerRow);
// 添加数据行
this.tableList.forEach((row, index) => {
const dataRow = columns.map(col => {
if (col.key === 'index') {
return (this.queryParams.pageNum - 1) * 10 + index + 1;
} else if (col.key === 'settlementType') {
// 处理结算类型显示
if (row.settlementType === 1) return '工器具';
if (row.settlementType === 2) return '安全工器具';
return '总费用';
} else if (col.key === 'costs') {
// 处理合计费用格式 - 前端计算
return parseFloat(this.calculateTotalCost(row).toFixed(2));
} else if (col.key === 'leaseCost' || col.key === 'repairCost' || col.key === 'loseCost' || col.key === 'scrapCost' || col.key === 'reductionCost') {
// 处理费用字段格式
return row[col.key] || 0;
} else {
return row[col.key] || '';
}
});
excelData.push(dataRow);
});
// 创建工作簿和工作表
const workbook = XLSX.utils.book_new();
const worksheet = XLSX.utils.aoa_to_sheet(excelData);
// 设置列宽
const columnWidths = [
{ wch: 8 }, // 序号
{ wch: 20 }, // 协议号
{ wch: 15 }, // 结算单位
{ wch: 20 }, // 结算工程
{ wch: 12 }, // 结算类型
{ wch: 12 }, // 租赁费用
{ wch: 12 }, // 维修费用
{ wch: 12 }, // 丢失费用
{ wch: 12 }, // 报废费用
{ wch: 12 }, // 减免费用
{ wch: 15 } // 合计费用
];
worksheet['!cols'] = columnWidths;
// 添加工作表到工作簿
XLSX.utils.book_append_sheet(workbook, worksheet, '未结算记录');
// 生成文件名
const fileName = `未结算记录_${new Date().toISOString().slice(0, 10)}.xlsx`;
// 生成Excel文件并下载
const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
const blob = new Blob([excelBuffer], { 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失败请稍后重试');
}
},
// 导出费用详情为Excel
exportCostDetail() {
if (!this.costDetailList || this.costDetailList.length === 0) {
this.$modal.msgWarning('没有可导出的数据');
return;
}
try {
// 根据费用类型定义不同的列配置
let columns = [];
let fileName = '';
let sheetName = '';
switch (this.costDetailType) {
case 'lease':
columns = [
{ key: 'name', title: '名称' },
{ key: 'model', title: '型号' },
{ key: 'unit', title: '单位' },
{ key: 'unitPrice', title: '单价(元)' },
{ key: 'quantity', title: '数量' },
{ key: 'returnQuantity', title: '归还数量' },
{ key: 'leaseDate', title: '租赁日期' },
{ key: 'returnDate', title: '退还日期' },
{ key: 'days', title: '天数' },
{ key: 'cost', title: '费用(元)' }
];
fileName = '租赁费用详情';
sheetName = '租赁费用';
break;
case 'repair':
columns = [
{ key: 'name', title: '机具名称' },
{ key: 'model', title: '规格型号' },
{ key: 'unit', title: '单位' },
{ key: 'repairQuantity', title: '维修数量' },
{ key: 'partType', title: '是否收费' },
{ key: 'cost', title: '维修费用(元)' }
];
fileName = '维修费用详情';
sheetName = '维修费用';
break;
case 'lose':
columns = [
{ key: 'name', title: '机具名称' },
{ key: 'model', title: '规格型号' },
{ key: 'unit', title: '单位' },
{ key: 'loseQuantity', title: '丢失数量' },
{ key: 'cost', title: '丢失费用(元)' }
];
fileName = '丢失费用详情';
sheetName = '丢失费用';
break;
case 'scrap':
columns = [
{ key: 'name', title: '机具名称' },
{ key: 'model', title: '机具规格' },
{ key: 'unit', title: '单位' },
{ key: 'scrapQuantity', title: '报废数量' },
{ key: 'cost', title: '报废费用(元)' }
];
fileName = '报废费用详情';
sheetName = '报废费用';
break;
case 'reduction':
columns = [
{ key: 'name', title: '机具名称' },
{ key: 'model', title: '机具规格' },
{ key: 'unit', title: '单位' },
{ key: 'reductionQuantity', title: '减免数量' },
{ key: 'cost', title: '减免费用(元)' }
];
fileName = '减免费用详情';
sheetName = '减免费用';
break;
case 'total':
columns = [
{ key: 'name', title: '名称' },
{ key: 'model', title: '型号' },
{ key: 'unit', title: '单位' },
{ key: 'unitPrice', title: '单价(元)' },
{ key: 'quantity', title: '数量' },
{ key: 'returnQuantity', title: '归还数量' },
{ key: 'leaseDate', title: '租赁日期' },
{ key: 'returnDate', title: '退还日期' },
{ key: 'days', title: '天数' },
{ key: 'cost', title: '费用(元)' },
{ key: 'costType', title: '费用类型' }
];
fileName = '合计费用详情';
sheetName = '合计费用';
break;
default:
this.$modal.msgError('未知的费用类型');
return;
}
// 准备Excel数据
const excelData = [];
// 添加表头
const headerRow = columns.map(col => col.title);
excelData.push(headerRow);
// 添加数据行
this.costDetailList.forEach(row => {
const dataRow = columns.map(col => {
let value = row[col.key] || '';
// 特殊处理费用类型字段
if (col.key === 'costType') {
const typeMap = {
'lease': '租赁费用',
'repair': '维修费用',
'lose': '丢失费用',
'scrap': '报废费用',
'reduction': '减免费用'
};
value = typeMap[value] || value;
}
// 特殊处理是否收费字段
if (col.key === 'partType') {
if (value === '收费') {
value = '收费';
} else if (value === '不收费') {
value = '不收费';
} else {
value = value || '-';
}
}
// 处理数值字段的格式
if (col.key === 'cost' || col.key === 'unitPrice') {
value = typeof value === 'number' ? parseFloat(value.toFixed(2)) : value;
}
return value;
});
excelData.push(dataRow);
});
// 创建工作簿和工作表
const workbook = XLSX.utils.book_new();
const worksheet = XLSX.utils.aoa_to_sheet(excelData);
// 设置列宽
const columnWidths = columns.map(col => {
// 根据列内容设置不同的宽度
if (col.key === 'name') return { wch: 20 };
if (col.key === 'model') return { wch: 15 };
if (col.key === 'leaseDate' || col.key === 'returnDate') return { wch: 12 };
if (col.key === 'cost' || col.key === 'unitPrice') return { wch: 12 };
if (col.key === 'costType') return { wch: 12 };
return { wch: 10 };
});
worksheet['!cols'] = columnWidths;
// 添加工作表到工作簿
XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
// 生成Excel文件并下载
const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
const blob = new Blob([excelBuffer], { 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}_${new Date().toISOString().slice(0, 10)}.xlsx`);
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失败请稍后重试');
}
},
// 计算合计费用
calculateTotalCost(row) {
const leaseCost = Number(row.leaseCost) || 0;
const repairCost = Number(row.repairCost) || 0;
const loseCost = Number(row.loseCost) || 0;
const scrapCost = Number(row.scrapCost) || 0;
const reductionCost = Number(row.reductionCost) || 0;
return leaseCost + repairCost + loseCost + scrapCost - reductionCost;
},
},
}
</script>
<style lang="scss" scoped>
::v-deep.el-table .fixed-width .el-button--mini {
width: 80px !important;
margin-bottom: 10px;
}
.dialog-footer {
display: flex;
justify-content: flex-end;
align-items: center;
}
.tabelColumn {
width:1000px;
height: 50px;
display: flex;
align-items: center;
border: 1px solid #9c9c9c;
// margin-bottom: 1px;
border-bottom: none;
}
.columnLabel {
height: 50px;
line-height: 50px;
text-align: center;
border-left: none;
}
.columnContent {
height: 50px;
line-height: 50px;
text-align: center;
border-left: 1px solid #9c9c9c;
}
</style>