perf: 调整仪表盘显示内容

This commit is contained in:
“huailei000”
2022-11-29 23:00:05 +08:00
committed by huailei
parent f79121724d
commit fc0ee3d4f8
12 changed files with 501 additions and 205 deletions

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

View File

@@ -2,10 +2,10 @@
<div>
<el-row :gutter="16">
<el-col :lg="12" :sm="12">
<DataCard />
<DataCard :config="userConfig" />
</el-col>
<el-col :lg="12" :sm="12">
<DataCard />
<DataCard :config="assetConfig" />
</el-col>
</el-row>
</div>
@@ -21,15 +21,57 @@ export default {
},
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: {
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>

View File

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

View File

@@ -2,10 +2,10 @@
<div>
<el-row :gutter="16">
<el-col :lg="12" :sm="24">
<RankTable v-bind="userConfig" />
<RankTable :config="userConfig" />
</el-col>
<el-col :lg="12" :sm="24">
<RankTable v-bind="assetConfig" />
<RankTable :config="assetConfig" />
</el-col>
</el-row>
</div>
@@ -22,7 +22,7 @@ export default {
userConfig: {
title: '登录用户排名',
url: '/api/v1/index/?dates_login_times_top10_users=1',
note: '登录用户排名',
tip: '登录用户排名',
data: 'dates_login_times_top10_users',
columns: [
{
@@ -38,7 +38,7 @@ export default {
assetConfig: {
title: '活跃资产排名',
url: '/api/v1/index/?dates_login_times_top10_assets=1',
note: '活跃资产排名',
tip: '活跃资产排名',
data: 'dates_login_times_top10_assets',
columns: [
{
@@ -50,12 +50,8 @@ export default {
label: '访问次数'
}
]
},
columnsMeta: {}
}
}
},
methods: {
}
}
</script>

View File

@@ -1,12 +1,14 @@
<template>
<div class="card">
<div>
<div class="title">标题</div>
<div class="sub">二标题11111</div>
<div class="num">1231231213</div>
<div class="title">
<Title :config="config" />
</div>
<div class="sub">{{ config.subTitle }}</div>
<div class="num">{{ config.total }}</div>
<div class="add">
<span class="add-num">
本周新增0
本周新增{{ config.weekAdd }}
<svg-icon icon-class="broken-line" style="font-size: 18px;" />
</span>
<span class="add-icon">
@@ -15,33 +17,28 @@
</div>
</div>
<div class="ring">
<RingChart />
<RingChart :config="config" />
</div>
</div>
</template>
<script>
import Title from './Title.vue'
import RingChart from './RingChart'
export default {
components: {
Title,
RingChart
},
props: {
object: {
config: {
type: Object,
default: () => ({})
}
},
data() {
return {
}
},
created() {
},
methods: {
}
}
</script>
@@ -53,10 +50,6 @@ export default {
background-color: #FFF;
.title {
margin-bottom: 12px;
line-height: 26px;
font-weight: 500;
font-size: 16px;
color: #1F2329;
}
.sub {
font-weight: 400;
@@ -78,7 +71,7 @@ export default {
border-bottom: 1px solid #EFF0F1;
}
.ring {
padding: 26px 43px 10px;
padding: 26px 0 10px;
& >>> .echarts {
width: 100%!important;
height: 272px!important;

View File

@@ -1,11 +1,7 @@
<template>
<div class="box">
<div class="head">
<span class="title">
用户/资产活跃情况
<i class="fa fa-exclamation-circle icon" />
</span>
<!-- <span class="time">更新时间2022-11-17</span> -->
<Title :config="config" />
</div>
<echarts
ref="echarts"
@@ -22,9 +18,11 @@
<script>
// eslint-disable-next-line no-unused-vars
import * as echarts from 'echarts'
import Title from './Title.vue'
export default {
name: 'LoginMetric',
components: { Title },
props: {
range: {
type: String,
@@ -33,6 +31,10 @@ export default {
},
data: function() {
return {
config: {
title: '用户/资产活跃情况 ',
tip: '用户/资产活跃情况 '
},
dataUrl: '',
metricsData: {
dates_metrics_date: [],
@@ -136,15 +138,65 @@ export default {
{
name: this.$t('dashboard.LoginUsers'),
type: 'line',
areaStyle: {},
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
},
{
name: this.$t('dashboard.LoginAssets'),
type: 'line',
areaStyle: {},
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
}
]
@@ -161,7 +213,7 @@ export default {
},
methods: {
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)
this.metricsData = data
const activeAssets = 'dates_metrics_total_count_active_assets'

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

View File

@@ -1,18 +1,7 @@
<template>
<div class="box">
<div class="head">
<span class="title">
{{ 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>
<Title :config="config" />
<span>
<el-radio-group
v-model="select"
@@ -37,80 +26,66 @@
</template>
</el-table-column>
<el-table-column
v-for="i in columns"
v-for="i in config.columns"
:key="i.prop"
:prop="i.prop"
:label="i.label"
>
{{ i.prop }}
</el-table-column>
/>
</el-table>
</div>
</template>
<script>
import Title from './Title.vue'
export default {
components: {
Title
},
props: {
title: {
type: String,
default: ''
config: {
type: Object,
default: () => {}
},
url: {
type: String,
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() {
const defaultOptions = [
{
label: '今天',
value: '1'
},
{
label: '近7天',
value: '7'
},
{
label: '近30天',
value: '30'
}
]
return {
select: '1',
tableData: [],
tableUrl: this.url + `&days=1`
options: this.config.options || defaultOptions,
tableUrl: this.config.url + `&days=1`
}
},
created() {
this.init()
this.getList()
},
methods: {
init() {
getList() {
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() {
this.tableUrl = this.url + `&days=${this.select}`
this.init()
this.tableUrl = this.config.url + `&days=${this.select}`
this.getList()
}
}
}
@@ -125,17 +100,6 @@ export default {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
.title {
font-style: normal;
font-weight: 500;
font-size: 16px;
line-height: 26px;
color: #1F2329;
}
.icon {
color: #BBBFC4;
cursor: pointer;
}
.switch {
background: #EFF0F1;
border-radius: 4px;

View File

@@ -1,8 +1,7 @@
<template>
<div class="box">
<div style="margin-bottom: 12px;">
<span class="title">实时数据</span>
<!-- <span class="time">更新时间2022-11-17</span> -->
<Title :config="config" />
</div>
<div class="content">
<el-row type="flex" justify="space-between">
@@ -15,15 +14,17 @@
</template>
<script>
import Title from './Title.vue'
import SummaryCard from './SummaryCard'
export default {
components: { SummaryCard },
props: {
},
components: { Title, SummaryCard },
data() {
return {
config: {
title: '实时数据',
tip: '实时数据'
},
counter: {
total_count_online_sessions: '.',
total_count_online_users: '.',
@@ -75,18 +76,6 @@ export default {
.box {
padding: 20px;
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 {
.el-col {
padding-left: 16px;

View File

@@ -17,80 +17,86 @@ export default {
},
props: {
config: {
type: Object,
default: () => {}
}
},
data() {
return {
userConnectData: {
dates_total_count_active_users: 0,
dates_total_count_disabled_users: 0,
dates_total_count_inactive_users: 0
}
}
},
computed: {
themeColor() {
const documentStyle = document.documentElement.style
return {
primary: documentStyle.getPropertyValue('--color-primary'),
info: documentStyle.getPropertyValue('--color-info'),
success: documentStyle.getPropertyValue('--color-success')
}
},
options() {
const { primary, info, success } = this.themeColor
const { total, active, title } = this.config
const percentage = ((active / total) * 100).toFixed(0)
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: {
show: false
},
color: [primary, info, success],
color: [this.config.color, 'rgba(43, 147, 124, 0.05)'],
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
series: [
{
name: this.$t('dashboard.UserRatio'),
name: title,
type: 'pie',
radius: ['50%', '70%'],
radius: ['72%', '90%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
itemStyle: {
normal: {
label: {
show: false
},
labelLine: {
show: false
}
}
},
emphasis: {
label: {
show: true,
fontSize: '18',
fontWeight: 'bold'
show: false
}
},
labelLine: {
show: false
},
data: [
{ name: this.$t('dashboard.ActiveUser'), value: this.userConnectData.dates_total_count_active_users },
{ 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 }
]
startAngle: 180,
data: this.config.data
}
]
}
}
},
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>

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

View File

@@ -4,12 +4,14 @@
<Announcement />
<el-row :gutter="16">
<el-col :lg="12" :sm="24">
<LeftSummary />
<RealTimeSummary />
<LineChart />
</el-col>
<el-col :lg="12" :sm="24">
<DataSummary />
</el-col>
</el-row>
<AssetProportionSummary />
<RankSummary />
</div>
<Page403 v-else />
@@ -21,8 +23,10 @@ import { Announcement } from '@/components'
import { Page } from '@/layout/components'
import Page403 from '@/views/403'
import DataSummary from './DataSummary'
import LeftSummary from './LeftSummary'
import AssetProportionSummary from './AssetProportionSummary'
import RankSummary from './RankSummary'
import RealTimeSummary from './components/RealTimeSummary.vue'
import LineChart from './components/LineChart.vue'
export default {
name: 'Dashboard',
@@ -30,8 +34,10 @@ export default {
Page,
Announcement,
DataSummary,
LeftSummary,
AssetProportionSummary,
RankSummary,
RealTimeSummary,
LineChart,
Page403
},
data() {