diff --git a/cmdb-ui/public/iconfont/demo_index.html b/cmdb-ui/public/iconfont/demo_index.html
index 4fd6112..8a77542 100644
--- a/cmdb-ui/public/iconfont/demo_index.html
+++ b/cmdb-ui/public/iconfont/demo_index.html
@@ -5322,9 +5322,9 @@
@font-face {
font-family: 'iconfont';
- src: url('iconfont.woff2?t=1721640768584') format('woff2'),
- url('iconfont.woff?t=1721640768584') format('woff'),
- url('iconfont.ttf?t=1721640768584') format('truetype');
+ src: url('iconfont.woff2?t=1721959219377') format('woff2'),
+ url('iconfont.woff?t=1721959219377') format('woff'),
+ url('iconfont.ttf?t=1721959219377') format('truetype');
}
第二步:定义使用 iconfont 的样式
diff --git a/cmdb-ui/public/iconfont/iconfont.css b/cmdb-ui/public/iconfont/iconfont.css
index e05c3d9..a9a234b 100644
--- a/cmdb-ui/public/iconfont/iconfont.css
+++ b/cmdb-ui/public/iconfont/iconfont.css
@@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 3857903 */
- src: url('iconfont.woff2?t=1721640768584') format('woff2'),
- url('iconfont.woff?t=1721640768584') format('woff'),
- url('iconfont.ttf?t=1721640768584') format('truetype');
+ src: url('iconfont.woff2?t=1721959219377') format('woff2'),
+ url('iconfont.woff?t=1721959219377') format('woff'),
+ url('iconfont.ttf?t=1721959219377') format('truetype');
}
.iconfont {
diff --git a/cmdb-ui/public/iconfont/iconfont.ttf b/cmdb-ui/public/iconfont/iconfont.ttf
index ac43fa7..8ece7fd 100644
Binary files a/cmdb-ui/public/iconfont/iconfont.ttf and b/cmdb-ui/public/iconfont/iconfont.ttf differ
diff --git a/cmdb-ui/public/iconfont/iconfont.woff b/cmdb-ui/public/iconfont/iconfont.woff
index 8c5808d..1d2f154 100644
Binary files a/cmdb-ui/public/iconfont/iconfont.woff and b/cmdb-ui/public/iconfont/iconfont.woff differ
diff --git a/cmdb-ui/public/iconfont/iconfont.woff2 b/cmdb-ui/public/iconfont/iconfont.woff2
index 313fc9b..99e62c0 100644
Binary files a/cmdb-ui/public/iconfont/iconfont.woff2 and b/cmdb-ui/public/iconfont/iconfont.woff2 differ
diff --git a/cmdb-ui/src/components/CustomIconSelect/constants.js b/cmdb-ui/src/components/CustomIconSelect/constants.js
index 7638a37..8116a8b 100644
--- a/cmdb-ui/src/components/CustomIconSelect/constants.js
+++ b/cmdb-ui/src/components/CustomIconSelect/constants.js
@@ -905,6 +905,33 @@ export const multicolorIconList = [
value: 'caise-application',
label: '应用',
list: [{
+ value: 'caise-data_center',
+ label: '数据中心'
+ }, {
+ value: 'caise-folder',
+ label: '文件夹'
+ }, {
+ value: 'caise-resource_pool',
+ label: '资源池'
+ }, {
+ value: 'caise-network',
+ label: '网络'
+ }, {
+ value: 'caise-distributed_switch',
+ label: '分布式交换机'
+ }, {
+ value: 'caise-standard_switch',
+ label: '标准式交换机'
+ }, {
+ value: 'caise-host_cluster',
+ label: '主机集群'
+ }, {
+ value: 'caise-storage_cluster',
+ label: '数据存储集群'
+ }, {
+ value: 'caise-data_storage',
+ label: '数据存储'
+ }, {
value: 'caise-yilianjie',
label: '已连接'
}, {
diff --git a/cmdb-ui/src/modules/cmdb/components/attrMapTable/index.vue b/cmdb-ui/src/modules/cmdb/components/attrMapTable/index.vue
index 1a3aa21..815d507 100644
--- a/cmdb-ui/src/modules/cmdb/components/attrMapTable/index.vue
+++ b/cmdb-ui/src/modules/cmdb/components/attrMapTable/index.vue
@@ -21,15 +21,15 @@
>
*
-
+ showSearch
+ allowClear
+ :options="ciTypeAttributes"
+ style="width: 100%; height: 28px; line-height: 28px;"
+ class="attr-map-table-left-select"
+ >
@@ -49,7 +49,7 @@
>
-
+
{{ JSON.stringify(row.example) }}
{{ row.example }}
@@ -72,6 +72,8 @@
diff --git a/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/index.less b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/index.less
index ec64712..6245094 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/index.less
+++ b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/index.less
@@ -17,7 +17,7 @@
border: 1px solid #d9d9d9;
border-radius: 2px;
padding: 4px 8px;
- width: 100px;
+ width: auto;
text-align: center;
.title {
font-size: 16px;
@@ -73,7 +73,7 @@
}
}
.root {
- width: 100px;
+ width: auto;
border-color: @primary-color;
font-weight: 700;
padding: 4px 8px;
diff --git a/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/index.vue b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/index.vue
index b89c573..f57c86a 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/index.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/index.vue
@@ -29,6 +29,10 @@ export default {
methods: {
init() {
const root = document.getElementById('ci-detail-relation-topo')
+ const canvas = document.createElement('canvas')
+ const context = canvas.getContext('2d')
+ context.font = '16px'
+
this.canvas = new TreeCanvas({
root: root,
disLinkable: false, // 可删除连线
@@ -54,7 +58,15 @@ export default {
return 10
},
getWidth(d) {
- return 40
+ const metrics = context.measureText(d?.title || '')
+ const width = metrics.width
+ /**
+ * width 文字宽度
+ * 20 icon 宽度
+ * 4 盒子内边距
+ * 40 节点间距
+ */
+ return width + 20 + 4 + 40
},
getHGap(d) {
return 80
@@ -69,22 +81,27 @@ export default {
this.canvas.on('events', ({ type, data }) => {
const sourceNode = data?.id || null
if (type === 'custom:clickLeft') {
- searchCIRelation(`root_id=${Number(sourceNode)}&&level=1&&reverse=1&&count=10000`).then((res) => {
+ searchCIRelation(`root_id=${Number(sourceNode)}&level=1&reverse=1&count=10000`).then((res) => {
this.redrawData(res, sourceNode, 'left')
})
}
if (type === 'custom:clickRight') {
- searchCIRelation(`root_id=${Number(sourceNode)}&&level=1&&reverse=0&&count=10000`).then((res) => {
+ searchCIRelation(`root_id=${Number(sourceNode)}&level=1&reverse=0&count=10000`).then((res) => {
this.redrawData(res, sourceNode, 'right')
})
}
})
},
setTopoData(data) {
+ const root = document.getElementById('ci-detail-relation-topo')
+ if (root && root?.innerHTML) {
+ root.innerHTML = ''
+ }
this.canvas = null
this.init()
this.topoData = _.cloneDeep(data)
- this.canvas.draw(data, {}, () => {
+
+ this.canvas.redraw(data, {}, () => {
this.canvas.focusCenterWithAnimate()
})
},
diff --git a/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailTab.vue b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailTab.vue
index 7511f1b..786d9d3 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailTab.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailTab.vue
@@ -28,7 +28,7 @@
{{ $t('cmdb.relation') }}
-
+
@@ -181,6 +181,7 @@ export default {
hasPermission: true,
itsmInstalled: true,
tableHeight: this.attributeHistoryTableHeight || (this.$store.state.windowHeight - 120),
+ initQueryLoading: true,
}
},
computed: {
@@ -218,6 +219,7 @@ export default {
},
methods: {
async create(ciId, activeTabKey = 'tab_1', ciDetailRelationKey = '1') {
+ this.initQueryLoading = true
this.activeTabKey = activeTabKey
if (activeTabKey === 'tab_2') {
this.$nextTick(() => {
@@ -230,10 +232,13 @@ export default {
if (this.hasPermission) {
this.getAttributes()
this.getCIHistory()
- getCITypes().then((res) => {
- this.ci_types = res.ci_types
- })
+ const ciTypeRes = await getCITypes()
+ this.ci_types = ciTypeRes.ci_types
+ if (this.activeTabKey === 'tab_2') {
+ this.$refs.ciDetailRelation.init(true)
+ }
}
+ this.initQueryLoading = false
},
getAttributes() {
getCITypeGroupById(this.typeId, { need_other: 1 })
diff --git a/cmdb-ui/src/modules/cmdb/views/ci_types/allAttrDrawer.vue b/cmdb-ui/src/modules/cmdb/views/ci_types/allAttrDrawer.vue
new file mode 100644
index 0000000..339c945
--- /dev/null
+++ b/cmdb-ui/src/modules/cmdb/views/ci_types/allAttrDrawer.vue
@@ -0,0 +1,140 @@
+
+
+
+
+
+ {{ row.groupName }}
+
+
+
+
+
+
+
+ {{ row.code }}
+
+
+
+
+
+
+
+
+
diff --git a/cmdb-ui/src/modules/cmdb/views/ci_types/attrAD/cidrTags/index.vue b/cmdb-ui/src/modules/cmdb/views/ci_types/attrAD/cidrTags/index.vue
new file mode 100644
index 0000000..9bc195c
--- /dev/null
+++ b/cmdb-ui/src/modules/cmdb/views/ci_types/attrAD/cidrTags/index.vue
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cmdb-ui/src/modules/cmdb/views/ci_types/attrAD/portScanConfig/index.vue b/cmdb-ui/src/modules/cmdb/views/ci_types/attrAD/portScanConfig/index.vue
new file mode 100644
index 0000000..2729829
--- /dev/null
+++ b/cmdb-ui/src/modules/cmdb/views/ci_types/attrAD/portScanConfig/index.vue
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cmdb-ui/src/modules/cmdb/views/ci_types/attrAD/privateCloud/vcenterForm.vue b/cmdb-ui/src/modules/cmdb/views/ci_types/attrAD/privateCloud/vcenterForm.vue
index 1ead9d1..9f3077b 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci_types/attrAD/privateCloud/vcenterForm.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci_types/attrAD/privateCloud/vcenterForm.vue
@@ -6,7 +6,7 @@
/>
-
+
-
-
+
+
+
@@ -127,7 +128,7 @@
-
+
@@ -142,12 +143,17 @@
+
+
+
+
+
@@ -165,7 +171,7 @@ import { v4 as uuidv4 } from 'uuid'
import { mapState } from 'vuex'
import Vcrontab from '@/components/Crontab'
import { putCITypeDiscovery, postCITypeDiscovery } from '../../api/discovery'
-import { PRIVATE_CLOUD_NAME } from '@/modules/cmdb/views/discovery/constants.js'
+import { DISCOVERY_CATEGORY_TYPE, PRIVATE_CLOUD_NAME } from '@/modules/cmdb/views/discovery/constants.js'
import { TAB_KEY } from './attrAD/constants.js'
import HttpSnmpAD from '../../components/httpSnmpAD'
@@ -176,6 +182,8 @@ import AttrADTest from './attrADTest.vue'
import { Popover } from 'element-ui'
import VcenterForm from './attrAD/privateCloud/vcenterForm.vue'
import PublicCloud from './attrAD/publicCloud/index.vue'
+import PortScanConfig from './attrAD/portScanConfig/index.vue'
+import CIDRTags from './attrAD/cidrTags/index.vue'
export default {
name: 'AttrADTabpane',
@@ -188,7 +196,9 @@ export default {
AttrADTest,
ElPopover: Popover,
VcenterForm,
- PublicCloud
+ PublicCloud,
+ PortScanConfig,
+ CIDRTags
},
props: {
adr_id: {
@@ -229,7 +239,7 @@ export default {
query_expr: '',
enabled: true,
},
- form2: {
+ publicCloudForm: {
key: '',
secret: '',
_reference: '',
@@ -244,25 +254,31 @@ export default {
_reference: '',
tabActive: TAB_KEY.CUSTOM,
},
- interval: 'cron', // interval cron
+ portScanConfigForm: {
+ cidr: '',
+ ports: '',
+ enable_cidr: '',
+ },
cron: '',
+ cronVisible: false,
intervalValue: 3,
agent_type: 'agent_id',
nodes: [
{
id: uuidv4(),
ip: '',
- community: '',
+ community: 'public',
version: '',
},
],
- form3: this.$form.createForm(this, { name: 'snmp_form' }),
- cronVisible: false,
+ nodeSettingForm: this.$form.createForm(this, { name: 'snmp_form' }),
uniqueKey: '',
isPrivateCloud: false,
privateCloudName: '',
PRIVATE_CLOUD_NAME,
+ DISCOVERY_CATEGORY_TYPE,
isClient: false, // 是否前端新增临时数据
+ cidrList: [],
}
},
provide() {
@@ -293,26 +309,28 @@ export default {
]
const permissions = this?.user?.roles?.permissions
- if ((permissions.includes('cmdb_admin') || permissions.includes('admin')) && this.adrType === 'agent') {
+ if ((permissions.includes('cmdb_admin') || permissions.includes('admin')) && this.adrType === DISCOVERY_CATEGORY_TYPE.AGENT) {
radios.unshift({ value: 'all', label: this.$t('cmdb.ciType.allNodes') })
}
- if (this.adrType !== 'agent' || this?.currentAdr?.is_plugin) {
+ if (this.adrType !== DISCOVERY_CATEGORY_TYPE.AGENTv || this?.currentAdr?.is_plugin) {
radios.unshift({ value: 'master', label: this.$t('cmdb.ciType.masterNode') })
}
return radios
},
- radioList() {
- return [
- { value: 'interval', label: this.$t('cmdb.ciType.byInterval') },
- { value: 'cron', label: '按cron', layout: 'vertical' },
- ]
- },
labelCol() {
- const span = this.$i18n.locale === 'en' ? 5 : 3
+ const isEn = this.$i18n.locale === 'en'
return {
- span
+ xl: {
+ span: isEn ? 4 : 2
+ },
+ lg: {
+ span: isEn ? 5 : 3
+ },
+ sm: {
+ span: isEn ? 6 : 4
+ }
}
}
},
@@ -324,7 +342,7 @@ export default {
this.uniqueKey = _find?.unique_key ?? ''
this.isClient = _findADT?.isClient ?? false
- if (this.adrType === 'http') {
+ if (this.adrType === DISCOVERY_CATEGORY_TYPE.HTTP) {
const {
category = undefined,
key = '',
@@ -358,7 +376,7 @@ export default {
}
} else {
this.isPrivateCloud = false
- this.form2 = {
+ this.publicCloudForm = {
key,
secret,
_reference,
@@ -371,23 +389,47 @@ export default {
this.$refs.httpForm.init(this.adr_id)
})
}
- if (this.adrType === 'snmp') {
- this.nodes = _findADT?.extra_option?.nodes?.length ? _findADT?.extra_option?.nodes : [
+
+ if (this.adrType === DISCOVERY_CATEGORY_TYPE.COMPONENT) {
+ const {
+ cidr = '',
+ ports = '',
+ enable_cidr = '',
+ } = _findADT?.extra_option ?? {}
+ this.portScanConfigForm = {
+ cidr,
+ ports,
+ enable_cidr
+ }
+ }
+
+ if (this.adrType === DISCOVERY_CATEGORY_TYPE.SNMP) {
+ const nodes = _findADT?.extra_option?.nodes?.length ? _findADT?.extra_option?.nodes : [
{
id: uuidv4(),
ip: '',
- community: '',
+ community: 'public',
version: '',
},
]
+ this.nodes = nodes
this.$nextTick(() => {
this.$refs.nodeSetting.initNodesFunc()
- this.$nextTick(() => {
- this.$refs.nodeSetting.setNodeField()
- })
})
+
+ let cidrList = []
+ const cidr = _findADT?.extra_option?.cidr
+ if (Array.isArray(cidr) && cidr?.length) {
+ cidrList = cidr.map((v) => {
+ return {
+ id: uuidv4(),
+ value: v?.value ? v.value : v
+ }
+ })
+ }
+ this.cidrList = cidrList
}
- if (this.adrType === 'agent') {
+ if (this.adrType === DISCOVERY_CATEGORY_TYPE.AGENT) {
this.tableData = (_find?.attributes || []).map((item) => {
if (_findADT.attributes) {
return {
@@ -420,7 +462,6 @@ export default {
this.agent_type = this.agentTypeRadioList[0].value
}
- this.interval = 'cron'
this.cron = _findADT?.cron || ''
},
@@ -431,13 +472,12 @@ export default {
const { currentAdt } = this
let params
- // 校验 HTTP 表单
- const { isError, data: cloudOption } = this.validateHTTPForm()
- if (isError) {
- return
- }
+ if (this.adrType === DISCOVERY_CATEGORY_TYPE.HTTP) {
+ const { isError, data: cloudOption } = this.validateHTTPForm()
+ if (isError) {
+ return
+ }
- if (this.adrType === 'http') {
params = {
extra_option: {
...cloudOption,
@@ -445,12 +485,25 @@ export default {
},
}
}
- if (this.adrType === 'snmp') {
+
+ if (this.adrType === DISCOVERY_CATEGORY_TYPE.COMPONENT) {
+ const portScanConfigForm = _.omitBy(this.portScanConfigForm, _.isEmpty) || {}
params = {
- extra_option: { nodes: this.$refs.nodeSetting?.getNodeValue() ?? [] },
+ extra_option: {
+ ...portScanConfigForm,
+ },
}
}
- if (this.adrType === 'agent') {
+
+ if (this.adrType === DISCOVERY_CATEGORY_TYPE.SNMP) {
+ params = {
+ extra_option: {
+ nodes: this.$refs.nodeSetting?.getNodeValue() ?? [],
+ cidr: this?.cidrList?.map((item) => item.value) || []
+ },
+ }
+ }
+ if (this.adrType === DISCOVERY_CATEGORY_TYPE.AGENT) {
const $table = this.$refs.attrMapTable
const { fullData: _tableData } = $table.getTableData()
const attributes = {}
@@ -481,7 +534,7 @@ export default {
...params,
...this.form,
adr_id: currentAdt.adr_id,
- cron: this.interval === 'cron' ? this.cron : null,
+ cron: this.cron,
}
if (this.agent_type === 'agent_id' || this.agent_type === 'all') {
@@ -534,55 +587,57 @@ export default {
}
},
+ /**
+ * HTTP 表单校验
+ * 公有云 私有云
+ */
validateHTTPForm() {
let isError = false
let data = {}
- if (this.adrType === 'http') {
- const formData = this?.[this.isPrivateCloud ? 'privateCloudForm' : 'form2']
- if (formData.tabActive === TAB_KEY.CONFIG) {
- if (!formData._reference) {
- isError = true
- this.$message.error(this.$t('cmdb.ad.configErrTip'))
- }
-
- data._reference = formData._reference
- if (this.privateCloudName === PRIVATE_CLOUD_NAME.VCenter) {
- data.vcenterName = formData.vcenterName
- }
-
- return {
- isError,
- data
- }
+ const formData = this?.[this.isPrivateCloud ? 'privateCloudForm' : 'publicCloudForm']
+ if (formData.tabActive === TAB_KEY.CONFIG) {
+ if (!formData._reference) {
+ isError = true
+ this.$message.error(this.$t('cmdb.ad.configErrTip'))
}
- if (this.isPrivateCloud) {
- if (this.privateCloudName === PRIVATE_CLOUD_NAME.VCenter) {
- data = _.pick(this.privateCloudForm, ['host', 'account', 'password', 'vcenterName'])
- const vcenterErros = {
- 'host': `${this.$t('placeholder1')} ${this.$t('cmdb.ciType.host')}`,
- 'account': `${this.$t('placeholder1')} ${this.$t('cmdb.ciType.account')}`,
- 'password': `${this.$t('placeholder1')} ${this.$t('cmdb.ciType.password')}`
- }
- const findError = Object.keys(this.privateCloudForm).find((key) => !this.privateCloudForm[key] && vcenterErros[key])
- if (findError) {
- isError = true
- this.$message.error(this.$t(vcenterErros[findError]))
- }
+ data._reference = formData._reference
+ if (this.privateCloudName === PRIVATE_CLOUD_NAME.VCenter) {
+ data.vcenterName = formData.vcenterName
+ }
+
+ return {
+ isError,
+ data
+ }
+ }
+
+ if (this.isPrivateCloud) {
+ if (this.privateCloudName === PRIVATE_CLOUD_NAME.VCenter) {
+ data = _.pick(this.privateCloudForm, ['host', 'account', 'password', 'vcenterName'])
+ const vcenterErros = {
+ 'host': `${this.$t('placeholder1')} ${this.$t('cmdb.ciType.host')}`,
+ 'account': `${this.$t('placeholder1')} ${this.$t('cmdb.ciType.account')}`,
+ 'password': `${this.$t('placeholder1')} ${this.$t('cmdb.ciType.password')}`
}
- } else {
- data = _.pick(this.form2, ['key', 'secret'])
- const publicCloudErros = {
- 'key': `${this.$t('placeholder1')} key`,
- 'secret': `${this.$t('placeholder1')} secret`
- }
- const findError = Object.keys(this.form2).find((key) => !this.form2[key] && publicCloudErros[key])
+ const findError = Object.keys(this.privateCloudForm).find((key) => !this.privateCloudForm[key] && vcenterErros[key])
if (findError) {
isError = true
- this.$message.error(this.$t(publicCloudErros[findError]))
+ this.$message.error(this.$t(vcenterErros[findError]))
}
}
+ } else {
+ data = _.pick(this.publicCloudForm, ['key', 'secret'])
+ const publicCloudErros = {
+ 'key': `${this.$t('placeholder1')} key`,
+ 'secret': `${this.$t('placeholder1')} secret`
+ }
+ const findError = Object.keys(this.publicCloudForm).find((key) => !this.publicCloudForm[key] && publicCloudErros[key])
+ if (findError) {
+ isError = true
+ this.$message.error(this.$t(publicCloudErros[findError]))
+ }
}
return {
@@ -591,6 +646,9 @@ export default {
}
},
+ /**
+ * 去除多余旧配置
+ */
handleOldExtraOption(option) {
let extra_option = _.cloneDeep(option)
@@ -600,7 +658,7 @@ export default {
}
// 根据 HTTP 选项去除多余属性
- const formData = this?.[this.isPrivateCloud ? 'privateCloudForm' : 'form2']
+ const formData = this?.[this.isPrivateCloud ? 'privateCloudForm' : 'publicCloudForm']
switch (formData.tabActive) {
case TAB_KEY.CUSTOM:
Reflect.deleteProperty(extra_option, '_reference')
@@ -694,6 +752,7 @@ export default {
.radio-master-tip {
font-size: 12px;
color: #86909c;
+ line-height: 14px;
}
}
.attr-ad-snmp-form {
diff --git a/cmdb-ui/src/modules/cmdb/views/ci_types/attributeEditForm.vue b/cmdb-ui/src/modules/cmdb/views/ci_types/attributeEditForm.vue
index 18bcbb6..29dabbc 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci_types/attributeEditForm.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci_types/attributeEditForm.vue
@@ -375,6 +375,10 @@
name="is_computed"
v-decorator="['is_computed', { rules: [], valuePropName: 'checked' }]"
/>
+
+
1. {{ $t('cmdb.ciType.computedAttrTip1') }}
+
2. {{ $t('cmdb.ciType.computedAttrTip2') }}
+
-
+