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.

206 lines
5.9 KiB

<template>
<div>
<el-main style="padding-top:0px">
<!-- 页面标题和操作 -->
<div class="d-flex justify-between align-center mb-4" style="margin: 0px 0 16px 0;">
<h3 style="display: inline-block;"><i class="el-icon-data-analysis"></i> 科室资金执行率</h3>
<div>
<el-date-picker size="small" v-model="select.year"
value-format="yyyy" format="yyyy" type="year" placeholder="选择年">
</el-date-picker>
<el-button style="margin-left:10px" type="primary" size="small" @click="getProgress"></el-button>
</div>
</div>
<!-- 科室执行率卡片 -->
<el-row :gutter="20">
<el-col :xs="24" :sm="12" :md="8" v-for="(dept, idx) in list" :key="dept.idx">
<el-card class="department-card" shadow="hover">
<div>
<h4 class="card-title">{{ dept.plan_department?dept.plan_department.name:'' }}</h4>
<div class="mb-2">
<div class="d-flex justify-between mb-1">
<span class="fw-bold">当前执行率</span>
<span class="execution-rate text-primary">{{ getCompletionRate(dept.rate) }}%</span>
</div>
<el-progress :show-text='false' :percentage="getCompletionRate(dept.rate)" :stroke-width="8" color="#409EFF" />
</div>
<div class="mb-2">
<div class="d-flex justify-between mb-1">
<span class="fw-bold">完成后执行率</span>
<span class="execution-rate text-success">{{ getCompletionRate(dept.rate_end) }}%</span>
</div>
<el-progress :show-text='false' :percentage="getCompletionRate(dept.rate_end)" :stroke-width="8" color="#67C23A" />
</div>
<el-row class="text-center" :gutter="0">
<el-col :span="8">
<div class="text-muted">预算总额</div>
<div class="text-muted fw-bold">{{ formatToWan(dept.money_total) }}</div>
</el-col>
<el-col :span="8">
<div class="text-muted">已执行</div>
<div class="text-muted fw-bold text-success">{{ formatToWan(dept.use_money_total) }}</div>
</el-col>
<el-col :span="8">
<div class="text-muted">进行中</div>
<div class="text-muted fw-bold text-warning">{{ getDoingMoneyTotal(dept.money_total,dept.use_money_total) }}</div>
</el-col>
</el-row>
<div class="mt-3 detail" @click="goToDetail(dept)">
<el-button type="text">
<i class="el-icon-view"></i> 查看详情
</el-button>
</div>
</div>
</el-card>
</el-col>
</el-row>
</el-main>
</el-container>
<departmentProgressDetail ref="departmentProgressDetail"></departmentProgressDetail>
</div>
</template>
<script>
import {
statisticDepartment
} from "@/api/departmentProgress"
import departmentProgressDetail from './components/departmentProgressDetail.vue'
export default {
name: 'DepartmentProgress',
components:{
departmentProgressDetail
},
data() {
return {
select: {
year: new Date().getFullYear()+''
},
list:[]
}
},
created(){
this.getProgress()
},
methods: {
async getProgress() {
const res = await statisticDepartment({
year: this.select.year
},true)
const data = res.departmentList
data.sort((a,b)=>{
return a.plan_department.sortnumber - b.plan_department.sortnumber
})
this.list = data
},
getCompletionRate(dept) {
return dept?Number(dept.toFixed(2)):0
},
formatToWan(num) {
if (num === null || num === undefined) return '0元';
num = Number(num);
if (isNaN(num)) return '0元';
if (Math.abs(num) < 10000) {
return num.toString() + '元'; // 小于1万直接返回原数值
} else {
return (num / 10000).toFixed(2) + '万元'; // 除以1万并保留两位小数
}
},
getDoingMoneyTotal(contractPlanSum, useMoneyTotal) {
// 转换为数字并处理非数字情况
const plan = Number(contractPlanSum) || 0;
const used = Number(useMoneyTotal) || 0;
// 计算差值若小于0则取0
const doing = Math.max(plan - used, 0);
return this.formatToWan(doing)
},
goToDetail(row) {
this.$refs.departmentProgressDetail.row = row
this.$refs.departmentProgressDetail.isShowModal = true
},
}
}
</script>
<style scoped>
.department-card {
border-radius: 8px;
margin-bottom: 15px;
transition: all 0.3s;
}
.department-card:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
}
.card-title {
font-size: 18px;
font-weight: bold;
margin-bottom: 10px;
}
.execution-rate {
font-size: 20px;
font-weight: bold;
}
.text-muted {
color: #909399;
text-align: center;
margin-bottom:10px;
font-size: 16px;
}
.fw-bold {
font-weight: bold;
color:#000;
font-size: 16px;
}
.text-success {
color: #67C23A;
}
.text-warning {
color: #E6A23C;
}
.text-primary{
color: #409EFF;
}
.d-flex {
display: flex;
}
.justify-between {
justify-content: space-between;
}
.align-center {
align-items: center;
}
.detail{
border:1px solid #409EFF;
text-align: center;
cursor:pointer
}
.mb-1 {
margin-bottom: 4px;
}
.mb-2 {
margin-bottom: 12px;
}
.mb-4 {
margin-bottom: 24px;
}
.mt-3 {
margin-top: 16px;
}
</style>