mirror of
https://github.com/jumpserver/lina.git
synced 2025-09-17 15:52:32 +00:00
perf: 调整仪表盘显示内容
This commit is contained in:
53
src/views/dashboard/AssetProportionSummary.vue
Normal file
53
src/views/dashboard/AssetProportionSummary.vue
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
<div class="head">
|
||||||
|
<Title :config="titleConfig" />
|
||||||
|
</div>
|
||||||
|
<ProgressChart v-bind="config" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Title from './components/Title.vue'
|
||||||
|
import ProgressChart from './components/ProgressChart.vue'
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Title,
|
||||||
|
ProgressChart
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
titleConfig: {
|
||||||
|
title: '资产类型占比',
|
||||||
|
tip: '资产类型占比'
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getChartData()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getChartData() {
|
||||||
|
const url = '/api/v1/index/?total_count_type_to_assets_amount=1'
|
||||||
|
const data = await this.$axios.get(url)
|
||||||
|
this.$set(this.config, 'data', data.total_count_type_to_assets_amount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.box {
|
||||||
|
margin-top: 16px;
|
||||||
|
padding: 20px;
|
||||||
|
background: #fff;
|
||||||
|
.head {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@@ -2,10 +2,10 @@
|
|||||||
<div>
|
<div>
|
||||||
<el-row :gutter="16">
|
<el-row :gutter="16">
|
||||||
<el-col :lg="12" :sm="12">
|
<el-col :lg="12" :sm="12">
|
||||||
<DataCard />
|
<DataCard :config="userConfig" />
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :lg="12" :sm="12">
|
<el-col :lg="12" :sm="12">
|
||||||
<DataCard />
|
<DataCard :config="assetConfig" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
@@ -21,15 +21,57 @@ export default {
|
|||||||
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
const documentStyle = document.documentElement.style
|
||||||
|
const themeColor = documentStyle.getPropertyValue('--color-primary')
|
||||||
|
|
||||||
|
return {
|
||||||
|
userConfig: {
|
||||||
|
title: '用户数据',
|
||||||
|
tip: '用户数据',
|
||||||
|
subTitle: '用户总数',
|
||||||
|
color: '#FFD260',
|
||||||
|
chartTitle: '今日登录用户数',
|
||||||
|
data: []
|
||||||
|
},
|
||||||
|
assetConfig: {
|
||||||
|
title: '资产数据',
|
||||||
|
tip: '资产数据',
|
||||||
|
subTitle: '资产总数',
|
||||||
|
color: themeColor,
|
||||||
|
chartTitle: '今日活跃资产数',
|
||||||
|
data: []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
mounted() {
|
||||||
|
this.init()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async init() {
|
||||||
|
const data = await this.$axios.get(`/api/v1/index/?total_count_users=1
|
||||||
|
&total_count_users_this_week=1
|
||||||
|
&total_count_today_login_users=1
|
||||||
|
&total_count_assets=1
|
||||||
|
&total_count_assets_this_week=1
|
||||||
|
&total_count_today_active_assets=1
|
||||||
|
`)
|
||||||
|
const users = [
|
||||||
|
{ name: this.$t('dashboard.ActiveUser'), value: data.total_count_users },
|
||||||
|
{ name: this.$t('dashboard.DisabledUser'), value: data.total_count_today_login_users }
|
||||||
|
]
|
||||||
|
this.$set(this.userConfig, 'data', users)
|
||||||
|
this.$set(this.userConfig, 'total', data.total_count_users)
|
||||||
|
this.$set(this.userConfig, 'active', data.total_count_today_login_users)
|
||||||
|
this.$set(this.userConfig, 'weekAdd', data.total_count_users_this_week)
|
||||||
|
const assets = [
|
||||||
|
{ name: this.$t('dashboard.ActiveUser'), value: data.total_count_assets },
|
||||||
|
{ name: this.$t('dashboard.DisabledUser'), value: data.total_count_today_active_assets }
|
||||||
|
]
|
||||||
|
this.$set(this.assetConfig, 'data', assets)
|
||||||
|
this.$set(this.assetConfig, 'total', data.total_count_assets)
|
||||||
|
this.$set(this.assetConfig, 'active', data.total_count_today_active_assets)
|
||||||
|
this.$set(this.assetConfig, 'weekAdd', data.total_count_assets_this_week)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@@ -1,35 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<RealTimeSummary />
|
|
||||||
<LineChart />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import RealTimeSummary from './components/RealTimeSummary.vue'
|
|
||||||
import LineChart from './components/LineChart.vue'
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
RealTimeSummary,
|
|
||||||
LineChart
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
@@ -2,10 +2,10 @@
|
|||||||
<div>
|
<div>
|
||||||
<el-row :gutter="16">
|
<el-row :gutter="16">
|
||||||
<el-col :lg="12" :sm="24">
|
<el-col :lg="12" :sm="24">
|
||||||
<RankTable v-bind="userConfig" />
|
<RankTable :config="userConfig" />
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :lg="12" :sm="24">
|
<el-col :lg="12" :sm="24">
|
||||||
<RankTable v-bind="assetConfig" />
|
<RankTable :config="assetConfig" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
@@ -22,7 +22,7 @@ export default {
|
|||||||
userConfig: {
|
userConfig: {
|
||||||
title: '登录用户排名',
|
title: '登录用户排名',
|
||||||
url: '/api/v1/index/?dates_login_times_top10_users=1',
|
url: '/api/v1/index/?dates_login_times_top10_users=1',
|
||||||
note: '登录用户排名',
|
tip: '登录用户排名',
|
||||||
data: 'dates_login_times_top10_users',
|
data: 'dates_login_times_top10_users',
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
@@ -38,7 +38,7 @@ export default {
|
|||||||
assetConfig: {
|
assetConfig: {
|
||||||
title: '活跃资产排名',
|
title: '活跃资产排名',
|
||||||
url: '/api/v1/index/?dates_login_times_top10_assets=1',
|
url: '/api/v1/index/?dates_login_times_top10_assets=1',
|
||||||
note: '活跃资产排名',
|
tip: '活跃资产排名',
|
||||||
data: 'dates_login_times_top10_assets',
|
data: 'dates_login_times_top10_assets',
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
@@ -50,12 +50,8 @@ export default {
|
|||||||
label: '访问次数'
|
label: '访问次数'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
columnsMeta: {}
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@@ -1,12 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div>
|
<div>
|
||||||
<div class="title">标题</div>
|
<div class="title">
|
||||||
<div class="sub">二标题11111</div>
|
<Title :config="config" />
|
||||||
<div class="num">1231231213</div>
|
</div>
|
||||||
|
<div class="sub">{{ config.subTitle }}</div>
|
||||||
|
<div class="num">{{ config.total }}</div>
|
||||||
<div class="add">
|
<div class="add">
|
||||||
<span class="add-num">
|
<span class="add-num">
|
||||||
本周新增:0
|
本周新增:{{ config.weekAdd }}
|
||||||
<svg-icon icon-class="broken-line" style="font-size: 18px;" />
|
<svg-icon icon-class="broken-line" style="font-size: 18px;" />
|
||||||
</span>
|
</span>
|
||||||
<span class="add-icon">
|
<span class="add-icon">
|
||||||
@@ -15,33 +17,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ring">
|
<div class="ring">
|
||||||
<RingChart />
|
<RingChart :config="config" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Title from './Title.vue'
|
||||||
import RingChart from './RingChart'
|
import RingChart from './RingChart'
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
Title,
|
||||||
RingChart
|
RingChart
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
object: {
|
config: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
created() {
|
|
||||||
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -53,10 +50,6 @@ export default {
|
|||||||
background-color: #FFF;
|
background-color: #FFF;
|
||||||
.title {
|
.title {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
line-height: 26px;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #1F2329;
|
|
||||||
}
|
}
|
||||||
.sub {
|
.sub {
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
@@ -78,7 +71,7 @@ export default {
|
|||||||
border-bottom: 1px solid #EFF0F1;
|
border-bottom: 1px solid #EFF0F1;
|
||||||
}
|
}
|
||||||
.ring {
|
.ring {
|
||||||
padding: 26px 43px 10px;
|
padding: 26px 0 10px;
|
||||||
& >>> .echarts {
|
& >>> .echarts {
|
||||||
width: 100%!important;
|
width: 100%!important;
|
||||||
height: 272px!important;
|
height: 272px!important;
|
||||||
|
@@ -1,11 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="head">
|
<div class="head">
|
||||||
<span class="title">
|
<Title :config="config" />
|
||||||
用户/资产活跃情况
|
|
||||||
<i class="fa fa-exclamation-circle icon" />
|
|
||||||
</span>
|
|
||||||
<!-- <span class="time">更新时间:2022-11-17</span> -->
|
|
||||||
</div>
|
</div>
|
||||||
<echarts
|
<echarts
|
||||||
ref="echarts"
|
ref="echarts"
|
||||||
@@ -22,9 +18,11 @@
|
|||||||
<script>
|
<script>
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
|
import Title from './Title.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'LoginMetric',
|
name: 'LoginMetric',
|
||||||
|
components: { Title },
|
||||||
props: {
|
props: {
|
||||||
range: {
|
range: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -33,6 +31,10 @@ export default {
|
|||||||
},
|
},
|
||||||
data: function() {
|
data: function() {
|
||||||
return {
|
return {
|
||||||
|
config: {
|
||||||
|
title: '用户/资产活跃情况 ',
|
||||||
|
tip: '用户/资产活跃情况 '
|
||||||
|
},
|
||||||
dataUrl: '',
|
dataUrl: '',
|
||||||
metricsData: {
|
metricsData: {
|
||||||
dates_metrics_date: [],
|
dates_metrics_date: [],
|
||||||
@@ -136,15 +138,65 @@ export default {
|
|||||||
{
|
{
|
||||||
name: this.$t('dashboard.LoginUsers'),
|
name: this.$t('dashboard.LoginUsers'),
|
||||||
type: 'line',
|
type: 'line',
|
||||||
areaStyle: {},
|
|
||||||
smooth: true,
|
smooth: true,
|
||||||
|
areaStyle: {
|
||||||
|
// 区域填充样式
|
||||||
|
normal: {
|
||||||
|
color: new echarts.graphic.LinearGradient(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
[{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(50, 220, 182, 0.6)'
|
||||||
|
}, {
|
||||||
|
offset: 0.6,
|
||||||
|
color: 'rgba(50, 220, 182, 0.2)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 0.8,
|
||||||
|
color: 'rgba(50, 220, 182, 0.1)'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
false
|
||||||
|
),
|
||||||
|
shadowColor: 'rgba(50, 220, 182, 0.1)',
|
||||||
|
shadowBlur: 6
|
||||||
|
}
|
||||||
|
},
|
||||||
data: this.metricsData.dates_metrics_total_count_active_users
|
data: this.metricsData.dates_metrics_total_count_active_users
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: this.$t('dashboard.LoginAssets'),
|
name: this.$t('dashboard.LoginAssets'),
|
||||||
type: 'line',
|
type: 'line',
|
||||||
areaStyle: {},
|
|
||||||
smooth: true,
|
smooth: true,
|
||||||
|
areaStyle: {
|
||||||
|
// 区域填充样式
|
||||||
|
normal: {
|
||||||
|
color: new echarts.graphic.LinearGradient(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
[{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(249, 199, 79, 0.6)'
|
||||||
|
}, {
|
||||||
|
offset: 0.6,
|
||||||
|
color: 'rgba(249, 199, 79, 0.2)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 0.8,
|
||||||
|
color: 'rgba(249, 199, 79, 0.1)'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
false
|
||||||
|
),
|
||||||
|
shadowColor: 'rgba(249, 199, 79, 0.1)',
|
||||||
|
shadowBlur: 6
|
||||||
|
}
|
||||||
|
},
|
||||||
data: this.metricsData.dates_metrics_total_count_active_assets
|
data: this.metricsData.dates_metrics_total_count_active_assets
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -161,7 +213,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getMetricData() {
|
async getMetricData() {
|
||||||
const url = '/api/v1/index/?dates_metrics=1&'
|
const url = '/api/v1/index/?dates_metrics=1&days=7'
|
||||||
const data = await this.$axios.get(url)
|
const data = await this.$axios.get(url)
|
||||||
this.metricsData = data
|
this.metricsData = data
|
||||||
const activeAssets = 'dates_metrics_total_count_active_assets'
|
const activeAssets = 'dates_metrics_total_count_active_assets'
|
||||||
|
176
src/views/dashboard/components/ProgressChart.vue
Normal file
176
src/views/dashboard/components/ProgressChart.vue
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<echarts
|
||||||
|
ref="echarts"
|
||||||
|
:options="options"
|
||||||
|
:autoresize="true"
|
||||||
|
class="disabled-when-print"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
import * as echarts from 'echarts'
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
colors: {
|
||||||
|
type: Array,
|
||||||
|
default: () => {
|
||||||
|
const documentStyle = document.documentElement.style
|
||||||
|
const themeColor = documentStyle.getPropertyValue('--color-primary')
|
||||||
|
return [
|
||||||
|
themeColor, '#B3D6CE', '#F3B44B', 'rgba(243, 180, 75, 0.5)',
|
||||||
|
'#535C65', 'rgba(83, 92, 101, 0.5)', '#29448A', 'rgba(41, 68, 138, 0.5)'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
options() {
|
||||||
|
const seriesList = []
|
||||||
|
const num = this.data.reduce((a, b) => a + b.total, 0)
|
||||||
|
const labels = this.data.map(item => item.label)
|
||||||
|
for (let i = 0; i < this.data.length; i++) {
|
||||||
|
const current = this.data[i]
|
||||||
|
seriesList.push({
|
||||||
|
type: 'bar',
|
||||||
|
stack: '2',
|
||||||
|
barWidth: 32,
|
||||||
|
name: current.label,
|
||||||
|
itemStyle: {
|
||||||
|
borderRadius: 0
|
||||||
|
},
|
||||||
|
data: [{
|
||||||
|
value: ((current.total / num) * 100).toFixed(2),
|
||||||
|
itemStyle: {
|
||||||
|
color: this.colors[i]
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
color: this.colors[i]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
legend: {
|
||||||
|
left: 'auto',
|
||||||
|
icon: 'rect',
|
||||||
|
itemWidth: 10,
|
||||||
|
itemHeight: 10,
|
||||||
|
textStyle: {
|
||||||
|
color: '#000',
|
||||||
|
lineHeight: 30
|
||||||
|
},
|
||||||
|
data: labels
|
||||||
|
|
||||||
|
},
|
||||||
|
color: [
|
||||||
|
{
|
||||||
|
colorStops: [
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: '#0176ff'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: '#0093ff'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 1,
|
||||||
|
y2: 0,
|
||||||
|
type: 'linear',
|
||||||
|
global: false
|
||||||
|
}, {
|
||||||
|
colorStops: [
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: '#9700ff'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: '#9700ff'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 1,
|
||||||
|
y2: 0,
|
||||||
|
type: 'linear',
|
||||||
|
global: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'shadow',
|
||||||
|
color: 'red'
|
||||||
|
},
|
||||||
|
formatter: () => {
|
||||||
|
let tip = ''
|
||||||
|
for (let i = 0; i < this.data.length; i++) {
|
||||||
|
const current = this.data[i]
|
||||||
|
tip += current.label + ':' + current.total + '<br/>'
|
||||||
|
}
|
||||||
|
return tip
|
||||||
|
}
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: '0%',
|
||||||
|
containLabel: true,
|
||||||
|
bottom: '-50%',
|
||||||
|
left: '0%',
|
||||||
|
right: '0%'
|
||||||
|
},
|
||||||
|
series: seriesList,
|
||||||
|
xAxis: {
|
||||||
|
type: 'value',
|
||||||
|
axisLabel: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'category',
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
data: [''],
|
||||||
|
axisLabel: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.echarts {
|
||||||
|
width: 100%;
|
||||||
|
height: 72px;
|
||||||
|
}
|
||||||
|
</style>
|
@@ -1,18 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="head">
|
<div class="head">
|
||||||
<span class="title">
|
<Title :config="config" />
|
||||||
{{ title }}
|
|
||||||
<el-tooltip
|
|
||||||
v-if="note"
|
|
||||||
effect="dark"
|
|
||||||
:content="note"
|
|
||||||
placement="top"
|
|
||||||
>
|
|
||||||
<i class="fa fa-exclamation-circle icon" />
|
|
||||||
</el-tooltip>
|
|
||||||
<i v-else class="fa fa-exclamation-circle icon" />
|
|
||||||
</span>
|
|
||||||
<span>
|
<span>
|
||||||
<el-radio-group
|
<el-radio-group
|
||||||
v-model="select"
|
v-model="select"
|
||||||
@@ -37,80 +26,66 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
v-for="i in columns"
|
v-for="i in config.columns"
|
||||||
:key="i.prop"
|
:key="i.prop"
|
||||||
:prop="i.prop"
|
:prop="i.prop"
|
||||||
:label="i.label"
|
:label="i.label"
|
||||||
>
|
/>
|
||||||
{{ i.prop }}
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Title from './Title.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
Title
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
title: {
|
config: {
|
||||||
type: String,
|
type: Object,
|
||||||
default: ''
|
default: () => {}
|
||||||
},
|
},
|
||||||
url: {
|
url: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
|
||||||
note: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
type: String,
|
|
||||||
default: () => ''
|
|
||||||
},
|
|
||||||
columns: {
|
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
type: Array,
|
|
||||||
default: () => [
|
|
||||||
{
|
|
||||||
label: '今天',
|
|
||||||
value: '1'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '近7天',
|
|
||||||
value: '7'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '近30天',
|
|
||||||
value: '30'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
const defaultOptions = [
|
||||||
|
{
|
||||||
|
label: '今天',
|
||||||
|
value: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '近7天',
|
||||||
|
value: '7'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '近30天',
|
||||||
|
value: '30'
|
||||||
|
}
|
||||||
|
]
|
||||||
return {
|
return {
|
||||||
select: '1',
|
select: '1',
|
||||||
tableData: [],
|
tableData: [],
|
||||||
tableUrl: this.url + `&days=1`
|
options: this.config.options || defaultOptions,
|
||||||
|
tableUrl: this.config.url + `&days=1`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.init()
|
this.getList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
init() {
|
getList() {
|
||||||
this.$axios.get(this.tableUrl).then(res => {
|
this.$axios.get(this.tableUrl).then(res => {
|
||||||
this.tableData = this.data ? res?.[this.data] : res
|
this.tableData = this.config.data ? res?.[this.config.data] : res
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
onChange() {
|
onChange() {
|
||||||
this.tableUrl = this.url + `&days=${this.select}`
|
this.tableUrl = this.config.url + `&days=${this.select}`
|
||||||
this.init()
|
this.getList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,17 +100,6 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
.title {
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 26px;
|
|
||||||
color: #1F2329;
|
|
||||||
}
|
|
||||||
.icon {
|
|
||||||
color: #BBBFC4;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.switch {
|
.switch {
|
||||||
background: #EFF0F1;
|
background: #EFF0F1;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div style="margin-bottom: 12px;">
|
<div style="margin-bottom: 12px;">
|
||||||
<span class="title">实时数据</span>
|
<Title :config="config" />
|
||||||
<!-- <span class="time">更新时间:2022-11-17</span> -->
|
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<el-row type="flex" justify="space-between">
|
<el-row type="flex" justify="space-between">
|
||||||
@@ -15,15 +14,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Title from './Title.vue'
|
||||||
import SummaryCard from './SummaryCard'
|
import SummaryCard from './SummaryCard'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { SummaryCard },
|
components: { Title, SummaryCard },
|
||||||
props: {
|
|
||||||
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
config: {
|
||||||
|
title: '实时数据',
|
||||||
|
tip: '实时数据'
|
||||||
|
},
|
||||||
counter: {
|
counter: {
|
||||||
total_count_online_sessions: '.',
|
total_count_online_sessions: '.',
|
||||||
total_count_online_users: '.',
|
total_count_online_users: '.',
|
||||||
@@ -75,18 +76,6 @@ export default {
|
|||||||
.box {
|
.box {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
.title {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #1F2329;
|
|
||||||
}
|
|
||||||
.time {
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 10px;
|
|
||||||
margin-left: 8px;
|
|
||||||
color: #8F959E;
|
|
||||||
}
|
|
||||||
.content {
|
.content {
|
||||||
.el-col {
|
.el-col {
|
||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
|
@@ -17,80 +17,86 @@ export default {
|
|||||||
|
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
config: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
userConnectData: {
|
|
||||||
dates_total_count_active_users: 0,
|
|
||||||
dates_total_count_disabled_users: 0,
|
|
||||||
dates_total_count_inactive_users: 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
themeColor() {
|
|
||||||
const documentStyle = document.documentElement.style
|
|
||||||
return {
|
|
||||||
primary: documentStyle.getPropertyValue('--color-primary'),
|
|
||||||
info: documentStyle.getPropertyValue('--color-info'),
|
|
||||||
success: documentStyle.getPropertyValue('--color-success')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
options() {
|
options() {
|
||||||
const { primary, info, success } = this.themeColor
|
const { total, active, title } = this.config
|
||||||
|
const percentage = ((active / total) * 100).toFixed(0)
|
||||||
return {
|
return {
|
||||||
|
title: [
|
||||||
|
{
|
||||||
|
text: this.config.chartTitle,
|
||||||
|
textStyle: {
|
||||||
|
color: '#646A73',
|
||||||
|
fontSize: 12
|
||||||
|
},
|
||||||
|
textAlign: 'center',
|
||||||
|
left: '48%',
|
||||||
|
top: '32%'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
left: '48%',
|
||||||
|
top: '42%',
|
||||||
|
textAlign: 'center',
|
||||||
|
text: this.config.active,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 24,
|
||||||
|
color: '#646A73'
|
||||||
|
},
|
||||||
|
subtext: '占比' + percentage + '%',
|
||||||
|
subtextStyle: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: '#646A73'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
legend: {
|
legend: {
|
||||||
show: false
|
show: false
|
||||||
},
|
},
|
||||||
color: [primary, info, success],
|
color: [this.config.color, 'rgba(43, 147, 124, 0.05)'],
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'item',
|
trigger: 'item',
|
||||||
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name: this.$t('dashboard.UserRatio'),
|
name: title,
|
||||||
type: 'pie',
|
type: 'pie',
|
||||||
radius: ['50%', '70%'],
|
radius: ['72%', '90%'],
|
||||||
avoidLabelOverlap: false,
|
avoidLabelOverlap: false,
|
||||||
label: {
|
itemStyle: {
|
||||||
show: false,
|
normal: {
|
||||||
position: 'center'
|
label: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
},
|
},
|
||||||
emphasis: {
|
emphasis: {
|
||||||
label: {
|
label: {
|
||||||
show: true,
|
show: false
|
||||||
fontSize: '18',
|
|
||||||
fontWeight: 'bold'
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
labelLine: {
|
labelLine: {
|
||||||
show: false
|
show: false
|
||||||
},
|
},
|
||||||
data: [
|
startAngle: 180,
|
||||||
{ name: this.$t('dashboard.ActiveUser'), value: this.userConnectData.dates_total_count_active_users },
|
data: this.config.data
|
||||||
{ name: this.$t('dashboard.DisabledUser'), value: this.userConnectData.dates_total_count_disabled_users },
|
|
||||||
{ name: this.$t('dashboard.InActiveUser'), value: this.userConnectData.dates_total_count_inactive_users }
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.getTotalActiveRadioData()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async getTotalActiveRadioData() {
|
|
||||||
let url = '/api/v1/index/?dates_total_count_users=1&dates_total_count_assets=1'
|
|
||||||
if (this.range === 'monthly') {
|
|
||||||
url = `${url}&monthly=1`
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = await this.$axios.get(url)
|
|
||||||
this.userConnectData = data
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
54
src/views/dashboard/components/Title.vue
Normal file
54
src/views/dashboard/components/Title.vue
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<template>
|
||||||
|
<div class="content">
|
||||||
|
<span class="title">{{ config.title }}</span>
|
||||||
|
<el-tooltip
|
||||||
|
v-if="config.tip"
|
||||||
|
effect="dark"
|
||||||
|
:content="config.tip"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<i class="fa fa-exclamation-circle icon" />
|
||||||
|
</el-tooltip>
|
||||||
|
<i v-else class="fa fa-exclamation-circle icon" />
|
||||||
|
<span v-if="config.time" class="time">更新时间:{{ config.time }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
config: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.content {
|
||||||
|
display: inline-block;
|
||||||
|
.title {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #1F2329;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
color: #BBBFC4;
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.time {
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 10px;
|
||||||
|
margin-left: 8px;
|
||||||
|
color: #8F959E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
@@ -4,12 +4,14 @@
|
|||||||
<Announcement />
|
<Announcement />
|
||||||
<el-row :gutter="16">
|
<el-row :gutter="16">
|
||||||
<el-col :lg="12" :sm="24">
|
<el-col :lg="12" :sm="24">
|
||||||
<LeftSummary />
|
<RealTimeSummary />
|
||||||
|
<LineChart />
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :lg="12" :sm="24">
|
<el-col :lg="12" :sm="24">
|
||||||
<DataSummary />
|
<DataSummary />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<AssetProportionSummary />
|
||||||
<RankSummary />
|
<RankSummary />
|
||||||
</div>
|
</div>
|
||||||
<Page403 v-else />
|
<Page403 v-else />
|
||||||
@@ -21,8 +23,10 @@ import { Announcement } from '@/components'
|
|||||||
import { Page } from '@/layout/components'
|
import { Page } from '@/layout/components'
|
||||||
import Page403 from '@/views/403'
|
import Page403 from '@/views/403'
|
||||||
import DataSummary from './DataSummary'
|
import DataSummary from './DataSummary'
|
||||||
import LeftSummary from './LeftSummary'
|
import AssetProportionSummary from './AssetProportionSummary'
|
||||||
import RankSummary from './RankSummary'
|
import RankSummary from './RankSummary'
|
||||||
|
import RealTimeSummary from './components/RealTimeSummary.vue'
|
||||||
|
import LineChart from './components/LineChart.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
@@ -30,8 +34,10 @@ export default {
|
|||||||
Page,
|
Page,
|
||||||
Announcement,
|
Announcement,
|
||||||
DataSummary,
|
DataSummary,
|
||||||
LeftSummary,
|
AssetProportionSummary,
|
||||||
RankSummary,
|
RankSummary,
|
||||||
|
RealTimeSummary,
|
||||||
|
LineChart,
|
||||||
Page403
|
Page403
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
Reference in New Issue
Block a user