新增结算报表页面

This commit is contained in:
syruan 2025-08-21 20:20:31 +08:00
parent b844e6ff6f
commit acaf3f0a15
5 changed files with 1658 additions and 34 deletions

View File

@ -9,6 +9,15 @@ export function getSltAgreementInfo(query) {
})
}
// 查询费用结算申请列表
export function getSltReportList(query) {
return request({
url: '/material/slt_agreement_info/getSltReportList',
method: 'get',
params: query
})
}
// 查询材料站费用结算申请列表
export function getClzSltAgreementInfo(query) {
return request({
@ -110,6 +119,14 @@ export function getSltList(query) {
})
}
// 查询已结算报表列表
export function getSltReportedList(params){
return request({
url: '/material/slt_agreement_info/getSltReportedList',
method: 'get',
params: params
})
}
// 结算审批提交
export function costExamine(params){
@ -196,3 +213,5 @@ export function getClzAgreementInfoById(data) {

View File

@ -117,6 +117,33 @@
</div>
</div>
<div>
<el-table :data="loseList">
<el-table-column label="丢失费用明细" align="center">
<el-table-column label="序号" align="center" type="index" width="60"/>
<el-table-column label="设备名称" align="center" prop="typeName" :show-overflow-tooltip="true"/>
<el-table-column label="规格型号" align="center" prop="modelName" :show-overflow-tooltip="true"/>
<el-table-column label="计量单位" align="center" prop="mtUnitName" :show-overflow-tooltip="true"/>
<el-table-column label="丢失数量" align="center" prop="num" :show-overflow-tooltip="true">
<template slot-scope="scope" v-show="scope.row.num">
{{ scope.row.num.toFixed(2) }}
</template>
</el-table-column>
<el-table-column label="丢失费用(元)" align="center" prop="costs" :show-overflow-tooltip="true">
<template slot-scope="scope" v-show="scope.row.costs">
{{ scope.row.costs.toFixed(2) }}
</template>
</el-table-column>
</el-table-column>
</el-table>
<div class="tabelAll">
<div class="columnAllNum">费用小计</div>
<div class="columnAll">
{{ loseCost }}
</div>
</div>
</div>
<div>
<el-table :data="scrapList">
<el-table-column label="报废费用明细" align="center">
@ -145,33 +172,6 @@
</div>
</div>
<div>
<el-table :data="loseList">
<el-table-column label="丢失费用明细" align="center">
<el-table-column label="序号" align="center" type="index" width="60"/>
<el-table-column label="设备名称" align="center" prop="typeName" :show-overflow-tooltip="true"/>
<el-table-column label="规格型号" align="center" prop="modelName" :show-overflow-tooltip="true"/>
<el-table-column label="计量单位" align="center" prop="mtUnitName" :show-overflow-tooltip="true"/>
<el-table-column label="丢失数量" align="center" prop="num" :show-overflow-tooltip="true">
<template slot-scope="scope" v-show="scope.row.num">
{{ scope.row.num.toFixed(2) }}
</template>
</el-table-column>
<el-table-column label="丢失费用(元)" align="center" prop="costs" :show-overflow-tooltip="true">
<template slot-scope="scope" v-show="scope.row.costs">
{{ scope.row.costs.toFixed(2) }}
</template>
</el-table-column>
</el-table-column>
</el-table>
<div class="tabelAll">
<div class="columnAllNum">费用小计</div>
<div class="columnAll">
{{ loseCost }}
</div>
</div>
</div>
<div>
<el-table :data="reducList">
<el-table-column label="减免费用明细" align="center">

View File

@ -223,9 +223,9 @@
<script>
import {
// getProjectList,
getUnitList,
// getAgreementInfoById,
// getProjectList,
getUnitList, getUnitListFilterTeam,
// getAgreementInfoById,
} from '@/api/back/index.js'
import { getSltAgreementInfo,getProjectListByUnitIds,getAgreementInfoById, getSltInfo } from '@/api/cost/cost'
import { toChineseAmount } from '@/utils/bonus.js'
@ -326,13 +326,13 @@ export default {
}
const res = await getUnitList(params)
this.unitList = res.data;
if(this.queryParams.projectId){
this.getAgreementInfo()
}
if (this.queryParams.projectId) {
this.getAgreementInfo()
}
},
unitChange(val){
console.log('Selected values:', val); //
console.log('Selected values:', val); //
// this.unitIds.push(Number(val.id));
// if(val&&val.length>0){
// this.queryParams.unitId=this.unitIds[this.unitIds.length - 1]

View File

@ -0,0 +1,812 @@
<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 disabled/>
</el-form-item>
<el-form-item prop="sltStatus">
<el-select v-model="queryParams.sltStatus" placeholder="请选择结算状态" clearable filterable>
<el-option
v-for="dict in statusList"
:key="dict.id"
:label="dict.name"
:value="dict.id"
></el-option>
</el-select>
</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-form-item>
</el-form>
<el-table v-loading="loading" :data="tableList" >
<el-table-column label="序号" align="center" type="index" width="60">
<template slot-scope="scope">
<span>{{
(queryParams.pageNum - 1) * 10 + 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="createTime" width="100" />
<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="costs" :show-overflow-tooltip="true">
<template slot-scope="scope">
<el-button
type="text"
@click="showCostDetail(scope.row, 'total')"
:style="{color: scope.row.costs > 0 ? '#409EFF' : '#606266'}"
:disabled="!(scope.row.costs > 0)">
<span v-if="scope.row.costs != null && scope.row.costs != ''">
{{ scope.row.costs.toFixed(2) }}
</span>
<span v-else>{{ 0.00 }}</span>
</el-button>
</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="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="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 === '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" />
<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-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>未知</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,
} from '@/api/back/index.js'
import {getSltList, costExamine, getSltInfo, getSltReportedList} 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: 'CostApplyList',
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: 10000,
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 getUnitList(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
getSltReportedList(this.queryParams).then((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: 10000,
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' };
},
async openPrintDialog(row){
this.openPrint = true
try {
const res = await getSltInfo([row])
console.log('🚀 ~ openPrintDialog ~ res:', res)
if (!res.data) return
this.agreementContent = res.data
this.agreementContent.agreementCode = row.agreementCode
this.agreementContent.costAll = Number(res.data.leaseCost) + Number(res.data.repairCost) + Number(res.data.scrapCost) + Number(res.data.loseCost) - Number(res.data.reductionCost)
// costAllUpper
this.agreementContent.costAllUpper = toChineseAmount(this.agreementContent.costAll.toFixed(2))
} catch (error) {
console.log('🚀 ~ openPrintDialog ~ error:', error)
}
},
//
print() {
this.$refs.remarksPrintRef.print();
},
//
async showCostDetail(row, costType) {
const costTypeMap = {
'lease': '租赁费用',
'repair': '维修费用',
'lose': '丢失费用',
'scrap': '报废费用',
'total': '合计费用'
};
this.costDetailTitle = `${costTypeMap[costType]}详情 - ${row.agreementCode}`;
this.costDetailType = costType;
this.costDetailVisible = true;
this.costDetailLoading = true;
this.costDetailList = [];
try {
// 使
const requestData = [row];
const response = await getSltInfo(requestData);
if (response.code === 200 && response.data) {
let sourceList = [];
//
switch (costType) {
case 'lease':
sourceList = response.data.leaseList || [];
break;
case 'repair':
sourceList = response.data.repairList || [];
break;
case 'lose':
sourceList = response.data.loseList || [];
break;
case 'scrap':
sourceList = response.data.scrapList || [];
break;
case 'total':
//
const allLists = [
...(response.data.leaseList || []).map(item => ({...item, costType: 'lease'})),
...(response.data.repairList || []).map(item => ({...item, costType: 'repair'})),
...(response.data.loseList || []).map(item => ({...item, costType: 'lose'})),
...(response.data.scrapList || []).map(item => ({...item, costType: 'scrap'}))
];
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
};
} 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
};
}
return baseData;
});
} else {
this.$modal.msgError(response.msg || '获取费用详情失败');
}
} catch (error) {
console.error('获取费用详情失败:', error);
this.$modal.msgError('获取费用详情失败,请稍后重试');
} finally {
this.costDetailLoading = false;
}
},
// 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: '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 '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': '报废费用'
};
value = typeMap[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失败请稍后重试');
}
},
},
}
</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>

View File

@ -0,0 +1,793 @@
<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 disabled/>
</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-form-item>
</el-form>
<el-table v-loading="loading" :data="tableList" >
<el-table-column label="序号" align="center" type="index" width="60">
<template slot-scope="scope">
<span>{{
(queryParams.pageNum - 1) * 10 + 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="costs" :show-overflow-tooltip="true">
<template slot-scope="scope">
<el-button
type="text"
@click="showCostDetail(scope.row, 'total')"
:style="{color: scope.row.costs > 0 ? '#409EFF' : '#606266'}"
:disabled="!(scope.row.costs > 0)">
<span v-if="scope.row.costs != null && scope.row.costs != ''">
{{ scope.row.costs.toFixed(2) }}
</span>
<span v-else>{{ 0.00 }}</span>
</el-button>
</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="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="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 === '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" />
<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-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>未知</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,
} 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: 'CostApplyList',
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: 10000,
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 getUnitList(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: 10000,
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 = Number(this.agreementContent.leaseCost) + Number(this.agreementContent.repairCost) + Number(this.agreementContent.scrapCost) + Number(this.agreementContent.loseCost) - Number(this.agreementContent.reductionCost)
// 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': '报废费用',
'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 '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'}))
];
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
};
} 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
};
}
return baseData;
});
},
// 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: '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 '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': '报废费用'
};
value = typeMap[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失败请稍后重试');
}
},
},
}
</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>