39 changed files with 5087 additions and 165 deletions
-
BINsrc/assets/image/datav_bg2.png
-
39src/components/NoticeMsgBar/index.vue
-
40src/components/TopModules/index.vue
-
36src/router/index.js
-
6src/router/routes_datav_xm.js
-
30src/router/routes_my_work.js
-
1src/router/routes_workflow.js
-
2src/styles/variables.scss
-
3src/views/dashboard/admin/index.vue
-
29src/views/datav/xm/FullScreenLayout.vue
-
2src/views/datav/xm/branch/index.vue
-
275src/views/datav/xm/branch1/cards.vue
-
215src/views/datav/xm/branch1/digitalFlop.vue
-
104src/views/datav/xm/branch1/index.less
-
463src/views/datav/xm/branch1/index.vue
-
108src/views/datav/xm/branch1/rankingBoard.vue
-
176src/views/datav/xm/branch1/roseChart.vue
-
66src/views/datav/xm/branch1/scrollBoard.vue
-
46src/views/datav/xm/branch1/topHeader.vue
-
109src/views/datav/xm/branch1/waterLevelChart.vue
-
65src/views/datav/xm/common/index.vue
-
490src/views/datav/xm/common/theme.json
-
31src/views/datav/xm/project/index.vue
-
269src/views/datav/xm/project1/cards.vue
-
214src/views/datav/xm/project1/digitalFlop.vue
-
103src/views/datav/xm/project1/index.less
-
466src/views/datav/xm/project1/index.vue
-
102src/views/datav/xm/project1/rankingBoard.vue
-
176src/views/datav/xm/project1/roseChart.vue
-
66src/views/datav/xm/project1/scrollBoard.vue
-
109src/views/datav/xm/project1/waterLevelChart.vue
-
59src/views/datav/xm/utils/drawMixin.js
-
51src/views/datav/xm/utils/index.js
-
2src/views/layout/components/AppMain.vue
-
151src/views/layout/components/Navbar.vue
-
5src/views/layout/components/Sidebar/Logo.vue
-
4src/views/layout/components/Sidebar/index.vue
-
2src/views/xm/XmOverview.vue
-
1137src/views/xm/XmOverview2.vue
|
After Width: 1920 | Height: 1080 | Size: 289 KiB |
@ -0,0 +1,30 @@ |
|||||
|
/* Layout */ |
||||
|
import Layout from '../views/layout/Layout' |
||||
|
const _import = require('./_import_' + process.env.NODE_ENV) |
||||
|
|
||||
|
export default { |
||||
|
routes: [ |
||||
|
{ |
||||
|
path: '/my/work', |
||||
|
component: Layout, |
||||
|
name: '我的工作台', |
||||
|
meta: { |
||||
|
title: 'TaskCenter', |
||||
|
icon: 'task' |
||||
|
}, |
||||
|
iconCls: 'fa el-icon-menu', |
||||
|
// leaf: true,
|
||||
|
children: [ |
||||
|
{ |
||||
|
path: 'updateUserInfo', |
||||
|
component: _import('mdp/sys/user/UpdateUserInfo'), |
||||
|
name: '账户设置', |
||||
|
meta: { |
||||
|
title: '修改个人信息', |
||||
|
icon: 'component' |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
] |
||||
|
} |
||||
@ -0,0 +1,275 @@ |
|||||
|
<template> |
||||
|
<div class="d_cards"> |
||||
|
<div |
||||
|
class="card-item" |
||||
|
v-for="(card, i) in myData" |
||||
|
:key="i" |
||||
|
> |
||||
|
<div class="card-header"> |
||||
|
<div class="card-header-left">{{ card.title }}</div> |
||||
|
<div class="card-header-right">{{ '0' + (i + 1) }}</div> |
||||
|
</div> |
||||
|
<dv-charts class="ring-charts" :option="card.ring" /> |
||||
|
<div class="card-footer"> |
||||
|
<div class="card-footer-item"> |
||||
|
<div class="footer-title">总工作量</div> |
||||
|
<div class="footer-detail"> |
||||
|
<dv-digital-flop :config="card.total" style="width:70%;height:35px;" />人月 |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="card-footer-item"> |
||||
|
<div class="footer-title">当前进度</div> |
||||
|
<div class="footer-detail"> |
||||
|
<dv-digital-flop :config="card.num" style="width:70%;height:35px;" />% |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'Cards', |
||||
|
props:['data'], |
||||
|
computed:{ |
||||
|
myData(){ |
||||
|
if(this.data && this.data.length>0){ |
||||
|
var cards= this.data.map(i=>{ |
||||
|
var card=JSON.parse(JSON.stringify(this.cardConfig)) |
||||
|
card.title=i.productName |
||||
|
card.total.number=[i.planWorkload/8/20];//累计工作量 人月 |
||||
|
card.num.number=[i.finishRate];//当前进度 |
||||
|
//资金占比 |
||||
|
card.ring.series[0].data[0].value=(i.planWorkload/i.totalPlanWorkload) //工作量占比 |
||||
|
return card |
||||
|
}); |
||||
|
if(cards.length<5){ |
||||
|
var count=5-cards.length |
||||
|
for(var i=0;i<count;i++){ |
||||
|
cards.push(this.cards[i]); |
||||
|
} |
||||
|
} |
||||
|
return cards; |
||||
|
}else{ |
||||
|
return this.cards; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
cards: [], |
||||
|
cardConfig:{ |
||||
|
title: '', |
||||
|
total: { |
||||
|
number: [10], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#ea6027', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
num: { |
||||
|
number: [20], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#26fcd8', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
ring: { |
||||
|
series: [ |
||||
|
{ |
||||
|
type: 'gauge', |
||||
|
startAngle: -Math.PI / 2, |
||||
|
endAngle: Math.PI * 1.5, |
||||
|
arcLineWidth: 13, |
||||
|
radius: '80%', |
||||
|
data: [ |
||||
|
{ name: '工作量占比', value: 22 } |
||||
|
], |
||||
|
axisLabel: { |
||||
|
show: false |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: false |
||||
|
}, |
||||
|
pointer: { |
||||
|
show: false |
||||
|
}, |
||||
|
backgroundArc: { |
||||
|
style: { |
||||
|
stroke: '#224590' |
||||
|
} |
||||
|
}, |
||||
|
details: { |
||||
|
show: true, |
||||
|
formatter: '工作量占比{value}%', |
||||
|
style: { |
||||
|
fill: '#1ed3e5', |
||||
|
fontSize: 20 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
color: ['#03d3ec'] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
createData () { |
||||
|
const { randomExtend } = this |
||||
|
const productNames=['商城','营销','项目管理工具','支付','智慧党建'] |
||||
|
this.cards = new Array(5).fill(0).map((foo, i) => ({ |
||||
|
title: productNames[i], |
||||
|
total: { |
||||
|
number: [randomExtend(90, 100)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#ea6027', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
num: { |
||||
|
number: [randomExtend(30, 60)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#26fcd8', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
ring: { |
||||
|
series: [ |
||||
|
{ |
||||
|
type: 'gauge', |
||||
|
startAngle: -Math.PI / 2, |
||||
|
endAngle: Math.PI * 1.5, |
||||
|
arcLineWidth: 13, |
||||
|
radius: '80%', |
||||
|
data: [ |
||||
|
{ name: '资金占比', value: randomExtend(40, 60) } |
||||
|
], |
||||
|
axisLabel: { |
||||
|
show: false |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: false |
||||
|
}, |
||||
|
pointer: { |
||||
|
show: false |
||||
|
}, |
||||
|
backgroundArc: { |
||||
|
style: { |
||||
|
stroke: '#224590' |
||||
|
} |
||||
|
}, |
||||
|
details: { |
||||
|
show: true, |
||||
|
formatter: '资金占比{value}%', |
||||
|
style: { |
||||
|
fill: '#1ed3e5', |
||||
|
fontSize: 20 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
color: ['#03d3ec'] |
||||
|
} |
||||
|
})) |
||||
|
}, |
||||
|
randomExtend (minNum, maxNum) { |
||||
|
if (arguments.length === 1) { |
||||
|
return parseInt(Math.random() * minNum + 1, 10) |
||||
|
} else { |
||||
|
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
mounted () { |
||||
|
const { createData } = this |
||||
|
createData() |
||||
|
setInterval(this.createData, 300) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less"> |
||||
|
.d_cards { |
||||
|
display: flex; |
||||
|
width: 100%; |
||||
|
justify-content: space-between; |
||||
|
height: 100%; |
||||
|
margin-left: 15px; |
||||
|
margin-top: 10px; |
||||
|
|
||||
|
.card-item { |
||||
|
background-color: rgba(6, 30, 93, 0.5); |
||||
|
border-top: 2px solid rgba(1, 153, 209, .5); |
||||
|
width: 19%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: space-around; |
||||
|
} |
||||
|
|
||||
|
.card-header { |
||||
|
display: flex; |
||||
|
height: 20%; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
|
||||
|
.card-header-left { |
||||
|
font-size: 18px; |
||||
|
font-weight: bold; |
||||
|
padding-left: 20px; |
||||
|
} |
||||
|
|
||||
|
.card-header-right { |
||||
|
padding-right: 20px; |
||||
|
font-size: 40px; |
||||
|
color: #03d3ec; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.ring-charts { |
||||
|
height: 55%; |
||||
|
} |
||||
|
|
||||
|
.card-footer { |
||||
|
height: 25%; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-around; |
||||
|
} |
||||
|
|
||||
|
.card-footer-item { |
||||
|
padding: 5px 10px 0px 10px; |
||||
|
box-sizing: border-box; |
||||
|
width: 40%; |
||||
|
background-color: rgba(6, 30, 93, 0.7); |
||||
|
border-radius: 3px; |
||||
|
|
||||
|
.footer-title { |
||||
|
font-size: 15px; |
||||
|
margin-bottom: 5px; |
||||
|
} |
||||
|
|
||||
|
.footer-detail { |
||||
|
font-size: 20px; |
||||
|
color: #1294fb; |
||||
|
display: flex; |
||||
|
font-size: 18px; |
||||
|
align-items: center; |
||||
|
|
||||
|
.dv-digital-flop { |
||||
|
margin-right: 5px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,215 @@ |
|||||
|
<template> |
||||
|
<div class="flop"> |
||||
|
<div |
||||
|
class="digital-flop-item" |
||||
|
v-for="item in myData" |
||||
|
:key="item.title" |
||||
|
> |
||||
|
<p class="digital-flop-title">{{ item.title }}</p> |
||||
|
<div class="digital-flop"> |
||||
|
<dv-digital-flop |
||||
|
:config="item.number" |
||||
|
style="width:100px; height:50px;" |
||||
|
/> |
||||
|
<span class="unit">{{ item.unit }}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'DigitalFlop', |
||||
|
data () { |
||||
|
return { |
||||
|
defaultDigitalFlopData: [] |
||||
|
} |
||||
|
}, |
||||
|
computed:{ |
||||
|
myData(){ |
||||
|
if(this.data){ |
||||
|
return this.data |
||||
|
}else{ |
||||
|
return this.defaultDigitalFlopData |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
props:['data'], |
||||
|
methods: { |
||||
|
createData () { |
||||
|
const { randomExtend } = this |
||||
|
|
||||
|
this.defaultDigitalFlopData = [ |
||||
|
{ |
||||
|
title: '累计金额', |
||||
|
number: { |
||||
|
number: [randomExtend(5000000, 10000000000000)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#40faee', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '元' |
||||
|
}, |
||||
|
{ |
||||
|
title: '发布总任务数', |
||||
|
number: { |
||||
|
number: [randomExtend(20000, 30000)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#4d99fc', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '项目', |
||||
|
number: { |
||||
|
number: [randomExtend(200, 300)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#f46827', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '参与人数', |
||||
|
number: { |
||||
|
number: [randomExtend(2000, 3000)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#40faee', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '客户', |
||||
|
number: { |
||||
|
number: [randomExtend(100, 200)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#4d99fc', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '需求', |
||||
|
number: { |
||||
|
number: [randomExtend(5000, 100000)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#f46827', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '产品', |
||||
|
number: { |
||||
|
number: [randomExtend(50, 100)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#40faee', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '测试用例', |
||||
|
number: { |
||||
|
number: [randomExtend(5000, 100000)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#4d99fc', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '迭代', |
||||
|
number: { |
||||
|
number: [randomExtend(500, 10000)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#f46827', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
randomExtend (minNum, maxNum) { |
||||
|
if (arguments.length === 1) { |
||||
|
return parseInt(Math.random() * minNum + 1, 10) |
||||
|
} else { |
||||
|
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
const { createData } = this |
||||
|
|
||||
|
createData() |
||||
|
|
||||
|
setInterval(createData, 30000) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped> |
||||
|
.flop { |
||||
|
width: 100%; |
||||
|
height: 120px; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
background-color: rgba(13,20,39,0.5); |
||||
|
.digital-flop-item { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
border-left: 3px solid rgb(6, 30, 93); |
||||
|
border-right: 3px solid rgb(6, 30, 93); |
||||
|
} |
||||
|
|
||||
|
.digital-flop-title { |
||||
|
font-size: 24px; |
||||
|
margin:20px 20px 10px 20px; |
||||
|
} |
||||
|
|
||||
|
.digital-flop { |
||||
|
display: flex; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.unit { |
||||
|
margin-left: 10px; |
||||
|
display: flex; |
||||
|
align-items: flex-end; |
||||
|
box-sizing: border-box; |
||||
|
padding-bottom: 13px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,104 @@ |
|||||
|
#data-branch { |
||||
|
color: #d3d6dd; |
||||
|
width: 1920px; |
||||
|
height: 1080px; |
||||
|
position: absolute; |
||||
|
top: 50%; |
||||
|
left: 50%; |
||||
|
transform: translate(-50%, -50%); |
||||
|
transform-origin: left top; |
||||
|
overflow: hidden; |
||||
|
.bg { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
padding: 16px 16px 0 16px; |
||||
|
background-image: url("../../../../assets/image/datav_bg2.png"); |
||||
|
background-size: cover; |
||||
|
background-position: center center; |
||||
|
} |
||||
|
|
||||
|
.row_1 { |
||||
|
display: flex; |
||||
|
.dv-dec-10, |
||||
|
.dv-dec-10-s { |
||||
|
width: 33.3%; |
||||
|
height: 5px; |
||||
|
} |
||||
|
.dv-dec-10-s { |
||||
|
transform: rotateY(180deg); |
||||
|
} |
||||
|
.middle { |
||||
|
display: flex; |
||||
|
.dv-dec-8 { |
||||
|
width: 200px; |
||||
|
height: 30px; |
||||
|
} |
||||
|
.title { |
||||
|
position: relative; |
||||
|
width: 500px; |
||||
|
height: 40px; |
||||
|
text-align: center; |
||||
|
background-size: cover; |
||||
|
background-repeat: no-repeat; |
||||
|
line-height: 40px; |
||||
|
.title-text { |
||||
|
font-size: 36px; |
||||
|
position: absolute; |
||||
|
bottom: 0; |
||||
|
left: 50%; |
||||
|
width: 500px; |
||||
|
transform: translate(-50%); |
||||
|
} |
||||
|
.dv-dec-6 { |
||||
|
position: absolute; |
||||
|
bottom: -30px; |
||||
|
left: 50%; |
||||
|
width: 250px; |
||||
|
height: 8px; |
||||
|
transform: translate(-50%); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.row_2 { |
||||
|
display: flex; |
||||
|
margin-top: 42px; |
||||
|
} |
||||
|
|
||||
|
.row_3 { |
||||
|
display: flex; |
||||
|
margin-top: 10px; |
||||
|
.left { |
||||
|
width: 300px; |
||||
|
height: 826px; |
||||
|
} |
||||
|
.right { |
||||
|
flex: 1; |
||||
|
height: 820px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
.r_top { |
||||
|
display: flex; |
||||
|
flex: 1; |
||||
|
.top_1, .top_2, .top_3 { |
||||
|
height: 400px; |
||||
|
} |
||||
|
.top_1 { |
||||
|
width: 480px; |
||||
|
} |
||||
|
.top_2 { |
||||
|
width: 325px; |
||||
|
} |
||||
|
.top_3 { |
||||
|
width: 772px; |
||||
|
} |
||||
|
} |
||||
|
.r_bottom { |
||||
|
display: flex; |
||||
|
flex: 1; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,463 @@ |
|||||
|
<template> |
||||
|
<div id="data-branch" ref="appRef"> |
||||
|
<div class="bg"> |
||||
|
<dv-loading v-if="loading">加载中</dv-loading> |
||||
|
<div v-else class="host-body"> |
||||
|
<!-- 第一行 --> |
||||
|
<div class="row_1"> |
||||
|
<dv-decoration-10 class="dv-dec-10" /> |
||||
|
<div class="middle"> |
||||
|
<dv-decoration-8 class="dv-dec-8" :color="['#568aea', '#000000']" /> |
||||
|
<div class="title"> |
||||
|
<span class="title-text">唛盟项目管理综合数据监控</span> |
||||
|
<dv-decoration-6 class="dv-dec-6" :reverse="true" :color="['#50e3c2', '#67a1e5']"></dv-decoration-6> |
||||
|
</div> |
||||
|
<dv-decoration-8 class="dv-dec-8" :reverse="true" :color="['#568aea', '#000000']" /> |
||||
|
</div> |
||||
|
<dv-decoration-10 class="dv-dec-10-s" /> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 第二行 --> |
||||
|
<div class="row_2"> |
||||
|
<digital-flop :data="digitalFlopData" :title="'汇总数据'"/> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 第三行 --> |
||||
|
<div class="row_3"> |
||||
|
<div class="left"> |
||||
|
<ranking-board :data="rankingBoardData" :title="'项目进度'" /> |
||||
|
</div> |
||||
|
<div class="right"> |
||||
|
<div class="r_top"> |
||||
|
<div class="top_1"> |
||||
|
<rose-chart :data="roseChartData" :title="'资金分布'"/> |
||||
|
</div> |
||||
|
<div class="top_2"> |
||||
|
<water-level-chart :data="waterLevelChartData" :title="'计划资金累计完成情况'"/> |
||||
|
</div> |
||||
|
<div class="top_3"> |
||||
|
<scroll-board :data="scrollBoardData" :title="'动态'" :header="['时间','操作人','动作','备注']"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="r_bottom"> |
||||
|
<cards :data="cardsData" :title="'产品'" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import Vue from 'vue' |
||||
|
import topHeader from './topHeader' |
||||
|
import digitalFlop from './digitalFlop' |
||||
|
import rankingBoard from './rankingBoard' |
||||
|
import roseChart from './roseChart' |
||||
|
import waterLevelChart from './waterLevelChart' |
||||
|
import scrollBoard from './scrollBoard' |
||||
|
import cards from './cards' |
||||
|
import dataV from '@jiaminghi/data-view' |
||||
|
Vue.use(dataV) |
||||
|
import { listOption } from '@/api/mdp/meta/itemOption';//下拉框数据查询 |
||||
|
import { listXmBranchState } from '@/api/xm/core/xmBranchState'; |
||||
|
import { listXmProjectState} from '@/api/xm/core/xmProjectState'; |
||||
|
import { listXmBranchTaskTypeState } from '@/api/xm/core/xmBranchTaskTypeState'; |
||||
|
import { listXmRecord } from '@/api/xm/core/xmRecord'; |
||||
|
import { listXmProductState } from '@/api/xm/core/xmProductState'; |
||||
|
import { mapGetters } from 'vuex' |
||||
|
import drawMixin from "../utils/drawMixin"; |
||||
|
|
||||
|
|
||||
|
export default { |
||||
|
name: 'BranchDataView', |
||||
|
mixins: [ drawMixin ], |
||||
|
components: { |
||||
|
topHeader, |
||||
|
digitalFlop, |
||||
|
rankingBoard, |
||||
|
roseChart, |
||||
|
waterLevelChart, |
||||
|
scrollBoard, |
||||
|
cards |
||||
|
}, |
||||
|
computed: { |
||||
|
...mapGetters([ |
||||
|
'userInfo' |
||||
|
]), |
||||
|
digitalFlopData(){ |
||||
|
if(!this.xmBranchState){ |
||||
|
return null; |
||||
|
} |
||||
|
var digitalFlopData = [ |
||||
|
{ |
||||
|
title: '累计金额', |
||||
|
number: { |
||||
|
number: [(this.floatValue(this.xmBranchState.totalBudgetNouserAmount) + this.floatValue(this.xmBranchState.totalBudgetIuserAmount) + this.floatValue(this.xmBranchState.totalBudgetOuserAmount))/10000], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#40faee', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '万元' |
||||
|
}, |
||||
|
{ |
||||
|
title: '发布总任务数', |
||||
|
number: { |
||||
|
number: [this.xmBranchState.totalTaskCnt ], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#4d99fc', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '项目', |
||||
|
number: { |
||||
|
number: [this.xmBranchState.projectCnt ], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#f46827', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '参与人数', |
||||
|
number: { |
||||
|
number: [this.xmBranchState.totalStaffCnt], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#40faee', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '人' |
||||
|
}, |
||||
|
{ |
||||
|
title: '客户', |
||||
|
number: { |
||||
|
number: [this.xmBranchState.productCnt], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#4d99fc', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '需求', |
||||
|
number: { |
||||
|
number: [this.xmBranchState.menuCnt], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#f46827', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '产品', |
||||
|
number: { |
||||
|
number: [this.xmBranchState.productCnt], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#40faee', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '测试用例', |
||||
|
number: { |
||||
|
number: [this.xmBranchState.testCases], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#4d99fc', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '迭代', |
||||
|
number: { |
||||
|
number: [this.xmBranchState.iterationCnt], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#f46827', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
} |
||||
|
] |
||||
|
return digitalFlopData; |
||||
|
}, |
||||
|
rankingBoardData(){ |
||||
|
if( !this.xmProjectStates || this.xmProjectStates.length==0 ){ |
||||
|
return []; |
||||
|
} |
||||
|
var rankingBoardData=this.xmProjectStates.map(i=>{ |
||||
|
return {name:i.projectName,value:i.totalProgress+'%'} |
||||
|
}) |
||||
|
return rankingBoardData |
||||
|
}, |
||||
|
roseChartData(){ |
||||
|
var taskTypeList=this.options.taskType |
||||
|
if(this.xmBranchTaskTypeStates && this.xmBranchTaskTypeStates.length>0){ |
||||
|
var xmBranchTaskTypeStates=this.xmBranchTaskTypeStates.filter(i=>i.planAmount>0); |
||||
|
var roseChartData=xmBranchTaskTypeStates.map(i=>{ |
||||
|
|
||||
|
if(!taskTypeList || taskTypeList.length==0){ |
||||
|
return { |
||||
|
name:i.taskType?i.taskType:'其它', |
||||
|
value:i.planAmount?i.planAmount:0 |
||||
|
} |
||||
|
}else{ |
||||
|
var taskTypes=taskTypeList.filter(k=>k.optionValue==i.taskType) |
||||
|
if(taskTypes && taskTypes.length>0){ |
||||
|
var taskType=taskTypes[0] |
||||
|
return { |
||||
|
name:taskType.optionName, |
||||
|
value:i.planAmount?i.planAmount:0 |
||||
|
} |
||||
|
}else{ |
||||
|
return { |
||||
|
name:i.taskType?i.taskType:'其它', |
||||
|
value:i.planAmount?i.planAmount:0 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
return roseChartData |
||||
|
}else{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
waterLevelChartData(){ |
||||
|
if(this.xmBranchState){ |
||||
|
var data={} |
||||
|
var allAmount=this.floatValue(this.xmBranchState.totalBudgetNouserAmount) + this.floatValue(this.xmBranchState.totalBudgetIuserAmount) + this.floatValue(this.xmBranchState.totalBudgetOuserAmount); |
||||
|
data.finishNum= this.floatValue(this.xmBranchState.totalCostNouserAmount) + this.floatValue(this.xmBranchState.totalCostIuserAmount) +this.floatValue(this.xmBranchState.totalCostOuserAmount) |
||||
|
data.finishPercent= parseFloat(data.finishNum/allAmount * 100).toFixed(0) |
||||
|
return data; |
||||
|
}else{ |
||||
|
return null; |
||||
|
} |
||||
|
}, |
||||
|
scrollBoardData(){ |
||||
|
if(this.xmRecords && this.xmRecords.length>0){ |
||||
|
var data = this.xmRecords.map(i=>{ |
||||
|
return [i.operTime,i.operUsername,i.action,i.remarks] |
||||
|
}) |
||||
|
return data; |
||||
|
}else{ |
||||
|
return null; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
cardsData(){ |
||||
|
if(this.xmProductStates && this.xmProductStates.length>0){ |
||||
|
var totalPlanWorkload=this.floatValue(this.xmBranchState.totalPlanWorkload) |
||||
|
this.xmProductStates.map(i=>{ |
||||
|
i.totalPlanWorkload=totalPlanWorkload |
||||
|
return i; |
||||
|
}) |
||||
|
return this.xmProductStates.slice(0, 5); |
||||
|
}else{ |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
data () { |
||||
|
return { |
||||
|
loading: true, |
||||
|
xmBranchState:null, |
||||
|
xmProjectStates:[], |
||||
|
xmBranchTaskTypeStates:[], |
||||
|
xmRecords:[], |
||||
|
xmProductStates:[], |
||||
|
options:{ |
||||
|
taskType:[], |
||||
|
}, |
||||
|
|
||||
|
xmRecordPageInfo:{//分页数据 |
||||
|
total:0,//服务器端收到0时,会自动计算总记录数,如果上传>0的不自动计算。 |
||||
|
pageSize:20,//每页数据 |
||||
|
count:false,//是否需要重新计算总记录数 |
||||
|
pageNum:1,//当前页码、从1开始计算 |
||||
|
orderFields:["oper_time"],//排序列 如 ['sex','student_id'],必须为数据库字段 |
||||
|
orderDirs:["desc"]//升序 asc,降序desc 如 性别 升序、学生编号降序 ['asc','desc'] |
||||
|
}, |
||||
|
|
||||
|
xmProjectStatePageInfo:{//分页数据 |
||||
|
total:0,//服务器端收到0时,会自动计算总记录数,如果上传>0的不自动计算。 |
||||
|
pageSize:20,//每页数据 |
||||
|
count:false,//是否需要重新计算总记录数 |
||||
|
pageNum:1,//当前页码、从1开始计算 |
||||
|
orderFields:["calc_time"],//排序列 如 ['sex','student_id'],必须为数据库字段 |
||||
|
orderDirs:["desc"]//升序 asc,降序desc 如 性别 升序、学生编号降序 ['asc','desc'] |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
xmProductStatePageInfo:{//分页数据 |
||||
|
total:0,//服务器端收到0时,会自动计算总记录数,如果上传>0的不自动计算。 |
||||
|
pageSize:20,//每页数据 |
||||
|
count:false,//是否需要重新计算总记录数 |
||||
|
pageNum:1,//当前页码、从1开始计算 |
||||
|
orderFields:["calc_time"],//排序列 如 ['sex','student_id'],必须为数据库字段 |
||||
|
orderDirs:["desc"]//升序 asc,降序desc 如 性别 升序、学生编号降序 ['asc','desc'] |
||||
|
}, |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
getXmBranchState(){ |
||||
|
var params = { |
||||
|
branchId:this.userInfo.branchId |
||||
|
} |
||||
|
listXmBranchState(params).then(res=>{ |
||||
|
var tips = res.data.tips; |
||||
|
if(tips.isOk){ |
||||
|
if(res.data.data.length>0){ |
||||
|
this.xmBranchState=res.data.data[0] |
||||
|
} |
||||
|
setTimeout(() => { |
||||
|
this.loading = false; |
||||
|
}, 100); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
getXmProjectStates(){ |
||||
|
let params = { |
||||
|
pageSize: this.xmProjectStatePageInfo.pageSize, |
||||
|
pageNum: this.xmProjectStatePageInfo.pageNum, |
||||
|
total: this.xmProjectStatePageInfo.total, |
||||
|
count:this.xmProjectStatePageInfo.count |
||||
|
}; |
||||
|
if(this.xmProjectStatePageInfo.orderFields!=null && this.xmProjectStatePageInfo.orderFields.length>0){ |
||||
|
let orderBys=[]; |
||||
|
for(var i=0;i<this.xmProjectStatePageInfo.orderFields.length;i++){ |
||||
|
orderBys.push(this.xmProjectStatePageInfo.orderFields[i]+" "+this.xmProjectStatePageInfo.orderDirs[i]) |
||||
|
} |
||||
|
params.orderBy= orderBys.join(",") |
||||
|
} |
||||
|
params.branchId=this.userInfo.branchId |
||||
|
listXmProjectState(params).then(res=>{ |
||||
|
var tips = res.data.tips; |
||||
|
if(tips.isOk){ |
||||
|
if(res.data.data.length>0){ |
||||
|
this.xmProjectStates=res.data.data |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
getXmBranchTaskTypeStates(){ |
||||
|
var params = { |
||||
|
branchId:this.userInfo.branchId |
||||
|
} |
||||
|
listXmBranchTaskTypeState(params).then(res=>{ |
||||
|
var tips = res.data.tips; |
||||
|
if(tips.isOk){ |
||||
|
if(res.data.data.length>0){ |
||||
|
this.xmBranchTaskTypeStates=res.data.data |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
},//获取列表 XmRecord xm_record |
||||
|
getXmRecords() { |
||||
|
let params = { |
||||
|
pageSize: this.xmRecordPageInfo.pageSize, |
||||
|
pageNum: this.xmRecordPageInfo.pageNum, |
||||
|
total: this.xmRecordPageInfo.total, |
||||
|
count:this.xmRecordPageInfo.count |
||||
|
}; |
||||
|
if(this.xmRecordPageInfo.orderFields!=null && this.xmRecordPageInfo.orderFields.length>0){ |
||||
|
let orderBys=[]; |
||||
|
for(var i=0;i<this.xmRecordPageInfo.orderFields.length;i++){ |
||||
|
orderBys.push(this.xmRecordPageInfo.orderFields[i]+" "+this.xmRecordPageInfo.orderDirs[i]) |
||||
|
} |
||||
|
params.orderBy= orderBys.join(",") |
||||
|
} |
||||
|
listXmRecord(params).then((res) => { |
||||
|
var tips=res.data.tips; |
||||
|
if(tips.isOk){ |
||||
|
this.xmRecordPageInfo.total = res.data.total; |
||||
|
this.xmRecordPageInfo.count=false; |
||||
|
this.xmRecords = res.data.data; |
||||
|
}else{ |
||||
|
} |
||||
|
}) ; |
||||
|
}, |
||||
|
//获取列表 XmProductState 功能状态表,无需前端维护,所有数据由汇总统计得出 |
||||
|
getXmProductStates() { |
||||
|
let params = { |
||||
|
pageSize: this.xmProductStatePageInfo.pageSize, |
||||
|
pageNum: this.xmProductStatePageInfo.pageNum, |
||||
|
total: this.xmProductStatePageInfo.total, |
||||
|
count:this.xmProductStatePageInfo.count |
||||
|
}; |
||||
|
if(this.xmProductStatePageInfo.orderFields!=null && this.xmProductStatePageInfo.orderFields.length>0){ |
||||
|
let orderBys=[]; |
||||
|
for(var i=0;i<this.xmProductStatePageInfo.orderFields.length;i++){ |
||||
|
orderBys.push(this.xmProductStatePageInfo.orderFields[i]+" "+this.xmProductStatePageInfo.orderDirs[i]) |
||||
|
} |
||||
|
params.orderBy= orderBys.join(",") |
||||
|
} |
||||
|
params.branchId=this.userInfo.branchId |
||||
|
listXmProductState(params).then((res) => { |
||||
|
var tips=res.data.tips; |
||||
|
if(tips.isOk){ |
||||
|
this.xmProductStatePageInfo.total = res.data.total; |
||||
|
this.xmProductStatePageInfo.count=false; |
||||
|
this.xmProductStates = res.data.data; |
||||
|
}else{ |
||||
|
} |
||||
|
}) ; |
||||
|
}, |
||||
|
floatValue(value){ |
||||
|
if(!value){ |
||||
|
return 0.0; |
||||
|
}else{ |
||||
|
return value |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
mounted(){ |
||||
|
this.getXmBranchState(); |
||||
|
this.getXmProjectStates(); |
||||
|
this.getXmBranchTaskTypeStates(); |
||||
|
this.getXmRecords(); |
||||
|
this.getXmProductStates(); |
||||
|
listOption([{categoryId:'all',itemCode:'taskType'}] ).then(res=>{ |
||||
|
if(res.data.tips.isOk){ |
||||
|
this.options=res.data.data |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less"> |
||||
|
@import './index.less'; |
||||
|
</style> |
||||
@ -0,0 +1,108 @@ |
|||||
|
<template> |
||||
|
<div class="ranking-board"> |
||||
|
<span class="ranking-board-title">{{title}}</span> |
||||
|
<dv-scroll-ranking-board :config="config" style="height: 500px;" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'RankingBoard', |
||||
|
props:['data','title'], |
||||
|
computed:{ |
||||
|
config(){ |
||||
|
if( !this.data || this.data.length==0){ |
||||
|
return this.defaultConfig; |
||||
|
}else{ |
||||
|
var data=this.data; |
||||
|
if(data.length<5){ |
||||
|
const count = 5-data.length; |
||||
|
for(var i=0;i< count;i++){ |
||||
|
var defaultOne=JSON.parse(JSON.stringify(this.defaultConfig.data[i])) |
||||
|
data.push(defaultOne); |
||||
|
} |
||||
|
} |
||||
|
data.forEach(element => { |
||||
|
element.name = `<span style="font-size:16px;">${element.name}</span>` |
||||
|
}); |
||||
|
var config={ |
||||
|
data:data |
||||
|
} |
||||
|
return config |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
defaultConfig: { |
||||
|
data: [ |
||||
|
{ |
||||
|
name: '商城项目', |
||||
|
value: '30%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '营销项目', |
||||
|
value: '40%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '支付项目', |
||||
|
value: '50%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '短信项目', |
||||
|
value: '60%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '党建项目', |
||||
|
value: '50%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '协同办公项目', |
||||
|
value: '90%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '即聊项目', |
||||
|
value: '40%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '审计项目', |
||||
|
value: '60%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '溯源项目', |
||||
|
value: '90%' |
||||
|
} |
||||
|
], |
||||
|
rowNum: 9 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped> |
||||
|
.ranking-board { |
||||
|
width: 300px; |
||||
|
height: 100%; |
||||
|
box-shadow: 0 0 3px blue; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
background-color: rgba(10, 13, 28, 0.5); |
||||
|
border-top: 2px solid rgba(1, 153, 209, .5); |
||||
|
box-sizing: border-box; |
||||
|
padding: 0px 30px; |
||||
|
|
||||
|
.ranking-board-title { |
||||
|
font-weight: bold; |
||||
|
height: 50px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
font-size: 20px; |
||||
|
font-weight: 700; |
||||
|
} |
||||
|
|
||||
|
.dv-scroll-ranking-board { |
||||
|
flex: 1; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,176 @@ |
|||||
|
<template> |
||||
|
<div class="rose-chart"> |
||||
|
<div class="rose-chart-title">{{title}}</div> |
||||
|
<Echart |
||||
|
:options="option" |
||||
|
id="dv_roseChart" |
||||
|
height="340px" |
||||
|
width="100%" |
||||
|
></Echart> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import Echart from '../common' |
||||
|
export default { |
||||
|
name: 'RoseChart', |
||||
|
props:['data','title'], |
||||
|
components: {Echart}, |
||||
|
computed:{ |
||||
|
option(){ |
||||
|
if( !this.data || this.data.length==0){ |
||||
|
return this.defaultOption; |
||||
|
}else{ |
||||
|
this.createData() |
||||
|
let tempData = this.data.slice(0, 5); |
||||
|
let obj = {name: '其它', value : 0}; |
||||
|
let v = 0; |
||||
|
this.data.forEach((element,index) => { |
||||
|
if(index > 5) { |
||||
|
v += element.value; |
||||
|
} |
||||
|
}); |
||||
|
obj.value = v; |
||||
|
if(obj.value > 0) { |
||||
|
tempData.push(obj); |
||||
|
} |
||||
|
var option = JSON.parse(JSON.stringify(this.options)) |
||||
|
option.series[0].data = tempData |
||||
|
option.legend.data = tempData |
||||
|
return option |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
defaultOption: {}, |
||||
|
options : { |
||||
|
color: [ |
||||
|
"#37a2da", |
||||
|
"#32c5e9", |
||||
|
"#9fe6b8", |
||||
|
"#ffdb5c", |
||||
|
"#ff9f7f", |
||||
|
"#fb7293", |
||||
|
"#e7bcf3" |
||||
|
], |
||||
|
tooltip: { |
||||
|
trigger: "item", |
||||
|
formatter: "{b} : {c} ({d}%)" |
||||
|
}, |
||||
|
legend: { |
||||
|
orient: "horizontal", |
||||
|
icon: "circle", |
||||
|
bottom: 0, |
||||
|
x: "center", |
||||
|
data: |
||||
|
[ |
||||
|
{ value: 40, name: 'rose 1' }, |
||||
|
{ value: 38, name: 'rose 2' }, |
||||
|
{ value: 32, name: 'rose 3' }, |
||||
|
{ value: 30, name: 'rose 4' }, |
||||
|
{ value: 28, name: 'rose 5' }, |
||||
|
], |
||||
|
textStyle: { |
||||
|
color: "#fff", |
||||
|
fontSize: 18 |
||||
|
} |
||||
|
}, |
||||
|
calculable: true, |
||||
|
series: [ |
||||
|
{ |
||||
|
type: 'pie', |
||||
|
radius: [35, 80], |
||||
|
center: ['50%', '45%'], |
||||
|
roseType: 'area', |
||||
|
data: [ |
||||
|
{ value: 40, name: 'rose 1' }, |
||||
|
{ value: 38, name: 'rose 2' }, |
||||
|
{ value: 32, name: 'rose 3' }, |
||||
|
{ value: 30, name: 'rose 4' }, |
||||
|
{ value: 28, name: 'rose 5' }, |
||||
|
] |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
createData () { |
||||
|
const { randomExtend } = this |
||||
|
|
||||
|
this.defaultOption = { |
||||
|
series: [ |
||||
|
{ |
||||
|
type: 'pie', |
||||
|
radius: '50%', |
||||
|
roseSort: false, |
||||
|
data: [ |
||||
|
{ name: '需求', value: randomExtend(40, 70) }, |
||||
|
{ name: '开发', value: randomExtend(20, 30) }, |
||||
|
{ name: '测试', value: randomExtend(10, 50) }, |
||||
|
{ name: '设计', value: randomExtend(5, 20) }, |
||||
|
{ name: '运营', value: randomExtend(40, 50) }, |
||||
|
{ name: '客服', value: randomExtend(20, 30) }, |
||||
|
{ name: '管理', value: randomExtend(5, 10) }, |
||||
|
{ name: '产品', value: randomExtend(20, 35) }, |
||||
|
{ name: '运维', value: randomExtend(5, 10) } |
||||
|
], |
||||
|
insideLabel: { |
||||
|
show: false |
||||
|
}, |
||||
|
outsideLabel: { |
||||
|
formatter: '{name} {percent}%', |
||||
|
labelLineEndLength: 20, |
||||
|
style: { |
||||
|
fill: '#fff' |
||||
|
}, |
||||
|
labelLineStyle: { |
||||
|
stroke: '#fff' |
||||
|
} |
||||
|
}, |
||||
|
roseType: true |
||||
|
} |
||||
|
], |
||||
|
color: ['#da2f00', '#fa3600', '#ff4411', '#ff724c', '#541200', '#801b00', '#a02200', '#5d1400', '#b72700'] |
||||
|
} |
||||
|
}, |
||||
|
randomExtend (minNum, maxNum) { |
||||
|
if (arguments.length === 1) { |
||||
|
return parseInt(Math.random() * minNum + 1, 10) |
||||
|
} else { |
||||
|
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
const { createData } = this |
||||
|
createData() |
||||
|
setInterval(createData, 30000) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less"> |
||||
|
.rose-chart { |
||||
|
width: 450px; |
||||
|
height: 400px; |
||||
|
margin: 0 0px 0 15px; |
||||
|
background-color: rgba(6, 30, 93, 0.5); |
||||
|
border-top: 2px solid rgba(1, 153, 209, .5); |
||||
|
box-sizing: border-box; |
||||
|
.rose-chart-title { |
||||
|
height: 50px; |
||||
|
font-weight: bold; |
||||
|
text-indent: 20px; |
||||
|
font-size: 20px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.dv-charts-container { |
||||
|
height: calc(~"100% - 20px"); |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
@ -0,0 +1,66 @@ |
|||||
|
<template> |
||||
|
<div class="scroll-board"> |
||||
|
<dv-scroll-board :config="myConfig" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'ScrollBoard', |
||||
|
props:['data','header'], |
||||
|
computed:{ |
||||
|
myConfig(){ |
||||
|
if(this.data && this.data.length>0){ |
||||
|
var config=JSON.parse(JSON.stringify(this.config)); |
||||
|
this.data.forEach(d => { |
||||
|
d.forEach((text, index) => { |
||||
|
d[index] = `<span style="font-size:16px;">${text}</span>`; |
||||
|
}); |
||||
|
}); |
||||
|
config.header=this.header |
||||
|
config.data=this.data |
||||
|
return config; |
||||
|
}else{ |
||||
|
return this.config |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
config: { |
||||
|
header: ['时间', '项目', '金额', '变动情况'], |
||||
|
data: [ |
||||
|
['2019-07-01 19:25:00', '唛萌项目管理工具', '500万元', '立项'], |
||||
|
['2019-07-02 17:25:00', '唛盟商城项目', '300万元', '通过验收'], |
||||
|
['2019-07-03 16:25:00', '唛萌营销项目', '200万元', '测试完成'], |
||||
|
['2019-07-04 15:25:00', '组织管理系统项目', '100万', '竞标中'], |
||||
|
['2019-07-05 14:25:00', '支付管理系统', '700万元', '完成第一里程碑'], |
||||
|
['2019-07-06 13:25:00', '溯源系统', '300万元', '系统对接完成'], |
||||
|
['2019-07-07 12:25:00', '智能办公系统', '400万元', '试运行中'], |
||||
|
['2019-07-08 11:25:00', '数据可视化系统', '600万元', '开发中'], |
||||
|
['2019-07-09 10:25:00', '党建系统', '500万元', '上线成功'], |
||||
|
['2019-07-10 09:25:00', '智慧社区系统', '300万元', '运营中'] |
||||
|
], |
||||
|
index: true, |
||||
|
columnWidth: [50, 150, 100,200,200], |
||||
|
align: ['center'], |
||||
|
rowNum: 7, |
||||
|
headerBGC: '#1981f6', |
||||
|
headerHeight: 45, |
||||
|
oddRowBGC: 'rgba(0, 44, 81, 0.8)', |
||||
|
evenRowBGC: 'rgba(10, 29, 50, 0.8)' |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less"> |
||||
|
.scroll-board { |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
margin-left: 10px; |
||||
|
height: 100%; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,46 @@ |
|||||
|
<template> |
||||
|
<div id="top-header"> |
||||
|
<dv-decoration-8 class="header-left-decoration" /> |
||||
|
<dv-decoration-5 class="header-center-decoration" /> |
||||
|
<dv-decoration-8 class="header-right-decoration" :reverse="true" /> |
||||
|
<div class="center-title">{{title}}</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'TopHeader', |
||||
|
props:['title'], |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less"> |
||||
|
#top-header { |
||||
|
position: relative; |
||||
|
width: 100%; |
||||
|
height: 100px; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
flex-shrink: 0; |
||||
|
|
||||
|
.header-center-decoration { |
||||
|
width: 40%; |
||||
|
height: 60px; |
||||
|
margin-top: 30px; |
||||
|
} |
||||
|
|
||||
|
.header-left-decoration, .header-right-decoration { |
||||
|
width: 25%; |
||||
|
height: 60px; |
||||
|
} |
||||
|
|
||||
|
.center-title { |
||||
|
position: absolute; |
||||
|
font-size: 30px; |
||||
|
font-weight: bold; |
||||
|
left: 50%; |
||||
|
top: 15px; |
||||
|
transform: translateX(-50%); |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,109 @@ |
|||||
|
<template> |
||||
|
<div class="water-level-chart"> |
||||
|
<div class="water-level-chart-title">{{title}}</div> |
||||
|
|
||||
|
<div class="water-level-chart-details"> |
||||
|
累计完成<span>{{myData.finishNum}}</span>元 |
||||
|
</div> |
||||
|
|
||||
|
<div class="chart-container"> |
||||
|
<dv-water-level-pond :config="myData.config" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'WaterLevelChart', |
||||
|
props:['data','title'], |
||||
|
computed:{ |
||||
|
myData(){ |
||||
|
if(this.data){ |
||||
|
|
||||
|
var config=JSON.parse(JSON.stringify( this.config)) |
||||
|
config.data=[this.data.finishPercent] |
||||
|
return { |
||||
|
finishNum:this.data.finishNum, |
||||
|
config:config |
||||
|
} |
||||
|
} else{ |
||||
|
return { |
||||
|
finishNum:12350, |
||||
|
config:this.config |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
config: { |
||||
|
data: [45], |
||||
|
shape: 'round', |
||||
|
waveHeight: 25, |
||||
|
waveNum: 2 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less"> |
||||
|
.water-level-chart { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
box-sizing: border-box; |
||||
|
margin-right: 20px; |
||||
|
background-color: rgba(6, 30, 93, 0.5); |
||||
|
border-top: 2px solid rgba(1, 153, 209, .5); |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
|
||||
|
.water-level-chart-title { |
||||
|
font-weight: bold; |
||||
|
height: 50px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
font-size: 20px; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.water-level-chart-details { |
||||
|
height: 15%; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
font-size: 17px; |
||||
|
align-items: flex-end; |
||||
|
|
||||
|
span { |
||||
|
font-size: 35px; |
||||
|
font-weight: bold; |
||||
|
color: #58a1ff; |
||||
|
margin: 0 5px; |
||||
|
margin-bottom: -5px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.chart-container { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.dv-water-pond-level { |
||||
|
max-width: 90%; |
||||
|
width: 200px; |
||||
|
height: 200px; |
||||
|
border: 10px solid #19c3eb; |
||||
|
border-radius: 50%; |
||||
|
|
||||
|
ellipse { |
||||
|
stroke: transparent !important; |
||||
|
} |
||||
|
|
||||
|
text { |
||||
|
font-size: 40px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,65 @@ |
|||||
|
<template> |
||||
|
<div :id="id" :class="className" :style="{ height: height, width: width }" /> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import tdTheme from './theme.json' // 引入默认主题 |
||||
|
|
||||
|
export default { |
||||
|
name: 'echart', |
||||
|
props: { |
||||
|
className: { |
||||
|
type: String, |
||||
|
default: 'chart' |
||||
|
}, |
||||
|
id: { |
||||
|
type: String, |
||||
|
default: 'chart' |
||||
|
}, |
||||
|
width: { |
||||
|
type: String, |
||||
|
default: '100%' |
||||
|
}, |
||||
|
height: { |
||||
|
type: String, |
||||
|
default: '2.5rem' |
||||
|
}, |
||||
|
options: { |
||||
|
type: Object, |
||||
|
default: ()=>({}) |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
chart: null |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
options: { |
||||
|
handler (options) { |
||||
|
// 设置true清空echart缓存 |
||||
|
this.chart.setOption(options, true) |
||||
|
}, |
||||
|
deep: true |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
this.$echarts.registerTheme('tdTheme', tdTheme); // 覆盖默认主题 |
||||
|
this.initChart(); |
||||
|
}, |
||||
|
beforeDestroy () { |
||||
|
this.chart.dispose() |
||||
|
this.chart = null |
||||
|
}, |
||||
|
methods: { |
||||
|
initChart () { |
||||
|
// 初始化echart |
||||
|
this.chart = this.$echarts.init(this.$el, 'tdTheme') |
||||
|
this.chart.setOption(this.options, true) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
</style> |
||||
@ -0,0 +1,490 @@ |
|||||
|
{ |
||||
|
"color": [ |
||||
|
"#2d8cf0", |
||||
|
"#19be6b", |
||||
|
"#ff9900", |
||||
|
"#E46CBB", |
||||
|
"#9A66E4", |
||||
|
"#ed3f14" |
||||
|
], |
||||
|
"backgroundColor": "rgba(0,0,0,0)", |
||||
|
"textStyle": {}, |
||||
|
"title": { |
||||
|
"textStyle": { |
||||
|
"color": "#516b91" |
||||
|
}, |
||||
|
"subtextStyle": { |
||||
|
"color": "#93b7e3" |
||||
|
} |
||||
|
}, |
||||
|
"line": { |
||||
|
"itemStyle": { |
||||
|
"normal": { |
||||
|
"borderWidth": "2" |
||||
|
} |
||||
|
}, |
||||
|
"lineStyle": { |
||||
|
"normal": { |
||||
|
"width": "2" |
||||
|
} |
||||
|
}, |
||||
|
"symbolSize": "6", |
||||
|
"symbol": "emptyCircle", |
||||
|
"smooth": true |
||||
|
}, |
||||
|
"radar": { |
||||
|
"itemStyle": { |
||||
|
"normal": { |
||||
|
"borderWidth": "2" |
||||
|
} |
||||
|
}, |
||||
|
"lineStyle": { |
||||
|
"normal": { |
||||
|
"width": "2" |
||||
|
} |
||||
|
}, |
||||
|
"symbolSize": "6", |
||||
|
"symbol": "emptyCircle", |
||||
|
"smooth": true |
||||
|
}, |
||||
|
"bar": { |
||||
|
"itemStyle": { |
||||
|
"normal": { |
||||
|
"barBorderWidth": 0, |
||||
|
"barBorderColor": "#ccc" |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"barBorderWidth": 0, |
||||
|
"barBorderColor": "#ccc" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"pie": { |
||||
|
"itemStyle": { |
||||
|
"normal": { |
||||
|
"borderWidth": 0, |
||||
|
"borderColor": "#ccc" |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"borderWidth": 0, |
||||
|
"borderColor": "#ccc" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"scatter": { |
||||
|
"itemStyle": { |
||||
|
"normal": { |
||||
|
"borderWidth": 0, |
||||
|
"borderColor": "#ccc" |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"borderWidth": 0, |
||||
|
"borderColor": "#ccc" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"boxplot": { |
||||
|
"itemStyle": { |
||||
|
"normal": { |
||||
|
"borderWidth": 0, |
||||
|
"borderColor": "#ccc" |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"borderWidth": 0, |
||||
|
"borderColor": "#ccc" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"parallel": { |
||||
|
"itemStyle": { |
||||
|
"normal": { |
||||
|
"borderWidth": 0, |
||||
|
"borderColor": "#ccc" |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"borderWidth": 0, |
||||
|
"borderColor": "#ccc" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"sankey": { |
||||
|
"itemStyle": { |
||||
|
"normal": { |
||||
|
"borderWidth": 0, |
||||
|
"borderColor": "#ccc" |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"borderWidth": 0, |
||||
|
"borderColor": "#ccc" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"funnel": { |
||||
|
"itemStyle": { |
||||
|
"normal": { |
||||
|
"borderWidth": 0, |
||||
|
"borderColor": "#ccc" |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"borderWidth": 0, |
||||
|
"borderColor": "#ccc" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"gauge": { |
||||
|
"itemStyle": { |
||||
|
"normal": { |
||||
|
"borderWidth": 0, |
||||
|
"borderColor": "#ccc" |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"borderWidth": 0, |
||||
|
"borderColor": "#ccc" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"candlestick": { |
||||
|
"itemStyle": { |
||||
|
"normal": { |
||||
|
"color": "#edafda", |
||||
|
"color0": "transparent", |
||||
|
"borderColor": "#d680bc", |
||||
|
"borderColor0": "#8fd3e8", |
||||
|
"borderWidth": "2" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"graph": { |
||||
|
"itemStyle": { |
||||
|
"normal": { |
||||
|
"borderWidth": 0, |
||||
|
"borderColor": "#ccc" |
||||
|
} |
||||
|
}, |
||||
|
"lineStyle": { |
||||
|
"normal": { |
||||
|
"width": 1, |
||||
|
"color": "#aaa" |
||||
|
} |
||||
|
}, |
||||
|
"symbolSize": "6", |
||||
|
"symbol": "emptyCircle", |
||||
|
"smooth": true, |
||||
|
"color": [ |
||||
|
"#2d8cf0", |
||||
|
"#19be6b", |
||||
|
"#f5ae4a", |
||||
|
"#9189d5", |
||||
|
"#56cae2", |
||||
|
"#cbb0e3" |
||||
|
], |
||||
|
"label": { |
||||
|
"normal": { |
||||
|
"textStyle": { |
||||
|
"color": "#eee" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"map": { |
||||
|
"itemStyle": { |
||||
|
"normal": { |
||||
|
"areaColor": "#f3f3f3", |
||||
|
"borderColor": "#516b91", |
||||
|
"borderWidth": 0.5 |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"areaColor": "rgba(165,231,240,1)", |
||||
|
"borderColor": "#516b91", |
||||
|
"borderWidth": 1 |
||||
|
} |
||||
|
}, |
||||
|
"label": { |
||||
|
"normal": { |
||||
|
"textStyle": { |
||||
|
"color": "#000" |
||||
|
} |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"textStyle": { |
||||
|
"color": "rgb(81,107,145)" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"geo": { |
||||
|
"itemStyle": { |
||||
|
"normal": { |
||||
|
"areaColor": "#f3f3f3", |
||||
|
"borderColor": "#516b91", |
||||
|
"borderWidth": 0.5 |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"areaColor": "rgba(165,231,240,1)", |
||||
|
"borderColor": "#516b91", |
||||
|
"borderWidth": 1 |
||||
|
} |
||||
|
}, |
||||
|
"label": { |
||||
|
"normal": { |
||||
|
"textStyle": { |
||||
|
"color": "#000" |
||||
|
} |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"textStyle": { |
||||
|
"color": "rgb(81,107,145)" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"categoryAxis": { |
||||
|
"axisLine": { |
||||
|
"show": true, |
||||
|
"lineStyle": { |
||||
|
"color": "#cccccc" |
||||
|
} |
||||
|
}, |
||||
|
"axisTick": { |
||||
|
"show": false, |
||||
|
"lineStyle": { |
||||
|
"color": "#333" |
||||
|
} |
||||
|
}, |
||||
|
"axisLabel": { |
||||
|
"show": true, |
||||
|
"textStyle": { |
||||
|
"color": "#fff" |
||||
|
} |
||||
|
}, |
||||
|
"splitLine": { |
||||
|
"show": false, |
||||
|
"lineStyle": { |
||||
|
"color": [ |
||||
|
"#eeeeee" |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
"splitArea": { |
||||
|
"show": false, |
||||
|
"areaStyle": { |
||||
|
"color": [ |
||||
|
"rgba(250,250,250,0.05)", |
||||
|
"rgba(200,200,200,0.02)" |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"valueAxis": { |
||||
|
"axisLine": { |
||||
|
"show": true, |
||||
|
"lineStyle": { |
||||
|
"color": "#cccccc" |
||||
|
} |
||||
|
}, |
||||
|
"axisTick": { |
||||
|
"show": false, |
||||
|
"lineStyle": { |
||||
|
"color": "#333" |
||||
|
} |
||||
|
}, |
||||
|
"axisLabel": { |
||||
|
"show": true, |
||||
|
"textStyle": { |
||||
|
"color": "#fff" |
||||
|
} |
||||
|
}, |
||||
|
"splitLine": { |
||||
|
"show": false, |
||||
|
"lineStyle": { |
||||
|
"color": [ |
||||
|
"#eeeeee" |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
"splitArea": { |
||||
|
"show": false, |
||||
|
"areaStyle": { |
||||
|
"color": [ |
||||
|
"rgba(250,250,250,0.05)", |
||||
|
"rgba(200,200,200,0.02)" |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"logAxis": { |
||||
|
"axisLine": { |
||||
|
"show": true, |
||||
|
"lineStyle": { |
||||
|
"color": "#cccccc" |
||||
|
} |
||||
|
}, |
||||
|
"axisTick": { |
||||
|
"show": false, |
||||
|
"lineStyle": { |
||||
|
"color": "#333" |
||||
|
} |
||||
|
}, |
||||
|
"axisLabel": { |
||||
|
"show": true, |
||||
|
"textStyle": { |
||||
|
"color": "#999999" |
||||
|
} |
||||
|
}, |
||||
|
"splitLine": { |
||||
|
"show": true, |
||||
|
"lineStyle": { |
||||
|
"color": [ |
||||
|
"#eeeeee" |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
"splitArea": { |
||||
|
"show": false, |
||||
|
"areaStyle": { |
||||
|
"color": [ |
||||
|
"rgba(250,250,250,0.05)", |
||||
|
"rgba(200,200,200,0.02)" |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"timeAxis": { |
||||
|
"axisLine": { |
||||
|
"show": true, |
||||
|
"lineStyle": { |
||||
|
"color": "#cccccc" |
||||
|
} |
||||
|
}, |
||||
|
"axisTick": { |
||||
|
"show": false, |
||||
|
"lineStyle": { |
||||
|
"color": "#333" |
||||
|
} |
||||
|
}, |
||||
|
"axisLabel": { |
||||
|
"show": true, |
||||
|
"textStyle": { |
||||
|
"color": "#999999" |
||||
|
} |
||||
|
}, |
||||
|
"splitLine": { |
||||
|
"show": true, |
||||
|
"lineStyle": { |
||||
|
"color": [ |
||||
|
"#eeeeee" |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
"splitArea": { |
||||
|
"show": false, |
||||
|
"areaStyle": { |
||||
|
"color": [ |
||||
|
"rgba(250,250,250,0.05)", |
||||
|
"rgba(200,200,200,0.02)" |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"toolbox": { |
||||
|
"iconStyle": { |
||||
|
"normal": { |
||||
|
"borderColor": "#999" |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"borderColor": "#666" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"legend": { |
||||
|
"textStyle": { |
||||
|
"color": "#fff" |
||||
|
} |
||||
|
}, |
||||
|
"tooltip": { |
||||
|
"axisPointer": { |
||||
|
"lineStyle": { |
||||
|
"color": "#ccc", |
||||
|
"width": 1 |
||||
|
}, |
||||
|
"crossStyle": { |
||||
|
"color": "#ccc", |
||||
|
"width": 1 |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"timeline": { |
||||
|
"lineStyle": { |
||||
|
"color": "#8fd3e8", |
||||
|
"width": 1 |
||||
|
}, |
||||
|
"itemStyle": { |
||||
|
"normal": { |
||||
|
"color": "#8fd3e8", |
||||
|
"borderWidth": 1 |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"color": "#8fd3e8" |
||||
|
} |
||||
|
}, |
||||
|
"controlStyle": { |
||||
|
"normal": { |
||||
|
"color": "#8fd3e8", |
||||
|
"borderColor": "#8fd3e8", |
||||
|
"borderWidth": 0.5 |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"color": "#8fd3e8", |
||||
|
"borderColor": "#8fd3e8", |
||||
|
"borderWidth": 0.5 |
||||
|
} |
||||
|
}, |
||||
|
"checkpointStyle": { |
||||
|
"color": "#8fd3e8", |
||||
|
"borderColor": "rgba(138,124,168,0.37)" |
||||
|
}, |
||||
|
"label": { |
||||
|
"normal": { |
||||
|
"textStyle": { |
||||
|
"color": "#8fd3e8" |
||||
|
} |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"textStyle": { |
||||
|
"color": "#8fd3e8" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"visualMap": { |
||||
|
"color": [ |
||||
|
"#516b91", |
||||
|
"#59c4e6", |
||||
|
"#a5e7f0" |
||||
|
] |
||||
|
}, |
||||
|
"dataZoom": { |
||||
|
"backgroundColor": "rgba(0,0,0,0)", |
||||
|
"dataBackgroundColor": "rgba(255,255,255,0.3)", |
||||
|
"fillerColor": "rgba(167,183,204,0.4)", |
||||
|
"handleColor": "#a7b7cc", |
||||
|
"handleSize": "100%", |
||||
|
"textStyle": { |
||||
|
"color": "#333" |
||||
|
} |
||||
|
}, |
||||
|
"markPoint": { |
||||
|
"label": { |
||||
|
"normal": { |
||||
|
"textStyle": { |
||||
|
"color": "#eee" |
||||
|
} |
||||
|
}, |
||||
|
"emphasis": { |
||||
|
"textStyle": { |
||||
|
"color": "#eee" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,269 @@ |
|||||
|
<template> |
||||
|
<div class="d_cards"> |
||||
|
<div |
||||
|
class="card-item" |
||||
|
v-for="(card, i) in myData" |
||||
|
:key="card.title" |
||||
|
> |
||||
|
<div class="card-header"> |
||||
|
<div class="card-header-left">{{ card.title }}</div> |
||||
|
<div class="card-header-right">{{ '0' + (i + 1) }}</div> |
||||
|
</div> |
||||
|
<dv-charts class="ring-charts" :option="card.ring" /> |
||||
|
<div class="card-footer"> |
||||
|
<div class="card-footer-item"> |
||||
|
<div class="footer-title">总工作量</div> |
||||
|
<div class="footer-detail"> |
||||
|
<dv-digital-flop :config="card.total" style="width:65%;height:35px;" /> |
||||
|
<span style="font-size: 16px">人时</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="card-footer-item"> |
||||
|
<div class="footer-title">当前进度</div> |
||||
|
<div class="footer-detail"> |
||||
|
<dv-digital-flop :config="card.num" style="width:65%;height:35px;" />% |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'Cards', |
||||
|
props:['data'], |
||||
|
computed:{ |
||||
|
myData(){ |
||||
|
if(this.data && this.data.length>0){ |
||||
|
var cards= this.data.map(i=>{ |
||||
|
var card=JSON.parse(JSON.stringify(this.cardConfig)) |
||||
|
card.title=i.name |
||||
|
card.total.number=[i.budgetWorkload];//累计工作量 人月 |
||||
|
card.num.number=[i.actRate];//当前进度 |
||||
|
//资金占比 |
||||
|
card.ring.series[0].data[0].value=(i.budgetWorkload/i.totalPlanWorkload) //工作量占比 |
||||
|
console.log(card, ""); |
||||
|
return card |
||||
|
}); |
||||
|
return cards; |
||||
|
}else{ |
||||
|
return this.cards; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
cards: [], |
||||
|
cardConfig:{ |
||||
|
title: '', |
||||
|
total: { |
||||
|
number: [10], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#ea6027', |
||||
|
fontWeight: 'bold', |
||||
|
fontSize: 24 |
||||
|
} |
||||
|
}, |
||||
|
num: { |
||||
|
number: [20], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#26fcd8', |
||||
|
fontWeight: 'bold', |
||||
|
fontSize: 26 |
||||
|
} |
||||
|
}, |
||||
|
ring: { |
||||
|
series: [ |
||||
|
{ |
||||
|
type: 'gauge', |
||||
|
startAngle: -Math.PI / 2, |
||||
|
endAngle: Math.PI * 1.5, |
||||
|
arcLineWidth: 13, |
||||
|
radius: '80%', |
||||
|
data: [ |
||||
|
{ name: '工作量占比', value: 22 } |
||||
|
], |
||||
|
axisLabel: { |
||||
|
show: false |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: false |
||||
|
}, |
||||
|
pointer: { |
||||
|
show: false |
||||
|
}, |
||||
|
backgroundArc: { |
||||
|
style: { |
||||
|
stroke: '#224590' |
||||
|
} |
||||
|
}, |
||||
|
details: { |
||||
|
show: true, |
||||
|
formatter: '工作量占比{value}%', |
||||
|
style: { |
||||
|
fill: '#1ed3e5', |
||||
|
fontSize: 20 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
color: ['#03d3ec'] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
createData () { |
||||
|
const { randomExtend } = this |
||||
|
const productNames=['商城','营销','项目管理工具','支付','智慧党建'] |
||||
|
this.cards = new Array(5).fill(0).map((foo, i) => ({ |
||||
|
title: productNames[i], |
||||
|
total: { |
||||
|
number: [randomExtend(90, 100)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#ea6027', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
num: { |
||||
|
number: [randomExtend(30, 60)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#26fcd8', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
ring: { |
||||
|
series: [ |
||||
|
{ |
||||
|
type: 'gauge', |
||||
|
startAngle: -Math.PI / 2, |
||||
|
endAngle: Math.PI * 1.5, |
||||
|
arcLineWidth: 13, |
||||
|
radius: '80%', |
||||
|
data: [ |
||||
|
{ name: '资金占比', value: randomExtend(40, 60) } |
||||
|
], |
||||
|
axisLabel: { |
||||
|
show: false |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: false |
||||
|
}, |
||||
|
pointer: { |
||||
|
show: false |
||||
|
}, |
||||
|
backgroundArc: { |
||||
|
style: { |
||||
|
stroke: '#224590' |
||||
|
} |
||||
|
}, |
||||
|
details: { |
||||
|
show: true, |
||||
|
formatter: '资金占比{value}%', |
||||
|
style: { |
||||
|
fill: '#1ed3e5', |
||||
|
fontSize: 20 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
], |
||||
|
color: ['#03d3ec'] |
||||
|
} |
||||
|
})) |
||||
|
}, |
||||
|
randomExtend (minNum, maxNum) { |
||||
|
if (arguments.length === 1) { |
||||
|
return parseInt(Math.random() * minNum + 1, 10) |
||||
|
} else { |
||||
|
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
const { createData } = this |
||||
|
createData() |
||||
|
setInterval(this.createData, 300) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less"> |
||||
|
.d_cards { |
||||
|
display: flex; |
||||
|
width: 100%; |
||||
|
justify-content: space-between; |
||||
|
height: 100%; |
||||
|
margin-left: 15px; |
||||
|
margin-top: 10px; |
||||
|
|
||||
|
.card-item { |
||||
|
background-color: rgba(6, 30, 93, 0.5); |
||||
|
border-top: 2px solid rgba(1, 153, 209, .5); |
||||
|
width: 19%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: space-around; |
||||
|
} |
||||
|
|
||||
|
.card-header { |
||||
|
display: flex; |
||||
|
height: 20%; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
|
||||
|
.card-header-left { |
||||
|
font-size: 18px; |
||||
|
font-weight: bold; |
||||
|
padding-left: 20px; |
||||
|
} |
||||
|
|
||||
|
.card-header-right { |
||||
|
padding-right: 20px; |
||||
|
font-size: 40px; |
||||
|
color: #03d3ec; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.ring-charts { |
||||
|
height: 55%; |
||||
|
} |
||||
|
|
||||
|
.card-footer { |
||||
|
height: 25%; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-around; |
||||
|
} |
||||
|
|
||||
|
.card-footer-item { |
||||
|
// padding: 5px 5px 0px 10px; |
||||
|
box-sizing: border-box; |
||||
|
width: 46% !important; |
||||
|
background-color: rgba(6, 30, 93, 0.7); |
||||
|
border-radius: 3px; |
||||
|
|
||||
|
.footer-title { |
||||
|
font-size: 15px; |
||||
|
margin-bottom: 5px; |
||||
|
} |
||||
|
.footer-detail { |
||||
|
color: #1294fb; |
||||
|
display: flex; |
||||
|
font-size: 18px; |
||||
|
align-items: center; |
||||
|
.dv-digital-flop { |
||||
|
margin-right: 5px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,214 @@ |
|||||
|
<template> |
||||
|
<div class="flop"> |
||||
|
<div |
||||
|
class="digital-flop-item" |
||||
|
v-for="item in myData" |
||||
|
:key="item.title" |
||||
|
> |
||||
|
<p class="digital-flop-title">{{ item.title }}</p> |
||||
|
<div class="digital-flop"> |
||||
|
<dv-digital-flop |
||||
|
:config="item.number" |
||||
|
style="width:140px; height:50px;" |
||||
|
/> |
||||
|
<span class="unit">{{ item.unit }}</span> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'DigitalFlop', |
||||
|
data () { |
||||
|
return { |
||||
|
defaultDigitalFlopData: [] |
||||
|
} |
||||
|
}, |
||||
|
computed:{ |
||||
|
myData(){ |
||||
|
if(this.data){ |
||||
|
return this.data |
||||
|
}else{ |
||||
|
return this.defaultDigitalFlopData |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
props:['data'], |
||||
|
methods: { |
||||
|
createData () { |
||||
|
const { randomExtend } = this |
||||
|
|
||||
|
this.defaultDigitalFlopData = [ |
||||
|
{ |
||||
|
title: '累计金额', |
||||
|
number: { |
||||
|
number: [randomExtend(50000, 10000000)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#40faee', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '元' |
||||
|
}, |
||||
|
{ |
||||
|
title: '发布总任务数', |
||||
|
number: { |
||||
|
number: [randomExtend(20000, 30000)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#4d99fc', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '项目', |
||||
|
number: { |
||||
|
number: [randomExtend(200, 300)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#f46827', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '参与人数', |
||||
|
number: { |
||||
|
number: [randomExtend(2000, 3000)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#40faee', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '客户', |
||||
|
number: { |
||||
|
number: [randomExtend(100, 200)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#4d99fc', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '需求', |
||||
|
number: { |
||||
|
number: [randomExtend(5000, 100000)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#f46827', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '产品', |
||||
|
number: { |
||||
|
number: [randomExtend(50, 100)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#40faee', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '测试用例', |
||||
|
number: { |
||||
|
number: [randomExtend(5000, 100000)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#4d99fc', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '迭代', |
||||
|
number: { |
||||
|
number: [randomExtend(500, 10000)], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#f46827', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
randomExtend (minNum, maxNum) { |
||||
|
if (arguments.length === 1) { |
||||
|
return parseInt(Math.random() * minNum + 1, 10) |
||||
|
} else { |
||||
|
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
const { createData } = this |
||||
|
createData() |
||||
|
setInterval(createData, 30000) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped> |
||||
|
.flop { |
||||
|
width: 100%; |
||||
|
height: 120px; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
background-color: rgba(13,20,39,0.5); |
||||
|
.digital-flop-item { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
border-left: 3px solid rgb(6, 30, 93); |
||||
|
border-right: 3px solid rgb(6, 30, 93); |
||||
|
} |
||||
|
|
||||
|
.digital-flop-title { |
||||
|
font-size: 24px; |
||||
|
margin:20px 20px 10px 20px; |
||||
|
} |
||||
|
|
||||
|
.digital-flop { |
||||
|
display: flex; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.unit { |
||||
|
margin-left: 10px; |
||||
|
display: flex; |
||||
|
align-items: flex-end; |
||||
|
box-sizing: border-box; |
||||
|
padding-bottom: 13px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,103 @@ |
|||||
|
#index { |
||||
|
color: #d3d6dd; |
||||
|
width: 1920px; |
||||
|
height: 1080px; |
||||
|
position: absolute; |
||||
|
top: 50%; |
||||
|
left: 50%; |
||||
|
transform: translate(-50%, -50%); |
||||
|
transform-origin: left top; |
||||
|
overflow: hidden; |
||||
|
.bg { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
padding: 16px 16px 0 16px; |
||||
|
background-image: url("../../../../assets/image/datav_bg2.png"); |
||||
|
background-size: cover; |
||||
|
background-position: center center; |
||||
|
} |
||||
|
|
||||
|
.row_1 { |
||||
|
display: flex; |
||||
|
.dv-dec-10, |
||||
|
.dv-dec-10-s { |
||||
|
width: 33.3%; |
||||
|
height: 5px; |
||||
|
} |
||||
|
.dv-dec-10-s { |
||||
|
transform: rotateY(180deg); |
||||
|
} |
||||
|
.middle { |
||||
|
display: flex; |
||||
|
.dv-dec-8 { |
||||
|
width: 200px; |
||||
|
height: 30px; |
||||
|
} |
||||
|
.title { |
||||
|
position: relative; |
||||
|
width: 500px; |
||||
|
height: 40px; |
||||
|
text-align: center; |
||||
|
background-size: cover; |
||||
|
background-repeat: no-repeat; |
||||
|
line-height: 40px; |
||||
|
.title-text { |
||||
|
font-size: 36px; |
||||
|
position: absolute; |
||||
|
bottom: 0; |
||||
|
left: 50%; |
||||
|
transform: translate(-50%); |
||||
|
} |
||||
|
.dv-dec-6 { |
||||
|
position: absolute; |
||||
|
bottom: -30px; |
||||
|
left: 50%; |
||||
|
width: 250px; |
||||
|
height: 8px; |
||||
|
transform: translate(-50%); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.row_2 { |
||||
|
display: flex; |
||||
|
margin-top: 42px; |
||||
|
} |
||||
|
|
||||
|
.row_3 { |
||||
|
display: flex; |
||||
|
margin-top: 20px; |
||||
|
.left { |
||||
|
width: 300px; |
||||
|
height: 826px; |
||||
|
} |
||||
|
.right { |
||||
|
flex: 1; |
||||
|
height: 820px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
.r_top { |
||||
|
display: flex; |
||||
|
flex: 1; |
||||
|
.top_1, .top_2, .top_3 { |
||||
|
height: 400px; |
||||
|
} |
||||
|
.top_1 { |
||||
|
width: 480px; |
||||
|
} |
||||
|
.top_2 { |
||||
|
width: 325px; |
||||
|
} |
||||
|
.top_3 { |
||||
|
width: 772px; |
||||
|
} |
||||
|
} |
||||
|
.r_bottom { |
||||
|
display: flex; |
||||
|
flex: 1; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,466 @@ |
|||||
|
<template> |
||||
|
<div id="index" ref="appRef"> |
||||
|
<div class="bg"> |
||||
|
<dv-loading v-if="loading">加载中</dv-loading> |
||||
|
<div v-else class="host-body"> |
||||
|
<!-- 第一行 --> |
||||
|
<div class="row_1"> |
||||
|
<dv-decoration-10 class="dv-dec-10" /> |
||||
|
<div class="middle"> |
||||
|
<dv-decoration-8 class="dv-dec-8" :color="['#568aea', '#000000']" /> |
||||
|
<div class="title"> |
||||
|
<span class="title-text">综合数据监控</span> |
||||
|
<dv-decoration-6 class="dv-dec-6" :reverse="true" :color="['#50e3c2', '#67a1e5']"></dv-decoration-6> |
||||
|
</div> |
||||
|
<dv-decoration-8 class="dv-dec-8" :reverse="true" :color="['#568aea', '#000000']" /> |
||||
|
</div> |
||||
|
<dv-decoration-10 class="dv-dec-10-s" /> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 第二行 --> |
||||
|
<div class="row_2"> |
||||
|
<digital-flop /> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 第三行 --> |
||||
|
<div class="row_3"> |
||||
|
<div class="left"> |
||||
|
<ranking-board :data="rankingBoardData" :title="'团队进度'" /> |
||||
|
</div> |
||||
|
<div class="right"> |
||||
|
<div class="r_top"> |
||||
|
<div class="top_1"> |
||||
|
<rose-chart :data="roseChartData" :title="'资金分布'"/> |
||||
|
</div> |
||||
|
<div class="top_2"> |
||||
|
<water-level-chart :data="waterLevelChartData" :title="'计划资金累计完成情况'"/> |
||||
|
</div> |
||||
|
<div class="top_3"> |
||||
|
<scroll-board :data="scrollBoardData" :title="'动态'" :header="['时间','操作人','动作','备注']"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="r_bottom"> |
||||
|
<cards :data="cardsData" :title="'阶段计划'" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import digitalFlop from './digitalFlop'; |
||||
|
import drawMixin from "../utils/drawMixin"; |
||||
|
import rankingBoard from './rankingBoard' |
||||
|
import roseChart from './roseChart' |
||||
|
import waterLevelChart from './waterLevelChart' |
||||
|
import scrollBoard from './scrollBoard' |
||||
|
import cards from './cards' |
||||
|
import { listOption } from '@/api/mdp/meta/itemOption';//下拉框数据查询 |
||||
|
import { listXmProjectState } from '@/api/xm/core/xmProjectState'; |
||||
|
import { listXmGroupState} from '@/api/xm/core/xmGroupState'; |
||||
|
import { listXmProjectTaskTypeState } from '@/api/xm/core/xmProjectTaskTypeState'; |
||||
|
import { listXmRecord } from '@/api/xm/core/xmRecord'; |
||||
|
import { listXmPhase } from '@/api/xm/core/xmPhase'; |
||||
|
import { mapGetters } from 'vuex' |
||||
|
|
||||
|
import Vue from 'vue' |
||||
|
import dataV from '@jiaminghi/data-view' |
||||
|
Vue.use(dataV) |
||||
|
|
||||
|
export default { |
||||
|
mixins: [ drawMixin ], |
||||
|
components: {digitalFlop, rankingBoard, roseChart, waterLevelChart, scrollBoard, cards}, |
||||
|
computed: { |
||||
|
|
||||
|
...mapGetters([ |
||||
|
'userInfo' |
||||
|
]), |
||||
|
digitalFlopData(){ |
||||
|
if(!this.xmProjectState){ |
||||
|
return null; |
||||
|
} |
||||
|
var digitalFlopData = [ |
||||
|
{ |
||||
|
title: '累计金额', |
||||
|
number: { |
||||
|
number: [(this.floatValue(this.xmProjectState.totalBudgetNouserAmount) + this.floatValue(this.xmProjectState.totalBudgetIuserAmount) + this.floatValue(this.xmProjectState.totalBudgetOuserAmount))/10000], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#40faee', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '万元' |
||||
|
}, |
||||
|
{ |
||||
|
title: '发布总任务数', |
||||
|
number: { |
||||
|
number: [this.xmProjectState.totalTaskCnt ], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#4d99fc', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '项目进度', |
||||
|
number: { |
||||
|
number: [this.xmProjectState.totalProgress ], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#f46827', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '%' |
||||
|
}, |
||||
|
{ |
||||
|
title: '参与人数', |
||||
|
number: { |
||||
|
number: [this.xmProjectState.totalStaffCnt], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#40faee', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '人' |
||||
|
}, |
||||
|
{ |
||||
|
title: '客户', |
||||
|
number: { |
||||
|
number: [this.xmProjectState.productCnt], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#4d99fc', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '需求', |
||||
|
number: { |
||||
|
number: [this.xmProjectState.menuCnt], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#f46827', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '产品', |
||||
|
number: { |
||||
|
number: [this.xmProjectState.productCnt], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#40faee', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '测试用例', |
||||
|
number: { |
||||
|
number: [this.xmProjectState.testCases], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#4d99fc', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
}, |
||||
|
{ |
||||
|
title: '迭代', |
||||
|
number: { |
||||
|
number: [this.xmProjectState.iterationCnt], |
||||
|
content: '{nt}', |
||||
|
textAlign: 'right', |
||||
|
style: { |
||||
|
fill: '#f46827', |
||||
|
fontWeight: 'bold' |
||||
|
} |
||||
|
}, |
||||
|
unit: '个' |
||||
|
} |
||||
|
] |
||||
|
return digitalFlopData; |
||||
|
}, |
||||
|
rankingBoardData(){ |
||||
|
if( !this.xmGroupStates || this.xmGroupStates.length==0 ){ |
||||
|
return []; |
||||
|
} |
||||
|
var rankingBoardData=this.xmGroupStates.map(i=>{ |
||||
|
return {name:i.groupName,value:i.finishRate+'%'} |
||||
|
}) |
||||
|
return rankingBoardData |
||||
|
}, |
||||
|
roseChartData(){ |
||||
|
var taskTypeList=this.options.taskType |
||||
|
if(this.xmProjectTaskTypeStates && this.xmProjectTaskTypeStates.length>0){ |
||||
|
var xmProjectTaskTypeStates=this.xmProjectTaskTypeStates.filter(i=>i.planAmount>0); |
||||
|
var roseChartData=xmProjectTaskTypeStates.map(i=>{ |
||||
|
|
||||
|
if(!taskTypeList || taskTypeList.length==0){ |
||||
|
return { |
||||
|
name:i.taskType?i.taskType:'其它', |
||||
|
value:i.planAmount?i.planAmount:0 |
||||
|
} |
||||
|
}else{ |
||||
|
var taskTypes=taskTypeList.filter(k=>k.optionValue==i.taskType) |
||||
|
if(taskTypes && taskTypes.length>0){ |
||||
|
var taskType=taskTypes[0] |
||||
|
return { |
||||
|
name:taskType.optionName, |
||||
|
value:i.planAmount?i.planAmount:0 |
||||
|
} |
||||
|
}else{ |
||||
|
return { |
||||
|
name:i.taskType?i.taskType:'其它', |
||||
|
value:i.planAmount?i.planAmount:0 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
return roseChartData |
||||
|
}else{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
waterLevelChartData(){ |
||||
|
if(this.xmProjectState){ |
||||
|
var data={} |
||||
|
var allAmount=this.floatValue(this.xmProjectState.totalBudgetNouserAmount) + this.floatValue(this.xmProjectState.totalBudgetIuserAmount) + this.floatValue(this.xmProjectState.totalBudgetOuserAmount); |
||||
|
data.finishNum= this.floatValue(this.xmProjectState.totalCostNouserAmount) + this.floatValue(this.xmProjectState.totalCostIuserAmount) +this.floatValue(this.xmProjectState.totalCostOuserAmount) |
||||
|
data.finishPercent= parseFloat(data.finishNum/allAmount * 100).toFixed(0) |
||||
|
return data; |
||||
|
}else{ |
||||
|
return null; |
||||
|
} |
||||
|
}, |
||||
|
scrollBoardData(){ |
||||
|
if(this.xmRecords && this.xmRecords.length>0){ |
||||
|
var data = this.xmRecords.map(i=>{ |
||||
|
return [i.operTime,i.operUsername,i.action,i.remarks] |
||||
|
}) |
||||
|
return data; |
||||
|
}else{ |
||||
|
return null; |
||||
|
} |
||||
|
}, |
||||
|
cardsData(){ |
||||
|
if(this.xmPhases && this.xmPhases.length>0){ |
||||
|
var totalPlanWorkload=this.floatValue(this.xmProjectState.totalPlanWorkload) |
||||
|
return this.xmPhases.map(i=>{ |
||||
|
i.totalPlanWorkload=totalPlanWorkload |
||||
|
return i; |
||||
|
}) |
||||
|
}else{ |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
loading: true, |
||||
|
filters:{ |
||||
|
projectId:null, |
||||
|
}, |
||||
|
xmProjectState:null, |
||||
|
xmGroupStates:[], |
||||
|
xmProjectTaskTypeStates:[], |
||||
|
xmRecords:[], |
||||
|
xmPhases:[], |
||||
|
options:{ |
||||
|
taskType:[], |
||||
|
}, |
||||
|
xmRecordPageInfo:{//分页数据 |
||||
|
total:0,//服务器端收到0时,会自动计算总记录数,如果上传>0的不自动计算。 |
||||
|
pageSize:20,//每页数据 |
||||
|
count:false,//是否需要重新计算总记录数 |
||||
|
pageNum:1,//当前页码、从1开始计算 |
||||
|
orderFields:["oper_time"],//排序列 如 ['sex','student_id'],必须为数据库字段 |
||||
|
orderDirs:["desc"]//升序 asc,降序desc 如 性别 升序、学生编号降序 ['asc','desc'] |
||||
|
}, |
||||
|
|
||||
|
xmGroupStatePageInfo:{//分页数据 |
||||
|
total:0,//服务器端收到0时,会自动计算总记录数,如果上传>0的不自动计算。 |
||||
|
pageSize:5,//每页数据 |
||||
|
count:false,//是否需要重新计算总记录数 |
||||
|
pageNum:1,//当前页码、从1开始计算 |
||||
|
orderFields:["calc_time"],//排序列 如 ['sex','student_id'],必须为数据库字段 |
||||
|
orderDirs:["desc"]//升序 asc,降序desc 如 性别 升序、学生编号降序 ['asc','desc'] |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
xmPhasePageInfo:{//分页数据 |
||||
|
total:0,//服务器端收到0时,会自动计算总记录数,如果上传>0的不自动计算。 |
||||
|
pageSize:5,//每页数据 |
||||
|
count:false,//是否需要重新计算总记录数 |
||||
|
pageNum:1,//当前页码、从1开始计算 |
||||
|
orderFields:["calc_time"],//排序列 如 ['sex','student_id'],必须为数据库字段 |
||||
|
orderDirs:["desc"]//升序 asc,降序desc 如 性别 升序、学生编号降序 ['asc','desc'] |
||||
|
}, |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
getXmProjectState(){ |
||||
|
var params = { |
||||
|
projectId:this.filters.projectId |
||||
|
} |
||||
|
listXmProjectState(params).then(res=>{ |
||||
|
var tips = res.data.tips; |
||||
|
if(tips.isOk){ |
||||
|
if(res.data.data.length>0){ |
||||
|
this.xmProjectState=res.data.data[0] |
||||
|
} |
||||
|
setTimeout(() => { |
||||
|
this.loading = false; |
||||
|
}, 100); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
getXmGroupStates(){ |
||||
|
let params = { |
||||
|
pageSize: this.xmGroupStatePageInfo.pageSize, |
||||
|
pageNum: this.xmGroupStatePageInfo.pageNum, |
||||
|
total: this.xmGroupStatePageInfo.total, |
||||
|
count:this.xmGroupStatePageInfo.count |
||||
|
}; |
||||
|
if(this.xmGroupStatePageInfo.orderFields!=null && this.xmGroupStatePageInfo.orderFields.length>0){ |
||||
|
let orderBys=[]; |
||||
|
for(var i=0;i<this.xmGroupStatePageInfo.orderFields.length;i++){ |
||||
|
orderBys.push(this.xmGroupStatePageInfo.orderFields[i]+" "+this.xmGroupStatePageInfo.orderDirs[i]) |
||||
|
} |
||||
|
params.orderBy= orderBys.join(",") |
||||
|
} |
||||
|
params.branchId=this.userInfo.branchId |
||||
|
params.projectId=this.filters.projectId |
||||
|
listXmGroupState(params).then(res=>{ |
||||
|
var tips = res.data.tips; |
||||
|
if(tips.isOk){ |
||||
|
if(res.data.data.length>0){ |
||||
|
this.xmGroupStates=res.data.data |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
getXmProjectTaskTypeStates(){ |
||||
|
var params = { |
||||
|
} |
||||
|
params.projectId=this.filters.projectId |
||||
|
|
||||
|
listXmProjectTaskTypeState(params).then(res=>{ |
||||
|
var tips = res.data.tips; |
||||
|
if(tips.isOk){ |
||||
|
if(res.data.data.length>0){ |
||||
|
this.xmProjectTaskTypeStates=res.data.data |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
},//获取列表 XmRecord xm_record |
||||
|
getXmRecords() { |
||||
|
let params = { |
||||
|
pageSize: this.xmRecordPageInfo.pageSize, |
||||
|
pageNum: this.xmRecordPageInfo.pageNum, |
||||
|
total: this.xmRecordPageInfo.total, |
||||
|
count:this.xmRecordPageInfo.count |
||||
|
}; |
||||
|
params.projectId=this.filters.projectId |
||||
|
|
||||
|
if(this.xmRecordPageInfo.orderFields!=null && this.xmRecordPageInfo.orderFields.length>0){ |
||||
|
let orderBys=[]; |
||||
|
for(var i=0;i<this.xmRecordPageInfo.orderFields.length;i++){ |
||||
|
orderBys.push(this.xmRecordPageInfo.orderFields[i]+" "+this.xmRecordPageInfo.orderDirs[i]) |
||||
|
} |
||||
|
params.orderBy= orderBys.join(",") |
||||
|
} |
||||
|
listXmRecord(params).then((res) => { |
||||
|
var tips=res.data.tips; |
||||
|
if(tips.isOk){ |
||||
|
this.xmRecordPageInfo.total = res.data.total; |
||||
|
this.xmRecordPageInfo.count=false; |
||||
|
this.xmRecords = res.data.data; |
||||
|
}else{ |
||||
|
} |
||||
|
}) ; |
||||
|
}, |
||||
|
//获取列表 XmPhase 功能状态表,无需前端维护,所有数据由汇总统计得出 |
||||
|
getXmPhases() { |
||||
|
let params = { |
||||
|
pageSize: this.xmPhasePageInfo.pageSize, |
||||
|
pageNum: this.xmPhasePageInfo.pageNum, |
||||
|
total: this.xmPhasePageInfo.total, |
||||
|
count:this.xmPhasePageInfo.count |
||||
|
}; |
||||
|
if(this.xmPhasePageInfo.orderFields!=null && this.xmPhasePageInfo.orderFields.length>0){ |
||||
|
let orderBys=[]; |
||||
|
for(var i=0;i<this.xmPhasePageInfo.orderFields.length;i++){ |
||||
|
orderBys.push(this.xmPhasePageInfo.orderFields[i]+" "+this.xmPhasePageInfo.orderDirs[i]) |
||||
|
} |
||||
|
params.orderBy= orderBys.join(",") |
||||
|
} |
||||
|
|
||||
|
params.projectId=this.filters.projectId |
||||
|
listXmPhase(params).then((res) => { |
||||
|
var tips=res.data.tips; |
||||
|
if(tips.isOk){ |
||||
|
this.xmPhasePageInfo.total = res.data.total; |
||||
|
this.xmPhasePageInfo.count=false; |
||||
|
this.xmPhases = res.data.data; |
||||
|
}else{ |
||||
|
} |
||||
|
}) ; |
||||
|
}, |
||||
|
floatValue(value){ |
||||
|
if(!value){ |
||||
|
return 0.0; |
||||
|
}else{ |
||||
|
return value |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
mounted(){ |
||||
|
if(this.$route.params){ |
||||
|
this.filters.projectId=this.$route.params.projectId; |
||||
|
} |
||||
|
|
||||
|
this.getXmProjectState(); |
||||
|
this.getXmGroupStates(); |
||||
|
this.getXmProjectTaskTypeStates(); |
||||
|
this.getXmRecords(); |
||||
|
this.getXmPhases(); |
||||
|
|
||||
|
listOption([{categoryId:'all',itemCode:'taskType'}] ).then(res=>{ |
||||
|
if(res.data.tips.isOk){ |
||||
|
this.options=res.data.data |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less"> |
||||
|
@import './index.less'; |
||||
|
</style> |
||||
@ -0,0 +1,102 @@ |
|||||
|
<template> |
||||
|
<div class="ranking-board"> |
||||
|
<span class="ranking-board-title">{{title}}</span> |
||||
|
<dv-scroll-ranking-board :config="config"/> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'RankingBoard', |
||||
|
props:['data','title'], |
||||
|
computed:{ |
||||
|
config(){ |
||||
|
if( !this.data || this.data.length==0){ |
||||
|
return this.defaultConfig; |
||||
|
}else{ |
||||
|
var data=this.data; |
||||
|
data.forEach(element => { |
||||
|
element.name = `<span style="font-size:16px;">${element.name}</span>` |
||||
|
}); |
||||
|
var config={ |
||||
|
data:data, |
||||
|
carousel: "page" |
||||
|
} |
||||
|
return config |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
defaultConfig: { |
||||
|
data: [ |
||||
|
{ |
||||
|
name: '商城项目', |
||||
|
value: '30%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '营销项目', |
||||
|
value: '40%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '支付项目', |
||||
|
value: '50%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '短信项目', |
||||
|
value: '60%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '党建项目', |
||||
|
value: '50%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '协同办公项目', |
||||
|
value: '90%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '即聊项目', |
||||
|
value: '40%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '审计项目', |
||||
|
value: '60%' |
||||
|
}, |
||||
|
{ |
||||
|
name: '溯源项目', |
||||
|
value: '90%' |
||||
|
} |
||||
|
], |
||||
|
rowNum: 9, |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped> |
||||
|
.ranking-board { |
||||
|
width: 300px; |
||||
|
height: 100%; |
||||
|
box-shadow: 0 0 3px blue; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
background-color: rgba(10, 13, 28, 0.5); |
||||
|
border-top: 2px solid rgba(1, 153, 209, .5); |
||||
|
box-sizing: border-box; |
||||
|
padding: 0px 30px; |
||||
|
|
||||
|
.ranking-board-title { |
||||
|
height: 50px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
font-size: 20px; |
||||
|
font-weight: 700; |
||||
|
} |
||||
|
|
||||
|
.dv-scroll-ranking-board { |
||||
|
flex: 1; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,176 @@ |
|||||
|
<template> |
||||
|
<div class="rose-chart"> |
||||
|
<div class="rose-chart-title">{{title}}</div> |
||||
|
<Echart |
||||
|
:options="option" |
||||
|
id="dv_roseChart" |
||||
|
height="340px" |
||||
|
width="100%" |
||||
|
></Echart> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import Echart from '../common' |
||||
|
export default { |
||||
|
name: 'RoseChart1', |
||||
|
components: {Echart}, |
||||
|
props:['data','title'], |
||||
|
computed:{ |
||||
|
option(){ |
||||
|
if( !this.data || this.data.length==0){ |
||||
|
return this.defaultOption; |
||||
|
}else{ |
||||
|
this.createData() |
||||
|
let tempData = this.data.slice(0, 5); |
||||
|
let obj = {name: '其它', value : 0}; |
||||
|
let v = 0; |
||||
|
this.data.forEach((element,index) => { |
||||
|
if(index > 5) { |
||||
|
v += element.value; |
||||
|
} |
||||
|
}); |
||||
|
obj.value = v; |
||||
|
if(obj.value > 0) { |
||||
|
tempData.push(obj); |
||||
|
} |
||||
|
var option = JSON.parse(JSON.stringify(this.options)) |
||||
|
option.series[0].data = tempData |
||||
|
option.legend.data = tempData |
||||
|
return option |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
defaultOption: {}, |
||||
|
options : { |
||||
|
color: [ |
||||
|
"#37a2da", |
||||
|
"#32c5e9", |
||||
|
"#9fe6b8", |
||||
|
"#ffdb5c", |
||||
|
"#ff9f7f", |
||||
|
"#fb7293", |
||||
|
"#e7bcf3" |
||||
|
], |
||||
|
tooltip: { |
||||
|
trigger: "item", |
||||
|
formatter: "{b} : {c} ({d}%)" |
||||
|
}, |
||||
|
legend: { |
||||
|
orient: "horizontal", |
||||
|
icon: "circle", |
||||
|
bottom: 0, |
||||
|
x: "center", |
||||
|
data: |
||||
|
[ |
||||
|
{ value: 40, name: 'rose 1' }, |
||||
|
{ value: 38, name: 'rose 2' }, |
||||
|
{ value: 32, name: 'rose 3' }, |
||||
|
{ value: 30, name: 'rose 4' }, |
||||
|
{ value: 28, name: 'rose 5' }, |
||||
|
], |
||||
|
textStyle: { |
||||
|
color: "#fff", |
||||
|
fontSize: 18 |
||||
|
} |
||||
|
}, |
||||
|
calculable: true, |
||||
|
series: [ |
||||
|
{ |
||||
|
type: 'pie', |
||||
|
radius: [35, 80], |
||||
|
center: ['50%', '45%'], |
||||
|
roseType: 'area', |
||||
|
data: [ |
||||
|
{ value: 40, name: 'rose 1' }, |
||||
|
{ value: 38, name: 'rose 2' }, |
||||
|
{ value: 32, name: 'rose 3' }, |
||||
|
{ value: 30, name: 'rose 4' }, |
||||
|
{ value: 28, name: 'rose 5' }, |
||||
|
] |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
createData () { |
||||
|
const { randomExtend } = this |
||||
|
this.defaultOption = { |
||||
|
series: [ |
||||
|
{ |
||||
|
type: 'pie', |
||||
|
radius: '50%', |
||||
|
roseSort: false, |
||||
|
data: [ |
||||
|
{ name: '需求', value: randomExtend(40, 70) }, |
||||
|
{ name: '开发', value: randomExtend(20, 30) }, |
||||
|
{ name: '测试', value: randomExtend(10, 50) }, |
||||
|
{ name: '设计', value: randomExtend(5, 20) }, |
||||
|
{ name: '运营', value: randomExtend(40, 50) }, |
||||
|
{ name: '客服', value: randomExtend(20, 30) }, |
||||
|
{ name: '管理', value: randomExtend(5, 10) }, |
||||
|
{ name: '产品', value: randomExtend(20, 35) }, |
||||
|
{ name: '运维', value: randomExtend(5, 10) } |
||||
|
], |
||||
|
insideLabel: { |
||||
|
show: false |
||||
|
}, |
||||
|
outsideLabel: { |
||||
|
formatter: '{name} {percent}%', |
||||
|
labelLineEndLength: 20, |
||||
|
style: { |
||||
|
fill: '#fff' |
||||
|
}, |
||||
|
labelLineStyle: { |
||||
|
stroke: '#fff' |
||||
|
} |
||||
|
}, |
||||
|
roseType: true |
||||
|
} |
||||
|
], |
||||
|
color: ['#da2f00', '#fa3600', '#ff4411', '#ff724c', '#541200', '#801b00', '#a02200', '#5d1400', '#b72700'] |
||||
|
} |
||||
|
}, |
||||
|
randomExtend (minNum, maxNum) { |
||||
|
if (arguments.length === 1) { |
||||
|
return parseInt(Math.random() * minNum + 1, 10) |
||||
|
} else { |
||||
|
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
// const { createData } = this |
||||
|
// createData() |
||||
|
// setInterval(createData, 30000) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less"> |
||||
|
.rose-chart { |
||||
|
width: 450px; |
||||
|
height: 400px; |
||||
|
margin: 0 15px 0 15px; |
||||
|
background-color: rgba(6, 30, 93, 0.5); |
||||
|
border-top: 2px solid rgba(1, 153, 209, .5); |
||||
|
box-sizing: border-box; |
||||
|
.rose-chart-title { |
||||
|
height: 50px; |
||||
|
font-weight: bold; |
||||
|
text-indent: 20px; |
||||
|
font-size: 20px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.dv-charts-container { |
||||
|
height: calc(~"100% - 20px"); |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,66 @@ |
|||||
|
<template> |
||||
|
<div class="scroll-board"> |
||||
|
<dv-scroll-board :config="myConfig" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'ScrollBoard1', |
||||
|
props:['data','header'], |
||||
|
computed:{ |
||||
|
myConfig(){ |
||||
|
if(this.data && this.data.length>0){ |
||||
|
var config=JSON.parse(JSON.stringify(this.config)); |
||||
|
this.data.forEach(d => { |
||||
|
d.forEach((text, index) => { |
||||
|
d[index] = `<span style="font-size:16px;">${text}</span>`; |
||||
|
}); |
||||
|
}); |
||||
|
config.header=this.header |
||||
|
config.data=this.data |
||||
|
return config; |
||||
|
}else{ |
||||
|
return this.config |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
config: { |
||||
|
header: ['时间', '项目', '金额', '变动情况'], |
||||
|
data: [ |
||||
|
['2019-07-01 19:25:00', '唛萌项目管理工具', '500万元', '立项'], |
||||
|
['2019-07-02 17:25:00', '唛盟商城项目', '300万元', '通过验收'], |
||||
|
['2019-07-03 16:25:00', '唛萌营销项目', '200万元', '测试完成'], |
||||
|
['2019-07-04 15:25:00', '组织管理系统项目', '100万', '竞标中'], |
||||
|
['2019-07-05 14:25:00', '支付管理系统', '700万元', '完成第一里程碑'], |
||||
|
['2019-07-06 13:25:00', '溯源系统', '300万元', '系统对接完成'], |
||||
|
['2019-07-07 12:25:00', '智能办公系统', '400万元', '试运行中'], |
||||
|
['2019-07-08 11:25:00', '数据可视化系统', '600万元', '开发中'], |
||||
|
['2019-07-09 10:25:00', '党建系统', '500万元', '上线成功'], |
||||
|
['2019-07-10 09:25:00', '智慧社区系统', '300万元', '运营中'] |
||||
|
], |
||||
|
index: true, |
||||
|
columnWidth: [50, 150, 100,200,200], |
||||
|
align: ['center'], |
||||
|
rowNum: 7, |
||||
|
headerBGC: '#1981f6', |
||||
|
headerHeight: 45, |
||||
|
oddRowBGC: 'rgba(0, 44, 81, 0.8)', |
||||
|
evenRowBGC: 'rgba(10, 29, 50, 0.8)', |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less"> |
||||
|
.scroll-board { |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
margin-left: 10px; |
||||
|
height: 100%; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,109 @@ |
|||||
|
<template> |
||||
|
<div class="water-level-chart"> |
||||
|
<div class="water-level-chart-title">{{title}}</div> |
||||
|
|
||||
|
<div class="water-level-chart-details"> |
||||
|
累计完成<span>{{myData.finishNum}}</span>元 |
||||
|
</div> |
||||
|
|
||||
|
<div class="chart-container"> |
||||
|
<dv-water-level-pond :config="myData.config" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'WaterLevelChart1', |
||||
|
props:['data','title'], |
||||
|
computed:{ |
||||
|
myData(){ |
||||
|
if(this.data){ |
||||
|
|
||||
|
var config=JSON.parse(JSON.stringify( this.config)) |
||||
|
config.data=[this.data.finishPercent] |
||||
|
return { |
||||
|
finishNum:this.data.finishNum, |
||||
|
config:config |
||||
|
} |
||||
|
} else{ |
||||
|
return { |
||||
|
finishNum:12350, |
||||
|
config:this.config |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
config: { |
||||
|
data: [45], |
||||
|
shape: 'round', |
||||
|
waveHeight: 25, |
||||
|
waveNum: 2 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less"> |
||||
|
.water-level-chart { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
box-sizing: border-box; |
||||
|
margin-right: 20px; |
||||
|
background-color: rgba(6, 30, 93, 0.5); |
||||
|
border-top: 2px solid rgba(1, 153, 209, .5); |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
|
||||
|
.water-level-chart-title { |
||||
|
font-weight: bold; |
||||
|
height: 50px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
font-size: 20px; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.water-level-chart-details { |
||||
|
height: 15%; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
font-size: 17px; |
||||
|
align-items: flex-end; |
||||
|
|
||||
|
span { |
||||
|
font-size: 35px; |
||||
|
font-weight: bold; |
||||
|
color: #58a1ff; |
||||
|
margin: 0 5px; |
||||
|
margin-bottom: -5px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.chart-container { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.dv-water-pond-level { |
||||
|
max-width: 90%; |
||||
|
width: 200px; |
||||
|
height: 200px; |
||||
|
border: 10px solid #19c3eb; |
||||
|
border-radius: 50%; |
||||
|
|
||||
|
ellipse { |
||||
|
stroke: transparent !important; |
||||
|
} |
||||
|
|
||||
|
text { |
||||
|
font-size: 40px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,59 @@ |
|||||
|
// 屏幕适配 mixin 函数
|
||||
|
|
||||
|
// * 默认缩放值
|
||||
|
const scale = { |
||||
|
width: '1', |
||||
|
height: '1', |
||||
|
} |
||||
|
|
||||
|
// * 设计稿尺寸(px)
|
||||
|
const baseWidth = 1920 |
||||
|
const baseHeight = 1080 |
||||
|
|
||||
|
// * 需保持的比例(默认1.77778)
|
||||
|
// const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))
|
||||
|
const baseProportion = 1.91 |
||||
|
|
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
// * 定时函数
|
||||
|
drawTiming: null |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
this.calcRate() |
||||
|
window.addEventListener('resize', this.resize) |
||||
|
}, |
||||
|
beforeDestroy () { |
||||
|
window.removeEventListener('resize', this.resize) |
||||
|
}, |
||||
|
methods: { |
||||
|
calcRate () { |
||||
|
console.log(window.innerWidth, window.innerHeight); |
||||
|
const appRef = this.$refs["appRef"] |
||||
|
if (!appRef) return |
||||
|
// 当前宽高比
|
||||
|
const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5)) |
||||
|
if (appRef) { |
||||
|
if (currentRate > baseProportion) { |
||||
|
// 表示更宽
|
||||
|
scale.width = ((window.innerHeight * baseProportion) / baseWidth).toFixed(5) |
||||
|
scale.height = (window.innerHeight / baseHeight).toFixed(5) |
||||
|
appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)` |
||||
|
} else { |
||||
|
// 表示更高
|
||||
|
scale.height = ((window.innerWidth / baseProportion) / baseHeight).toFixed(5) |
||||
|
scale.width = (window.innerWidth / baseWidth).toFixed(5) |
||||
|
appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)` |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
resize () { |
||||
|
clearTimeout(this.drawTiming) |
||||
|
this.drawTiming = setTimeout(() => { |
||||
|
this.calcRate() |
||||
|
}, 200) |
||||
|
} |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,51 @@ |
|||||
|
/** |
||||
|
* @param {Function} fn 防抖函数 |
||||
|
* @param {Number} delay 延迟时间 |
||||
|
*/ |
||||
|
export function debounce(fn, delay) { |
||||
|
var timer; |
||||
|
return function () { |
||||
|
var context = this; |
||||
|
var args = arguments; |
||||
|
clearTimeout(timer); |
||||
|
timer = setTimeout(function () { |
||||
|
fn.apply(context, args); |
||||
|
}, delay); |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param {date} time 需要转换的时间 |
||||
|
* @param {String} fmt 需要转换的格式 如 yyyy-MM-dd、yyyy-MM-dd HH:mm:ss |
||||
|
*/ |
||||
|
export function formatTime(time, fmt) { |
||||
|
if (!time) return ''; |
||||
|
else { |
||||
|
const date = new Date(time); |
||||
|
const o = { |
||||
|
'M+': date.getMonth() + 1, |
||||
|
'd+': date.getDate(), |
||||
|
'H+': date.getHours(), |
||||
|
'm+': date.getMinutes(), |
||||
|
's+': date.getSeconds(), |
||||
|
'q+': Math.floor((date.getMonth() + 3) / 3), |
||||
|
S: date.getMilliseconds(), |
||||
|
}; |
||||
|
if (/(y+)/.test(fmt)) |
||||
|
fmt = fmt.replace( |
||||
|
RegExp.$1, |
||||
|
(date.getFullYear() + '').substr(4 - RegExp.$1.length) |
||||
|
); |
||||
|
for (const k in o) { |
||||
|
if (new RegExp('(' + k + ')').test(fmt)) { |
||||
|
fmt = fmt.replace( |
||||
|
RegExp.$1, |
||||
|
RegExp.$1.length === 1 |
||||
|
? o[k] |
||||
|
: ('00' + o[k]).substr(('' + o[k]).length) |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
return fmt; |
||||
|
} |
||||
|
} |
||||
1137
src/views/xm/XmOverview2.vue
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue