Skip to content

Commit 7472cfb

Browse files
authoredMar 7, 2025··
feat: 优化cmdb模块数据量大时页面打开慢 (#8354)
* feat: 优化cmdb模块数据量大时页面打开慢 --story=122100257 * 代码优化
1 parent c348d49 commit 7472cfb

File tree

5 files changed

+184
-87
lines changed

5 files changed

+184
-87
lines changed
 

‎src/ui/src/service/auth.js

+2-19
Original file line numberDiff line numberDiff line change
@@ -41,32 +41,15 @@ export const verifyAuth = resources => $http.post('auth/verify', {
4141
/**
4242
* 获取免查看鉴权的模型
4343
*/
44-
export const getViewAuthFreeModels = () => {
45-
const allModels = store.getters['objectModelClassify/models']
46-
const presetModels = store.getters['objectModelClassify/presetModels']
47-
48-
// mainLineModel中默认没有id,在此先补充
49-
const mainLineModels = store.state.objectMainLineModule.mainLineModels.map(mainItem => ({
50-
id: allModels.find(preItem => preItem.bk_obj_id === mainItem.bk_obj_id)?.id,
51-
bk_obj_id: mainItem.bk_obj_id,
52-
bk_obj_name: mainItem.bk_obj_name
53-
}))
54-
55-
return ([...mainLineModels, ...presetModels]).map(model => ({
56-
id: model.id,
57-
bk_obj_id: model.bk_obj_id,
58-
bk_obj_name: model.bk_obj_name
59-
}))
60-
}
44+
export const getViewAuthFreeModels = () => store.getters['objectModelClassify/viewAuthFreeModels']
6145

6246
/**
6347
* 判断一个模型是否为免查看鉴权
6448
* @param {Object} model 单个模型
6549
*/
6650
export const isViewAuthFreeModel = (model) => {
67-
const authFreeModels = getViewAuthFreeModels()
6851
const dataKey = model.bk_obj_id ? 'bk_obj_id' : 'id'
69-
return authFreeModels.some(item => item[dataKey] === model[dataKey])
52+
return store.getters['objectModelClassify/viewAuthFreeModelSet'].has(model[dataKey])
7053
}
7154

7255
/**

‎src/ui/src/store/modules/api/object-model-classify.js

+45-14
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,17 @@ import $http from '@/api'
1515
import { CONTAINER_OBJECTS, CONTAINER_OBJECT_NAMES } from '@/dictionary/container.js'
1616

1717
const state = {
18-
classifications: []
18+
classifications: [],
19+
models: [],
20+
viewAuthFreeModels: [],
21+
viewAuthFreeModelSet: new Set()
1922
}
2023

2124
const getters = {
2225
classifications: state => state.classifications,
23-
models: (state) => {
24-
const models = []
25-
state.classifications.forEach((classification) => {
26-
(classification.bk_objects || []).forEach((model) => {
27-
models.push({
28-
...model,
29-
bk_classification_name: classification.bk_classification_name,
30-
bk_classification_id: classification.bk_classification_id
31-
})
32-
})
33-
})
34-
return models
35-
},
26+
models: state => state.models,
27+
viewAuthFreeModels: state => state.viewAuthFreeModels,
28+
viewAuthFreeModelSet: state => state.viewAuthFreeModelSet,
3629
getModelById: (state, getters) => id => getters.models.find(model => model.bk_obj_id === id),
3730
presetModels: (state, getters) => getters.models.filter(model => model.ispre)
3831
}
@@ -143,6 +136,44 @@ const actions = {
143136
const mutations = {
144137
setClassificationsObjects(state, classifications) {
145138
state.classifications = classifications
139+
this.commit('objectModelClassify/setModels')
140+
this.commit('objectModelClassify/setViewAuthFreeModels')
141+
this.commit('objectModelClassify/setViewAuthFreeModelSet')
142+
},
143+
setViewAuthFreeModelSet(state) {
144+
state.viewAuthFreeModels.forEach((item)=> {
145+
state.viewAuthFreeModelSet.add(item?.bk_obj_id || item?.id)
146+
})
147+
},
148+
setViewAuthFreeModels(state) {
149+
const begin = new Date().valueOf()
150+
const presetModels = this.getters['objectModelClassify/presetModels']
151+
const allModels = state.models
152+
// mainLineModel中默认没有id,在此先补充
153+
const mainLineModels = this.getters['objectMainLineModule/mainLineModels'].map(mainItem => ({
154+
id: allModels.find(preItem => preItem.bk_obj_id === mainItem.bk_obj_id)?.id,
155+
bk_obj_id: mainItem.bk_obj_id,
156+
bk_obj_name: mainItem.bk_obj_name
157+
}))
158+
159+
state.viewAuthFreeModels = ([...mainLineModels, ...presetModels]).map(model => ({
160+
id: model.id,
161+
bk_obj_id: model.bk_obj_id,
162+
bk_obj_name: model.bk_obj_name
163+
}))
164+
},
165+
setModels(state) {
166+
const models = []
167+
state.classifications.forEach((classification) => {
168+
(classification.bk_objects || []).forEach((model) => {
169+
models.push({
170+
...model,
171+
bk_classification_name: classification.bk_classification_name,
172+
bk_classification_id: classification.bk_classification_id
173+
})
174+
})
175+
})
176+
state.models = models
146177
},
147178
updateClassify(state, classification) {
148179
// eslint-disable-next-line max-len

‎src/ui/src/views/model-manage/children/collapse-group-title.vue

+8-50
Original file line numberDiff line numberDiff line change
@@ -20,55 +20,9 @@
2020
<div class="drag-icon" v-if="dragIcon"></div>
2121
<bk-icon class="group-collapse-icon" type="down-shape" />
2222
<p class="group-title-text" v-bk-overflow-tips>{{title}}</p>
23-
<bk-dropdown-menu
24-
@click.native.stop
25-
v-if="dropdownMenu"
26-
class="group-dropdown-menu"
27-
trigger="click"
28-
align="left"
29-
>
30-
<template #dropdown-trigger>
31-
<div class="more-operation-btn">
32-
<bk-icon type="more" />
33-
</div>
34-
</template>
35-
36-
<template #dropdown-content>
37-
<ul class="bk-dropdown-list" v-if="visibleCommands.length">
38-
<li v-for="(cmd, cmdIndex) in visibleCommands" :key="cmdIndex">
39-
<!-- 带权限的按钮 -->
40-
<cmdb-auth
41-
v-if="cmd.auth"
42-
:auth="cmd.auth"
43-
@update-auth="cmd.onUpdateAuth"
44-
>
45-
<template #default="{ disabled: authDisabled }">
46-
<dropdown-option-button
47-
v-bk-tooltips="{
48-
content: cmd.disabledTooltips,
49-
disabled: !cmd.disabled && cmd.disabledTooltips,
50-
placement: 'right'
51-
}"
52-
:disabled="authDisabled || cmd.disabled"
53-
@click="cmd.handler"
54-
>
55-
{{ cmd.text }}
56-
</dropdown-option-button>
57-
</template>
58-
</cmdb-auth>
59-
60-
<!-- 无权限按钮 -->
61-
<dropdown-option-button
62-
v-else
63-
:disabled="cmd.disabled"
64-
@click="cmd.handler"
65-
>
66-
{{ cmd.text }}
67-
</dropdown-option-button>
68-
</li>
69-
</ul>
70-
</template>
71-
</bk-dropdown-menu>
23+
<div class="more-operation-btn" v-if="dropdownMenu" @click.stop="handleClick">
24+
<bk-icon type="more" />
25+
</div>
7226
<bk-tag v-if="isNewClassify" theme="success" radius="2px">{{$t('新的')}}</bk-tag>
7327
</div>
7428
</template>
@@ -127,7 +81,7 @@
12781
default: false
12882
}
12983
},
130-
setup(props) {
84+
setup(props, { emit }) {
13185
const isDropdownVisible = ref(false)
13286
const commandsRef = toRef(props, 'commands')
13387
const visibleCommands = computed(() => commandsRef.value.map((cmd) => {
@@ -148,9 +102,13 @@
148102
})
149103
.filter(cmd => cmd.visible))
150104

105+
const handleClick = (event) => {
106+
emit('showOperation', event, visibleCommands.value)
107+
}
151108
return {
152109
visibleCommands,
153110
isDropdownVisible,
111+
handleClick
154112
}
155113
},
156114
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<!--
2+
* Tencent is pleased to support the open source community by making 蓝鲸 available.
3+
* Copyright (C) 2017-2022 THL A29 Limited, a Tencent company. All rights reserved.
4+
* Licensed under the MIT License (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
* http://opensource.org/licenses/MIT
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
9+
* either express or implied. See the License for the specific language governing permissions and
10+
* limitations under the License.
11+
-->
12+
13+
<script setup>
14+
import { reactive, ref, watch } from 'vue'
15+
import { $bkPopover } from '@/magicbox/index.js'
16+
import DropdownOptionButton from './dropdown-option-button.vue'
17+
18+
const props = defineProps({
19+
commands: {
20+
type: Array,
21+
default: () => ([])
22+
},
23+
show: Boolean,
24+
target: [Element, null]
25+
})
26+
27+
const emit = defineEmits(['hide'])
28+
29+
const content = ref(null)
30+
31+
const operateModelPopover = reactive({
32+
instance: null,
33+
})
34+
35+
const showModelOperation = () => {
36+
const { target } = props
37+
operateModelPopover.instance?.destroy?.()
38+
operateModelPopover.instance = $bkPopover(target, {
39+
content: content.value,
40+
delay: 0,
41+
hideOnClick: true,
42+
placement: 'bottom',
43+
animateFill: false,
44+
sticky: true,
45+
theme: 'light bound-model-popover',
46+
boundary: 'window',
47+
trigger: 'manual', // 'manual mouseenter',
48+
arrow: true,
49+
onHidden: () => {
50+
emit('hide')
51+
}
52+
})
53+
54+
operateModelPopover.instance.show()
55+
}
56+
57+
watch(()=> props.show, (val)=> {
58+
if(val) showModelOperation()
59+
})
60+
</script>
61+
62+
<template>
63+
<ul class="bk-dropdown-list" ref="content">
64+
<li v-for="(cmd, cmdIndex) in props.commands" :key="cmdIndex">
65+
<!-- 带权限的按钮 -->
66+
<cmdb-auth
67+
v-if="cmd.auth"
68+
:auth="cmd.auth"
69+
@update-auth="cmd.onUpdateAuth"
70+
>
71+
<template #default="{ disabled: authDisabled }">
72+
<dropdown-option-button
73+
v-bk-tooltips="{
74+
content: cmd.disabledTooltips,
75+
disabled: !cmd.disabled && cmd.disabledTooltips,
76+
placement: 'right'
77+
}"
78+
:disabled="authDisabled || cmd.disabled"
79+
@click="cmd.handler"
80+
>
81+
{{ cmd.text }}
82+
</dropdown-option-button>
83+
</template>
84+
</cmdb-auth>
85+
<!-- 无权限按钮 -->
86+
<dropdown-option-button
87+
v-else
88+
:disabled="cmd.disabled"
89+
@click="cmd.handler"
90+
>
91+
{{ cmd.text }}
92+
</dropdown-option-button>
93+
</li>
94+
</ul>
95+
</template>

‎src/ui/src/views/model-manage/index.vue

+34-4
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,10 @@
148148
<collapse-group-title
149149
:is-new-classify="classification.isNewClassify"
150150
:dropdown-menu="!isModelSelectable"
151-
:collapse=" classificationsCollapseState[classification.id]"
151+
:collapse="classificationsCollapseState[classification.id]"
152152
:title="`${classification.bk_classification_name} ( ${ classification.bk_objects.length} )`"
153153
@click.native="toggleModelList(classification)"
154+
@showOperation="handleShowOperation"
154155
:commands="groupCommands(classification)"
155156
v-bk-tooltips="{
156157
disabled: !isBuiltinClass(classification),
@@ -171,7 +172,7 @@
171172
:class="{
172173
'is-empty': isGroupEmpty(classification)
173174
}"
174-
v-show="!classificationsCollapseState[classification.id]"
175+
v-show="getShow(classification.id)"
175176
tag="div"
176177
:sort="false"
177178
:animation="200"
@@ -422,6 +423,14 @@
422423
@cancel="doubleCheckCancelImport"
423424
@done="doneImport">
424425
</model-import-pane>
426+
427+
<model-operation-list
428+
:show="modelOperationList.show"
429+
:commands="modelOperationList.commands"
430+
:target="modelOperationList.target"
431+
@hide="handleHide">
432+
</model-operation-list>
433+
425434
</div>
426435
</template>
427436

@@ -435,6 +444,7 @@
435444
import Draggable from 'vuedraggable'
436445
import ModelExportPane from './children/model-import-export/model-export-pane/index.vue'
437446
import ModelImportPane from './children/model-import-export//model-import-pane/index.vue'
447+
import ModelOperationList from './children/model-operation-list.vue'
438448
import {
439449
MENU_RESOURCE_INSTANCE,
440450
MENU_MODEL_DETAILS,
@@ -461,7 +471,8 @@
461471
CollapseGroupTitle,
462472
Draggable,
463473
ModelExportPane,
464-
ModelImportPane
474+
ModelImportPane,
475+
ModelOperationList
465476
},
466477
data() {
467478
return {
@@ -524,7 +535,13 @@
524535
}
525536
},
526537

527-
editAuthResult: {}
538+
editAuthResult: {},
539+
540+
modelOperationList: {
541+
show: false,
542+
commands: [],
543+
target: null
544+
}
528545
}
529546
},
530547
computed: {
@@ -700,6 +717,19 @@
700717
'deleteClassification',
701718
]),
702719
...mapActions('objectModel', ['createObject', 'updateObject']),
720+
getShow(id) {
721+
return !this.classificationsCollapseState[id]
722+
},
723+
handleShowOperation(event, commands) {
724+
this.modelOperationList.show = true
725+
this.modelOperationList.commands = commands
726+
this.modelOperationList.target = event?.target
727+
},
728+
handleHide() {
729+
this.modelOperationList.show = false
730+
this.modelOperationList.commands = []
731+
this.modelOperationList.target = null
732+
},
703733
inputChange(val) {
704734
// 在输入过程中如果是中文输入法 不让modelSearchKey变化
705735
if (this.isComposition) {

0 commit comments

Comments
 (0)
Please sign in to comment.