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

6 months ago
<template>
<div>
<el-drawer
5 months ago
size="1250px"
6 months ago
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">
6 months ago
6 months ago
<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"
6 months ago
@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]
},
6 months ago
data() {
return {
type: [],
drawer: false,
select: {
page_size: 100,
6 months ago
page: 1,
top_pid: 1,
sort_name:'pid',
sort_type:'ASC'
6 months ago
},
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'
},
5 months ago
6 months ago
{
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) => {
1 month ago
let m2 = row.update_money||0;
6 months ago
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>)
}
},
5 months ago
{
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
},
6 months ago
]
}
},
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
})
6 months ago
for (let m of res.list.data) {
m.pid_info_name = m.pid_info?.name
5 months ago
m.pid_info_id = m.pid_info?.id
1 month ago
// console.log('m.pid_info_name',m.pid_info_name)
6 months ago
}
5 months ago
res.list.data.sort((a,b)=>{
return b.pid_info_id - a.pid_info_id
})
6 months ago
this.list =
mergeTableRow({
data: res.list.data,
5 months ago
mergeColNames: ["pid_info_name",'index'], // 需要合并的列,默认合并列相同的数据
6 months ago
firstMergeColNames: ["pid_info_name"], // 受影响的列只合并以firstMerge为首的同类型数据
firstMerge: 'pid_info_name' // 以哪列为基础进行合并,一般为第一列
})
this.total = res.list.total
},
selected (selections, selected) {
1 month ago
// selections: 所有已选中的行数组
// selected: 当前点击的行
// 确保 selected 存在且有效
if (!selected || !selected.id) {
// 如果没有 selected说明可能是取消选择操作使用 selections 更新
this.selections = Array.isArray(selections) ? selections : []
return
}
// 直接使用 selections 参数来更新选中列表,这样更可靠
// 因为 selections 是表格组件当前所有已选中的行
this.selections = Array.isArray(selections) ? [...selections] : []
5 months ago
// 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 {
1 month ago
// const existingIndex = this.selections.findIndex(i => i.id === selected.id)
// if (existingIndex > -1) {
// // 已选中,取消选中
// this.selections.splice(existingIndex, 1)
// } else {
// // 未选中,添加到选中列表
// this.selections.push(selected)
// }
5 months ago
// }
6 months ago
},
selectAll (selections) {
1 month ago
// 确保 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()
}
}
})
6 months ago
},
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
1 month ago
},
drawer: {
handler: function(val) {
if (val) {
// 打开抽屉时,清空选中状态
this.selections = []
this.$nextTick(() => {
if (this.$refs.xyTable && this.$refs.xyTable.clearSelection) {
this.$refs.xyTable.clearSelection()
}
})
}
}
}
},
6 months ago
created() {
// this.getPlanProgress()
6 months ago
}
}
</script>
<style scoped lang="scss">
</style>