Perf: Perf Dashboard

This commit is contained in:
zhaojisen 2025-01-22 18:51:53 +08:00 committed by ZhaoJiSen
parent 369247d987
commit b1137249f1
4 changed files with 153 additions and 178 deletions

View File

@ -41,23 +41,10 @@ export default {
computed: { computed: {
chartOption() { chartOption() {
return { return {
tooltip: {
trigger: 'item',
formatter: '{b}: {c} ({d}%)',
backgroundColor: 'rgba(255, 255, 255, 0.9)',
borderColor: '#eee',
borderWidth: 1,
padding: [10, 15],
textStyle: {
color: '#666'
}
},
legend: { legend: {
type: 'scroll', orient: 'vertical',
orient: 'horizontal', top: '13%',
top: 0, right: '15%',
left: 0,
right: 0,
itemGap: 20, itemGap: 20,
textStyle: { textStyle: {
color: '#666', color: '#666',
@ -65,33 +52,31 @@ export default {
}, },
icon: 'circle', icon: 'circle',
itemWidth: 8, itemWidth: 8,
itemHeight: 8 itemHeight: 8,
formatter: (name) => {
const data = [
{ name: '账号收集任务', value: this.counter.total_count_gathered_account_automation },
{ name: '账号推送任务', value: this.counter.total_count_push_account_automation },
{ name: '账号备份任务', value: this.counter.total_count_backup_account_automation },
{ name: '风险账号', value: this.counter.total_count_risk_account },
{ name: '集成应用', value: this.counter.total_count_integration_application }
]
const item = data.find(item => item.name === name)
return name.padEnd(10, '\u2003') + (item.value || 0)
}
}, },
series: [ series: [
{ {
name: '任务分布', name: '任务分布',
type: 'pie', type: 'pie',
radius: ['45%', '65%'], radius: ['50%', '70'],
center: ['50%', '55%'], center: ['25%', '50%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 8
},
label: { label: {
show: true, show: false
position: 'outside',
formatter: '{b}\n{c}',
color: '#666',
fontSize: 12,
lineHeight: 18
}, },
labelLine: { labelLine: {
show: true, show: false
length: 15,
length2: 10,
smooth: true
}, },
data: [ data: [
{ {
@ -152,8 +137,7 @@ export default {
}, },
methods: { methods: {
async getResourcesCount() { async getResourcesCount() {
return this.$axios.get('/api/v1/accounts/pam-dashboard/', return this.$axios.get('/api/v1/accounts/pam-dashboard/', {
{
params: { params: {
total_count_gathered_account_automation: 1, total_count_gathered_account_automation: 1,
total_count_push_account_automation: 1, total_count_push_account_automation: 1,
@ -161,8 +145,7 @@ export default {
total_count_risk_account: 1, total_count_risk_account: 1,
total_count_integration_application: 1 total_count_integration_application: 1
} }
} })
)
}, },
initChart() { initChart() {
this.chart = echarts.init(this.$refs.chartRef) this.chart = echarts.init(this.$refs.chartRef)
@ -192,7 +175,12 @@ export default {
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.header { .header {
padding: 16px 20px 0; padding: 1.25rem;
.content {
justify-content: flex-start;
padding: unset;
}
} }
.content { .content {
@ -205,7 +193,7 @@ export default {
.chart-container { .chart-container {
width: 100%; width: 100%;
height: 420px; height: 226px;
} }
} }
} }

View File

@ -1,14 +1,23 @@
<template> <template>
<div class="box"> <div class="card">
<div style="margin-bottom: 12px;"> <div class="title-section">
<Title :config="config" /> <Title :config="config" />
</div> </div>
<div class="content">
<el-row justify="space-between" type="flex"> <div class="metrics-section">
<el-col v-for="item of summaryItems" :key="item.title" :md="8" :sm="12" :xs="12"> <template v-for="item of summaryItems">
<SummaryCard
:key="item.title"
:body="item.body"
:title="item.title"
class="metric-item"
/>
</template>
<!-- <el-row :gutter="20">
<el-col v-for="item of summaryItems" :key="item.title" :md="6" :sm="12" :xs="12">
<SummaryCard :body="item.body" :title="item.title" /> <SummaryCard :body="item.body" :title="item.title" />
</el-col> </el-col>
</el-row> </el-row> -->
</div> </div>
</div> </div>
</template> </template>
@ -38,10 +47,10 @@ export default {
summaryItems() { summaryItems() {
return [ return [
{ {
title: this.$t('LongTimeNoLogin'), title: this.$t('LeakedPassword'),
body: { body: {
route: { name: `SessionList`, params: { activeMenu: 'OnlineList' }}, count: this.counter.total_leaked_password_accounts,
count: this.counter.total_long_time_no_login_accounts disabled: true
} }
}, },
{ {
@ -51,6 +60,14 @@ export default {
disabled: true disabled: true
} }
}, },
{
title: this.$t('LongTimeNoLogin'),
body: {
route: { name: `SessionList`, params: { activeMenu: 'OnlineList' }},
count: this.counter.total_long_time_no_login_accounts
}
},
{ {
title: this.$t('LongTimeNoChangeSecret'), title: this.$t('LongTimeNoChangeSecret'),
body: { body: {
@ -58,19 +75,24 @@ export default {
disabled: true disabled: true
} }
}, },
{
title: this.$t('LeakedPassword'),
body: {
count: this.counter.total_leaked_password_accounts,
disabled: true
}
},
{ {
title: this.$t('RepeatedPassword'), title: this.$t('RepeatedPassword'),
body: { body: {
count: this.counter.total_repeated_password_accounts, count: this.counter.total_repeated_password_accounts,
disabled: true disabled: true
} }
},
{
title: 'Unmanaged'
},
{
title: 'Password expiration'
},
{
title: 'Wrong password'
},
{
title: 'No admin'
} }
] ]
} }
@ -100,34 +122,49 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.box { .card {
padding: 20px; display: flex;
background: #FFFFFF; flex-direction: column;
gap: 1.25rem;
width: 100%;
height: 100%;
padding: 1.25rem;
background-color: #FFF;
overflow: hidden;
.content { .metrics-section {
.el-col { display: flex;
padding-left: 16px; flex-wrap: wrap;
border-left: 1px solid #EFF0F1; row-gap: 1.25rem;
&:first-child { .metric-item {
padding-left: 0; width: 25%;
border-left: none;
}
}
.sub {
font-style: normal;
font-weight: 400;
font-size: 12px;
line-height: 20px;
color: #646A73;
}
.num {
font-style: normal;
font-weight: 500;
font-size: 24px;
cursor: pointer; cursor: pointer;
transition: all 0.3s ease-in-out;
::v-deep .summary-header {
.title {
color: #646A73;
font-size: 0.9rem;
font-weight: 400;
line-height: 1.4rem;
text-transform: unset;
}
h3 span {
font-size: 1.5rem;
}
}
&:hover {
transform: translateY(-0.2rem);
::v-deep .no-margins {
.num {
color: var(--color-primary);
}
}
}
} }
} }
} }

View File

@ -16,6 +16,8 @@
</div> </div>
</div> </div>
<el-divider />
<div class="metrics-section"> <div class="metrics-section">
<div <div
v-for="item in summaryItems" v-for="item in summaryItems"
@ -76,12 +78,17 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
$text-color: #646A73; $text-color: #646A73;
.el-divider--horizontal {
margin: unset !important;
}
.card { .card {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 1.25rem; gap: 1.25rem;
width: 100%; width: 100%;
height: 100%; height: 100%;
padding: 1.25rem;
background-color: #FFF; background-color: #FFF;
overflow: hidden; overflow: hidden;

View File

@ -2,34 +2,28 @@
<Page> <Page>
<div v-if="this.$hasPerm('rbac.view_console')"> <div v-if="this.$hasPerm('rbac.view_console')">
<Announcement /> <Announcement />
<div class="dashboard-container">
<el-row :gutter="20" class="top-summary"> <div class="summary-container">
<el-col :lg="16" :xs="24" class="left-column"> <el-row :gutter="20">
<div class="mission-wrapper"> <el-col :span="16">
<DataSummary class="summary-card" /> <DataSummary class="data-summery" />
</div>
<div class="account-wrapper">
<AccountSummary class="summary-card" />
</div>
<div class="risk-wrapper">
<RiskSummary class="summary-card" />
</div>
</el-col> </el-col>
<el-col :lg="8" :xs="24" class="right-column"> <el-col :span="8">
<MissionSummery class="summary-card" /> <AccountSecretSummary class="account-secret-summary" />
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="20" class="middle-section"> <el-row :gutter="20">
<el-col :span="24"> <el-col :span="16">
<AccountSecretSummary class="secret-summary" /> <RiskSummary class="risk-summary" />
</el-col>
<el-col :span="8">
<MissionSummery class="mission-summery" />
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="20" class="bottom-section"> <el-row>
<el-col :span="24" class="asset-proportion-wrapper"> <AssetProportionSummary :url="url" class="asset-proportion-summary" />
<AssetProportionSummary :url="url" class="summary-card" />
</el-col>
</el-row> </el-row>
</div> </div>
</div> </div>
@ -43,7 +37,6 @@ import { Announcement } from '@/components'
import Page403 from '@/views/403' import Page403 from '@/views/403'
import DataSummary from './DataSummary' import DataSummary from './DataSummary'
import RiskSummary from './RiskSummary.vue' import RiskSummary from './RiskSummary.vue'
import AccountSummary from './AccountSummary.vue'
import AssetProportionSummary from './AssetProportionSummary' import AssetProportionSummary from './AssetProportionSummary'
import MissionSummery from './MissionSummery.vue' import MissionSummery from './MissionSummery.vue'
import AccountSecretSummary from '../ChangeSecret/AccountSummary.vue' import AccountSecretSummary from '../ChangeSecret/AccountSummary.vue'
@ -57,7 +50,6 @@ export default {
RiskSummary, RiskSummary,
Announcement, Announcement,
MissionSummery, MissionSummery,
AccountSummary,
AccountSecretSummary, AccountSecretSummary,
AssetProportionSummary AssetProportionSummary
}, },
@ -70,80 +62,31 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.dashboard-container { .el-row {
.top-summary,
.middle-section,
.bottom-section {
margin-bottom: 1.25rem; margin-bottom: 1.25rem;
} }
.top-summary { .summary-container {
.left-column {
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.right-column { .account-secret-summary,
max-height: 540px; .asset-proportion-summary,
height: 540px; .risk-summary,
.mission-summery {
::v-deep .el-row,
::v-deep .el-col {
height: 100%;
}
}
}
.bottom-section {
.data-summary-wrapper {
margin-bottom: 1.25rem;
}
}
.summary-card {
background: #fff;
padding: 1.25rem;
height: 100%;
box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
transition: all .3s;
border-radius: 0.5rem; border-radius: 0.5rem;
::v-deep .card-content {
padding-bottom: unset;
border-bottom: unset;
} }
::v-deep .ring { .account-secret-summary,
display: none; .asset-proportion-summary {
margin-top: unset;
}
.account-secret-summary {
margin-top: unset;
::v-deep .echarts {
height: 205px;
} }
} }
.mission-summary {
background: #fff;
padding: 1.25rem;
box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
}
.secret-summary {
background: #fff;
padding: 1.25rem;
margin-bottom: 1.25rem;
box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
}
@media screen and (max-width: 1200px) {
.right-column {
margin-top: 1.25rem;
}
}
@media screen and (max-width: 768px) {
padding: 0.625rem;
.el-col {
margin-bottom: 1.25rem;
}
}
} }
</style> </style>