|
|
<template>
|
|
|
<div>
|
|
|
|
|
|
<el-drawer
|
|
|
size="1250px"
|
|
|
title="预算统计"
|
|
|
:visible.sync="drawer"
|
|
|
direction="rtl">
|
|
|
<div style="padding: 0 10px;">
|
|
|
<xy-table style="width: 100%;"
|
|
|
ref="xyTable"
|
|
|
:objectSpanMethod="objectSpanMethod"
|
|
|
:table-item="table"
|
|
|
:list="list"
|
|
|
:show-summary="true"
|
|
|
:summary-method="summary"
|
|
|
@select="selected"
|
|
|
@select-all="selectAll">
|
|
|
|
|
|
<template v-slot:btns>
|
|
|
<div></div>
|
|
|
</template>
|
|
|
</xy-table>
|
|
|
|
|
|
<div style="display: flex;justify-content: flex-end;">
|
|
|
<Page :total="total"
|
|
|
show-elevator
|
|
|
:page-size="select.page_size"
|
|
|
@on-change="e => {
|
|
|
select.page = e;
|
|
|
getPlanProgress();
|
|
|
}" />
|
|
|
</div>
|
|
|
</div>
|
|
|
</el-drawer>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import { moneyFormatter } from '@/utils'
|
|
|
import { getProgress } from '@/api/budget/budget'
|
|
|
import { mergeTableRow } from '@/utils/mergeTableRow'
|
|
|
|
|
|
export default {
|
|
|
props: {
|
|
|
year: [Number,String]
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
type: [],
|
|
|
drawer: false,
|
|
|
select: {
|
|
|
page_size: 100,
|
|
|
page: 1,
|
|
|
top_pid: 1,
|
|
|
sort_name:'pid',
|
|
|
sort_type:'ASC'
|
|
|
},
|
|
|
total: 0,
|
|
|
list: [],
|
|
|
selections: [],
|
|
|
table: [
|
|
|
{
|
|
|
prop: 'selection',
|
|
|
type: 'selection',
|
|
|
width: 50,
|
|
|
label: ' ',
|
|
|
reserveSelection: true,
|
|
|
fixed: 'left'
|
|
|
},
|
|
|
{
|
|
|
label: "隶属项目",
|
|
|
prop: 'pid_info_name',
|
|
|
width: 200,
|
|
|
align: 'left',
|
|
|
sortable: false,
|
|
|
fixed: this.$store.getters.device === 'mobile'?false:'left'
|
|
|
},
|
|
|
{
|
|
|
prop: 'name',
|
|
|
label: '项目名称',
|
|
|
width: 200,
|
|
|
align: 'left',
|
|
|
fixed: this.$store.getters.device === 'mobile'?false:'left'
|
|
|
},
|
|
|
|
|
|
{
|
|
|
prop: 'money',
|
|
|
width: 180,
|
|
|
label: '年初预算金额(元)',
|
|
|
align: 'right'
|
|
|
},
|
|
|
{
|
|
|
prop: 'update_money',
|
|
|
width: 180,
|
|
|
label: '调整后预算金额(元)',
|
|
|
align: 'right'
|
|
|
},
|
|
|
{
|
|
|
prop: 'use_money_total',
|
|
|
label: '使用金额',
|
|
|
align: 'right',
|
|
|
width: 180
|
|
|
},
|
|
|
{
|
|
|
prop: 'rate',
|
|
|
label: '进展率',
|
|
|
width: 200,
|
|
|
customFn: (row) => {
|
|
|
let m2 = row.update_money||0;
|
|
|
let m1 = row.money;
|
|
|
let m3 = row.use_money_total;
|
|
|
let per = 0;
|
|
|
|
|
|
if (m2 != 0) {
|
|
|
per = ((m3 / m2) * 100).toFixed(2);
|
|
|
} else if (m1 != 0) {
|
|
|
per = ((m3 / m1) * 100).toFixed(2);
|
|
|
}
|
|
|
let perShow = Number(per)
|
|
|
return ( <div><el-progress percentage={perShow}> </el-progress></div>)
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
prop: 'type_detail.value',
|
|
|
label: '预算类型',
|
|
|
width: 120,
|
|
|
},
|
|
|
{
|
|
|
prop: 'year',
|
|
|
label: '所属年份',
|
|
|
width: 160
|
|
|
},
|
|
|
{
|
|
|
prop: 'plan_department.name',
|
|
|
label: "相关科室",
|
|
|
width: 180
|
|
|
},
|
|
|
{
|
|
|
prop: 'content',
|
|
|
label: '描述',
|
|
|
align: 'left',
|
|
|
minWidth: 300
|
|
|
},
|
|
|
]
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
show () {
|
|
|
this.drawer = true
|
|
|
},
|
|
|
hide () {
|
|
|
this.drawer = false
|
|
|
},
|
|
|
objectSpanMethod({
|
|
|
row,
|
|
|
column,
|
|
|
}) {
|
|
|
const span = column['property'] + '-span'
|
|
|
if (row[span]) {
|
|
|
return row[span]
|
|
|
}
|
|
|
},
|
|
|
async getPlanProgress(val) {
|
|
|
const res = await getProgress({
|
|
|
year:this.year,
|
|
|
...this.select
|
|
|
})
|
|
|
for (let m of res.list.data) {
|
|
|
m.pid_info_name = m.pid_info?.name
|
|
|
m.pid_info_id = m.pid_info?.id
|
|
|
// console.log('m.pid_info_name',m.pid_info_name)
|
|
|
}
|
|
|
res.list.data.sort((a,b)=>{
|
|
|
return b.pid_info_id - a.pid_info_id
|
|
|
})
|
|
|
this.list =
|
|
|
mergeTableRow({
|
|
|
data: res.list.data,
|
|
|
mergeColNames: ["pid_info_name",'index'], // 需要合并的列,默认合并列相同的数据
|
|
|
firstMergeColNames: ["pid_info_name"], // 受影响的列,只合并以firstMerge为首的同类型数据
|
|
|
firstMerge: 'pid_info_name' // 以哪列为基础进行合并,一般为第一列
|
|
|
})
|
|
|
this.total = res.list.total
|
|
|
|
|
|
},
|
|
|
|
|
|
selected (selections, selected) {
|
|
|
// selections: 所有已选中的行数组
|
|
|
// selected: 当前点击的行
|
|
|
|
|
|
// 确保 selected 存在且有效
|
|
|
if (!selected || !selected.id) {
|
|
|
// 如果没有 selected,说明可能是取消选择操作,使用 selections 更新
|
|
|
this.selections = Array.isArray(selections) ? selections : []
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 直接使用 selections 参数来更新选中列表,这样更可靠
|
|
|
// 因为 selections 是表格组件当前所有已选中的行
|
|
|
this.selections = Array.isArray(selections) ? [...selections] : []
|
|
|
|
|
|
// if (selected['pid_info_name-span']?.rowspan > 1) {
|
|
|
// if (this.selections.find(i => i.id === selected.id)) {
|
|
|
// let len = selected['pid_info_name-span'].rowspan
|
|
|
// let idx = this.selections.indexOf(selected)
|
|
|
// this.selections.splice(idx,len)
|
|
|
// } else {
|
|
|
// let len = selected['pid_info_name-span'].rowspan
|
|
|
// let idx = this.list.indexOf(selected)
|
|
|
// this.selections.push(...this.list.slice(idx,idx+len))
|
|
|
// }
|
|
|
// } else {
|
|
|
// const existingIndex = this.selections.findIndex(i => i.id === selected.id)
|
|
|
// if (existingIndex > -1) {
|
|
|
// // 已选中,取消选中
|
|
|
// this.selections.splice(existingIndex, 1)
|
|
|
// } else {
|
|
|
// // 未选中,添加到选中列表
|
|
|
// this.selections.push(selected)
|
|
|
// }
|
|
|
// }
|
|
|
},
|
|
|
selectAll (selections) {
|
|
|
// 确保 selections 是一个数组
|
|
|
this.selections = Array.isArray(selections) ? [...selections] : []
|
|
|
|
|
|
// 强制更新视图,确保选中状态同步
|
|
|
this.$nextTick(() => {
|
|
|
// 如果取消全选,确保表格的选中状态也被清除
|
|
|
if (this.selections.length === 0) {
|
|
|
if (this.$refs.xyTable && this.$refs.xyTable.clearSelection) {
|
|
|
this.$refs.xyTable.clearSelection()
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
summary ({ columns,data }) {
|
|
|
return columns.map((column,index) => {
|
|
|
if (index === 0) return '总计';
|
|
|
if (column.property === 'money') {
|
|
|
return this.selections.reduce((pre,cur) => (pre + Number(cur['money'] || 0)),0).toFixed(2)
|
|
|
}
|
|
|
if (column.property === 'update_money') {
|
|
|
return this.selections.reduce((pre,cur) => (pre + Number(cur['update_money'] || 0)),0).toFixed(2)
|
|
|
}
|
|
|
if (column.property === 'use_money_total') {
|
|
|
return this.selections.reduce((pre,cur) => (pre + Number(cur['use_money_total'] || 0)),0).toFixed(2)
|
|
|
}
|
|
|
if (column.property === 'rate') {
|
|
|
let moneyTotal = this.selections.reduce((pre,cur) => (pre + Number(cur['money'] || 0)),0)
|
|
|
let useMoneyTotal = this.selections.reduce((pre,cur) => (pre + Number(cur['use_money_total'] || 0)),0)
|
|
|
let updateMoneyTotal = this.selections.reduce((pre,cur) => (pre + Number(cur['update_money'] || 0)),0)
|
|
|
if (updateMoneyTotal !== 0) return ((useMoneyTotal / updateMoneyTotal) * 100).toFixed(2) + '%';
|
|
|
if (moneyTotal !== 0) return ((useMoneyTotal / moneyTotal) * 100).toFixed(2) + '%';
|
|
|
return '0%';
|
|
|
}
|
|
|
return '';
|
|
|
})
|
|
|
|
|
|
}
|
|
|
},
|
|
|
computed: {},
|
|
|
watch: {
|
|
|
year: {
|
|
|
handler:function(val) {
|
|
|
console.log("val",val)
|
|
|
this.getPlanProgress(val)
|
|
|
},
|
|
|
immediate: true
|
|
|
},
|
|
|
drawer: {
|
|
|
handler: function(val) {
|
|
|
if (val) {
|
|
|
// 打开抽屉时,清空选中状态
|
|
|
this.selections = []
|
|
|
this.$nextTick(() => {
|
|
|
if (this.$refs.xyTable && this.$refs.xyTable.clearSelection) {
|
|
|
this.$refs.xyTable.clearSelection()
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
created() {
|
|
|
// this.getPlanProgress()
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
</style>
|