You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

294 lines
8.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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>