mirror of https://github.com/veops/cmdb.git
feat(cmdb-ui):多对多关系&&仪表盘色卡调整 (#271)
This commit is contained in:
parent
2699c263d9
commit
91555ffa64
|
@ -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
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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') {
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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',
|
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Reference in New Issue