perf: 完善过滤

This commit is contained in:
ibuler 2024-10-23 18:52:50 +08:00
parent 6e894c31a1
commit 4fabdfdc5f
10 changed files with 194 additions and 165 deletions

View File

@ -158,15 +158,21 @@ export default {
options: [
{
label: '最近发现',
value: ''
filter: {
name: 'asdf'
}
},
{
label: '最近被登录',
value: ''
filter: {
username: 'root'
}
},
{
label: '最近修改',
value: ''
filter: {
username: 'admin'
}
},
{
label: '最近改密',

View File

@ -1,18 +1,16 @@
<template>
<el-card shadow="never">
<div slot="header" class="summary-header">
<span class="header-title">{{ title }}</span>
<div>
<div class="summary-header">
<span class="title">{{ title }}</span>
</div>
<slot>
<h1 class="no-margins">
<span v-if="body.disabled" class="disabled-link">{{ body.count }}</span>
<router-link v-else :to="body.route">
<span>{{ body.count }}</span>
</router-link>
</h1>
<small>{{ body.comment }}</small>
<h3 class="no-margins ">
<span class="num" @click="handleClick">
{{ iCount }}
</span>
</h3>
</slot>
</el-card>
</div>
</template>
<script>
@ -23,56 +21,84 @@ export default {
type: String,
default: ''
},
rightSideLabel: {
type: Object,
default: () => ({})
},
body: {
type: Object,
default: () => ({})
},
count: {
type: [Number, String],
default: 0
},
route: {
type: [String, Object],
default: ''
},
callback: {
type: Function,
default: () => {
}
},
disabled: {
type: Boolean,
default: false
}
},
data() {
return {}
},
computed: {
iCount() {
return this.body.count || this.count
},
iRoute() {
return this.body.route || this.route
},
iDisabled() {
return this.body.disabled === undefined ? this.disabled : this.body.disabled
}
},
methods: {
handleClick() {
if (this.iDisabled) {
return
}
if (this.iRoute) {
this.$router.push(this.iRoute)
return
}
this.callback()
}
}
}
</script>
<style lang="scss" scoped>
.pull-right {
float: right !important;
}
.summary-header {
color: var(--color-icon-primary);
.header-title {
font-size: 14px;
margin: 0 0 7px;
.title {
font-style: normal;
font-weight: 600;
font-size: 12px;
text-transform: uppercase;
line-height: 1.2;
}
}
.right-side ::v-deep .el-tag {
font-weight: 600;
padding: 3px 8px;
text-shadow: none;
line-height: 1;
}
.no-margins {
margin: 0 !important;
h1 {
font-size: 30px;
font-weight: 100;
}
.num {
font-style: normal;
font-weight: 500;
font-size: 24px;
line-height: 40px;
color: var(--color-text-primary);
cursor: pointer;
.el-card__body {
background-color: #ffffff;
color: inherit;
padding: 15px 20px 20px 20px !important;
border-color: #e7eaec;
border-image: none;
border-style: solid solid none;
border-width: 1px 0;
}
.no-margins {
margin: 0 !important;
}
.disabled-link {
color: #428bca;
&:hover {
color: var(--color-primary);
}
}
}
</style>

View File

@ -2,10 +2,16 @@
<div v-if="filters || summary" :class="isExpand ? 'expand': 'shrink' " class="quick-filter">
<div v-show="isExpand" class="quick-filter-wrap">
<div v-show="filters" class="quick-filter-zone">
<div v-for="category in filters" :key="category.label" class="item-zone">
<div v-for="category in iFilters" :key="category.label" class="item-zone">
<h5>{{ category.label }}</h5>
<div class="filter-options">
<span v-for="option in category.options" :key="option.label" class="item">
<span
v-for="option in category.options"
:key="option.label"
:class="option.active ? 'active' : ''"
class="item"
@click="handleClick(option)"
>
{{ option.label }}
</span>
</div>
@ -13,7 +19,7 @@
</div>
<div v-show="summary" class="summary-zone">
<span v-for="item of summary" :key="item.title">
<SummaryCard :body="item.body" :title="item.title" />
<SummaryCard :count="item.count" :title="item.title" @click="handleSummaryClick(item)" />
</span>
</div>
</div>
@ -27,7 +33,7 @@
</template>
<script>
import SummaryCard from '@/views/dashboard/components/SummaryCard.vue'
import SummaryCard from '@/components/Cards/SummaryCard'
export default {
name: 'QuickFilter',
@ -48,9 +54,13 @@ export default {
},
data() {
return {
isExpand: this.expand
isExpand: this.expand,
iFilters: this.cleanFilters(),
filtered: {},
activeFilters: []
}
},
computed: {},
watch: {
isExpand(val) {
this.$emit('expand', val)
@ -59,8 +69,49 @@ export default {
mounted() {
},
methods: {
cleanFilters() {
return this.filters.map(category => {
return {
...category,
options: category.options.map(option => {
return {
category: category.label,
...option,
active: false,
filter: option.filter || {}
}
})
}
})
},
toggle() {
this.isExpand = !this.isExpand
},
handleClick(option) {
if (!option.active) {
this.activeFilters = this.activeFilters.filter(item => {
const conflict = Object.keys(item.filter).some(key => {
return Object.keys(option.filter).includes(key)
})
if (conflict) {
item.active = false
}
return !conflict
})
this.activeFilters.push(option)
} else {
this.activeFilters = this.activeFilters.filter(item => {
return item.label !== option.label && item.category !== option.category
})
}
option.active = !option.active
this.activeFilters.forEach(item => {
this.filtered = { ...item.filter }
})
this.$emit('filter', this.filtered)
},
handleSummaryClick(item) {
this.$emit('filter', item)
}
}
}
@ -119,6 +170,11 @@ export default {
font-size: 12px;
cursor: pointer;
&.active {
color: var(--color-primary);
font-weight: 500;
}
&:hover {
color: var(--color-primary);
}

View File

@ -1,6 +1,6 @@
<template>
<div>
<QuickFilter :filters="quickFilters" :summary="quickSummary" @filter="handleQuickFilter" />
<QuickFilter :filters="quickFilters" :summary="quickSummary" @filter="filter" />
<TableAction
v-if="hasActions"
:date-pick="handleDateChange"
@ -219,8 +219,24 @@ export default {
})
},
methods: {
handleQuickFilter() {
handleQuickFilter(option) {
if (option.route) {
this.$router.push(option.route)
return
}
if (option.filter) {
const filter = { ...option.filter }
if (option.active) {
for (const key in filter) {
filter[key] = ''
}
}
this.filter(option.filter)
return
}
if (option.callback) {
option.callback(option.active)
}
},
handleActionInitialDone() {
setTimeout(() => {

View File

@ -55,25 +55,23 @@ export default {
quickSummary: [
{
title: '最近一周发现',
body: {
route: { name: `SessionList`, params: { activeMenu: 'OnlineList' }},
count: 10,
disabled: 0
count: 10,
filter: {
name: 'admin'
}
},
{
title: '最近一月发现',
body: {
route: { name: `SessionList`, params: { activeMenu: 'OnlineList' }},
count: 321,
disabled: 0
count: 321,
filter: {
username: 'admin'
}
},
{
title: '待确认',
body: {
count: 544,
disabled: true
count: 544,
filter: {
username: 'admin'
}
}
],

View File

@ -15,7 +15,7 @@
<script>
import Title from '../components/Title.vue'
import SummaryCard from '../components/SummaryCard'
import SummaryCard from '@/components/Cards/SummaryCard'
export default {
components: { Title, SummaryCard },

View File

@ -15,7 +15,7 @@
<script>
import Title from '../components/Title.vue'
import SummaryCard from '../components/SummaryCard'
import SummaryCard from '@/components/Cards/SummaryCard'
export default {
components: { Title, SummaryCard },

View File

@ -15,7 +15,7 @@
<script>
import Title from './Title.vue'
import SummaryCard from './SummaryCard'
import SummaryCard from '@/components/Cards/SummaryCard'
export default {
components: { Title, SummaryCard },
@ -85,15 +85,18 @@ export default {
.box {
padding: 20px;
background: #FFFFFF;
.content {
.el-col {
padding-left: 16px;
border-left: 1px solid #EFF0F1;
&:first-child {
padding-left: 0;
border-left: none;
}
}
.sub {
font-style: normal;
font-weight: 400;
@ -101,6 +104,7 @@ export default {
line-height: 20px;
color: #646A73;
}
.num {
font-style: normal;
font-weight: 500;

View File

@ -1,71 +0,0 @@
<template>
<div>
<div class="summary-header">
<span class="title">{{ title }}</span>
</div>
<slot>
<h3 class="no-margins">
<span v-if="body.disabled" class="num">
{{ body.count }}
</span>
<router-link v-else :to="body.route">
<span class="num disabled-link">{{ body.count }}</span>
</router-link>
</h3>
</slot>
</div>
</template>
<script>
export default {
name: 'SummaryCard',
props: {
title: {
type: String,
default: ''
},
rightSideLabel: {
type: Object,
default: () => ({})
},
body: {
type: Object,
default: () => ({})
}
}
}
</script>
<style lang="scss" scoped>
.summary-header {
color: var(--color-icon-primary);
.title {
font-style: normal;
font-weight: 600;
font-size: 12px;
text-transform: uppercase;
line-height: 1.2;
}
}
.no-margins {
margin: 0 !important;
.num {
font-style: normal;
font-weight: 500;
font-size: 24px;
line-height: 40px;
color: var(--color-text-primary);
}
.disabled-link {
cursor: pointer;
&:hover {
color: var(--color-primary);
}
}
}
</style>

View File

@ -4,18 +4,20 @@
<Title :config="config" />
</div>
<div class="content">
<el-row type="flex" justify="space-between">
<el-col v-for="item of items" :key="item.title" :md="8" :sm="12" :xs="12">
<SummaryCard :title="item.title" :body="item.body" />
</el-col>
</el-row>
<SummaryCard
v-for="item of items"
:key="item.title"
:body="item.body"
:title="item.title"
class="summary-card"
/>
</div>
</div>
</template>
<script>
import Title from '../components/Title.vue'
import SummaryCard from '../components/SummaryCard'
import SummaryCard from '@/components/Cards/SummaryCard'
export default {
components: { Title, SummaryCard },
@ -35,8 +37,7 @@ export default {
}
},
data() {
return {
}
return {}
}
}
</script>
@ -45,28 +46,21 @@ export default {
.box {
padding: 20px;
background: #FFFFFF;
.content {
.el-col {
display: flex;
justify-content: space-between;
padding: 0 10px;
.summary-card {
padding-left: 16px;
border-left: 1px solid #EFF0F1;
&:first-child {
padding-left: 0;
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;
}
}
}
</style>