diff --git a/cmdb-ui/src/modules/cmdb/api/CIRelation.js b/cmdb-ui/src/modules/cmdb/api/CIRelation.js index 468bad8..cc6f6e4 100644 --- a/cmdb-ui/src/modules/cmdb/api/CIRelation.js +++ b/cmdb-ui/src/modules/cmdb/api/CIRelation.js @@ -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 }) } diff --git a/cmdb-ui/src/modules/cmdb/api/CITypeRelation.js b/cmdb-ui/src/modules/cmdb/api/CITypeRelation.js index 3aaf654..c812506 100644 --- a/cmdb-ui/src/modules/cmdb/api/CITypeRelation.js +++ b/cmdb-ui/src/modules/cmdb/api/CITypeRelation.js @@ -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' + }) +} diff --git a/cmdb-ui/src/modules/cmdb/views/batch/modules/CiTypeChoice.vue b/cmdb-ui/src/modules/cmdb/views/batch/modules/CiTypeChoice.vue index 49686c7..5a7dc39 100644 --- a/cmdb-ui/src/modules/cmdb/views/batch/modules/CiTypeChoice.vue +++ b/cmdb-ui/src/modules/cmdb/views/batch/modules/CiTypeChoice.vue @@ -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) diff --git a/cmdb-ui/src/modules/cmdb/views/ci/modules/CreateInstanceForm.vue b/cmdb-ui/src/modules/cmdb/views/ci/modules/CreateInstanceForm.vue index aedfeca..ffadaa2 100644 --- a/cmdb-ui/src/modules/cmdb/views/ci/modules/CreateInstanceForm.vue +++ b/cmdb-ui/src/modules/cmdb/views/ci/modules/CreateInstanceForm.vue @@ -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) diff --git a/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelation.vue b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelation.vue index b862510..f89028c 100644 --- a/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelation.vue +++ b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelation.vue @@ -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,76 +312,85 @@ export default { .catch((e) => {}) }, async getParentCITypes() { - await getCITypeParent(this.typeId) - .then((res) => { - this.parentCITypes = res.parents - - 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 + 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, + } }) - .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() { - await getCITypeChildren(this.typeId) - .then((res) => { - this.childCITypes = res.children + const res = await getCITypeChildren(this.typeId) - 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 + 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, + } }) - .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() { this.init() diff --git a/cmdb-ui/src/modules/cmdb/views/custom_dashboard/chartForm.vue b/cmdb-ui/src/modules/cmdb/views/custom_dashboard/chartForm.vue index f96c9df..00ce9cd 100644 --- a/cmdb-ui/src/modules/cmdb/views/custom_dashboard/chartForm.vue +++ b/cmdb-ui/src/modules/cmdb/views/custom_dashboard/chartForm.vue @@ -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') { diff --git a/cmdb-ui/src/modules/cmdb/views/custom_dashboard/chartOptions.js b/cmdb-ui/src/modules/cmdb/views/custom_dashboard/chartOptions.js index 767bf0b..a256dbb 100644 --- a/cmdb-ui/src/modules/cmdb/views/custom_dashboard/chartOptions.js +++ b/cmdb-ui/src/modules/cmdb/views/custom_dashboard/chartOptions.js @@ -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', diff --git a/cmdb-ui/src/modules/cmdb/views/custom_dashboard/colorListPicker.vue b/cmdb-ui/src/modules/cmdb/views/custom_dashboard/colorListPicker.vue index d51f03b..400717b 100644 --- a/cmdb-ui/src/modules/cmdb/views/custom_dashboard/colorListPicker.vue +++ b/cmdb-ui/src/modules/cmdb/views/custom_dashboard/colorListPicker.vue @@ -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', ], } }, diff --git a/cmdb-ui/src/modules/cmdb/views/relation_views/index.vue b/cmdb-ui/src/modules/cmdb/views/relation_views/index.vue index 4be72b0..3310c5d 100644 --- a/cmdb-ui/src/modules/cmdb/views/relation_views/index.vue +++ b/cmdb-ui/src/modules/cmdb/views/relation_views/index.vue @@ -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('删除成功!') - that.reload() + 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) diff --git a/cmdb-ui/src/modules/cmdb/views/relation_views/modules/AddTableModal.vue b/cmdb-ui/src/modules/cmdb/views/relation_views/modules/AddTableModal.vue index 3621e91..10d7229 100644 --- a/cmdb-ui/src/modules/cmdb/views/relation_views/modules/AddTableModal.vue +++ b/cmdb-ui/src/modules/cmdb/views/relation_views/modules/AddTableModal.vue @@ -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]) } - this.$message.success('添加成功!') - this.handleClose() - this.$emit('reload') + setTimeout(() => { + this.$message.success('添加成功!') + this.handleClose() + this.$emit('reload') + }, 500) } }, handleSearch() {