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' import { axios } from '@/utils/request'
export function getFirstCIs(ciId) { export function getFirstCIsByCiId(ciId) {
return axios({ return axios({
url: '/v0.1/ci_relations/' + ciId + '/first_cis', url: '/v0.1/ci_relations/' + ciId + '/first_cis',
method: 'GET' method: 'GET'
}) })
} }
export function getSecondCIs(ciId) { export function getSecondCIsByCiId(ciId) {
return axios({ return axios({
url: '/v0.1/ci_relations/' + ciId + '/second_cis', url: '/v0.1/ci_relations/' + ciId + '/second_cis',
method: 'GET' 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({ return axios({
url: '/v0.1/ci_relations/batch', url: '/v0.1/ci_relations/batch',
method: 'POST', 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({ return axios({
url: '/v0.1/ci_relations/batch', url: '/v0.1/ci_relations/batch',
method: 'DELETE', 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({ return axios({
url: `/v0.1/ci_relations/${firstCiId}/${secondCiId}`, url: `/v0.1/ci_relations/${firstCiId}/${secondCiId}`,
method: 'POST', method: 'POST',
data
}) })
} }
// 单个删除 // 单个删除
export function deleteCIRelationView(firstCiId, secondCiId) { export function deleteCIRelationView(firstCiId, secondCiId, data) {
return axios({ return axios({
url: `/v0.1/ci_relations/${firstCiId}/${secondCiId}`, url: `/v0.1/ci_relations/${firstCiId}/${secondCiId}`,
method: 'DELETE', method: 'DELETE',
data
}) })
} }

View File

@ -68,3 +68,10 @@ export function getRecursive_level2children(type_id) {
method: 'GET' 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> </a-checkbox>
<br /> <br />
<a-checkbox-group v-model="checkedAttrs"> <a-checkbox-group style="width:100%" v-model="checkedAttrs">
<a-row> <a-row>
<a-col :span="6" v-for="item in selectCiTypeAttrList.attributes" :key="item.alias || item.name"> <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"> <a-checkbox :disabled="item.name === selectCiTypeAttrList.unique" :value="item.alias || item.name">
@ -87,10 +87,11 @@
</template> </template>
<script> <script>
import _ from 'lodash'
import { downloadExcel } from '../../../utils/helper' import { downloadExcel } from '../../../utils/helper'
import { getCITypes } from '@/modules/cmdb/api/CIType' import { getCITypes } from '@/modules/cmdb/api/CIType'
import { getCITypeAttributesById } from '@/modules/cmdb/api/CITypeAttr' import { getCITypeAttributesById } from '@/modules/cmdb/api/CITypeAttr'
import { getCITypeParent } from '@/modules/cmdb/api/CITypeRelation' import { getCITypeParent, getCanEditByParentIdChildId } from '@/modules/cmdb/api/CITypeRelation'
export default { export default {
name: 'CiTypeChoice', name: 'CiTypeChoice',
@ -107,6 +108,7 @@ export default {
parentsType: [], parentsType: [],
parentsForm: {}, parentsForm: {},
checkedParents: [], checkedParents: [],
canEdit: {},
} }
}, },
created: function() { created: function() {
@ -143,8 +145,17 @@ export default {
}, },
openModal() { openModal() {
getCITypeParent(this.selectNum).then((res) => { getCITypeParent(this.selectNum).then(async (res) => {
this.parentsType = res.parents 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 = {} const _parentsForm = {}
res.parents.forEach((item) => { res.parents.forEach((item) => {
const _find = item.attributes.find((attr) => attr.id === item.unique_id) 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-button type="primary" ghost icon="plus" @click="handleAdd">新增修改字段</a-button>
</a-form> </a-form>
</template> </template>
<!-- </a-form> -->
<JsonEditor ref="jsonEditor" @jsonEditorOk="jsonEditorOk" /> <JsonEditor ref="jsonEditor" @jsonEditorOk="jsonEditorOk" />
</CustomDrawer> </CustomDrawer>
</template> </template>
<script> <script>
import _ from 'lodash'
import moment from 'moment' import moment from 'moment'
import { Select, Option } from 'element-ui' import { Select, Option } from 'element-ui'
import { getCIType, getCITypeGroupById } from '@/modules/cmdb/api/CIType' 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 JsonEditor from '../../../components/JsonEditor/jsonEditor.vue'
import { valueTypeMap } from '../../../utils/const' import { valueTypeMap } from '../../../utils/const'
import CreateInstanceFormByGroup from './createInstanceFormByGroup.vue' import CreateInstanceFormByGroup from './createInstanceFormByGroup.vue'
import { getCITypeParent } from '@/modules/cmdb/api/CITypeRelation' import { getCITypeParent, getCanEditByParentIdChildId } from '@/modules/cmdb/api/CITypeRelation'
export default { export default {
name: 'CreateInstanceForm', name: 'CreateInstanceForm',
@ -166,6 +166,7 @@ export default {
attributesByGroup: [], attributesByGroup: [],
parentsType: [], parentsType: [],
parentsForm: {}, parentsForm: {},
canEdit: {},
} }
}, },
computed: { computed: {
@ -300,8 +301,16 @@ export default {
this.batchUpdateLists = [{ name: this.attributeList[0].name }] this.batchUpdateLists = [{ name: this.attributeList[0].name }]
}) })
if (action === 'create') { if (action === 'create') {
getCITypeParent(this.typeId).then((res) => { getCITypeParent(this.typeId).then(async (res) => {
this.parentsType = 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,
}
})
}
this.parentsType = res.parents.filter((parent) => this.canEdit[parent.id])
const _parentsForm = {} const _parentsForm = {}
res.parents.forEach((item) => { res.parents.forEach((item) => {
const _find = item.attributes.find((attr) => attr.id === item.unique_id) const _find = item.attributes.find((attr) => attr.id === item.unique_id)

View File

@ -15,6 +15,7 @@
<div class="ci-detail-relation-table-title"> <div class="ci-detail-relation-table-title">
{{ parent.alias || parent.name }} {{ parent.alias || parent.name }}
<a <a
:disabled="!canEdit[parent.id]"
@click=" @click="
() => { () => {
$refs.addTableModal.openModal({ [`${ci.unique}`]: ci[ci.unique] }, ci._id, parent.id, 'parents') $refs.addTableModal.openModal({ [`${ci.unique}`]: ci[ci.unique] }, ci._id, parent.id, 'parents')
@ -23,6 +24,7 @@
><a-icon ><a-icon
type="plus-square" type="plus-square"
/></a> /></a>
<span v-if="!canEdit[parent.id]">当前模型关系为多对多请前往关系视图进行增删操作</span>
</div> </div>
<vxe-grid <vxe-grid
v-if="firstCIs[parent.name]" v-if="firstCIs[parent.name]"
@ -38,7 +40,14 @@
> >
<template #operation_default="{ row }"> <template #operation_default="{ row }">
<a-popconfirm arrowPointAtCenter title="确认删除关系?" @confirm="deleteRelation(row._id, ciId)"> <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> </a-popconfirm>
</template> </template>
</vxe-grid> </vxe-grid>
@ -50,6 +59,7 @@
<div class="ci-detail-relation-table-title"> <div class="ci-detail-relation-table-title">
{{ child.alias || child.name }} {{ child.alias || child.name }}
<a <a
:disabled="!canEdit[child.id]"
@click=" @click="
() => { () => {
$refs.addTableModal.openModal({ [`${ci.unique}`]: ci[ci.unique] }, ci._id, child.id, 'children') $refs.addTableModal.openModal({ [`${ci.unique}`]: ci[ci.unique] }, ci._id, child.id, 'children')
@ -58,6 +68,7 @@
><a-icon ><a-icon
type="plus-square" type="plus-square"
/></a> /></a>
<span v-if="!canEdit[child.id]">当前模型关系为多对多请前往关系视图进行增删操作</span>
</div> </div>
<vxe-grid <vxe-grid
v-if="secondCIs[child.name]" v-if="secondCIs[child.name]"
@ -72,7 +83,14 @@
> >
<template #operation_default="{ row }"> <template #operation_default="{ row }">
<a-popconfirm arrowPointAtCenter title="确认删除关系?" @confirm="deleteRelation(ciId, row._id)"> <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> </a-popconfirm>
</template> </template>
</vxe-grid> </vxe-grid>
@ -85,7 +103,7 @@
<script> <script>
import _ from 'lodash' 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 { searchCIRelation, deleteCIRelationView } from '@/modules/cmdb/api/CIRelation'
import CiDetailRelationTopo from './ciDetailRelationTopo/index.vue' import CiDetailRelationTopo from './ciDetailRelationTopo/index.vue'
import Node from './ciDetailRelationTopo/node.js' import Node from './ciDetailRelationTopo/node.js'
@ -118,6 +136,7 @@ export default {
secondCIColumns: {}, secondCIColumns: {},
firstCIJsonAttr: {}, firstCIJsonAttr: {},
secondCIJsonAttr: {}, secondCIJsonAttr: {},
canEdit: {},
} }
}, },
computed: { computed: {
@ -293,76 +312,85 @@ export default {
.catch((e) => {}) .catch((e) => {})
}, },
async getParentCITypes() { async getParentCITypes() {
await getCITypeParent(this.typeId) const res = await getCITypeParent(this.typeId)
.then((res) => { this.parentCITypes = res.parents
this.parentCITypes = res.parents for (let i = 0; i < res.parents.length; i++) {
await getCanEditByParentIdChildId(res.parents[i].id, this.typeId).then((p_res) => {
const firstCIColumns = {} this.canEdit = {
const firstCIJsonAttr = {} ..._.cloneDeep(this.canEdit),
res.parents.forEach((item) => { [res.parents[i].id]: p_res.result,
const columns = [] }
const jsonAttr = []
item.attributes.forEach((attr) => {
columns.push({ key: 'p_' + attr.id, field: attr.name, title: attr.alias, minWidth: '100px' })
if (attr.value_type === '6') {
jsonAttr.push(attr.name)
}
})
firstCIJsonAttr[item.id] = jsonAttr
firstCIColumns[item.id] = columns
firstCIColumns[item.id].push({
key: 'p_operation',
field: 'operation',
title: '操作',
width: '60px',
fixed: 'right',
slots: {
default: 'operation_default',
},
align: 'center',
})
})
this.firstCIColumns = firstCIColumns
this.firstCIJsonAttr = firstCIJsonAttr
}) })
.catch((e) => {}) }
const firstCIColumns = {}
const firstCIJsonAttr = {}
res.parents.forEach((item) => {
const columns = []
const jsonAttr = []
item.attributes.forEach((attr) => {
columns.push({ key: 'p_' + attr.id, field: attr.name, title: attr.alias, minWidth: '100px' })
if (attr.value_type === '6') {
jsonAttr.push(attr.name)
}
})
firstCIJsonAttr[item.id] = jsonAttr
firstCIColumns[item.id] = columns
firstCIColumns[item.id].push({
key: 'p_operation',
field: 'operation',
title: '操作',
width: '60px',
fixed: 'right',
slots: {
default: 'operation_default',
},
align: 'center',
})
})
this.firstCIColumns = firstCIColumns
this.firstCIJsonAttr = firstCIJsonAttr
}, },
async getChildCITypes() { async getChildCITypes() {
await getCITypeChildren(this.typeId) const res = await getCITypeChildren(this.typeId)
.then((res) => {
this.childCITypes = res.children
const secondCIColumns = {} this.childCITypes = res.children
const secondCIJsonAttr = {} for (let i = 0; i < res.children.length; i++) {
res.children.forEach((item) => { await getCanEditByParentIdChildId(this.typeId, res.children[i].id).then((c_res) => {
const columns = [] this.canEdit = {
const jsonAttr = [] ..._.cloneDeep(this.canEdit),
item.attributes.forEach((attr) => { [res.children[i].id]: c_res.result,
columns.push({ key: 'c_' + attr.id, field: attr.name, title: attr.alias, minWidth: '100px' }) }
if (attr.value_type === '6') {
jsonAttr.push(attr.name)
}
})
secondCIJsonAttr[item.id] = jsonAttr
secondCIColumns[item.id] = columns
secondCIColumns[item.id].push({
key: 'c_operation',
field: 'operation',
title: '操作',
width: '60px',
fixed: 'right',
slots: {
default: 'operation_default',
},
align: 'center',
})
})
this.secondCIColumns = secondCIColumns
this.secondCIJsonAttr = secondCIJsonAttr
}) })
.catch((e) => {}) }
const secondCIColumns = {}
const secondCIJsonAttr = {}
res.children.forEach((item) => {
const columns = []
const jsonAttr = []
item.attributes.forEach((attr) => {
columns.push({ key: 'c_' + attr.id, field: attr.name, title: attr.alias, minWidth: '100px' })
if (attr.value_type === '6') {
jsonAttr.push(attr.name)
}
})
secondCIJsonAttr[item.id] = jsonAttr
secondCIColumns[item.id] = columns
secondCIColumns[item.id].push({
key: 'c_operation',
field: 'operation',
title: '操作',
width: '60px',
fixed: 'right',
slots: {
default: 'operation_default',
},
align: 'center',
})
})
this.secondCIColumns = secondCIColumns
this.secondCIJsonAttr = secondCIJsonAttr
}, },
reload() { reload() {
this.init() this.init()

View File

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

View File

@ -24,7 +24,7 @@ export const category_1_bar_options = (data, options) => {
}) })
return { 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: { grid: {
top: 15, top: 15,
left: 'left', left: 'left',
@ -83,7 +83,7 @@ export const category_1_bar_options = (data, options) => {
export const category_1_line_options = (data, options) => { export const category_1_line_options = (data, options) => {
const xData = Object.keys(data) const xData = Object.keys(data)
return { 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: { grid: {
top: 15, top: 15,
left: 'left', left: 'left',
@ -117,7 +117,7 @@ export const category_1_line_options = (data, options) => {
x2: 0, x2: 0,
y2: 1, y2: 1,
colorStops: [{ 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% 处的颜色 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) => { export const category_1_pie_options = (data, options) => {
return { 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: { grid: {
top: 10, top: 10,
left: 'left', left: 'left',
@ -181,7 +181,7 @@ export const category_2_bar_options = (data, options, chartType) => {
}) })
const legend = [...new Set(_legend)] const legend = [...new Set(_legend)]
return { 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: { grid: {
top: 15, top: 15,
left: 'left', left: 'left',
@ -249,7 +249,7 @@ export const category_2_bar_options = (data, options, chartType) => {
x2: 0, x2: 0,
y2: 1, y2: 1,
colorStops: [{ 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% 处的颜色 offset: 1, color: '#ffffff' // 100% 处的颜色
}], }],
@ -269,7 +269,7 @@ export const category_2_pie_options = (data, options) => {
}) })
}) })
return { 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: { grid: {
top: 15, top: 15,
left: 'left', left: 'left',

View File

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

View File

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

View File

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