mirror of https://github.com/veops/cmdb.git
commit
90a97402ef
|
@ -38,6 +38,7 @@ pip-log.txt
|
||||||
.tox
|
.tox
|
||||||
nosetests.xml
|
nosetests.xml
|
||||||
.pytest_cache
|
.pytest_cache
|
||||||
|
cmdb-api/test-output
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
*.mo
|
*.mo
|
||||||
|
|
|
@ -23,6 +23,7 @@ from api.models.cmdb import CITypeGroupItem
|
||||||
from api.models.cmdb import CITypeRelation
|
from api.models.cmdb import CITypeRelation
|
||||||
from api.models.cmdb import PreferenceShowAttributes
|
from api.models.cmdb import PreferenceShowAttributes
|
||||||
from api.models.cmdb import PreferenceTreeView
|
from api.models.cmdb import PreferenceTreeView
|
||||||
|
from api.tasks.cmdb import ci_type_attribute_order_rebuild
|
||||||
|
|
||||||
|
|
||||||
class CITypeManager(object):
|
class CITypeManager(object):
|
||||||
|
@ -55,16 +56,32 @@ class CITypeManager(object):
|
||||||
ci_type = CITypeCache.get(_type) or abort(404, "CIType <{0}> is not found".format(_type))
|
ci_type = CITypeCache.get(_type) or abort(404, "CIType <{0}> is not found".format(_type))
|
||||||
return ci_type.to_dict()
|
return ci_type.to_dict()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _validate_unique(type_id=None, name=None, alias=None):
|
||||||
|
if name is not None:
|
||||||
|
ci_type = CIType.get_by(name=name, first=True, to_dict=False)
|
||||||
|
elif alias is not None:
|
||||||
|
ci_type = CIType.get_by(alias=alias, first=True, to_dict=False)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
if type_id is not None and ci_type.id != type_id:
|
||||||
|
return abort(400, "CIType <{0}> is already existed".format(name or alias))
|
||||||
|
|
||||||
|
if type_id is None and ci_type is not None:
|
||||||
|
return abort(400, "CIType <{0}> is already existed".format(name or alias))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@kwargs_required("name")
|
@kwargs_required("name")
|
||||||
def add(cls, **kwargs):
|
def add(cls, **kwargs):
|
||||||
unique_key = kwargs.pop("unique_key", None)
|
unique_key = kwargs.pop("unique_key", None)
|
||||||
unique_key = AttributeCache.get(unique_key) or abort(404, "Unique key is not defined")
|
unique_key = AttributeCache.get(unique_key) or abort(404, "Unique key is not defined")
|
||||||
|
|
||||||
CIType.get_by(name=kwargs['name']) and abort(404, "CIType <{0}> is already existed".format(kwargs.get("name")))
|
|
||||||
|
|
||||||
kwargs["alias"] = kwargs["name"] if not kwargs.get("alias") else kwargs["alias"]
|
kwargs["alias"] = kwargs["name"] if not kwargs.get("alias") else kwargs["alias"]
|
||||||
|
|
||||||
|
cls._validate_unique(name=kwargs['name'])
|
||||||
|
cls._validate_unique(alias=kwargs['alias'])
|
||||||
|
|
||||||
kwargs["unique_id"] = unique_key.id
|
kwargs["unique_id"] = unique_key.id
|
||||||
ci_type = CIType.create(**kwargs)
|
ci_type = CIType.create(**kwargs)
|
||||||
|
|
||||||
|
@ -88,6 +105,9 @@ class CITypeManager(object):
|
||||||
|
|
||||||
ci_type = cls.check_is_existed(type_id)
|
ci_type = cls.check_is_existed(type_id)
|
||||||
|
|
||||||
|
cls._validate_unique(type_id=type_id, name=kwargs.get('name'))
|
||||||
|
cls._validate_unique(type_id=type_id, alias=kwargs.get('alias'))
|
||||||
|
|
||||||
unique_key = kwargs.pop("unique_key", None)
|
unique_key = kwargs.pop("unique_key", None)
|
||||||
unique_key = AttributeCache.get(unique_key)
|
unique_key = AttributeCache.get(unique_key)
|
||||||
if unique_key is not None:
|
if unique_key is not None:
|
||||||
|
@ -305,6 +325,31 @@ class CITypeAttributeManager(object):
|
||||||
|
|
||||||
CITypeAttributesCache.clean(type_id)
|
CITypeAttributesCache.clean(type_id)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def transfer(cls, type_id, _from, _to):
|
||||||
|
current_app.logger.info("[{0}] {1} -> {2}".format(type_id, _from, _to))
|
||||||
|
attr_id = _from.get('attr_id')
|
||||||
|
from_group_id = _from.get('group_id')
|
||||||
|
to_group_id = _to.get('group_id')
|
||||||
|
order = _to.get('order')
|
||||||
|
|
||||||
|
if from_group_id != to_group_id:
|
||||||
|
if from_group_id is not None:
|
||||||
|
CITypeAttributeGroupManager.delete_item(from_group_id, attr_id)
|
||||||
|
|
||||||
|
if to_group_id is not None:
|
||||||
|
CITypeAttributeGroupManager.add_item(to_group_id, attr_id, order)
|
||||||
|
|
||||||
|
elif from_group_id:
|
||||||
|
CITypeAttributeGroupManager.update_item(from_group_id, attr_id, order)
|
||||||
|
|
||||||
|
else: # other attribute transfer
|
||||||
|
return abort(400, "invalid operation!!!")
|
||||||
|
|
||||||
|
CITypeAttributesCache.clean(type_id)
|
||||||
|
|
||||||
|
ci_type_attribute_order_rebuild.apply_async(args=(type_id,), queue=CMDB_QUEUE)
|
||||||
|
|
||||||
|
|
||||||
class CITypeRelationManager(object):
|
class CITypeRelationManager(object):
|
||||||
"""
|
"""
|
||||||
|
@ -457,3 +502,86 @@ class CITypeAttributeGroupManager(object):
|
||||||
item.soft_delete()
|
item.soft_delete()
|
||||||
|
|
||||||
return group_id
|
return group_id
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_item(cls, group_id, attr_id, order):
|
||||||
|
db.session.remove()
|
||||||
|
|
||||||
|
existed = CITypeAttributeGroupItem.get_by(group_id=group_id,
|
||||||
|
attr_id=attr_id,
|
||||||
|
first=True,
|
||||||
|
to_dict=False)
|
||||||
|
if existed is not None:
|
||||||
|
existed.update(order=order)
|
||||||
|
else:
|
||||||
|
CITypeAttributeGroupItem.create(group_id=group_id, attr_id=attr_id, order=order)
|
||||||
|
|
||||||
|
gt_items = db.session.query(CITypeAttributeGroupItem).filter(
|
||||||
|
CITypeAttributeGroupItem.deleted.is_(False)).filter(CITypeAttributeGroupItem.order > order)
|
||||||
|
for _item in gt_items:
|
||||||
|
_order = _item.order
|
||||||
|
_item.update(order=_order + 1)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update_item(cls, group_id, attr_id, order):
|
||||||
|
db.session.remove()
|
||||||
|
|
||||||
|
existed = CITypeAttributeGroupItem.get_by(group_id=group_id,
|
||||||
|
attr_id=attr_id,
|
||||||
|
first=True,
|
||||||
|
to_dict=False)
|
||||||
|
existed or abort(404, "Group<{0}> - Attribute<{1}> is not found".format(group_id, attr_id))
|
||||||
|
|
||||||
|
if existed.order > order: # forward, +1
|
||||||
|
items = db.session.query(CITypeAttributeGroupItem).filter(
|
||||||
|
CITypeAttributeGroupItem.deleted.is_(False)).filter(
|
||||||
|
CITypeAttributeGroupItem.order >= order).filter(
|
||||||
|
CITypeAttributeGroupItem.order < existed.order)
|
||||||
|
for item in items:
|
||||||
|
item.update(order=item.order + 1)
|
||||||
|
|
||||||
|
elif existed.order < order: # backward, -1
|
||||||
|
items = db.session.query(CITypeAttributeGroupItem).filter(
|
||||||
|
CITypeAttributeGroupItem.deleted.is_(False)).filter(
|
||||||
|
CITypeAttributeGroupItem.order > existed.order).filter(
|
||||||
|
CITypeAttributeGroupItem.order <= order)
|
||||||
|
for item in items:
|
||||||
|
item.update(order=item.order - 1)
|
||||||
|
|
||||||
|
existed.update(order=order)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def delete_item(cls, group_id, attr_id):
|
||||||
|
db.session.remove()
|
||||||
|
|
||||||
|
item = CITypeAttributeGroupItem.get_by(group_id=group_id,
|
||||||
|
attr_id=attr_id,
|
||||||
|
first=True,
|
||||||
|
to_dict=False)
|
||||||
|
|
||||||
|
if item is not None:
|
||||||
|
item.soft_delete()
|
||||||
|
order = item.order
|
||||||
|
gt_items = db.session.query(CITypeAttributeGroupItem).filter(
|
||||||
|
CITypeAttributeGroupItem.deleted.is_(False)).filter(CITypeAttributeGroupItem.order > order)
|
||||||
|
for _item in gt_items:
|
||||||
|
_order = _item.order
|
||||||
|
_item.update(order=_order - 1)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def transfer(cls, type_id, _from, _to):
|
||||||
|
current_app.logger.info("CIType[{0}] {1} -> {2}".format(type_id, _from, _to))
|
||||||
|
from_group = CITypeAttributeGroup.get_by_id(_from)
|
||||||
|
from_group or abort(404, "Group <{0}> is not found".format(_from))
|
||||||
|
|
||||||
|
to_group = CITypeAttributeGroup.get_by_id(_to)
|
||||||
|
to_group or abort(404, "Group <{0}> is not found".format(_to))
|
||||||
|
|
||||||
|
from_order, to_order = from_group.order, to_group.order
|
||||||
|
|
||||||
|
from_group.update(order=to_order)
|
||||||
|
to_group.update(order=from_order)
|
||||||
|
|
||||||
|
CITypeAttributesCache.clean(type_id)
|
||||||
|
|
||||||
|
ci_type_attribute_order_rebuild.apply_async(args=(type_id,), queue=CMDB_QUEUE)
|
||||||
|
|
|
@ -11,6 +11,7 @@ from api.extensions import celery
|
||||||
from api.extensions import db
|
from api.extensions import db
|
||||||
from api.extensions import es
|
from api.extensions import es
|
||||||
from api.extensions import rd
|
from api.extensions import rd
|
||||||
|
from api.lib.cmdb.cache import CITypeAttributeCache
|
||||||
from api.lib.cmdb.const import CMDB_QUEUE
|
from api.lib.cmdb.const import CMDB_QUEUE
|
||||||
from api.lib.cmdb.const import REDIS_PREFIX_CI
|
from api.lib.cmdb.const import REDIS_PREFIX_CI
|
||||||
from api.lib.cmdb.const import REDIS_PREFIX_CI_RELATION
|
from api.lib.cmdb.const import REDIS_PREFIX_CI_RELATION
|
||||||
|
@ -71,3 +72,23 @@ def ci_relation_delete(parent_id, child_id):
|
||||||
rd.create_or_update({parent_id: json.dumps(children)}, REDIS_PREFIX_CI_RELATION)
|
rd.create_or_update({parent_id: json.dumps(children)}, REDIS_PREFIX_CI_RELATION)
|
||||||
|
|
||||||
current_app.logger.info("DELETE ci relation cache: {0} -> {1}".format(parent_id, child_id))
|
current_app.logger.info("DELETE ci relation cache: {0} -> {1}".format(parent_id, child_id))
|
||||||
|
|
||||||
|
|
||||||
|
@celery.task(name="cmdb.ci_type_attribute_order_rebuild", queue=CMDB_QUEUE)
|
||||||
|
def ci_type_attribute_order_rebuild(type_id):
|
||||||
|
current_app.logger.info('rebuild attribute order')
|
||||||
|
db.session.remove()
|
||||||
|
|
||||||
|
from api.lib.cmdb.ci_type import CITypeAttributeGroupManager
|
||||||
|
|
||||||
|
attrs = CITypeAttributeCache.get(type_id)
|
||||||
|
id2attr = {attr.attr_id: attr for attr in attrs}
|
||||||
|
|
||||||
|
res = CITypeAttributeGroupManager.get_by_type_id(type_id, True)
|
||||||
|
order = 0
|
||||||
|
for group in res:
|
||||||
|
for _attr in group.get('attributes'):
|
||||||
|
if order != id2attr.get(_attr['id']) and id2attr.get(_attr['id']):
|
||||||
|
id2attr.get(_attr['id']).update(order=order)
|
||||||
|
|
||||||
|
order += 1
|
||||||
|
|
|
@ -164,6 +164,34 @@ class CITypeAttributeView(APIView):
|
||||||
return self.jsonify(attributes=attr_id_list)
|
return self.jsonify(attributes=attr_id_list)
|
||||||
|
|
||||||
|
|
||||||
|
class CITypeAttributeTransferView(APIView):
|
||||||
|
url_prefix = "/ci_types/<int:type_id>/attributes/transfer"
|
||||||
|
|
||||||
|
@args_required('from')
|
||||||
|
@args_required('to')
|
||||||
|
def post(self, type_id):
|
||||||
|
_from = request.values.get('from') # {'attr_id': xx, 'group_id': xx}
|
||||||
|
_to = request.values.get('to') # {'group_id': xx, 'order': xxx}
|
||||||
|
|
||||||
|
CITypeAttributeManager.transfer(type_id, _from, _to)
|
||||||
|
|
||||||
|
return self.jsonify(code=200)
|
||||||
|
|
||||||
|
|
||||||
|
class CITypeAttributeGroupTransferView(APIView):
|
||||||
|
url_prefix = "/ci_types/<int:type_id>/attribute_groups/transfer"
|
||||||
|
|
||||||
|
@args_required('from')
|
||||||
|
@args_required('to')
|
||||||
|
def post(self, type_id):
|
||||||
|
_from = request.values.get('from') # group_id
|
||||||
|
_to = request.values.get('to') # group_id
|
||||||
|
|
||||||
|
CITypeAttributeGroupManager.transfer(type_id, _from, _to)
|
||||||
|
|
||||||
|
return self.jsonify(code=200)
|
||||||
|
|
||||||
|
|
||||||
class CITypeAttributeGroupView(APIView):
|
class CITypeAttributeGroupView(APIView):
|
||||||
url_prefix = ("/ci_types/<int:type_id>/attribute_groups",
|
url_prefix = ("/ci_types/<int:type_id>/attribute_groups",
|
||||||
"/ci_types/attribute_groups/<int:group_id>")
|
"/ci_types/attribute_groups/<int:group_id>")
|
||||||
|
|
|
@ -122,3 +122,19 @@ export function deleteCITypeAttributesById (CITypeId, data) {
|
||||||
data: data
|
data: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function transferCITypeAttrIndex (CITypeId, data) {
|
||||||
|
return axios({
|
||||||
|
url: `/v0.1/ci_types/${CITypeId}/attributes/transfer`,
|
||||||
|
method: 'POST',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function transferCITypeGroupIndex (CITypeId, data) {
|
||||||
|
return axios({
|
||||||
|
url: `/v0.1/ci_types/${CITypeId}/attribute_groups/transfer`,
|
||||||
|
method: 'POST',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -86,8 +86,7 @@
|
||||||
v-model="CITypeGroup.attributes"
|
v-model="CITypeGroup.attributes"
|
||||||
group="properties"
|
group="properties"
|
||||||
@start="drag=true"
|
@start="drag=true"
|
||||||
@end="handleEnd"
|
@change="(e)=>{handleChange(e, CITypeGroup.id)}"
|
||||||
@change="handleChange"
|
|
||||||
:filter="'.filter-empty'"
|
:filter="'.filter-empty'"
|
||||||
:animation="100"
|
:animation="100"
|
||||||
tag="div"
|
tag="div"
|
||||||
|
@ -164,8 +163,7 @@
|
||||||
v-model="otherGroupAttributes"
|
v-model="otherGroupAttributes"
|
||||||
group="properties"
|
group="properties"
|
||||||
@start="drag=true"
|
@start="drag=true"
|
||||||
@end="handleEnd"
|
@change="(e)=>{handleChange(e, -1)}"
|
||||||
@change="handleChange"
|
|
||||||
:animation="0"
|
:animation="0"
|
||||||
style="min-height: 2rem; width: 100%; display: flex; flex-flow: wrap">
|
style="min-height: 2rem; width: 100%; display: flex; flex-flow: wrap">
|
||||||
|
|
||||||
|
@ -251,14 +249,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/* eslint-disable */
|
||||||
import {
|
import {
|
||||||
deleteCITypeGroupById,
|
deleteCITypeGroupById,
|
||||||
getCITypeGroupById,
|
getCITypeGroupById,
|
||||||
createCITypeGroupById,
|
createCITypeGroupById,
|
||||||
updateCITypeGroupById
|
updateCITypeGroupById
|
||||||
} from '@/api/cmdb/CIType'
|
} from '@/api/cmdb/CIType'
|
||||||
import { getCITypeAttributesById, updateCITypeAttributesById } from '@/api/cmdb/CITypeAttr'
|
import { getCITypeAttributesById, updateCITypeAttributesById, transferCITypeAttrIndex, transferCITypeGroupIndex } from '@/api/cmdb/CITypeAttr'
|
||||||
import draggable from 'vuedraggable'
|
import draggable from 'vuedraggable'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -272,6 +270,7 @@ export default {
|
||||||
CITypeId: this.$route.params.CITypeId,
|
CITypeId: this.$route.params.CITypeId,
|
||||||
CITypeName: this.$route.params.CITypeName,
|
CITypeName: this.$route.params.CITypeName,
|
||||||
CITypeGroups: [],
|
CITypeGroups: [],
|
||||||
|
addRemoveGroupFlag: {},
|
||||||
attributes: [],
|
attributes: [],
|
||||||
otherGroupAttributes: [],
|
otherGroupAttributes: [],
|
||||||
addGroupBtnVisible: true,
|
addGroupBtnVisible: true,
|
||||||
|
@ -312,7 +311,7 @@ export default {
|
||||||
group.editable = false
|
group.editable = false
|
||||||
group.originOrder = group.order
|
group.originOrder = group.order
|
||||||
group.originName = group.name
|
group.originName = group.name
|
||||||
group.attributes = group.attributes.sort((a, b) => a.order - b.order)
|
// group.attributes = group.attributes.sort((a, b) => a.order - b.order)
|
||||||
})
|
})
|
||||||
|
|
||||||
this.otherGroupAttributes = this.attributes.filter(x => !inGroupAttrKeys.includes(x.id)).sort((a, b) => a.order - b.order)
|
this.otherGroupAttributes = this.attributes.filter(x => !inGroupAttrKeys.includes(x.id)).sort((a, b) => a.order - b.order)
|
||||||
|
@ -322,7 +321,7 @@ export default {
|
||||||
attribute.originOrder = attribute.order
|
attribute.originOrder = attribute.order
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('setOtherGroupAttributes', this.CITypeGroups, this.otherGroupAttributes)
|
// console.log('setOtherGroupAttributes', this.CITypeGroups, this.otherGroupAttributes)
|
||||||
},
|
},
|
||||||
getCITypeGroupData () {
|
getCITypeGroupData () {
|
||||||
const promises = [
|
const promises = [
|
||||||
|
@ -387,13 +386,18 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
handleMoveGroup (beforeIndex, afterIndex) {
|
handleMoveGroup (beforeIndex, afterIndex) {
|
||||||
const beforeGroup = this.CITypeGroups[beforeIndex]
|
const fromGroupId = this.CITypeGroups[beforeIndex].id
|
||||||
this.CITypeGroups[beforeIndex] = this.CITypeGroups[afterIndex]
|
const toGroupId = this.CITypeGroups[afterIndex].id
|
||||||
|
transferCITypeGroupIndex(this.CITypeId, { from: fromGroupId, to: toGroupId }).then(res => {
|
||||||
|
this.$message.success('操作成功')
|
||||||
|
const beforeGroup = this.CITypeGroups[beforeIndex]
|
||||||
|
this.CITypeGroups[beforeIndex] = this.CITypeGroups[afterIndex]
|
||||||
|
|
||||||
this.$set(this.CITypeGroups, beforeIndex, this.CITypeGroups[afterIndex])
|
this.$set(this.CITypeGroups, beforeIndex, this.CITypeGroups[afterIndex])
|
||||||
this.$set(this.CITypeGroups, afterIndex, beforeGroup)
|
this.$set(this.CITypeGroups, afterIndex, beforeGroup)
|
||||||
|
}).catch(err => {
|
||||||
this.updatePropertyIndex()
|
this.$httpError(err, '移动出错')
|
||||||
|
})
|
||||||
},
|
},
|
||||||
handleAddExistGroupAttr (index) {
|
handleAddExistGroupAttr (index) {
|
||||||
const group = this.CITypeGroups[index]
|
const group = this.CITypeGroups[index]
|
||||||
|
@ -456,24 +460,50 @@ export default {
|
||||||
})
|
})
|
||||||
.catch(err => this.requestFailed(err))
|
.catch(err => this.requestFailed(err))
|
||||||
},
|
},
|
||||||
handleChange (e) {
|
handleChange (e, group) {
|
||||||
console.log(e)
|
if (e.hasOwnProperty('moved') && e.moved.oldIndex !== e.moved.newIndex) {
|
||||||
if (e.hasOwnProperty('moved')) {
|
if (group === -1) {
|
||||||
this.shouldUpdatePropertyIndex = e.moved.newIndex !== e.moved.oldIndex
|
this.$message.error('更多属性不能进行排序, 如需排序需添加入其他分组中!')
|
||||||
} else {
|
} else {
|
||||||
this.shouldUpdatePropertyIndex = true
|
transferCITypeAttrIndex(this.CITypeId,
|
||||||
|
{
|
||||||
|
from: { attr_id: e.moved.element.id, group_id: group > -1 ? group : null },
|
||||||
|
to: { order: e.moved.newIndex, group_id: group > -1 ? group : null }
|
||||||
|
}).then(res => this.$message.success('保存成功')).catch(err => {
|
||||||
|
this.$httpError(err)
|
||||||
|
this.abortDraggable()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.hasOwnProperty('added')) {
|
||||||
|
this.addRemoveGroupFlag = { to: { group_id: group > -1 ? group : null, order: e.added.newIndex }, inited: true }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.hasOwnProperty('removed')) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
transferCITypeAttrIndex(this.CITypeId,
|
||||||
|
{
|
||||||
|
from: { attr_id: e.removed.element.id, group_id: group > -1 ? group : null },
|
||||||
|
to: { group_id: this.addRemoveGroupFlag.to.group_id, order: this.addRemoveGroupFlag.to.order }
|
||||||
|
}).then(res => this.$message.success('保存成功')).catch(err => {
|
||||||
|
this.$httpError(err)
|
||||||
|
this.abortDraggable()
|
||||||
|
}).finally(() => {
|
||||||
|
this.addRemoveGroupFlag = {}
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleEnd (e) {
|
abortDraggable () {
|
||||||
if (this.shouldUpdatePropertyIndex) {
|
this.$nextTick(() => {
|
||||||
this.updatePropertyIndex()
|
this.$router.push({name: 'ci_type'})
|
||||||
this.shouldUpdatePropertyIndex = false
|
})
|
||||||
}
|
|
||||||
},
|
},
|
||||||
updatePropertyIndex () {
|
updatePropertyIndex () {
|
||||||
const attributes = []
|
const attributes = [] // 全部属性
|
||||||
let attributeOrder = 0
|
let attributeOrder = 0 // 属性组
|
||||||
let groupOrder = 0
|
let groupOrder = 0 // 组排序
|
||||||
const promises = [
|
const promises = [
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue