perf(仪表板): 优化仪表板查询按钮

This commit is contained in:
fit2cloud-chenyw 2022-07-25 17:21:56 +08:00
parent e10108c8e8
commit 1e32501653
15 changed files with 295 additions and 66 deletions

View File

@ -80,7 +80,7 @@ import UserViewDialog from '@/components/canvas/custom-component/UserViewDialog'
import CanvasOptBar from '@/components/canvas/components/Editor/CanvasOptBar'
import UserViewMobileDialog from '@/components/canvas/custom-component/UserViewMobileDialog'
import bus from '@/utils/bus'
import { buildFilterMap } from '@/utils/conditionUtil'
import { buildFilterMap, buildViewKeyMap, formatCondition, valueValid, viewIdMatch } from '@/utils/conditionUtil'
import { hasDataPermission } from '@/utils/permission'
const erd = elementResizeDetectorMaker()
@ -171,7 +171,8 @@ export default {
showChartTableInfo: {},
showChartInfoType: 'details',
// 1.pc pc 2.mobile
terminal: 'pc'
terminal: 'pc',
buttonFilterMap: null
}
},
created() {
@ -256,7 +257,7 @@ export default {
'isClickComponent'
]),
filterMap() {
const map = buildFilterMap(this.componentData)
const map = this.buttonFilterMap || buildFilterMap(this.componentData)
return map
}
},
@ -283,14 +284,79 @@ export default {
if (this.terminal === 'mobile') {
this.initMobileCanvas()
}
bus.$on('trigger-search-button', this.triggerSearchButton)
},
beforeDestroy() {
erd.uninstall(this.$refs.canvasInfoTemp)
erd.uninstall(this.$refs.canvasInfoMain)
clearInterval(this.timer)
eventBus.$off('openChartDetailsDialog', this.openChartDetailsDialog)
bus.$on('trigger-search-button', this.triggerSearchButton)
},
methods: {
triggerSearchButton() {
this.buttonFilterMap = this.buildButtonFilterMap(this.componentData)
},
buildButtonFilterMap(panelItems) {
const result = {
buttonExist: false,
relationFilterIds: [],
filterMap: {
}
}
if (!panelItems || !panelItems.length) return result
let sureButtonItem = null
result.buttonExist = panelItems.some(item => {
if (item.type === 'custom-button' && item.serviceName === 'buttonSureWidget') {
sureButtonItem = item
return true
}
})
if (!result.buttonExist) return result
const customRange = sureButtonItem.options.attrs.customRange
const allFilters = panelItems.filter(item => item.type === 'custom')
const matchFilters = customRange && allFilters.filter(item => sureButtonItem.options.attrs.filterIds.includes(item.id)) || allFilters
result.relationFilterIds = matchFilters.map(item => item.id)
let viewKeyMap = buildViewKeyMap(panelItems)
viewKeyMap = this.buildViewKeyFilters(matchFilters, viewKeyMap)
result.filterMap = viewKeyMap
return result
},
buildViewKeyFilters(panelItems, result) {
const refs = this.$refs
panelItems.forEach((element, index) => {
if (element.type !== 'custom') {
return true
}
let param = null
const wrapperChild = refs['wrapperChild'][index]
param = wrapperChild.getCondition && wrapperChild.getCondition()
const condition = formatCondition(param)
const vValid = valueValid(condition)
const filterComponentId = condition.componentId
Object.keys(result).forEach(viewId => {
const vidMatch = viewIdMatch(condition.viewIds, viewId)
const viewFilters = result[viewId]
let j = viewFilters.length
while (j--) {
const filter = viewFilters[j]
if (filter.componentId === filterComponentId) {
viewFilters.splice(j, 1)
}
}
vidMatch && vValid && viewFilters.push(condition)
})
})
return result
},
_isMobile() {
const flag = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)
this.terminal = flag ? 'mobile' : 'pc'

View File

@ -5,7 +5,7 @@
<slot name="icon" />
<el-dropdown-menu v-if="curComponent">
<el-dropdown-item v-if="editFilter.includes(curComponent.type)" icon="el-icon-edit-outline" @click.native="edit">{{ $t('panel.edit') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-document-copy" @click.native="copy">{{ $t('panel.copy') }}</el-dropdown-item>
<el-dropdown-item v-if="curComponent.type != 'custom-button'" icon="el-icon-document-copy" @click.native="copy">{{ $t('panel.copy') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-delete" @click.native="deleteComponent">{{ $t('panel.delete') }}</el-dropdown-item>
<el-dropdown-item v-if="!curComponent.auxiliaryMatrix">
<el-dropdown placement="right-start">
@ -73,7 +73,7 @@ export default {
edit() {
if (this.curComponent.type === 'custom') {
bus.$emit('component-dialog-edit', 'update')
}else if (this.curComponent.type === 'custom-button') {
} else if (this.curComponent.type === 'custom-button') {
bus.$emit('button-dialog-edit')
} else if (this.curComponent.type === 'v-text' || this.curComponent.type === 'de-rich-text' || this.curComponent.type === 'rect-shape') {
bus.$emit('component-dialog-style')

View File

@ -61,7 +61,7 @@
@editComponent="editComponent(index,item)"
>
<de-out-widget
v-if="renderOk&&item.type==='custom'"
v-if="renderOk && item.type==='custom'"
:id="'component' + item.id"
ref="wrapperChild"
class="component"
@ -74,7 +74,7 @@
/>
<component
:is="item.component"
v-else-if="renderOk&&item.type==='other'"
v-else-if="renderOk && item.type==='other'"
:id="'component' + item.id"
ref="wrapperChild"
class="component"
@ -207,7 +207,7 @@ import CanvasOptBar from '@/components/canvas/components/Editor/CanvasOptBar'
import DragShadow from '@/components/DeDrag/shadow'
import bus from '@/utils/bus'
import LinkJumpSet from '@/views/panel/LinkJumpSet'
import { buildFilterMap } from '@/utils/conditionUtil'
import { buildFilterMap, buildViewKeyMap, formatCondition, valueValid, viewIdMatch } from '@/utils/conditionUtil'
//
import _ from 'lodash'
import $ from 'jquery'
@ -929,7 +929,8 @@ export default {
yourList: [],
linkJumpSetVisible: false,
linkJumpSetViewId: null,
editShow: false
editShow: false,
buttonFilterMap: null
}
},
computed: {
@ -1004,7 +1005,7 @@ export default {
'batchOptStatus'
]),
filterMap() {
return buildFilterMap(this.componentData)
return this.buttonFilterMap || buildFilterMap(this.componentData)
}
},
watch: {
@ -1055,6 +1056,7 @@ export default {
eventBus.$on('startMoveIn', this.startMoveIn)
eventBus.$on('openChartDetailsDialog', this.openChartDetailsDialog)
bus.$on('onRemoveLastItem', this.removeLastItem)
bus.$on('trigger-search-button', this.triggerSearchButton)
//
if (this.psDebug) {
@ -1068,10 +1070,74 @@ export default {
eventBus.$off('startMoveIn', this.startMoveIn)
eventBus.$off('openChartDetailsDialog', this.openChartDetailsDialog)
bus.$off('onRemoveLastItem', this.removeLastItem)
bus.$off('trigger-search-button', this.triggerSearchButton)
},
created() {
},
methods: {
triggerSearchButton() {
this.buttonFilterMap = this.buildButtonFilterMap(this.componentData)
},
buildButtonFilterMap(panelItems) {
const result = {
buttonExist: false,
relationFilterIds: [],
filterMap: {
}
}
if (!panelItems || !panelItems.length) return result
let sureButtonItem = null
result.buttonExist = panelItems.some(item => {
if (item.type === 'custom-button' && item.serviceName === 'buttonSureWidget') {
sureButtonItem = item
return true
}
})
if (!result.buttonExist) return result
const customRange = sureButtonItem.options.attrs.customRange
const allFilters = panelItems.filter(item => item.type === 'custom')
const matchFilters = customRange && allFilters.filter(item => sureButtonItem.options.attrs.filterIds.includes(item.id)) || allFilters
result.relationFilterIds = matchFilters.map(item => item.id)
let viewKeyMap = buildViewKeyMap(panelItems)
viewKeyMap = this.buildViewKeyFilters(matchFilters, viewKeyMap)
result.filterMap = viewKeyMap
return result
},
buildViewKeyFilters(panelItems, result) {
const refs = this.$refs
panelItems.forEach((element, index) => {
if (element.type !== 'custom') {
return true
}
let param = null
const wrapperChild = refs['wrapperChild'][index]
param = wrapperChild.getCondition && wrapperChild.getCondition()
const condition = formatCondition(param)
const vValid = valueValid(condition)
const filterComponentId = condition.componentId
Object.keys(result).forEach(viewId => {
const vidMatch = viewIdMatch(condition.viewIds, viewId)
const viewFilters = result[viewId]
let j = viewFilters.length
while (j--) {
const filter = viewFilters[j]
if (filter.componentId === filterComponentId) {
viewFilters.splice(j, 1)
}
}
vidMatch && vValid && viewFilters.push(condition)
})
})
return result
},
pluginEditHandler({ e, id }) {
let index = -1
for (let i = 0; i < this.componentData.length; i++) {

View File

@ -27,7 +27,7 @@
:is="element.component"
v-if="element.type==='custom'"
:id="'component' + element.id"
ref="deOutWidget"
ref="filter-ref"
class="component-custom"
:out-style="element.style"
:element="element"
@ -152,6 +152,12 @@ export default {
alignItems: 'center'
}
}
},
getCondition() {
if (this.$refs && this.$refs['filter-ref'] && this.$refs['filter-ref'].getCondition) {
return this.$refs['filter-ref'].getCondition()
}
return null
}
}
}

View File

@ -6,12 +6,14 @@
:round="options.attrs.round"
:plain="options.attrs.plain"
:size="size"
@click="triggerSearch"
>
{{ options.value }}
</el-button>
</template>
<script>
import bus from '@/utils/bus'
export default {
props: {
@ -34,6 +36,11 @@ export default {
},
created() {
this.options = this.element.options
},
methods: {
triggerSearch() {
bus.$emit('trigger-search-button')
}
}
}
</script>

View File

@ -170,13 +170,17 @@ export default {
search() {
this.setCondition()
},
setCondition() {
getCondition() {
const param = {
component: this.element,
value: this.formatFilterValue(),
operator: this.operator
}
param.value = this.formatValues(param.value)
return param
},
setCondition() {
const param = this.getCondition()
this.inDraw && this.$store.commit('addViewFilter', param)
},
dateChange(value) {

View File

@ -91,12 +91,16 @@ export default {
}
this.setCondition()
},
setCondition() {
getCondition() {
const param = {
component: this.element,
value: !this.value ? [] : Array.isArray(this.value) ? this.value : [this.value],
operator: this.operator
}
return param
},
setCondition() {
const param = this.getCondition()
this.inDraw && this.$store.commit('addViewFilter', param)
},
setEdit() {

View File

@ -194,13 +194,33 @@ export default {
})
})
},
setCondition() {
getCondition() {
const param = {
component: this.element,
// value: !this.values ? [] : Array.isArray(this.values) ? this.values : [this.values],
value: [this.form.min, this.form.max],
operator: this.operator
}
if (this.form.min && this.form.max) {
return param
}
if (!this.form.min && !this.form.max) {
param.value = []
return param
}
if (this.form.min) {
param.value = [this.form.min]
param.operator = 'ge'
return param
}
if (this.form.max) {
param.value = [this.form.max]
param.operator = 'le'
return param
}
return param
},
setCondition() {
const param = this.getCondition()
if (this.form.min && this.form.max) {
this.inDraw && this.$store.commit('addViewFilter', param)

View File

@ -276,13 +276,16 @@ export default {
this.handleElTagStyle()
})
},
setCondition() {
getCondition() {
const param = {
component: this.element,
value: this.formatFilterValue(),
operator: this.operator
}
return param
},
setCondition() {
const param = this.getCondition()
this.inDraw && this.$store.commit('addViewFilter', param)
},
formatFilterValue() {

View File

@ -273,13 +273,16 @@ export default {
}
this.setCondition()
},
setCondition() {
getCondition() {
const param = {
component: this.element,
value: this.formatFilterValue(),
operator: this.operator
}
return param
},
setCondition() {
const param = this.getCondition()
this.inDraw && this.$store.commit('addViewFilter', param)
},
formatFilterValue() {

View File

@ -279,7 +279,7 @@ export default {
this.setCondition()
},
setCondition() {
getCondition() {
const val = this.formatFilterValue()
const param = {
@ -288,6 +288,11 @@ export default {
operator: this.operator,
isTree: true
}
return param
},
setCondition() {
const param = this.getCondition()
this.inDraw && this.$store.commit('addViewFilter', param)
},
formatFilterValue() {

View File

@ -24,7 +24,8 @@ const drawPanel = {
round: false,
plain: true,
customRange: false,
filterIds: []
filterIds: [],
autoTrigger: true
},
value: '查询'
},

View File

@ -51,8 +51,8 @@ export const formatLinkageCondition = obj => {
return condition
}
export const buildFilterMap = panelItems => {
const viewIdMatch = (viewIds, viewId) => !viewIds || viewIds.length === 0 || viewIds.includes(viewId)
export const viewIdMatch = (viewIds, viewId) => !viewIds || viewIds.length === 0 || viewIds.includes(viewId)
export const buildViewKeyMap = panelItems => {
const result = {}
panelItems.forEach(element => {
if (element.type === 'view') {
@ -66,12 +66,18 @@ export const buildFilterMap = panelItems => {
})
}
})
panelItems.forEach(element => {
return result
}
export const buildViewKeyFilters = (panelItems, result) => {
panelItems.forEach((element, index) => {
if (element.type !== 'custom') {
return true
}
let param = null
const widget = ApplicationContext.getService(element.serviceName)
const param = widget.getParam(element)
param = widget.getParam(element)
const condition = formatCondition(param)
const vValid = valueValid(condition)
const filterComponentId = condition.componentId
@ -90,3 +96,9 @@ export const buildFilterMap = panelItems => {
})
return result
}
export const buildFilterMap = panelItems => {
let result = buildViewKeyMap(panelItems)
result = buildViewKeyFilters(panelItems, result)
return result
}

View File

@ -1,23 +1,25 @@
<template>
<div>
<el-form size="mini" ref="form" :model="form" label-width="100px">
<el-form ref="form" size="mini" :model="form" label-width="90px">
<el-form-item label="名称">
<el-input v-model="currentElement.options.value"></el-input>
<el-input v-model="currentElement.options.value" />
</el-form-item>
<el-form-item label="自定义范围">
<el-switch v-model="myAttrs.customRange" @change="customRangeChange"></el-switch>
<el-form-item label="自动触发">
<el-switch v-model="myAttrs.autoTrigger" @change="autoTriggerChange" />
</el-form-item>
<el-form-item label="控制范围">
<el-switch v-model="myAttrs.customRange" @change="customRangeChange" />
<el-link style="margin-left: 10px;" type="warning" disabled>默认关联全部过滤组件</el-link>
</el-form-item>
<el-form-item label="关联组件" v-if="myAttrs.customRange">
<el-select style="width: 300px;" multiple clearable v-model="myAttrs.filterIds" placeholder="请选择活动区域">
<el-option v-for="(filter, index) in filters" :key="filter.id" :label="filter.showName" :value="filter.id" />
<el-form-item v-if="myAttrs.customRange" label="关联组件">
<el-select v-model="myAttrs.filterIds" style="width: 300px;" multiple clearable placeholder="请选择活动区域">
<el-option v-for="(filter, index) in filters" :key="filter.id + index" :label="filter.showName" :value="filter.id" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="sure">确定</el-button>
<el-button @click="cancel">取消</el-button>
@ -35,7 +37,7 @@ export default {
props: {
widgetInfo: {
type: Object,
default: null,
default: null
},
element: {
type: Object,
@ -45,35 +47,30 @@ export default {
data() {
return {
form: {
},
currentElement: null,
widget: null,
myAttrs: null
}
},
created() {
this.widget = this.widgetInfo
this.currentElement = JSON.parse(JSON.stringify(this.element))
this.myAttrs = this.currentElement.options.attrs
},
computed: {
...mapState([
'componentData'
]),
filters() {
const datas = this.componentData.filter(item => item.type === 'custom')
datas.forEach(item => {
const serviceName = item.serviceName
const widget = ApplicationContext.getService(serviceName)
const showName = widget.initLeftPanel().label
let result = ''
if(showName) {
if (showName) {
result = this.$t(showName)
}
if(item.options.attrs.title) {
if (item.options.attrs.title) {
result += '【' + item.options.attrs.title + '】'
}
@ -82,6 +79,11 @@ export default {
return datas
}
},
created() {
this.widget = this.widgetInfo
this.currentElement = JSON.parse(JSON.stringify(this.element))
this.myAttrs = this.currentElement.options.attrs
},
methods: {
sure() {
this.$emit('sure-handler')
@ -94,7 +96,10 @@ export default {
},
customRangeChange(val) {
this.myAttrs.filterIds = []
},
autoTriggerChange(val) {
}
}
}
</script>
</script>

View File

@ -9,7 +9,7 @@
v-for="(widget, index) in item"
:key="widget.widgetName+index"
:data-id="widget.widgetName"
draggable
:draggable="widget.widgetName !== 'buttonSureWidget' || !searchButtonExist"
:data-index="index"
:class="'filter-widget '+ (widget.defaultClass || '')"
>
@ -27,7 +27,7 @@
<script>
import { ApplicationContext } from '@/utils/ApplicationContext'
import { deepCopy, matrixBaseChange } from '@/components/canvas/utils/utils'
import { deepCopy } from '@/components/canvas/utils/utils'
import eventBus from '@/components/canvas/utils/eventBus'
import { mapState } from 'vuex'
export default {
@ -35,16 +35,11 @@ export default {
data() {
return {
panelInfo: this.$store.state.panel.panelInfo,
// widgetSubjects: {
// '': [
// 'mySelectWidget'
// ]
// }
widgetSubjects: {
'时间过滤组件': [
'timeYearWidget',
'timeMonthWidget',
// 'timeQuarterWidget',
'timeDateWidget',
'timeDateRangeWidget'
@ -69,22 +64,44 @@ export default {
computed: {
...mapState([
'canvasStyleData',
'curCanvasScale'
])
'curCanvasScale',
'componentData'
]),
searchButtonExist() {
return this.componentData && this.componentData.some(component => component.type === 'custom-button' && component.serviceName === 'buttonSureWidget')
}
},
watch: {
searchButtonExist(val, old) {
if (val === old) return
if (val) {
this.widgetSubjects['按钮'][0].widgetName = 'buttonSureWidget'
this.widgetSubjects['按钮'][0].defaultClass = 'button-disable-filter'
} else {
this.widgetSubjects['按钮'][0].widgetName = 'buttonSureWidget'
this.widgetSubjects['按钮'][0].defaultClass = 'time-filter'
}
}
},
created() {
for (const key in this.widgetSubjects) {
const widgetNames = this.widgetSubjects[key]
this.widgetSubjects[key] = widgetNames.map(widgetName => {
const widget = ApplicationContext.getService(widgetName)
const result = { widgetName: widgetName }
Object.assign(result, widget.getLeftPanel())
return result
})
}
this.init()
},
methods: {
init() {
for (const key in this.widgetSubjects) {
const widgetNames = this.widgetSubjects[key]
this.widgetSubjects[key] = widgetNames.map(widgetName => {
const widget = ApplicationContext.getService(widgetName)
const result = { widgetName: widgetName }
Object.assign(result, widget.getLeftPanel())
if (this.searchButtonExist && widgetName === 'buttonSureWidget') {
result.defaultClass = 'button-disable-filter'
}
return result
})
}
},
handleDragStart(ev) {
//
const dragComponentInfo = deepCopy(ApplicationContext.getService(ev.target.dataset.id).getDrawPanel())
@ -171,6 +188,16 @@ export default {
overflow: hidden;
}
.button-disable-filter {
background-color: #ecf5ff;
.filter-widget-icon {
color: #8cc5ff;
}
.filter-widget-text {
color: var(--TextActive, #8cc5ff);
}
}
.time-filter {
background-color: rgba(54,133,242,.1);
.filter-widget-icon {