Browse Source

Merge remote-tracking branch 'origin/master'

master
陈裕财 4 years ago
parent
commit
e6cfae43d3
  1. BIN
      src/assets/image/datav_bg2.png
  2. 39
      src/components/NoticeMsgBar/index.vue
  3. 40
      src/components/TopModules/index.vue
  4. 36
      src/router/index.js
  5. 6
      src/router/routes_datav_xm.js
  6. 30
      src/router/routes_my_work.js
  7. 1
      src/router/routes_workflow.js
  8. 2
      src/styles/variables.scss
  9. 3
      src/views/dashboard/admin/index.vue
  10. 29
      src/views/datav/xm/FullScreenLayout.vue
  11. 2
      src/views/datav/xm/branch/index.vue
  12. 275
      src/views/datav/xm/branch1/cards.vue
  13. 215
      src/views/datav/xm/branch1/digitalFlop.vue
  14. 104
      src/views/datav/xm/branch1/index.less
  15. 463
      src/views/datav/xm/branch1/index.vue
  16. 108
      src/views/datav/xm/branch1/rankingBoard.vue
  17. 176
      src/views/datav/xm/branch1/roseChart.vue
  18. 66
      src/views/datav/xm/branch1/scrollBoard.vue
  19. 46
      src/views/datav/xm/branch1/topHeader.vue
  20. 109
      src/views/datav/xm/branch1/waterLevelChart.vue
  21. 65
      src/views/datav/xm/common/index.vue
  22. 490
      src/views/datav/xm/common/theme.json
  23. 31
      src/views/datav/xm/project/index.vue
  24. 269
      src/views/datav/xm/project1/cards.vue
  25. 214
      src/views/datav/xm/project1/digitalFlop.vue
  26. 103
      src/views/datav/xm/project1/index.less
  27. 466
      src/views/datav/xm/project1/index.vue
  28. 102
      src/views/datav/xm/project1/rankingBoard.vue
  29. 176
      src/views/datav/xm/project1/roseChart.vue
  30. 66
      src/views/datav/xm/project1/scrollBoard.vue
  31. 109
      src/views/datav/xm/project1/waterLevelChart.vue
  32. 59
      src/views/datav/xm/utils/drawMixin.js
  33. 51
      src/views/datav/xm/utils/index.js
  34. 2
      src/views/layout/components/AppMain.vue
  35. 151
      src/views/layout/components/Navbar.vue
  36. 5
      src/views/layout/components/Sidebar/Logo.vue
  37. 4
      src/views/layout/components/Sidebar/index.vue
  38. 2
      src/views/xm/XmOverview.vue
  39. 1137
      src/views/xm/XmOverview2.vue

BIN
src/assets/image/datav_bg2.png

After

Width: 1920  |  Height: 1080  |  Size: 289 KiB

39
src/components/NoticeMsgBar/index.vue

@ -1,22 +1,23 @@
<template v-loadding="load.list">
<el-dropdown trigger="hover" class="avatar-container" @command="handleNoticeMsgClick">
<div class="avatar-wrapper">
<el-badge :value="noticeMsg.totalNum" class="item">
<img class="user-avatar" src="../../assets/image/platform/module-notice.png">
</el-badge>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="toPay" >待付款订单(<font color=red>{{noticeMsg.toPayNum}}</font>)</el-dropdown-item>
<el-dropdown-item command="toSend" >待发货订单(<font color=red>{{noticeMsg.toSendNum}}</font>)</el-dropdown-item>
<el-dropdown-item command="toRece" >待收货订单(<font color=red>{{noticeMsg.hadSendNum}}</font>)</el-dropdown-item>
<!--<el-dropdown-item command="hadFinish" >已完成订单(<font color=red>{{noticeMsg.hadFinishNum}}</font>)</el-dropdown-item>-->
<!-- <el-dropdown-item command="hadCancel" >已取消订单(<font color=red>{{noticeMsg.hadCancelNum}}</font>)</el-dropdown-item>-->
<el-dropdown-item command="toApprova" >待审核订单(<font color=red>{{noticeMsg.toApprovaNum}}</font>)</el-dropdown-item>
<!-- <el-dropdown-item command="hadApprova" >已审核订单(<font color=red>{{noticeMsg.hadApprovaNum}}</font>)</el-dropdown-item> -->
<el-dropdown-item command="doGetNoticeMsg" >刷新 </el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-dropdown trigger="hover" class="avatar-container" @command="handleNoticeMsgClick">
<div class="avatar-wrapper">
<i class="el-icon-bell"></i>
<span>未读消息{{noticeMsg.totalNum}}</span>
<!-- <el-badge :value="noticeMsg.totalNum" class="item">
<img class="user-avatar" src="../../assets/image/platform/module-notice.png">
</el-badge> -->
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="toPay" >待付款订单(<font color=red>{{noticeMsg.toPayNum || 0}}</font>)</el-dropdown-item>
<el-dropdown-item command="toSend" >待发货订单(<font color=red>{{noticeMsg.toSendNum || 0}}</font>)</el-dropdown-item>
<el-dropdown-item command="toRece" >待收货订单(<font color=red>{{noticeMsg.hadSendNum || 0}}</font>)</el-dropdown-item>
<!--<el-dropdown-item command="hadFinish" >已完成订单(<font color=red>{{noticeMsg.hadFinishNum}}</font>)</el-dropdown-item>-->
<!-- <el-dropdown-item command="hadCancel" >已取消订单(<font color=red>{{noticeMsg.hadCancelNum}}</font>)</el-dropdown-item>-->
<el-dropdown-item command="toApprova" >待审核订单(<font color=red>{{noticeMsg.toApprovaNum || 0}}</font>)</el-dropdown-item>
<!-- <el-dropdown-item command="hadApprova" >已审核订单(<font color=red>{{noticeMsg.hadApprovaNum}}</font>)</el-dropdown-item> -->
<el-dropdown-item command="doGetNoticeMsg" >刷新 </el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
@ -105,8 +106,8 @@ export default {
height: 50px;
.avatar-wrapper {
cursor: pointer;
margin-top: 8px;
position: relative;
font-size: 16px;
.user-avatar {
height: 30px;
border-radius: 10px;

40
src/components/TopModules/index.vue

@ -1,27 +1,29 @@
<template>
<section>
<div class="module-item" v-for="(item,index) in topModules" :key="index">
<section>
<!-- <div class="module-item" v-for="(item,index) in topModules" :key="index">
<div class="module-text" @click="gotolink(item)" >
<div class="box-icon">
<img :src="item.icon" height="20px" />
</div>
<div class="box-info">{{item.moduleName}}</div>
</div>
</div>
</div> -->
<div class="module-item">
<div class="module-text" @click="drawer=true" >
<div class="box-icon">
<i class="el-icon-menu" height="20px" />
</div>
<div class="module-text" @click="drawer = true" >
<div class="box-info">全部应用</div>
</div>
</div>
<div class="module-item">
<div class="module-text">
<div class="box-info">我的工作台</div>
</div>
</div>
<div class="drawer-box">
<el-drawer
:visible.sync="drawer"
:visible.sync="drawer"
:modal-append-to-body="false"
:direction="direction">
<div class="drawer">
<div class="drawer-content">
@ -49,7 +51,7 @@
</div>
</div>
</div>
</el-drawer>
</el-drawer>
</div>
</section>
</template>
@ -58,7 +60,6 @@
import NProgress from 'nprogress' // progress bar
const topModulesData = require("./top_modules_"+process.env.CONTEXT+".js")
const allModulesData = require("./all_modules.js")
export default {
@ -83,7 +84,6 @@ export default {
methods: {
//
gotolink(module) {
this.drawer = false
this.jumpToOtherSystem(module);
},
@ -91,8 +91,7 @@ export default {
jumpToOtherSystem(module) {
window.open(module.sysLink, module.moduleName,null,true);
NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
},
},
//
searchModule(){
for(let i =0 ; i <this.categorys.length; i++){
@ -118,7 +117,6 @@ export default {
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.drawer-box{
.drawer{
padding-left: 10px;
@ -126,6 +124,7 @@ export default {
display: flex;
justify-content: center;
align-items: center;
z-index: 9 !important;
.drawer-content{
width: 900px;
height: 100%;
@ -188,22 +187,21 @@ export default {
fill: #5a5e66;
align-items: center;
text-align: center;
margin-left: 10px;
margin-right: 30px;
.module-text{
line-height: 22px;
font-size: 22px;
}
.box-icon {
padding-top:5px;
text-align: center;
}
.box-info {
text-align: center;
font-size: 14px;
color: #000000;
color: #7D7D7D;
font-weight: bold;
}
}
@ -211,7 +209,7 @@ export default {
<style rel="stylesheet/scss" lang="scss">
.drawer-box{
.el-drawer{
height: 100%!important;
height: 100% !important;
overflow: auto;
}
}

36
src/router/index.js

@ -14,6 +14,7 @@ import routesXm from './routes_xm'
import routesDatavXm from './routes_datav_xm'
import routesArc from './routes_arc'
import routesIm from './routes_im'
import routesMyWork from './routes_my_work'
export { Layout }
@ -45,22 +46,23 @@ export const constantRouterMap = [
component: Layout,
redirect: 'dashboard',
meta:{title:'首页',icon: 'home-page'},
children: [{
path: 'dashboard',
component: _import('xm/XmOverview'),
name: '首页',
meta: { title: '首页', icon: 'home-page', noCache: true }
},
{
path: 'updateUserInfo',
component: _import('mdp/sys/user/UpdateUserInfo'),
name: '账户设置',
meta: {
title: '修改个人信息',
icon: 'component'
}
}
],
children: [
{
path: 'dashboard',
component: _import('xm/XmOverview2'),
name: '首页',
meta: { title: '首页', icon: 'home-page', noCache: true }
},
// {
// path: 'updateUserInfo',
// component: _import('mdp/sys/user/UpdateUserInfo'),
// name: '账户设置',
// meta: {
// title: '修改个人信息',
// icon: 'component'
// }
// }
],
hidden: false
},
@ -73,10 +75,10 @@ export default new Router({
})
let allRoutes = []
allRoutes=allRoutes.concat(routesMyWork.routes);
allRoutes=allRoutes.concat(routesXm.routes);
allRoutes=allRoutes.concat(routesDatavXm.routes);
allRoutes=allRoutes.concat(routesWorkflow.routes).concat(routesForm.routes)
allRoutes=allRoutes.concat(routesArc.routes);
allRoutes=allRoutes.concat(routesIm.routes);
export const asyncRouterMap = allRoutes

6
src/router/routes_datav_xm.js

@ -17,8 +17,10 @@ export default {
},
// leaf: true,//只有一个节点
children: [
{ path: 'project/projectDatavFullScreen', component: _import('datav/xm/project/index'), name: 'projectDatavFullScreen', meta: { title: '项目大屏' }},
{ path: 'branch/branchDatavFullScreen', component: _import('datav/xm/branch/index'), name: 'branchDatavFullScreen', meta: { title: '机构大屏' }},
// { path: 'project/projectDatavFullScreen', component: _import('datav/xm/project/index'), name: 'projectDatavFullScreen', meta: { title: '项目大屏' }},
{ path: 'project/projectDatavFullScreen', component: _import('datav/xm/project1/index'), name: 'projectDatavFullScreen', meta: { title: '项目大屏' }},
// { path: 'branch/branchDatavFullScreen', component: _import('datav/xm/branch/index'), name: 'branchDatavFullScreen', meta: { title: '机构大屏' }},
{ path: 'branch/branchDatavFullScreen', component: _import('datav/xm/branch1/index'), name: 'branchDatavFullScreen', meta: { title: '机构大屏' }},
]
}
]

30
src/router/routes_my_work.js

@ -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'
}
}
]
}
]
}

1
src/router/routes_workflow.js

@ -2,7 +2,6 @@
import Layout from '../views/layout/Layout'
const _import = require('./_import_' + process.env.NODE_ENV)
export default {
routes: [
{

2
src/styles/variables.scss

@ -8,6 +8,6 @@ $yellow:#FEC171;
$panGreen: #30B08F;
//sidebar
$menuBg:#304156;
$menuBg: #F4F5F8;
$subMenuBg:#1f2d3d;
$menuHover:#001528;

3
src/views/dashboard/admin/index.vue

@ -1,13 +1,10 @@
<template>
<div class="dashboard-editor-container">
<github-corner></github-corner>
<panel-group @handleSetLineChartData="handleSetLineChartData"></panel-group>
<el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
<line-chart :chart-data="lineChartData"></line-chart>
</el-row>
<el-row :gutter="32">
<el-col :xs="24" :sm="24" :lg="8">
<div class="chart-wrapper">

29
src/views/datav/xm/FullScreenLayout.vue

@ -1,6 +1,8 @@
<template>
<router-view></router-view>
</template>
<div class="app-wrapper">
<router-view></router-view>
</div>
</template>
<script>
@ -13,12 +15,19 @@ export default {
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
.app-wrapper {
@include clearfix;
position: relative;
height: 100%;
width: 100%;
}
<style lang="less" scoped>
.app-wrapper {
width: 100vw;
height: 100vh;
overflow: hidden;
background: rgb(2, 3, 8);
}
// @import "src/styles/mixin.scss";
// .app-wrapper {
// @include clearfix;
// position: relative;
// height: 100%;
// width: 100%;
// }
</style>

2
src/views/datav/xm/branch/index.vue

@ -1,9 +1,7 @@
<template>
<div id="data-view">
<dv-full-screen-container>
<top-header :title="'唛盟项目管理综合数据监控'"/>
<div class="main-content">
<digital-flop :data="digitalFlopData" :title="'汇总数据'" />

275
src/views/datav/xm/branch1/cards.vue

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

215
src/views/datav/xm/branch1/digitalFlop.vue

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

104
src/views/datav/xm/branch1/index.less

@ -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;
}
}
}
}

463
src/views/datav/xm/branch1/index.vue

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

108
src/views/datav/xm/branch1/rankingBoard.vue

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

176
src/views/datav/xm/branch1/roseChart.vue

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

66
src/views/datav/xm/branch1/scrollBoard.vue

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

46
src/views/datav/xm/branch1/topHeader.vue

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

109
src/views/datav/xm/branch1/waterLevelChart.vue

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

65
src/views/datav/xm/common/index.vue

@ -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) {
// trueechart
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>

490
src/views/datav/xm/common/theme.json

@ -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"
}
}
}
}
}

31
src/views/datav/xm/project/index.vue

@ -9,18 +9,14 @@
<div class="block-left-right-content">
<ranking-board :data="rankingBoardData" :title="'团队进度'" />
<div class="block-top-bottom-content">
<div class="block-top-content">
<rose-chart :data="roseChartData" :title="'资金分布'"/>
<water-level-chart :data="waterLevelChartData" :title="'计划资金累计完成情况'"/>
<scroll-board :data="scrollBoardData" :title="'动态'" :header="['时间','操作人','动作','备注']"/>
</div>
<cards :data="cardsData" :title="'阶段计划'" />
</div>
</div>
</div>
</div>
</dv-full-screen-container>
@ -36,20 +32,17 @@ 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 util from '@/common/js/util';//
import config from '@/common/config';//
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 dataV from '@jiaminghi/data-view'
Vue.use(dataV)
import util from '@/common/js/util';//
import config from '@/common/config';//
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'
export default {
name: 'BranchDataView',

269
src/views/datav/xm/project1/cards.vue

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

214
src/views/datav/xm/project1/digitalFlop.vue

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

103
src/views/datav/xm/project1/index.less

@ -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;
}
}
}
}

466
src/views/datav/xm/project1/index.vue

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

102
src/views/datav/xm/project1/rankingBoard.vue

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

176
src/views/datav/xm/project1/roseChart.vue

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

66
src/views/datav/xm/project1/scrollBoard.vue

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

109
src/views/datav/xm/project1/waterLevelChart.vue

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

59
src/views/datav/xm/utils/drawMixin.js

@ -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)
}
},
}

51
src/views/datav/xm/utils/index.js

@ -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-ddyyyy-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;
}
}

2
src/views/layout/components/AppMain.vue

@ -1,5 +1,5 @@
<template>
<section class="app-main" style="min-height: 100%">
<section class="app-main" style="min-height: 100%;">
<transition name="fade" mode="out-in">
<keep-alive :include="cachedViews">
<router-view></router-view>

151
src/views/layout/components/Navbar.vue

@ -1,5 +1,6 @@
<template>
<el-menu class="navbar" mode="horizontal">
<hamburger class="hamburger-container" :toggleClick="toggleSideBar" :isActive="sidebar.opened"></hamburger>
<!--<breadcrumb class="breadcrumb-container"></breadcrumb>-->
@ -18,44 +19,47 @@
</div>
-->
<error-log v-if="false" class="errLog-container right-menu-item hidden-sm-and-down"></error-log>
<error-log v-if="false" class="errLog-container right-menu-item hidden-sm-and-down"></error-log>
<screenfull v-if="false" class="screenfull right-menu-item"></screenfull>
<lang-select v-if="false" class="international right-menu-item hidden-sm-and-down"></lang-select>
<el-tooltip v-if="false" class="hidden-sm-and-down" effect="dark" :content="$t('navbar.theme')" placement="bottom">
<theme-picker class="theme-switch right-menu-item"></theme-picker>
</el-tooltip>
<el-divider direction="vertical" class="divider hidden-sm-and-down"></el-divider>
<el-dropdown class="avatar-container right-menu-item hidden-sm-and-down" trigger="hover" style="max-width:300px;" @command="handleCommand">
<div class="avatar-wrapper">
<img v-if="userInfo && userInfo.headimgurl && userInfo.headimgurl!=null && userInfo.headimgurl!=='' " class="user-avatar" :src="userInfo.headimgurl">
<img v-else class="user-avatar" src="../../../assets/image/user_img.gif">
<span class="username">{{userInfo.username}}</span>
<span class="username">早上好<b>{{userInfo.username}}</b></span>
<i class="el-icon-caret-bottom"></i>
</div>
<el-dropdown-menu slot="dropdown" style="width:400px;">
<el-dropdown-item divided command="updateUserInfo">
<div> 用户名{{userInfo.username}} <el-button style="float:right;" type="text" icon="el-icon-setting">账户设置</el-button></div>
<div>用户名{{userInfo.username}}
<el-button style="float:right;" type="text" icon="el-icon-setting">账户设置</el-button>
</div>
</el-dropdown-item>
<el-dropdown-item divided>
公司{{userInfo.branchName}}
公司{{userInfo.branchName}}
</el-dropdown-item>
<el-dropdown-item divided>
<div style="height:250px;">
<el-row v-for="(item ,index) in deptPostsTree" :label="item.deptName" :key="index">
部门{{item.deptName}}
<br>
岗位
<el-row v-for="(item ,index) in deptPostsTree" :label="item.deptName" :key="index">
部门{{item.deptName}}
<br>
岗位
<div v-if="item.children!=null && item.children.length>0" style="padding-left:40px;">
<el-row v-for="(post,idx) in item.children" :key="idx">
{{post.postName}}
</el-row>
</div>
</el-row>
</div>
<div v-if="item.children!=null && item.children.length>0" style="padding-left:40px;">
<el-row v-for="(post,idx) in item.children" :key="idx">
{{post.postName}}
</el-row>
</div>
</el-row>
</div>
</el-dropdown-item>
<el-dropdown-item v-if="false" divided>
<div style=" overflow-x:auto; height:250px;">
商户及门店 <el-form>
@ -81,18 +85,26 @@
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-divider direction="vertical" class="divider"></el-divider>
<!-- <div class="notice">
<i class="el-icon-bell"></i>
<span>未读消息(3)</span>
</div> -->
<div class="notice">
<notice-msg-bar class="avatar-container hidden-sm-and-down" ></notice-msg-bar>
</div>
<!--喇叭标记-->
<notice-msg-bar class="avatar-container hidden-sm-and-down" ></notice-msg-bar>
<el-divider direction="vertical" class="divider hidden-sm-and-down"></el-divider>
<el-link class="logout hidden-sm-and-down" @click="goToIndex" icon="el-icon-s-home">
<!-- <el-link class="logout hidden-sm-and-down" @click="goToIndex" icon="el-icon-s-home">
<span style="font-size: 17px">首页</span>
</el-link>
<el-divider direction="vertical" class="divider hidden-sm-and-down"></el-divider>
<el-link class="logout" @click="logout" icon="el-icon-switch-button">
<span style="font-size: 17px">退出</span>
</el-link>
<el-divider direction="vertical" class="divider"></el-divider>
</el-link> -->
<div class="logout">
<el-button size="mini" type="primary" round @click="logout">退出</el-button>
</div>
</div>
</el-menu>
</template>
@ -249,20 +261,31 @@ export default {
@import './iconfont.css';
.navbar {
height: 50px;
line-height: 50px;
border-radius: 0px !important;
background-color: lightblue;
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: nowrap;
background-color: #fff;
position: -webkit-sticky;
position: sticky;
top: 0;
z-index: 99;
.hamburger-container {
line-height: 58px;
height: 50px;
float: left;
padding: 0 10px;
margin-right: 24px;
color: #9D9D9E !important;
}
.modules-container {
line-height: 58px;
display: flex;
flex-direction: row;
align-items: center;
flex: 1;
height: 50px;
float: left;
padding: 0 10px;
}
.breadcrumb-container{
@ -272,60 +295,60 @@ export default {
display: inline-block;
vertical-align: top;
}
.right-menu {
float: right;
height: 100%;
display: flex;
flex-direction: row;
align-items: center;
&:focus{
outline: none;
}
.right-menu-item {
display: inline-block;
margin: 0 8px;
}
.divider{
vertical-align: 4px;
}
.screenfull {
height: 20px;
}
.international{
vertical-align: top;
}
.theme-switch {
vertical-align: 15px;
}
.logout{
display: flex;
align-items: center;
height: 50px;
vertical-align: top;
/*margin-right: 10px;*/
color: #fff;
font-size: 30px;
margin-right: 28px;
}
.avatar-container {
height: 50px;
display: flex;
align-items: center;
.avatar-wrapper {
cursor: pointer;
display: flex;
flex-direction: row;
align-items: center;
.user-avatar {
height: 30px;
width:30px;
height: 34px;
width: 34px;
border-radius: 50%;
margin-right: 12px;
}
.username{
line-height: 35px;
vertical-align: top;
/*margin-right: 20px;*/
color: #fff;
font-size: 17px;
color: #7D7D7D;
font-size: 18px;
margin-right: 2px;
}
.el-icon-caret-bottom {
position: absolute;
right: -20px;
top: 25px;
font-size: 12px;
font-size: 22px;
}
}
}
.notice {
display: flex;
flex-direction: row;
align-items: center;
margin: 0 18px;
color: #827E7E;
font-size: 16px;
}
}
}

5
src/views/layout/components/Sidebar/Logo.vue

@ -44,7 +44,7 @@ export default {
width: 100%;
height: 50px;
line-height: 50px;
background: #3594d3;
background: #282F40;
text-align: center;
overflow: hidden;
@ -58,12 +58,13 @@ export default {
vertical-align: middle;
margin-left:-4px;
}
& .sidebar-title {
display: inline-block;
margin: 0;
color: #fff;
line-height: 50px;
font-weight: 400;
font-weight: bold;
font-size: 16px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle;

4
src/views/layout/components/Sidebar/index.vue

@ -7,8 +7,8 @@
:show-timeout="200"
:default-active="$route.path"
:collapse="isCollapse"
background-color="#304156"
text-color="#bfcbd9"
background-color="#282F40"
text-color="rgba(255,255,255,.6)"
active-text-color="#409EFF"
>
<sidebar-item :routes="permission_routers"></sidebar-item>

2
src/views/xm/XmOverview.vue

@ -277,7 +277,7 @@
<el-col :span="16" >
<el-card class="box-card" style="padding:0px ;height:425px">
<div slot="header" class="clearfix">
<span class="el-icon-document" style=" color: #3E68fe;">任务每日状态趋势</span>
<span class="el-icon-document" style=" color: #3E68fe;">任务每日状态趋势</span>
</div>
<div>
<div id="taskChart" :style="{width: '100%', height: '320px'}"></div>

1137
src/views/xm/XmOverview2.vue
File diff suppressed because it is too large
View File

Loading…
Cancel
Save