feat(cmdb-ui):多对多关系&&仪表盘色卡调整 (#271)

This commit is contained in:
wang-liang0615 2023-11-24 10:25:56 +08:00 committed by GitHub
parent 2699c263d9
commit 91555ffa64
10 changed files with 253 additions and 114 deletions

View File

@ -1,13 +1,13 @@
import { axios } from '@/utils/request'
export function getFirstCIs(ciId) {
export function getFirstCIsByCiId(ciId) {
return axios({
url: '/v0.1/ci_relations/' + ciId + '/first_cis',
method: 'GET'
})
}
export function getSecondCIs(ciId) {
export function getSecondCIsByCiId(ciId) {
return axios({
url: '/v0.1/ci_relations/' + ciId + '/second_cis',
method: 'GET'
@ -30,11 +30,11 @@ export function statisticsCIRelation(params) {
}
// 批量添加子节点
export function batchUpdateCIRelationChildren(ciIds, parents) {
export function batchUpdateCIRelationChildren(ciIds, parents, ancestor_ids = undefined) {
return axios({
url: '/v0.1/ci_relations/batch',
method: 'POST',
data: { ci_ids: ciIds, parents: parents }
data: { ci_ids: ciIds, parents, ancestor_ids }
})
}
@ -48,26 +48,28 @@ export function batchUpdateCIRelationParents(ciIds, children) {
}
// 批量删除
export function batchDeleteCIRelation(ciIds, parents) {
export function batchDeleteCIRelation(ciIds, parents, ancestor_ids = undefined) {
return axios({
url: '/v0.1/ci_relations/batch',
method: 'DELETE',
data: { ci_ids: ciIds, parents: parents }
data: { ci_ids: ciIds, parents, ancestor_ids }
})
}
// 单个添加
export function addCIRelationView(firstCiId, secondCiId) {
export function addCIRelationView(firstCiId, secondCiId, data) {
return axios({
url: `/v0.1/ci_relations/${firstCiId}/${secondCiId}`,
method: 'POST',
data
})
}
// 单个删除
export function deleteCIRelationView(firstCiId, secondCiId) {
export function deleteCIRelationView(firstCiId, secondCiId, data) {
return axios({
url: `/v0.1/ci_relations/${firstCiId}/${secondCiId}`,
method: 'DELETE',
data
})
}

View File

@ -68,3 +68,10 @@ export function getRecursive_level2children(type_id) {
method: 'GET'
})
}
export function getCanEditByParentIdChildId(parent_id, child_id) {
return axios({
url: `/v0.1/ci_type_relations/${parent_id}/${child_id}/can_edit`,
method: 'GET'
})
}

View File

@ -40,7 +40,7 @@
全选
</a-checkbox>
<br />
<a-checkbox-group v-model="checkedAttrs">
<a-checkbox-group style="width:100%" v-model="checkedAttrs">
<a-row>
<a-col :span="6" v-for="item in selectCiTypeAttrList.attributes" :key="item.alias || item.name">
<a-checkbox :disabled="item.name === selectCiTypeAttrList.unique" :value="item.alias || item.name">
@ -87,10 +87,11 @@
</template>
<script>
import _ from 'lodash'
import { downloadExcel } from '../../../utils/helper'
import { getCITypes } from '@/modules/cmdb/api/CIType'
import { getCITypeAttributesById } from '@/modules/cmdb/api/CITypeAttr'
import { getCITypeParent } from '@/modules/cmdb/api/CITypeRelation'
import { getCITypeParent, getCanEditByParentIdChildId } from '@/modules/cmdb/api/CITypeRelation'
export default {
name: 'CiTypeChoice',
@ -107,6 +108,7 @@ export default {
parentsType: [],
parentsForm: {},
checkedParents: [],
canEdit: {},
}
},
created: function() {
@ -143,8 +145,17 @@ export default {
},
openModal() {
getCITypeParent(this.selectNum).then((res) => {
this.parentsType = res.parents
getCITypeParent(this.selectNum).then(async (res) => {
for (let i = 0; i < res.parents.length; i++) {
await getCanEditByParentIdChildId(res.parents[i].id, this.selectNum).then((p_res) => {
this.canEdit = {
..._.cloneDeep(this.canEdit),
[res.parents[i].id]: p_res.result,
}
})
}
this.parentsType = res.parents.filter((parent) => this.canEdit[parent.id])
const _parentsForm = {}
res.parents.forEach((item) => {
const _find = item.attributes.find((attr) => attr.id === item.unique_id)

View File

@ -122,12 +122,12 @@
<a-button type="primary" ghost icon="plus" @click="handleAdd">新增修改字段</a-button>
</a-form>
</template>
<!-- </a-form> -->
<JsonEditor ref="jsonEditor" @jsonEditorOk="jsonEditorOk" />
</CustomDrawer>
</template>
<script>
import _ from 'lodash'
import moment from 'moment'
import { Select, Option } from 'element-ui'
import { getCIType, getCITypeGroupById } from '@/modules/cmdb/api/CIType'
@ -135,7 +135,7 @@ import { addCI } from '@/modules/cmdb/api/ci'
import JsonEditor from '../../../components/JsonEditor/jsonEditor.vue'
import { valueTypeMap } from '../../../utils/const'
import CreateInstanceFormByGroup from './createInstanceFormByGroup.vue'
import { getCITypeParent } from '@/modules/cmdb/api/CITypeRelation'
import { getCITypeParent, getCanEditByParentIdChildId } from '@/modules/cmdb/api/CITypeRelation'
export default {
name: 'CreateInstanceForm',
@ -166,6 +166,7 @@ export default {
attributesByGroup: [],
parentsType: [],
parentsForm: {},
canEdit: {},
}
},
computed: {
@ -300,8 +301,16 @@ export default {
this.batchUpdateLists = [{ name: this.attributeList[0].name }]
})
if (action === 'create') {
getCITypeParent(this.typeId).then((res) => {
this.parentsType = res.parents
getCITypeParent(this.typeId).then(async (res) => {
for (let i = 0; i < res.parents.length; i++) {
await getCanEditByParentIdChildId(res.parents[i].id, this.typeId).then((p_res) => {
this.canEdit = {
..._.cloneDeep(this.canEdit),
[res.parents[i].id]: p_res.result,
}
})
}
this.parentsType = res.parents.filter((parent) => this.canEdit[parent.id])
const _parentsForm = {}
res.parents.forEach((item) => {
const _find = item.attributes.find((attr) => attr.id === item.unique_id)

View File

@ -15,6 +15,7 @@
<div class="ci-detail-relation-table-title">
{{ parent.alias || parent.name }}
<a
:disabled="!canEdit[parent.id]"
@click="
() => {
$refs.addTableModal.openModal({ [`${ci.unique}`]: ci[ci.unique] }, ci._id, parent.id, 'parents')
@ -23,6 +24,7 @@
><a-icon
type="plus-square"
/></a>
<span v-if="!canEdit[parent.id]">当前模型关系为多对多请前往关系视图进行增删操作</span>
</div>
<vxe-grid
v-if="firstCIs[parent.name]"
@ -38,7 +40,14 @@
>
<template #operation_default="{ row }">
<a-popconfirm arrowPointAtCenter title="确认删除关系?" @confirm="deleteRelation(row._id, ciId)">
<a :style="{ color: 'red' }"><a-icon type="delete"/></a>
<a
:disabled="!canEdit[parent.id]"
:style="{
color: !canEdit[parent.id] ? 'rgba(0, 0, 0, 0.25)' : 'red',
}"
><a-icon
type="delete"
/></a>
</a-popconfirm>
</template>
</vxe-grid>
@ -50,6 +59,7 @@
<div class="ci-detail-relation-table-title">
{{ child.alias || child.name }}
<a
:disabled="!canEdit[child.id]"
@click="
() => {
$refs.addTableModal.openModal({ [`${ci.unique}`]: ci[ci.unique] }, ci._id, child.id, 'children')
@ -58,6 +68,7 @@
><a-icon
type="plus-square"
/></a>
<span v-if="!canEdit[child.id]">当前模型关系为多对多请前往关系视图进行增删操作</span>
</div>
<vxe-grid
v-if="secondCIs[child.name]"
@ -72,7 +83,14 @@
>
<template #operation_default="{ row }">
<a-popconfirm arrowPointAtCenter title="确认删除关系?" @confirm="deleteRelation(ciId, row._id)">
<a :style="{ color: 'red' }"><a-icon type="delete"/></a>
<a
:disabled="!canEdit[child.id]"
:style="{
color: !canEdit[child.id] ? 'rgba(0, 0, 0, 0.25)' : 'red',
}"
><a-icon
type="delete"
/></a>
</a-popconfirm>
</template>
</vxe-grid>
@ -85,7 +103,7 @@
<script>
import _ from 'lodash'
import { getCITypeChildren, getCITypeParent } from '@/modules/cmdb/api/CITypeRelation'
import { getCITypeChildren, getCITypeParent, getCanEditByParentIdChildId } from '@/modules/cmdb/api/CITypeRelation'
import { searchCIRelation, deleteCIRelationView } from '@/modules/cmdb/api/CIRelation'
import CiDetailRelationTopo from './ciDetailRelationTopo/index.vue'
import Node from './ciDetailRelationTopo/node.js'
@ -118,6 +136,7 @@ export default {
secondCIColumns: {},
firstCIJsonAttr: {},
secondCIJsonAttr: {},
canEdit: {},
}
},
computed: {
@ -293,10 +312,16 @@ export default {
.catch((e) => {})
},
async getParentCITypes() {
await getCITypeParent(this.typeId)
.then((res) => {
const res = await getCITypeParent(this.typeId)
this.parentCITypes = res.parents
for (let i = 0; i < res.parents.length; i++) {
await getCanEditByParentIdChildId(res.parents[i].id, this.typeId).then((p_res) => {
this.canEdit = {
..._.cloneDeep(this.canEdit),
[res.parents[i].id]: p_res.result,
}
})
}
const firstCIColumns = {}
const firstCIJsonAttr = {}
res.parents.forEach((item) => {
@ -325,14 +350,19 @@ export default {
this.firstCIColumns = firstCIColumns
this.firstCIJsonAttr = firstCIJsonAttr
})
.catch((e) => {})
},
async getChildCITypes() {
await getCITypeChildren(this.typeId)
.then((res) => {
this.childCITypes = res.children
const res = await getCITypeChildren(this.typeId)
this.childCITypes = res.children
for (let i = 0; i < res.children.length; i++) {
await getCanEditByParentIdChildId(this.typeId, res.children[i].id).then((c_res) => {
this.canEdit = {
..._.cloneDeep(this.canEdit),
[res.children[i].id]: c_res.result,
}
})
}
const secondCIColumns = {}
const secondCIJsonAttr = {}
res.children.forEach((item) => {
@ -361,8 +391,6 @@ export default {
this.secondCIColumns = secondCIColumns
this.secondCIJsonAttr = secondCIJsonAttr
})
.catch((e) => {})
},
reload() {
this.init()

View File

@ -372,7 +372,7 @@ export default {
width: 3,
fontColor: '#ffffff',
bgColor: ['#6ABFFE', '#5375EB'],
chartColor: '#6592FD,#6EE3EB,#44C2FD,#5F59F7,#1A348F,#7D8FCF,#A6D1E5,#8E56DD', // 图表颜色
chartColor: '#5DADF2,#86DFB7,#5A6F96,#7BD5FF,#FFB980,#4D58D6,#D9B6E9,#8054FF', // 图表颜色
isShowPreview: false,
filterExp: undefined,
previewData: null,
@ -410,7 +410,7 @@ export default {
this.width = width
this.chartType = chartType
this.filterExp = item?.options?.filter ?? ''
this.chartColor = item?.options?.chartColor ?? '#6592FD,#6EE3EB,#44C2FD,#5F59F7,#1A348F,#7D8FCF,#A6D1E5,#8E56DD'
this.chartColor = item?.options?.chartColor ?? '#5DADF2,#86DFB7,#5A6F96,#7BD5FF,#FFB980,#4D58D6,#D9B6E9,#8054FF'
this.isShadow = item?.options?.isShadow ?? false
if (chartType === 'count') {

View File

@ -24,7 +24,7 @@ export const category_1_bar_options = (data, options) => {
})
return {
color: (options?.chartColor ?? '#6592FD,#6EE3EB,#44C2FD,#5F59F7,#1A348F,#7D8FCF,#A6D1E5,#8E56DD').split(','),
color: (options?.chartColor ?? '#5DADF2,#86DFB7,#5A6F96,#7BD5FF,#FFB980,#4D58D6,#D9B6E9,#8054FF').split(','),
grid: {
top: 15,
left: 'left',
@ -83,7 +83,7 @@ export const category_1_bar_options = (data, options) => {
export const category_1_line_options = (data, options) => {
const xData = Object.keys(data)
return {
color: (options?.chartColor ?? '#6592FD,#6EE3EB,#44C2FD,#5F59F7,#1A348F,#7D8FCF,#A6D1E5,#8E56DD').split(','),
color: (options?.chartColor ?? '#5DADF2,#86DFB7,#5A6F96,#7BD5FF,#FFB980,#4D58D6,#D9B6E9,#8054FF').split(','),
grid: {
top: 15,
left: 'left',
@ -117,7 +117,7 @@ export const category_1_line_options = (data, options) => {
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: (options?.chartColor ?? '#6592FD,#6EE3EB,#44C2FD,#5F59F7,#1A348F,#7D8FCF,#A6D1E5,#8E56DD').split(',')[0] // 0% 处的颜色
offset: 0, color: (options?.chartColor ?? '#5DADF2,#86DFB7,#5A6F96,#7BD5FF,#FFB980,#4D58D6,#D9B6E9,#8054FF').split(',')[0] // 0% 处的颜色
}, {
offset: 1, color: '#ffffff' // 100% 处的颜色
}],
@ -131,7 +131,7 @@ export const category_1_line_options = (data, options) => {
export const category_1_pie_options = (data, options) => {
return {
color: (options?.chartColor ?? '#6592FD,#6EE3EB,#44C2FD,#5F59F7,#1A348F,#7D8FCF,#A6D1E5,#8E56DD').split(','),
color: (options?.chartColor ?? '#5DADF2,#86DFB7,#5A6F96,#7BD5FF,#FFB980,#4D58D6,#D9B6E9,#8054FF').split(','),
grid: {
top: 10,
left: 'left',
@ -181,7 +181,7 @@ export const category_2_bar_options = (data, options, chartType) => {
})
const legend = [...new Set(_legend)]
return {
color: (options?.chartColor ?? '#6592FD,#6EE3EB,#44C2FD,#5F59F7,#1A348F,#7D8FCF,#A6D1E5,#8E56DD').split(','),
color: (options?.chartColor ?? '#5DADF2,#86DFB7,#5A6F96,#7BD5FF,#FFB980,#4D58D6,#D9B6E9,#8054FF').split(','),
grid: {
top: 15,
left: 'left',
@ -249,7 +249,7 @@ export const category_2_bar_options = (data, options, chartType) => {
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: (options?.chartColor ?? '#6592FD,#6EE3EB,#44C2FD,#5F59F7,#1A348F,#7D8FCF,#A6D1E5,#8E56DD').split(',')[index % 8] // 0% 处的颜色
offset: 0, color: (options?.chartColor ?? '#5DADF2,#86DFB7,#5A6F96,#7BD5FF,#FFB980,#4D58D6,#D9B6E9,#8054FF').split(',')[index % 8] // 0% 处的颜色
}, {
offset: 1, color: '#ffffff' // 100% 处的颜色
}],
@ -269,7 +269,7 @@ export const category_2_pie_options = (data, options) => {
})
})
return {
color: (options?.chartColor ?? '#6592FD,#6EE3EB,#44C2FD,#5F59F7,#1A348F,#7D8FCF,#A6D1E5,#8E56DD').split(','),
color: (options?.chartColor ?? '#5DADF2,#86DFB7,#5A6F96,#7BD5FF,#FFB980,#4D58D6,#D9B6E9,#8054FF').split(','),
grid: {
top: 15,
left: 'left',

View File

@ -24,10 +24,8 @@ export default {
data() {
return {
list: [
'#6592FD,#6EE3EB,#44C2FD,#5F59F7,#1A348F,#7D8FCF,#A6D1E5,#8E56DD',
'#C1A9DC,#E2B5CD,#EE8EBC,#8483C3,#4D66BD,#213764,#D9B6E9,#DD88EB',
'#6FC4DF,#9FE8CE,#16B4BE,#86E6FB,#1871A3,#E1BF8D,#ED8D8D,#DD88EB',
'#F8B751,#FC9054,#FFE380,#DF963F,#AB5200,#EA9387,#FFBB7C,#D27467',
'#5DADF2,#86DFB7,#5A6F96,#7BD5FF,#FFB980,#4D58D6,#D9B6E9,#8054FF',
'#9BA1F9,#0F2BA8,#A2EBFE,#4982F6,#FEB09C,#6C78E8,#FFDDAB,#4D66BD',
],
}
},

View File

@ -392,6 +392,7 @@ export default {
origShowTypes: [],
leaf2showTypes: {},
node2ShowTypes: {},
level2constraint: {},
leaf: [],
typeId: null,
viewId: null,
@ -595,6 +596,17 @@ export default {
}
} else {
q += `&root_id=${this.treeKeys[this.treeKeys.length - 1].split('%')[0]}`
if (
Object.keys(this.level2constraint).some(
(le) => le < Object.keys(this.level2constraint).length && this.level2constraint[le] === '2'
)
) {
q += `&ancestor_ids=${this.treeKeys
.slice(0, this.treeKeys.length - 1)
.map((item) => item.split('%')[0])
.join(',')}`
}
const typeId = parseInt(this.treeKeys[this.treeKeys.length - 1].split('%')[1])
let level = []
@ -649,7 +661,19 @@ export default {
if (refreshType === 'refreshNumber') {
const promises = this.treeKeys.map((key, index) => {
let ancestor_ids
if (
Object.keys(this.level2constraint).some(
(le) => le < Object.keys(this.level2constraint).length && this.level2constraint[le] === '2'
)
) {
ancestor_ids = `${this.treeKeys
.slice(0, index)
.map((item) => item.split('%')[0])
.join(',')}`
}
statisticsCIRelation({
ancestor_ids,
root_ids: key.split('%')[0],
level: this.treeKeys.length - index,
type_ids: this.showTypes.map((type) => type.id).join(','),
@ -780,16 +804,36 @@ export default {
const index = topo_flatten.findIndex((id) => id === typeId)
const _type = topo_flatten[index + 1]
if (_type) {
searchCIRelation(`q=_type:${_type}&root_id=${rootId}&level=1&count=10000`).then(async (res) => {
let q = `q=_type:${_type}&root_id=${rootId}&level=1&count=10000`
if (
Object.keys(this.level2constraint).some(
(le) => le < Object.keys(this.level2constraint).length && this.level2constraint[le] === '2'
)
) {
q += `&ancestor_ids=${this.treeKeys
.slice(0, this.treeKeys.length - 1)
.map((item) => item.split('%')[0])
.join(',')}`
}
searchCIRelation(q).then(async (res) => {
const facet = []
const ciIds = []
res.result.forEach((item) => {
facet.push([item[item.unique], 0, item._id, item._type, item.unique])
ciIds.push(item._id)
})
let ancestor_ids
if (
Object.keys(this.level2constraint).some(
(le) => le < Object.keys(this.level2constraint).length && this.level2constraint[le] === '2'
)
) {
ancestor_ids = `${this.treeKeys.map((item) => item.split('%')[0]).join(',')}`
}
const promises = level.map((_level) => {
if (_level > 1) {
return statisticsCIRelation({
ancestor_ids,
root_ids: ciIds.join(','),
level: _level - 1,
type_ids: this.showTypes.map((type) => type.id).join(','),
@ -889,6 +933,7 @@ export default {
this.origShowTypeIds = showTypeIds
this.leaf2showTypes = this.relationViews.views[this.viewName].leaf2show_types
this.node2ShowTypes = this.relationViews.views[this.viewName].node2show_types
this.level2constraint = this.relationViews.views[this.viewName].level2constraint
this.leaf = this.relationViews.views[this.viewName].leaf
this.currentView = `${this.viewId}`
this.typeId = this.levels[0][0]
@ -923,6 +968,17 @@ export default {
const _tempTree = splitTreeKey[splitTreeKey.length - 1].split('%')
const firstCIObj = JSON.parse(_tempTree[2])
const firstCIId = _tempTree[0]
let ancestor_ids
if (
Object.keys(this.level2constraint).some(
(le) => le < Object.keys(this.level2constraint).length && this.level2constraint[le] === '2'
)
) {
const ancestor = treeKey
.split('@^@')
.slice(0, menuKey === 'delete' ? treeKey.split('@^@').length - 2 : treeKey.split('@^@').length - 1)
ancestor_ids = ancestor.map((item) => item.split('%')[0]).join(',')
}
if (menuKey === 'delete') {
const _tempTreeParent = splitTreeKey[splitTreeKey.length - 2].split('%')
const that = this
@ -935,16 +991,17 @@ export default {
</div>
),
onOk() {
deleteCIRelationView(_tempTreeParent[0], _tempTree[0]).then((res) => {
deleteCIRelationView(_tempTreeParent[0], _tempTree[0], { ancestor_ids }).then((res) => {
that.$message.success('删除成功!')
setTimeout(() => {
that.reload()
}, 500)
})
},
})
} else {
const childTypeId = menuKey
console.log(menuKey)
this.$refs.addTableModal.openModal(firstCIObj, firstCIId, childTypeId, 'children')
this.$refs.addTableModal.openModal(firstCIObj, firstCIId, childTypeId, 'children', ancestor_ids)
}
}
},
@ -964,9 +1021,21 @@ export default {
onOk() {
const _tempTree = that.treeKeys[that.treeKeys.length - 1].split('%')
const first_ci_id = Number(_tempTree[0])
let ancestor_ids
if (
Object.keys(that.level2constraint).some(
(le) => le < Object.keys(that.level2constraint).length && that.level2constraint[le] === '2'
)
) {
ancestor_ids = `${that.treeKeys
.slice(0, that.treeKeys.length - 1)
.map((item) => item.split('%')[0])
.join(',')}`
}
batchDeleteCIRelation(
that.selectedRowKeys.map((item) => item._id),
[first_ci_id]
[first_ci_id],
ancestor_ids
).then((res) => {
that.$refs.xTable.clearCheckboxRow()
that.$refs.xTable.clearCheckboxReserve()
@ -1130,7 +1199,10 @@ export default {
const $table = this.$refs['xTable']
const data = {}
this.columns.forEach((item) => {
if (!(item.field in this.initialPasswordValue) && !_.isEqual(row[item.field], this.initialInstanceList[rowIndex][item.field])) {
if (
!(item.field in this.initialPasswordValue) &&
!_.isEqual(row[item.field], this.initialInstanceList[rowIndex][item.field])
) {
data[item.field] = row[item.field] ?? null
}
})
@ -1180,7 +1252,18 @@ export default {
},
sumbitFromCreateInstance({ ci_id }) {
const first_ci_id = this.treeKeys[this.treeKeys.length - 1].split('%')[0]
addCIRelationView(first_ci_id, ci_id).then((res) => {
let ancestor_ids
if (
Object.keys(this.level2constraint).some(
(le) => le < Object.keys(this.level2constraint).length && this.level2constraint[le] === '2'
)
) {
ancestor_ids = `${this.treeKeys
.slice(0, this.treeKeys.length - 1)
.map((item) => item.split('%')[0])
.join(',')}`
}
addCIRelationView(first_ci_id, ci_id, { ancestor_ids }).then((res) => {
setTimeout(() => {
this.loadData({}, 'refreshNumber')
}, 500)
@ -1270,9 +1353,7 @@ export default {
})
Promise.all(promises)
.then((res) => {
that.$message.success({
message: '删除成功',
})
that.$message.success('删除成功')
})
.catch((e) => {
console.log(e)

View File

@ -86,6 +86,7 @@ export default {
isFocusExpression: false,
type: 'children',
preferenceAttrList: [],
ancestor_ids: undefined,
}
},
computed: {
@ -101,13 +102,13 @@ export default {
},
watch: {},
methods: {
async openModal(ciObj, ciId, addTypeId, type) {
console.log(ciObj, addTypeId)
async openModal(ciObj, ciId, addTypeId, type, ancestor_ids = undefined) {
this.visible = true
this.ciObj = ciObj
this.ciId = ciId
this.addTypeId = addTypeId
this.type = type
this.ancestor_ids = ancestor_ids
await getSubscribeAttributes(addTypeId).then((res) => {
this.preferenceAttrList = res.attributes // 已经订阅的全部列
})
@ -168,13 +169,15 @@ export default {
const ciIds = [...selectRecordsCurrent, ...selectRecordsReserved].map((record) => record._id)
if (ciIds.length) {
if (this.type === 'children') {
await batchUpdateCIRelationChildren(ciIds, [this.ciId])
await batchUpdateCIRelationChildren(ciIds, [this.ciId], this.ancestor_ids)
} else {
await batchUpdateCIRelationParents(ciIds, [this.ciId])
}
setTimeout(() => {
this.$message.success('添加成功!')
this.handleClose()
this.$emit('reload')
}, 500)
}
},
handleSearch() {