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