@ -1,28 +1,21 @@
< template >
< div >
< el -drawer
size = "880px"
title = "执行统计"
: visible . sync = "drawer"
direction = "rtl" >
< el -drawer size = "880px" title = "执行统计" :visible.sync ="drawer" direction = "rtl" >
< div style = "padding: 0 20px;" >
< template v-if ="type === 1" >
< Card >
< el -checkbox :indeterminate ="isIndeterminate"
v - model = "checkAll"
@ change = " e => {
< el -checkbox :indeterminate ="isIndeterminate" v -model = " checkAll " @ change = " e = > {
departmentSelect = e ? departments . map ( i => ( i . plan _department _id ) ) : [ ] ;
isIndeterminate = false ;
} " > 全选 < / e l - c h e c k b o x >
< el -checkbox -group v -model = " departmentSelect "
size = "small"
@ change = " e => {
< el -checkbox -group style = "max-height:200px" v -model = " departmentSelect " size = "small" @ change = " e = > {
let count = e . length ;
checkAll = count === departments . length ;
isIndeterminate = count > 0 && count < departments . length ;
} " >
< el -checkbox v-for ="item in departments" :label="item.plan_department_id" :key="item.plan_department_id" > {{ item.plan_department ? item.plan_department.name : item.plan_department_id }} < / el -checkbox >
< el -checkbox v -for = " item in departments " :label ="item.plan_department_id"
: key = "item.plan_department_id" > { { item . plan _department ? item . plan _department . name : item . plan _department _id } } < / e l - c h e c k b o x >
< / e l - c h e c k b o x - g r o u p >
< / Card >
@ -42,22 +35,21 @@
< / div >
< div class = "item" >
< p class = "item__title" > 执行情况 < / p >
< el -progress class = "item__value" text -inside :stroke-width ="20" :percentage ="totalPercent" > < / e l - p r o g r e s s >
< el -progress class = "item__value" text -inside :stroke-width ="20"
: percentage = "totalPercent" > < / e l - p r o g r e s s >
< / div >
< / div >
< / Card >
< / template >
< template v-else >
< Card >
< el -checkbox :indeterminate ="isIndeterminate2"
v - model = "checkAll2"
@ change = " e => {
< Card >
< el -checkbox :indeterminate ="isIndeterminate2" v -model = " checkAll2 " @ change = " e = > {
typeSelect = e ? types . map ( i => ( i . id ) ) : [ ] ;
isIndeterminate = false ;
} " > 全选 < / e l - c h e c k b o x >
< el -checkbox -group v -model = " typeSelect "
size = "small"
@ change = " e = > {
< el -checkbox -group style = "max-height:200px" v -model = " typeSelect " size = "small" @ change = " e = > {
let count = e . length ;
checkAll2 = count === types . length ;
isIndeterminate2 = count > 0 && count < types . length ;
@ -82,175 +74,361 @@
< / div >
< div class = "item" >
< p class = "item__title" > 执行情况 < / p >
< el -progress class = "item__value" text -inside :stroke-width ="20" :percentage ="totalPercent" > < / e l - p r o g r e s s >
< el -progress class = "item__value" text -inside :stroke-width ="20"
: percentage = "totalPercent" > < / e l - p r o g r e s s >
< / div >
< / div >
< / Card >
< / template >
<!-- < barChart v -if = " drawer " :xAxisData ="xAxis" :seriesData ="seriesData" / > -- >
< div class = "bar-chart" v-if ="drawer" >
<!-- 图表容器 -- >
< div ref = "chartDom" class = "chart-container" style = "background: #fff; min-height: 400px;" > < / div >
< / div >
< / div >
< / e l - d r a w e r >
< / div >
< / template >
< script >
import { moneyFormatter } from "@/utils"
import { typeCarry } from "@/api/dashboard/notice"
export default {
props : {
departments : Array ,
year : [ Number , String ]
} ,
data ( ) {
return {
type : 1 , / / 1 科 室 2 类 型
drawer : false ,
isIndeterminate : false ,
checkAll : false ,
departmentSelect : [ ] ,
isIndeterminate2 : false ,
checkAll2 : false ,
types : [ ] ,
typeSelect : [ ] ,
}
} ,
methods : {
moneyFormatter ,
show ( ) {
this . drawer = true
} ,
hide ( ) {
this . drawer = false
} ,
setType ( type ) {
this . type = type
}
} ,
computed : {
selectedDepartments ( ) {
return this . departments ? . filter ( i => this . departmentSelect . find ( j => j === i . plan _department _id ) ) || [ ]
import * as echarts from 'echarts'
import {
moneyFormatter
} from "@/utils"
import {
typeCarry
} from "@/api/dashboard/notice"
/ / i m p o r t b a r C h a r t f r o m " @ / v i e w s / d a s h b o a r d / c o m p o n e n t s / b a r C h a r t . v u e "
export default {
props : {
departments : Array ,
year : [ Number , String ]
} ,
totalMoneyTotal1 ( ) {
return this . selectedDepartments . reduce ( ( pre , cur ) => ( pre + Number ( cur . money _total _1 || 0 ) ) , 0 ) || 0
components : {
/ / b a r C h a r t
} ,
totalMoneyTotal2 ( ) {
return this . selectedDepartments . reduce ( ( pre , cur ) => ( pre + Number ( cur . money _total _2 || 0 ) ) , 0 ) || 0
} ,
totalUseMoneyTotal ( ) {
return this . selectedDepartments . reduce ( ( pre , cur ) => ( pre + Number ( cur . use _money _total || 0 ) ) , 0 ) || 0
} ,
totalPercent ( ) {
if ( this . type === 1 ) {
return ( Number ( this . totalMoneyTotal2 !== 0 ) ? ( Math . round ( Number ( this . totalUseMoneyTotal ) / Number ( this . totalMoneyTotal2 ) * 10000 ) / 100 ) : ( Math . round ( Number ( this . totalUseMoneyTotal ) / Number ( this . totalMoneyTotal1 ) * 10000 ) / 100 ) ) || 0
} else {
return ( Number ( this . totalMoneyTotal2Type !== 0 ) ? ( Math . round ( Number ( this . totalUseMoneyTotalType ) / Number ( this . totalMoneyTotal2Type ) * 10000 ) / 100 ) : ( Math . round ( Number ( this . totalUseMoneyTotalType ) / Number ( this . totalMoneyTotal1Type ) * 10000 ) / 100 ) ) || 0
data ( ) {
return {
type : 1 , / / 1 科 室 2 类 型
drawer : false ,
isIndeterminate : false ,
checkAll : false ,
departmentSelect : [ ] ,
isIndeterminate2 : false ,
checkAll2 : false ,
types : [ ] ,
typeSelect : [ ] ,
chartInstance : null ,
}
} ,
mounted ( ) {
selectedTypes ( ) {
return this . types ? . filter ( i => this . typeSelect . find ( j => j === i . id ) ) || [ ]
} ,
totalMoneyTotal1Type ( ) {
return this . selectedTypes ? . reduce ( ( pre , cur ) => ( pre + Number ( cur . money _total _1 || 0 ) ) , 0 ) || 0
} ,
totalMoneyTotal2Type ( ) {
return this . selectedTypes ? . reduce ( ( pre , cur ) => ( pre + Number ( cur . money _total _2 || 0 ) ) , 0 ) || 0
methods : {
moneyFormatter ,
show ( ) {
this . drawer = true
} ,
hide ( ) {
this . drawer = false
} ,
setType ( type ) {
this . type = type
} ,
/ / 初 始 化 图 表
initChart ( ) {
this . chartInstance = echarts . init ( this . $refs . chartDom ) ;
console . log ( "this.chartInstance" , this . chartInstance )
this . updateChart ( )
} ,
/ / 更 新 图 表 数 据
updateChart ( ) {
if ( ! this . chartInstance ) return ;
console . log ( 'xAxisData' , this . xAxisData ) ;
console . log ( 'ydata1' , this . ydata1 ) ;
const option = {
tooltip : {
trigger : 'axis' ,
axisPointer : {
type : 'shadow'
} , / / 阴 影 指 示 器
formatter : function ( params ) {
console . log ( "params" , params )
let result = params [ 0 ] . axisValue + '<br/>' ;
params . forEach ( item => {
result += item . marker + item . seriesName + ': ' + item . value + '<br/>' ;
} ) ;
return result ;
}
} ,
legend : {
/ / 图 例 使 用 s e r i e s D a t a 中 的 n a m e
data : [ '年初预算合计金额' , '调整后预算合计金额' , '已使用' ] ,
top : 10
} ,
grid : {
left : '3%' ,
right : '4%' ,
bottom : '3%' ,
containLabel : true / / 包 含 坐 标 轴 刻 度 标 签
} ,
xAxis : {
type : 'category' ,
data : this . xAxisData , / / 用 c o m p u t e d 的 x A x i s D a t a
axisLabel : {
interval : 0 ,
rotate : 30 / / 可 根 据 实 际 情 况 调 整 角 度
}
} ,
yAxis : {
type : 'value' ,
/ / n a m e : ' 金 额 ( 元 ) ' ,
axisLabel : {
formatter : '{value}' / / 格 式 化 Y 轴 标 签
}
} ,
series : [ {
type : 'bar' ,
name : '年初预算合计金额' ,
data : this . ydata1 , / / 对 应 X 轴 每 项 的 数 值
itemStyle : {
color : '#5470C6'
} / / 自 定 义 颜 色
} ,
{
type : 'bar' ,
name : '调整后预算合计金额' ,
data : this . ydata2 ,
itemStyle : {
color : '#91CC75'
}
} ,
{
type : 'bar' ,
name : '已使用' ,
data : this . ydata3 ,
itemStyle : {
color : '#FAC858'
}
}
] ,
} ;
this . $nextTick ( ( ) => {
this . chartInstance . setOption ( option ) ;
} )
}
} ,
totalUseMoneyTotalType ( ) {
return this . selectedTypes ? . reduce ( ( pre , cur ) => ( pre + Number ( cur . use _money _total || 0 ) ) , 0 ) || 0
computed : {
selectedDepartments ( ) {
return this . departments ? . filter ( i => this . departmentSelect . find ( j => j === i . plan _department _id ) ) || [ ]
} ,
totalMoneyTotal1 ( ) {
return this . selectedDepartments . reduce ( ( pre , cur ) => ( pre + Number ( cur . money _total _1 || 0 ) ) , 0 ) || 0
} ,
totalMoneyTotal2 ( ) {
return this . selectedDepartments . reduce ( ( pre , cur ) => ( pre + Number ( cur . money _total _2 || 0 ) ) , 0 ) || 0
} ,
totalUseMoneyTotal ( ) {
return this . selectedDepartments . reduce ( ( pre , cur ) => ( pre + Number ( cur . use _money _total || 0 ) ) , 0 ) || 0
} ,
totalPercent ( ) {
if ( this . type === 1 ) {
return ( Number ( this . totalMoneyTotal2 !== 0 ) ? ( Math . round ( Number ( this . totalUseMoneyTotal ) / Number ( this
. totalMoneyTotal2 ) * 10000 ) / 100 ) : ( Math . round ( Number ( this . totalUseMoneyTotal ) / Number ( this
. totalMoneyTotal1 ) * 10000 ) / 100 ) ) || 0
} else {
return ( Number ( this . totalMoneyTotal2Type !== 0 ) ? ( Math . round ( Number ( this . totalUseMoneyTotalType ) / Number (
this . totalMoneyTotal2Type ) * 10000 ) / 100 ) : ( Math . round ( Number ( this . totalUseMoneyTotalType ) / Number (
this . totalMoneyTotal1Type ) * 10000 ) / 100 ) ) || 0
}
} ,
selectedTypes ( ) {
return this . types ? . filter ( i => this . typeSelect . find ( j => j === i . id ) ) || [ ]
} ,
totalMoneyTotal1Type ( ) {
return this . selectedTypes ? . reduce ( ( pre , cur ) => ( pre + Number ( cur . money _total _1 || 0 ) ) , 0 ) || 0
} ,
totalMoneyTotal2Type ( ) {
return this . selectedTypes ? . reduce ( ( pre , cur ) => ( pre + Number ( cur . money _total _2 || 0 ) ) , 0 ) || 0
} ,
totalUseMoneyTotalType ( ) {
return this . selectedTypes ? . reduce ( ( pre , cur ) => ( pre + Number ( cur . use _money _total || 0 ) ) , 0 ) || 0
} ,
xAxisData ( ) {
if ( this . type == 1 ) {
return this . selectedDepartments . map ( item => item . plan _department ? . name || '' ) ;
} else {
return this . selectedTypes . map ( item => item ? . name || '' ) ;
}
} ,
ydata1 ( ) {
if ( this . type == 1 ) {
return this . selectedDepartments . map ( item => Number ( item . money _total _1 ) || 0 )
} else {
return this . selectedTypes . map ( item => Number ( item . money _total _1 ) || 0 )
}
} ,
ydata2 ( ) {
if ( this . type == 1 ) {
return this . selectedDepartments . map ( item => Number ( item . money _total _2 ) || 0 )
} else {
return this . selectedTypes . map ( item => Number ( item . money _total _2 ) || 0 )
}
} ,
ydata3 ( ) {
if ( this . type == 1 ) {
return this . selectedDepartments . map ( item => Number ( item . use _money _total ) || 0 )
} else {
return this . selectedTypes . map ( item => Number ( item . use _money _total ) || 0 )
}
}
} ,
} ,
watch : {
year : {
handler : function ( val ) {
typeCarry ( {
year : val
} ) . then ( res => {
this . types = res
console . log ( res )
} )
watch : {
year : {
handler : function ( val ) {
typeCarry ( {
year : val
} ) . then ( res => {
this . types = res
/ / t h i s . x A x i s D a t a = t y p e s . m a p ( i t e m = > i t e m . n a m e ? i t e m . n a m e : ' ' ) / / 移 除 这 行 , x A x i s D a t a 由 c o m p u t e d 负 责
console . log ( res )
} )
} ,
immediate : true
} ,
departments : {
handler : function ( val ) {
/ / t h i s . x A x i s D a t a = v a l . m a p ( i t e m = > i t e m . p l a n _ d e p a r t m e n t ? i t e m . p l a n _ d e p a r t m e n t . n a m e : ' ' ) / / 移 除 这 行 , x A x i s D a t a 由 c o m p u t e d 负 责
} ,
immediate : true
} ,
immediate : true
drawer ( newVal ) {
if ( newVal ) {
this . $nextTick ( ( ) => {
/ / t h i s . u p d a t e C h a r t ( ) ;
this . initChart ( )
} )
} else {
if ( this . chartInstance ) {
this . chartInstance . dispose ( ) ;
}
}
} ,
departmentSelect : {
handler ( ) {
if ( this . drawer && this . chartInstance ) {
this . updateChart ( ) ;
}
} ,
deep : true
} ,
typeSelect : {
handler ( ) {
if ( this . drawer && this . chartInstance ) {
this . updateChart ( ) ;
}
} ,
deep : true
}
}
}
}
< / script >
< style scoped lang = "scss" >
$color : linear - gradient ( to top left , # ff6641 , # ec3634 ) ,
linear - gradient ( to top left , # 4 bfbb2 , # 49 f2ac ) ,
linear - gradient ( to top left , # efd458 , # ba840a ) ,
linear - gradient ( to top left , # 05 e6ff , # 0069 fe ) ,
linear - gradient ( to top left , # a5ffff , # 8 fccd9 ) ,
linear - gradient ( to top left , # fca7ff , # 7 a519a ) ,
linear - gradient ( to top left , # a4e829 , # 06 ac2e ) ;
@ for $index from 1 through length ( $color ) {
. card # { $index } {
color : # fff ;
display : flex ;
flex - direction : column ;
justify - content : center ;
background : nth ( $color , $index ) ;
grid - area : card # { $index } ;
border - radius : 4 px ;
filter : drop - shadow ( 0 2 px 8 px # 0004 ) ;
padding : 20 px ;
. chart - container {
width : 80 % ;
height : 250 px ;
margin : 0 auto ;
/* 固定高度,可根据需求调整 */
}
. item _ _title {
font - weight : 600 ;
text - align : center ;
$color : linear - gradient ( to top left , # ff6641 , # ec3634 ) ,
linear - gradient ( to top left , # 4 bfbb2 , # 49 f2ac ) ,
linear - gradient ( to top left , # efd458 , # ba840a ) ,
linear - gradient ( to top left , # 05 e6ff , # 0069 fe ) ,
linear - gradient ( to top left , # a5ffff , # 8 fccd9 ) ,
linear - gradient ( to top left , # fca7ff , # 7 a519a ) ,
linear - gradient ( to top left , # a4e829 , # 06 ac2e ) ;
@ for $index from 1 through length ( $color ) {
. card # { $index } {
color : # fff ;
display : flex ;
flex - direction : column ;
justify - content : center ;
background : nth ( $color , $index ) ;
grid - area : card # { $index } ;
border - radius : 4 px ;
filter : drop - shadow ( 0 2 px 8 px # 0004 ) ;
padding - bottom : 20 px ;
position : relative ;
padding : 20 px ;
& : : after {
content : '' ;
height : 2 px ;
background : linear - gradient ( to right , # fff 40 % , # 0000 ) ;
. item _ _title {
font - weight : 600 ;
text - align : center ;
position : absolute ;
bottom : - 1 px ;
left : 0 ;
right : 0 ;
padding - bottom : 20 px ;
position : relative ;
& : : after {
content : '' ;
height : 2 px ;
background : linear - gradient ( to right , # fff 40 % , # 0000 ) ;
position : absolute ;
bottom : - 1 px ;
left : 0 ;
right : 0 ;
}
}
. item _ _value {
text - align : center ;
flex : 1 ;
padding - top : 20 px ;
}
}
}
. content {
display : grid ;
grid - template - columns : repeat ( 4 , 1 fr ) ;
grid - gap : 20 px ;
padding : 20 px 0 ;
. item _ _title {
text - align : center ;
}
. item _ _value {
font - weight : 600 ;
font - size : 17 px ;
text - align : center ;
flex : 1 ;
padding - top : 20 px ;
}
}
}
. content {
display : grid ;
grid - template - columns : repeat ( 4 , 1 fr ) ;
grid - gap : 20 px ;
padding : 20 px 0 ;
. item _ _title {
text - align : center ;
: : v - deep . el - checkbox {
display : block ;
margin - bottom : 6 px ;
}
. item _ _value {
font - weight : 600 ;
font - size : 17 px ;
text - align : center ;
padding - top : 20 px ;
: : v - deep . el - checkbox - group {
max - height : 300 px ;
overflow - y : scroll ;
margin - left : 20 px ;
}
}
: : v - deep . el - checkbox {
display : block ;
margin - bottom : 6 px ;
}
: : v - deep . el - checkbox - group {
max - height : 300 px ;
overflow - y : scroll ;
margin - left : 20 px ;
}
< / style >