Merge branch 'master' of github.com:veops/cmdb

This commit is contained in:
pycook 2023-08-15 19:48:11 +08:00
commit 76a41a8e82
7 changed files with 389 additions and 144 deletions

View File

@ -10,7 +10,10 @@
</div> </div>
<div class="attribute-card_value-type">{{ valueTypeMap[property.value_type] }}</div> <div class="attribute-card_value-type">{{ valueTypeMap[property.value_type] }}</div>
</div> </div>
<div class="attribute-card-trigger" v-if="property.value_type === '3' || property.value_type === '4'"> <div
class="attribute-card-trigger"
v-if="(property.value_type === '3' || property.value_type === '4') && !isStore"
>
<a @click="openTrigger"><ops-icon type="ops-trigger"/></a> <a @click="openTrigger"><ops-icon type="ops-trigger"/></a>
</div> </div>
</div> </div>
@ -47,7 +50,7 @@
</a-popover> </a-popover>
<a-space class="attribute-card-operation"> <a-space class="attribute-card-operation">
<a><a-icon type="edit" @click="handleEdit"/></a> <a v-if="!isStore"><a-icon type="edit" @click="handleEdit"/></a>
<a style="color:red;"><a-icon type="delete" @click="handleDelete"/></a> <a style="color:red;"><a-icon type="delete" @click="handleDelete"/></a>
</a-space> </a-space>
</div> </div>
@ -56,7 +59,7 @@
</template> </template>
<script> <script>
import { deleteCITypeAttributesById } from '@/modules/cmdb/api/CITypeAttr' import { deleteCITypeAttributesById, deleteAttributesById } from '@/modules/cmdb/api/CITypeAttr'
import ValueTypeIcon from '@/components/CMDBValueTypeMapIcon' import ValueTypeIcon from '@/components/CMDBValueTypeMapIcon'
import { import {
ops_default_show, ops_default_show,
@ -92,6 +95,10 @@ export default {
type: Number, type: Number,
default: null, default: null,
}, },
isStore: {
type: Boolean,
default: false,
},
}, },
data() { data() {
const propertyList = [ const propertyList = [
@ -140,10 +147,17 @@ export default {
title: '警告', title: '警告',
content: `确认删除 ${that.property.alias || that.property.name}`, content: `确认删除 ${that.property.alias || that.property.name}`,
onOk() { onOk() {
deleteCITypeAttributesById(that.CITypeId, { attr_id: [that.property.id] }).then(() => { if (that.isStore) {
that.$message.success('删除成功!') deleteAttributesById(that.property.id).then(() => {
that.$emit('ok') that.$message.success('删除成功!')
}) that.$emit('ok')
})
} else {
deleteCITypeAttributesById(that.CITypeId, { attr_id: [that.property.id] }).then(() => {
that.$message.success('删除成功!')
that.$emit('ok')
})
}
}, },
onCancel() {}, onCancel() {},
}) })

View File

@ -0,0 +1,212 @@
<template>
<a-modal wrapClassName="attrbute-store-wrapper" width="80%" :visible="visible" @cancel="handleCancel">
<template slot="title">
<div class="attrbute-store-header">
<span>属性库</span>
<div class="attrbute-store-search">
<a-input-group compact>
<a-select class="attrbute-store-search-select" v-model="searchKey">
<a-select-option value="alias">
别名
</a-select-option>
<a-select-option value="name">
名称
</a-select-option>
</a-select>
<a-input
ref="input"
slot="default"
class="attrbute-store-search-input"
v-model="searchValue"
@pressEnter="pressEnter"
allowClear
@change="handleInput"
>
<a-icon slot="suffix" type="search" @click="pressEnter" :style="{ cursor: 'pointer' }" />
</a-input>
</a-input-group>
</div>
</div>
</template>
<a-spin :spinning="loading" :style="{ height: '100%' }">
<a-row v-if="attrList.length">
<a-col
class="attrbute-store-col"
:xxl="4"
:xl="6"
:lg="8"
:md="12"
:sm="24"
v-for="item in attrList"
:key="item.id"
>
<AttributeCard
@ok="
() => {
searchAttributes()
}
"
:isStore="true"
:property="item"
/>
</a-col>
</a-row>
<a-empty v-else>
<img slot="image" :src="require('@/assets/data_empty.png')" />
<span slot="description"> 暂无数据 </span>
</a-empty>
</a-spin>
<template slot="footer">
<a-pagination
size="small"
show-size-changer
show-quick-jumper
:current="tablePage.currentPage"
:total="tablePage.totalResult"
:show-total="(total, range) => `当前展示 ${range[0]}-${range[1]} 条数据, 共 ${total} 条`"
:page-size="tablePage.pageSize"
:default-current="1"
@change="pageOrSizeChange"
@showSizeChange="pageOrSizeChange"
:pageSizeOptions="['20', '50', '100', '200']"
/>
</template>
</a-modal>
</template>
<script>
import { searchAttributes } from '../../api/CITypeAttr'
import AttributeCard from './attributeCard.vue'
export default {
name: 'AttributeStore',
components: { AttributeCard },
data() {
return {
visible: false,
attrList: [],
tablePage: {
currentPage: 1,
pageSize: 50,
totalResult: 0,
},
loading: false,
searchKey: 'alias',
searchValue: '',
}
},
methods: {
open() {
this.visible = true
this.searchAttributes()
},
handleCancel() {
this.visible = false
},
async searchAttributes(currentPage = 1, pageSize = this.tablePage.pageSize) {
this.loading = true
const params = {
page: currentPage,
page_size: pageSize,
}
if (this.searchKey && this.searchValue) {
params[this.searchKey] = this.searchValue
}
searchAttributes(params)
.then((res) => {
this.attrList = res.attributes
this.tablePage = {
...this.tablePage,
currentPage: res.page,
pageSize: res.page_size,
totalResult: res.numfound,
}
})
.finally(() => {
this.loading = false
})
},
pageOrSizeChange(currentPage, pageSize) {
this.searchAttributes(currentPage, pageSize)
},
pressEnter() {
this.searchAttributes(1)
},
handleInput(e) {
if (!e.target.value) {
this.pressEnter()
}
},
},
}
</script>
<style lang="less" scoped>
.attrbute-store-wrapper {
.attrbute-store-col {
display: flex;
justify-content: center;
}
}
</style>
<style lang="less">
.attrbute-store-wrapper {
.ant-modal-body {
height: 70vh;
overflow: auto;
}
.attrbute-store-header {
display: flex;
align-items: center;
justify-content: space-between;
}
}
</style>
<style lang="less">
@import '~@/style/static.less';
.attrbute-store-search {
width: 300px;
display: inline-block;
margin-right: 60px;
.ant-input-group.ant-input-group-compact > *:first-child,
.ant-input-group.ant-input-group-compact > .ant-select:first-child > .ant-select-selection {
border-top-left-radius: 20px !important;
border-bottom-left-radius: 20px !important;
background-color: #custom_colors[color_1];
color: #fff;
border: none;
}
.ant-select-focused .ant-select-selection,
.ant-select-selection:focus {
box-shadow: none;
}
.ant-select-selection__rendered {
margin-right: 12px;
}
.ant-select-arrow {
color: #fff;
font-size: 10px;
right: 8px;
}
.attrbute-store-search-select {
width: 65px;
.ant-select-selection-selected-value {
font-size: 12px;
}
}
.attrbute-store-search-input {
display: inline-block;
width: calc(100% - 65px);
.ant-input {
background-color: #f0f5ff;
border: none;
border-radius: 20px;
&:focus {
box-shadow: none;
}
}
}
}
</style>

View File

@ -25,47 +25,71 @@
class="ops-button-primary" class="ops-button-primary"
>分组</a-button >分组</a-button
> >
<a-space v-if="permissions.includes('admin') || permissions.includes('cmdb_admin')"> <a-space>
<a-upload <a
name="file" @click="
accept="json" () => {
:showUploadList="false" $refs.attributeStore.open()
style="display: inline-block" }
action="/api/v0.1/ci_types/template/import/file " "
>属性库</a
> >
<a>导入</a> <a-dropdown v-if="permissions.includes('admin') || permissions.includes('cmdb_admin')">
</a-upload> <a><ops-icon type="ops-menu"/></a>
<a href="/api/v0.1/ci_types/template/export/file">导出</a> <a-menu slot="overlay">
<a-menu-item key="0">
<a-upload
name="file"
accept="json"
:showUploadList="false"
style="display: inline-block"
action="/api/v0.1/ci_types/template/import/file "
>
<a-space
><a><a-icon type="upload"/></a><a>导入</a></a-space
>
</a-upload>
</a-menu-item>
<a-menu-item key="1">
<a-space>
<a><a-icon type="download"/></a>
<a href="/api/v0.1/ci_types/template/export/file">导出</a>
</a-space>
</a-menu-item>
</a-menu>
</a-dropdown>
</a-space> </a-space>
</div> </div>
<draggable class="ci-types-left-content" :list="CITypeGroups" @end="handleChangeGroups" filter=".undraggable"> <draggable class="ci-types-left-content" :list="CITypeGroups" @end="handleChangeGroups" filter=".undraggable">
<div v-for="g in CITypeGroups" :key="g.id || g.name"> <div v-for="g in CITypeGroups" :key="g.id || g.name">
<div <div
:class="`${currentGId === g.id && !currentCId ? 'selected' : ''} ci-types-left-group ${ :class="
g.id === -1 ? 'undraggable' : '' `${currentGId === g.id && !currentCId ? 'selected' : ''} ci-types-left-group ${
}`" g.id === -1 ? 'undraggable' : ''
}`
"
@click="handleClickGroup(g.id)" @click="handleClickGroup(g.id)"
> >
<div> <div>
<OpsMoveIcon <OpsMoveIcon
style="width: 17px; height: 17px; display: none; position: absolute; left: -3px; top: 10px" style="width: 17px; height: 17px; display: none; position: absolute; left: -3px; top: 10px"
/> />
<span style="font-weight: 700">{{ g.name || '其他' }}</span> <span style="font-weight:700">{{ g.name || '其他' }}</span>
<span :style="{ color: '#c3cdd7' }">({{ g.ci_types.length }})</span> <span :style="{ color: '#c3cdd7' }">({{ g.ci_types.length }})</span>
</div> </div>
<a-space> <a-space>
<a-tooltip> <a-tooltip>
<template slot="title">在该组中新增CI模型</template> <template slot="title">在该组中新增CI模型</template>
<a><a-icon type="plus" @click="handleCreate(g)" /></a> <a><a-icon type="plus" @click="handleCreate(g)"/></a>
</a-tooltip> </a-tooltip>
<template v-if="g.id !== -1"> <template v-if="g.id !== -1">
<a-tooltip> <a-tooltip>
<template slot="title">编辑组名称</template> <template slot="title">编辑组名称</template>
<a><a-icon type="edit" @click="handleEditGroup(g)" /></a> <a><a-icon type="edit" @click="handleEditGroup(g)"/></a>
</a-tooltip> </a-tooltip>
<a-tooltip> <a-tooltip>
<template slot="title">删除该组</template> <template slot="title">删除该组</template>
<a style="color: red"><a-icon type="delete" @click="handleDeleteGroup(g)" /></a> <a style="color: red"><a-icon type="delete" @click="handleDeleteGroup(g)"/></a>
</a-tooltip> </a-tooltip>
</template> </template>
</a-space> </a-space>
@ -102,9 +126,9 @@
</div> </div>
<span class="ci-types-left-detail-title">{{ ci.alias || ci.name }}</span> <span class="ci-types-left-detail-title">{{ ci.alias || ci.name }}</span>
<a-space class="ci-types-left-detail-action"> <a-space class="ci-types-left-detail-action">
<a><a-icon type="user-add" @click="(e) => handlePerm(e, ci)" /></a> <a><a-icon type="user-add" @click="(e) => handlePerm(e, ci)"/></a>
<a><a-icon type="edit" @click="(e) => handleEdit(e, ci)" /></a> <a><a-icon type="edit" @click="(e) => handleEdit(e, ci)"/></a>
<a style="color: red" @click="(e) => handleDelete(e, ci)"><a-icon type="delete" /></a> <a style="color: red" @click="(e) => handleDelete(e, ci)"><a-icon type="delete"/></a>
</a-space> </a-space>
</div> </div>
</draggable> </draggable>
@ -185,8 +209,12 @@
<a-divider :style="{ margin: '5px 0' }" /> <a-divider :style="{ margin: '5px 0' }" />
<div :style="{ textAlign: 'right' }"> <div :style="{ textAlign: 'right' }">
<a-radio-group v-model="default_order_asc"> <a-radio-group v-model="default_order_asc">
<a-radio value="1"> 正序 </a-radio> <a-radio value="1">
<a-radio value="2"> 倒序 </a-radio> 正序
</a-radio>
<a-radio value="2">
倒序
</a-radio>
</a-radio-group> </a-radio-group>
</div> </div>
</el-select> </el-select>
@ -230,6 +258,7 @@
</a-form> </a-form>
</CustomDrawer> </CustomDrawer>
<CMDBGrant ref="cmdbGrant" resourceType="CIType" app_id="cmdb" /> <CMDBGrant ref="cmdbGrant" resourceType="CIType" app_id="cmdb" />
<AttributeStore ref="attributeStore" />
</div> </div>
</template> </template>
@ -257,6 +286,7 @@ import IconArea from './iconArea.vue'
import SplitPane from '@/components/SplitPane' import SplitPane from '@/components/SplitPane'
import CMDBGrant from '../../components/cmdbGrant' import CMDBGrant from '../../components/cmdbGrant'
import { ops_move_icon as OpsMoveIcon } from '@/core/icons' import { ops_move_icon as OpsMoveIcon } from '@/core/icons'
import AttributeStore from './attributeStore.vue'
export default { export default {
name: 'CITypes', name: 'CITypes',
@ -270,6 +300,7 @@ export default {
IconArea, IconArea,
SplitPane, SplitPane,
OpsMoveIcon, OpsMoveIcon,
AttributeStore,
}, },
data() { data() {
return { return {
@ -589,7 +620,6 @@ export default {
} }
}, },
async handleChangeCITypes(e, g) { async handleChangeCITypes(e, g) {
console.log(111, g)
if (g.id && g.id !== -1) { if (g.id && g.id !== -1) {
putCITypeGroupByGId(g.id, { name: g.name, type_ids: g.ci_types.map((i) => i.id) }) putCITypeGroupByGId(g.id, { name: g.name, type_ids: g.ci_types.map((i) => i.id) })
.then(() => { .then(() => {
@ -613,7 +643,6 @@ export default {
const { type_id } = await createCIType(data).catch(() => { const { type_id } = await createCIType(data).catch(() => {
this.loading = false this.loading = false
}) })
console.log(111)
this.$message.success(`添加成功`) this.$message.success(`添加成功`)
if (this.selectGroup && this.selectGroup.id && this.selectGroup.id !== -1) { if (this.selectGroup && this.selectGroup.id && this.selectGroup.id !== -1) {
const ids = this.selectGroup.ci_types.map((i) => i.id) const ids = this.selectGroup.ci_types.map((i) => i.id)

View File

@ -91,13 +91,8 @@ export default {
}) })
}, },
}, },
beforeMount() {
this.loadTotalAttrs()
},
methods: { methods: {
async handleSubmit(isCloseModal = true) { async handleSubmit(isCloseModal = true) {
console.log(this.targetKeys)
if (this.activeKey === '2') { if (this.activeKey === '2') {
if (this.targetKeys.length) { if (this.targetKeys.length) {
this.confirmLoading = true this.confirmLoading = true
@ -125,6 +120,7 @@ export default {
this.visible = true this.visible = true
this.currentGroup = group this.currentGroup = group
this.activeKey = '1' this.activeKey = '1'
this.loadTotalAttrs()
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.createNewAttribute.checkCanDefineComputed() this.$refs.createNewAttribute.checkCanDefineComputed()
}) })

View File

@ -90,7 +90,12 @@ export default {
) )
}, },
}, },
inject: ['refresh'], inject: {
refresh: {
from: 'refresh',
default: null,
},
},
methods: { methods: {
createFromTriggerTable(canAddTriggerAttr) { createFromTriggerTable(canAddTriggerAttr) {
this.visible = true this.visible = true
@ -163,7 +168,9 @@ export default {
await addTrigger(this.CITypeId, params) await addTrigger(this.CITypeId, params)
} }
this.handleCancel() this.handleCancel()
this.refresh() if (this.refresh) {
this.refresh()
}
} }
}) })
}, },
@ -176,7 +183,9 @@ export default {
deleteTrigger(that.CITypeId, that.triggerId).then(() => { deleteTrigger(that.CITypeId, that.triggerId).then(() => {
that.$message.success('删除成功!') that.$message.success('删除成功!')
that.handleCancel() that.handleCancel()
that.refresh() if (that.refresh) {
that.refresh()
}
}) })
}, },
}) })

View File

@ -1,65 +1,63 @@
<template> <template>
<div> <div class="model-relation">
<a-card :bordered="false"> <a-button @click="handleCreate" type="primary" style="margin-bottom: 15px;" icon="plus">新增关系</a-button>
<a-button @click="handleCreate" type="primary" style="margin-bottom: 15px;" icon="plus">新增关系</a-button> <model-relation-table ref="table"></model-relation-table>
<model-relation-table ref="table"></model-relation-table> <a-modal
<a-modal :closable="false"
:closable="false" :title="drawerTitle"
:title="drawerTitle" :visible="visible"
:visible="visible" @cancel="onClose"
@cancel="onClose" @ok="handleSubmit"
@ok="handleSubmit" width="500px"
width="500px" >
> <a-form :form="form" @submit="handleSubmit" :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }">
<a-form :form="form" @submit="handleSubmit" :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }"> <a-form-item label="源模型">
<a-form-item label="源模型"> <a-select
<a-select showSearch
showSearch name="source_ci_type_id"
name="source_ci_type_id" v-decorator="['source_ci_type_id', { rules: [{ required: true, message: '请选择源模型' }] }]"
v-decorator="['source_ci_type_id', { rules: [{ required: true, message: '请选择源模型' }] }]" @change="handleSourceTypeChange"
@change="handleSourceTypeChange" :filterOption="filterOption"
:filterOption="filterOption" >
> <a-select-option :value="CIType.id" :key="CIType.id" v-for="CIType in displayCITypes">{{
<a-select-option :value="CIType.id" :key="CIType.id" v-for="CIType in displayCITypes">{{ CIType.alias || CIType.name
CIType.alias || CIType.name }}</a-select-option>
}}</a-select-option> </a-select>
</a-select> </a-form-item>
</a-form-item> <a-form-item label="目标模型">
<a-form-item label="目标模型"> <a-select
<a-select showSearch
showSearch name="ci_type_id"
name="ci_type_id" v-decorator="['ci_type_id', { rules: [{ required: true, message: '请选择目标模型' }] }]"
v-decorator="['ci_type_id', { rules: [{ required: true, message: '请选择目标模型' }] }]" @change="handleTargetTypeChange"
@change="handleTargetTypeChange" :filterOption="filterOption"
:filterOption="filterOption" >
> <a-select-option :value="CIType.id" :key="CIType.id" v-for="CIType in displayTargetCITypes">
<a-select-option :value="CIType.id" :key="CIType.id" v-for="CIType in displayTargetCITypes"> {{ CIType.alias || CIType.name }}
{{ CIType.alias || CIType.name }} </a-select-option>
</a-select-option> </a-select>
</a-select> </a-form-item>
</a-form-item>
<a-form-item label="关联关系"> <a-form-item label="关联关系">
<a-select <a-select
name="relation_type_id" name="relation_type_id"
v-decorator="['relation_type_id', { rules: [{ required: true, message: '请选择关联关系' }] }]" v-decorator="['relation_type_id', { rules: [{ required: true, message: '请选择关联关系' }] }]"
> >
<a-select-option :value="relationType.id" :key="relationType.id" v-for="relationType in relationTypes">{{ <a-select-option :value="relationType.id" :key="relationType.id" v-for="relationType in relationTypes">{{
relationType.name relationType.name
}}</a-select-option> }}</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>
<a-form-item label="关联约束"> <a-form-item label="关联约束">
<a-select v-decorator="['constraint', { rules: [{ required: true, message: '请选择关联约束' }] }]"> <a-select v-decorator="['constraint', { rules: [{ required: true, message: '请选择关联约束' }] }]">
<a-select-option value="0">一对多</a-select-option> <a-select-option value="0">一对多</a-select-option>
<a-select-option value="1">一对一</a-select-option> <a-select-option value="1">一对一</a-select-option>
<a-select-option value="2">多对多</a-select-option> <a-select-option value="2">多对多</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>
</a-form> </a-form>
</a-modal> </a-modal>
</a-card>
</div> </div>
</template> </template>
@ -110,16 +108,13 @@ export default {
}, },
mounted() { mounted() {
const _currentId = localStorage.getItem('ops_cityps_currentId') const _currentId = localStorage.getItem('ops_cityps_currentId')
console.log(_currentId)
if (_currentId) { if (_currentId) {
this.currentId = _currentId this.currentId = _currentId
} }
searchResourceType({ page_size: 9999, app_id: 'cmdb' }).then((res) => { searchResourceType({ page_size: 9999, app_id: 'cmdb' }).then((res) => {
console.log('searchResourceType', res)
this.resource_type = { groups: res.groups, id2perms: res.id2perms } this.resource_type = { groups: res.groups, id2perms: res.id2perms }
}) })
this.loadCITypes(!_currentId) this.loadCITypes(!_currentId)
console.log(this.CITypeId)
}, },
computed: { computed: {
currentCId() { currentCId() {
@ -168,7 +163,6 @@ export default {
}, },
getCITypes() { getCITypes() {
getCITypes().then((res) => { getCITypes().then((res) => {
console.log('getCITypes', res.ci_types)
this.CITypes = res.ci_types this.CITypes = res.ci_types
}) })
}, },
@ -196,9 +190,6 @@ export default {
e.preventDefault() e.preventDefault()
this.form.validateFields((err, values) => { this.form.validateFields((err, values) => {
if (!err) { if (!err) {
// eslint-disable-next-line no-console
console.log('Received values of form: ', values)
createRelation(values.source_ci_type_id, values.ci_type_id, values.relation_type_id, values.constraint).then( createRelation(values.source_ci_type_id, values.ci_type_id, values.relation_type_id, values.constraint).then(
(res) => { (res) => {
this.$message.success(`添加成功`) this.$message.success(`添加成功`)
@ -215,8 +206,6 @@ export default {
this.$refs.table.refresh() this.$refs.table.refresh()
}, },
handleDelete(record) { handleDelete(record) {
console.log(record)
deleteRelation(record.source_ci_type_id, record.id).then((res) => { deleteRelation(record.source_ci_type_id, record.id).then((res) => {
this.$message.success(`删除成功`) this.$message.success(`删除成功`)
@ -236,4 +225,12 @@ export default {
} }
</script> </script>
<style></style> <style lang="less" scoped>
.model-relation {
background-color: #fff;
border-radius: 15px;
padding: 24px;
height: calc(100vh - 64px);
margin-bottom: -24px;
}
</style>

View File

@ -1,12 +1,13 @@
<template> <template>
<div> <div>
<vxe-table <vxe-table
ref="xTable"
stripe stripe
class="ops-stripe-table" class="ops-stripe-table"
show-header-overflow show-header-overflow
show-overflow show-overflow
resizable resizable
:max-height="`${windowHeight - 183}px`" :height="`${windowHeight - 160}px`"
:data="tableData" :data="tableData"
:sort-config="{ defaultSort: { field: 'created_at', order: 'desc' } }" :sort-config="{ defaultSort: { field: 'created_at', order: 'desc' } }"
> >
@ -16,21 +17,8 @@
field="relation_type_id" field="relation_type_id"
title="关系" title="关系"
:filters="[{ data: '' }]" :filters="[{ data: '' }]"
:filter-method="filterRelationMethod" :filter-multiple="false"
:filter-recover-method="filterRelationRecoverMethod"
> >
<template #filter="{ $panel, column }">
<template v-for="(option, index) in column.filters">
<input
type="type"
:key="index"
v-model="option.data"
@input="$panel.changeOption($event, !!option.data, option)"
@keyup.enter="$panel.confirmFilter()"
placeholder="按回车确认筛选"
/>
</template>
</template>
<template #default="{ row }"> <template #default="{ row }">
<a-tag color="cyan"> <a-tag color="cyan">
{{ row.relation_type.name }} {{ row.relation_type.name }}
@ -39,9 +27,14 @@
</vxe-column> </vxe-column>
<vxe-column field="child.alias" title="目标模型"></vxe-column> <vxe-column field="child.alias" title="目标模型"></vxe-column>
<vxe-column field="constraint" title="关联约束"></vxe-column> <vxe-column field="constraint" title="关联约束"></vxe-column>
<vxe-column field="authorization" title="授权" width="89px"> <vxe-column field="authorization" title="操作" width="89px">
<template #default="{ row }"> <template #default="{ row }">
<a @click="handleOpenGrant(row)"><a-icon type="user-add"/></a> <a-space>
<a @click="handleOpenGrant(row)"><a-icon type="user-add"/></a>
<a-popconfirm title="确认删除?" @confirm="deleteRelation(row)">
<a :style="{ color: 'red' }"><ops-icon type="icon-xianxing-delete"/></a>
</a-popconfirm>
</a-space>
</template> </template>
</vxe-column> </vxe-column>
</vxe-table> </vxe-table>
@ -50,7 +43,7 @@
</template> </template>
<script> <script>
import { getCITypeRelations } from '@/modules/cmdb/api/CITypeRelation' import { getCITypeRelations, deleteRelation } from '@/modules/cmdb/api/CITypeRelation'
import { getRelationTypes } from '@/modules/cmdb/api/relationType' import { getRelationTypes } from '@/modules/cmdb/api/relationType'
import CMDBGrant from '../../../components/cmdbGrant' import CMDBGrant from '../../../components/cmdbGrant'
@ -86,40 +79,35 @@ export default {
item.constraint = this.handleConstraint(item.constraint) item.constraint = this.handleConstraint(item.constraint)
}) })
this.tableData = res this.tableData = res
console.log('MainData', res)
}, },
// 获取关系 // 获取关系
async getRelationTypes() { async getRelationTypes() {
const res = await getRelationTypes() const res = await getRelationTypes()
const relationTypeMap = new Map() this.relationTypeList = res.map((item) => ({ value: item.id, label: item.name }))
res.forEach((item) => { const $table = this.$refs.xTable
relationTypeMap.set(item.id, item.name) if ($table) {
}) const nameColumn = $table.getColumnByField('relation_type_id')
this.relationTypeList = relationTypeMap if (nameColumn) {
console.log('relationTypeList', this.relationTypeList) $table.setFilter(nameColumn, this.relationTypeList)
}
}
}, },
// 转换关联关系 // 转换关联关系
handleConstraint(constraintId) { handleConstraint(constraintId) {
return this.constraintMap[constraintId] return this.constraintMap[constraintId]
}, },
handleOpenGrant(record) { handleOpenGrant(record) {
console.log('record', record)
console.log(`${record.parent.name} -> ${record.child.name}`)
// this.$refs.grantDrawer.open({ name: `${record.parent.name} -> ${record.child.name}` })
this.$refs.cmdbGrant.open({ this.$refs.cmdbGrant.open({
name: `${record.parent.name} -> ${record.child.name}`, name: `${record.parent.name} -> ${record.child.name}`,
typeRelationIds: [record.parent_id, record.child_id], typeRelationIds: [record.parent_id, record.child_id],
cmdbGrantType: 'type_relation', cmdbGrantType: 'type_relation',
}) })
}, },
filterRelationMethod({ option, row }) { deleteRelation(row) {
return row.relation_type.name.includes(String(option.data)) deleteRelation(row.parent_id, row.child_id).then((res) => {
}, this.$message.success(`删除成功`)
filterRelationRecoverMethod({ option }) { this.getRelationTypes()
option.data = '' })
},
refresh() {
this.getMainData()
}, },
}, },
} }