<template lang="html">
<div class="page-index page-home">css
<div class="page-home-header" @click="changeScreen"> <div class="logo-title"> <b>移動應用智能監控中心</b> </div> </div> <!-- 首頁地圖容器 --> <map-chart v-if="isReloadMap" ref="mapChart" :userLocaltionId="currentUserLocaltionId" :sourceInfo=' dashboardInfo && dashboardInfo.dataMap && dashboardInfo.dataMap.length ? dashboardInfo.dataMap : [] ' @change-location="getMapInfo"> </map-chart> <div class="chart-card-left chart-card-left-0"> <el-row> <el-col :span="24">監測應用總量</el-col> <el-col :span="24" class="tag-one"> <el-tag effect="plain"> {{ dashboardInfo && dashboardInfo.appTotalCount ? dashboardInfo.appTotalCount : 0 }} </el-tag> </el-col> <el-col :span="24">監測開發者總量</el-col> <el-col :span="24" class="tag-two"> <el-tag effect="plain"> {{ dashboardInfo && dashboardInfo.developerTotalCount ? dashboardInfo.developerTotalCount : 0 }} </el-tag> </el-col> <el-col :span="24">監測應用市場數</el-col> <el-col :span="24" class="tag-three"> <el-tag effect="plain"> {{ dashboardInfo && dashboardInfo.marketTotalCount ? dashboardInfo.marketTotalCount : 0 }} </el-tag> </el-col> </el-row> </div> <div class="chart-card-left chart-card-left-1"> <div v-if=" dashboardInfo && dashboardInfo.market && dashboardInfo.market.length " class="chart-card-title"> 應用市場分佈 </div> <field-chart ref="fieldChart" chartTitle="應用市場分佈" :sourceInfo=' dashboardInfo && dashboardInfo.market && dashboardInfo.market.length ? dashboardInfo.market : [] '> </field-chart> </div> <div class="chart-card-left chart-card-left-2"> <div v-if=" dashboardInfo && dashboardInfo.personalPrivacy && dashboardInfo.personalPrivacy.length " class="chart-card-title"> 隱私數據獲取 </div> <rose-chart ref="roseChart" chartTitle="隱私數據獲取" :sourceInfo=' dashboardInfo && dashboardInfo.personalPrivacy && dashboardInfo.personalPrivacy.length ? dashboardInfo.personalPrivacy : [] '> </rose-chart> </div> <div class="mid-select-group"> <div v-if=" dashboardInfo && dashboardInfo.riskApp && dashboardInfo.riskApp.length " class="chart-card-title"> 漏洞排行 </div> <bar-chart ref="barChart" chartTitle="漏洞排行" :barColors=" [ '#06fbfb', '#055a6e' ] " :sourceInfo=' dashboardInfo && dashboardInfo.riskApp && dashboardInfo.riskApp.length ? dashboardInfo.riskApp : [] '> </bar-chart> </div> <div class="chart-card-right chart-card-right-0"> <el-row> <el-col :span="6"> <div class="chart-ball chart-ball-left"> <div class="ball"> </div> <div class="ball1"> </div> <div class="ball2"> 風險應用 </div> </div> </el-col> <el-col :span="6"> <div class="chart-ball chart-ball-center"> <div class="ball"> </div> <div class="ball1"> </div> <div class="ball2"> 盜版仿冒 </div> </div> </el-col> <el-col :span="6"> <div class="chart-ball chart-ball-right"> <div class="ball"> </div> <div class="ball1"> </div> <div class="ball2"> 惡意應用 </div> </div> </el-col> </el-row> <el-row> <el-col :span="6"> <div class="chart-ball chart-ball-left"> <el-tag effect="plain"> <template v-if="dashboardInfo && dashboardInfo.safetyAnalysis && dashboardInfo.safetyAnalysis.riskAppCount"> {{ dashboardInfo.safetyAnalysis.riskAppCount | numberLevel }} </template> <template v-else>0</template> </el-tag> </div> </el-col> <el-col :span="6"> <div class="chart-ball chart-ball-center"> <el-tag effect="plain"> <template v-if="dashboardInfo && dashboardInfo.safetyAnalysis && dashboardInfo.safetyAnalysis.pirateCounterfeitCount"> {{ dashboardInfo.safetyAnalysis.pirateCounterfeitCount | numberLevel }} </template> <template v-else>0</template> </el-tag> </div> </el-col> <el-col :span="6"> <div class="chart-ball chart-ball-right"> <el-tag effect="plain"> <template v-if="dashboardInfo && dashboardInfo.safetyAnalysis && dashboardInfo.safetyAnalysis.maliceCount"> {{ dashboardInfo.safetyAnalysis.maliceCount | numberLevel }} </template> <template v-else>0</template> </el-tag> </div> </el-col> </el-row> </div> <div class="chart-card-right chart-card-right-1"> <div v-if=" dashboardInfo && dashboardInfo.malice && dashboardInfo.malice.locationIdArr && dashboardInfo.malice.locationIdArr.length && dashboardInfo.malice.locationNameArr && dashboardInfo.malice.locationNameArr.length && dashboardInfo.malice.maliceNameArr && dashboardInfo.malice.maliceNameArr.length && dashboardInfo.malice.maliceTypeArr && dashboardInfo.malice.maliceTypeArr.length " class="chart-card-title"> 惡意應用分佈 </div> <compose-chart ref="composeChart" chartTitle="惡意應用分佈" :barColors=" [ '#73bc6b', '#cde7ca' ] " :sourceInfo=' dashboardInfo && dashboardInfo.malice ? dashboardInfo.malice : {} '> </compose-chart> </div> <div class="chart-card-right chart-card-right-2"> <div v-if=" dashboardInfo && dashboardInfo.abroad && dashboardInfo.abroad.length " class="chart-card-title"> 境外數據傳輸 </div> <tree-chart ref="treeChart" chartTitle="境外數據傳輸" :barColors=" [ '#73bc6b', '#cde7ca' ] " :sourceInfo=' dashboardInfo && dashboardInfo.abroad && dashboardInfo.abroad.length ? dashboardInfo.abroad : [] '> </tree-chart> </div>
</div>
</template>html
<script>
import {mapState} from 'vuex';
import mapChart from 'components/Chart/chart-map.vue';
import barChart from 'components/Chart/chart-bar.vue';
import composeChart from 'components/Chart/chart-compose.vue';
import treeChart from 'components/Chart/chart-tree.vue';
import fieldChart from 'components/Chart/chart-field.vue';
import roseChart from 'components/Chart/chart-rose.vue';
export default {
data() {vue
return { isReloadMap: true, currentMap: 'china' }
},
components: { // 註冊插件web
mapChart, barChart, composeChart, treeChart, fieldChart, roseChart
},
computed: {vuex
...mapState('home', [ 'dashboardInfo' ]), currentUserLocaltionId() { let code = ''; const tempInfo = window.localStorage.__user_info__; if ( tempInfo && JSON.parse(tempInfo) && JSON.parse(tempInfo).detail && JSON.parse(tempInfo).detail.locationId ) { code = JSON.parse(tempInfo).detail.locationId; } return code; }, isFullScreen() { return this.$store.state.home.fullScreen; }
},
filters: {app
numberLevel(num) { if ( num !== 0 && (!num || isNaN(num)) ) { return 0; } // 此處爲防止字符串形式的數值進來,由於toFixed方法只能用於數值型數 num = Number(num); if (Math.abs(num) > 100000000) { return (num / 100000000).toFixed(0) + '億'; } else if (Math.abs(num) > 10000) { return (num / 10000).toFixed(0) + '萬'; } else { return num; } }
},
methods: {優化
getMapInfo(val) { // 從新加載數據 this.$refs.mapChart.showLoading(); this.$refs.barChart.showLoading(); this.$refs.composeChart.showLoading(); this.$refs.treeChart.showLoading(); this.$refs.roseChart.showLoading(); this.currentMap = val.currentLocationLabel; if ( val.currentLocationLabel === 'china') { this.$store.dispatch('home/GetChinaDashboardInfo'); } else { this.$store.dispatch('home/GetDashboardInfo', { locationId: val.currentLocationId }); } }, dataViewResize() { // 使用這種方式太暴力,解決地圖地標偏移的問題,後期需優化 this.isReloadMap = false; this.$nextTick( () => { this.isReloadMap = true; }) let resizeStart = null; if (resizeStart) { clearTimeout(resizeStart); } resizeStart = setTimeout( () => { this.$refs.mapChart.renderChart(this.currentMap); }, 20) }, changeScreen() { if (this.isFullScreen) { this.$store.dispatch('home/ChangeFullScreenFalse'); } else { this.$store.dispatch('home/ChangeFullScreenTrue'); } }
},
mounted() {this
this.$store.dispatch('home/ChangeTriangleColorFalse'); if ( this.currentUserLocaltionId === '100000' ) { this.$store.dispatch('home/GetChinaDashboardInfo'); } else if ( this.currentUserLocaltionId ) { this.$store.dispatch('home/GetDashboardInfo', { locationId: this.currentUserLocaltionId }); } window.addEventListener('resize', this.dataViewResize);
},
destroyed() {spa
window.removeEventListener('resize', this.dataViewResize); this.$store.dispatch('home/ClearHomeInfo'); this.$store.dispatch('home/ChangeFullScreenTrue');
}
}
</script>插件
<style lang="scss">
@import "~assets/css/_mixin";
.content {
overflow-y: auto;
}
.page-index {
background: #05092c; height: 100%; min-height: 600px; position: relative; padding-bottom: 20px; box-sizing: border-box; @media screen and (min-width: 1801px) { max-height: 938px; min-height: 870px; } @media screen and (min-width:1701px) and (max-width:1800px) { max-height: 860px; min-height: 840px; } @media screen and (min-width:1601px) and (max-width:1700px) { max-height: 810px; min-height: 790px; } @media screen and (min-width:1501px) and (max-width:1600px) { max-height: 790px; min-height: 770px; } @media screen and (min-width:1401px) and (max-width:1500px) { max-height: 760px; min-height: 740px; } @media screen and (min-width:1301px) and (max-width:1400px) { max-height: 770px; min-height: 700px; } .chart-card-title { font-weight: 800; line-height: 16px; height: 16px; font-size: 16px; color: #fff; >span { transition: .3s; transform: scale(1); &:hover { color: #3988ff; transform: scale(1.2); } } } .chart-card-left { position: absolute; width: 26%; left: 2%; .chart-card-box { height: calc(100% - 16px); } } .chart-card-left-1 { top: calc(25% + 40px); } .chart-card-left-2 { bottom: 5px; @media screen and (min-width: 1801px) { height: 280px; bottom: 10px; > .chart-rose { height: 250px; } } } .mid-select-group { position: absolute; left: 28%; width: 45%; bottom: 5px; @media screen and (min-width: 1801px) { height: 280px; bottom: 10px; > .chart-bar { height: 240px; } } } .chart-card-right { position: absolute; width: 26%; right: 2%; &.chart-card-right-0 { top: calc(6% - 4px); width: 28%; right: 0%; } .chart-card-box { @include magin_top_adjust (20px, 10px, 0px); height: 100%; } } .chart-card-right-1 { top: calc(25% + 40px); height: 30%; min-height: 250px; .chart-compose { height: 100%; @media screen and (min-width: 1801px) { margin-top: 20px; } } } .chart-card-right-2 { bottom: 5px; @media screen and (min-width: 1801px) { height: 280px; bottom: 10px; > .chart-tree { height: 260px; } } } .chart-table-box { @include magin_top_adjust (30px, 15px, 10px); } .chart-card-right-3 { top: calc(65% + 42px); } .chart > div { width: 100%; min-height: 200px; text-align: center; margin-top: 5px; height: 100%; } @mixin status-color($color) { .el-tag--plain { background-color: transparent; box-shadow: inset 1px 1px 6px $color; border-color: $color; color: $color; border-radius: 0px; } .ball { border: 1px solid $color; box-shadow: 0 0 35px $color; } .ball1 { border: 2px solid $color; box-shadow: 0 0 15px $color; } } .chart-card-left-0 { top: calc(4% - 4px); .el-col-24 { font-size: 14px; color: #dbdeef; margin-top: 10px; } .tag-one { @include status-color(#00eeff); } .tag-two { @include status-color(#fff42e); } .tag-three { @include status-color(#0092ff); } .tag-one, .tag-two, .tag-three { margin-top: 3px; .el-tag--plain { width: 100%; min-width: 300px; text-align: center; font-size: 20px; letter-spacing: 10px; font-weight: 600; } } } .chart-ball-left { @include status-color(#00eeff); } .chart-ball-center { margin-left: 15px; @include status-color(#fff42e); } .chart-ball-right { margin-left: 30px; @include status-color(#0092ff); } .chart-ball { position: relative; width: 150px; .el-tag { margin-top: 20px; margin-left: 37px; display: inline-block; width: 80px; text-align: center; font-weight: 600; font-size: 20px; } > .ball { background-color: rgba(0,0,0,0); opacity: .9; border-radius: 100%; width: 100px; height: 100px; margin: 0 auto; -moz-animation: spin 2.5s infinite linear; -webkit-animation: spin 2.5s infinite linear; } > .ball1 { background-color: rgba(0,0,0,0); opacity: .9; border-top: 2px solid rgba(0,0,0,0); border-bottom: 2px solid rgba(0,0,0,0); border-radius: 100%; width: 80px; height: 80px; margin: 0 auto; position: absolute; top: 9px; left: 33px; -moz-animation: spinoff 6s infinite linear; -webkit-animation: spinoff 6s infinite linear; } > .ball2 { background-color: rgba(0,0,0,0); width: 50px; height: 110px; font-size: 20px; position: absolute; left: 55px; top: 27px; color: #ffffff; } @keyframes spin { 0% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); } } @keyframes spinoff { 0% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(-360deg); } } }
}</style>