diff --git a/cmdb-api/api/lib/cmdb/ci.py b/cmdb-api/api/lib/cmdb/ci.py index 2594a08..88530d0 100644 --- a/cmdb-api/api/lib/cmdb/ci.py +++ b/cmdb-api/api/lib/cmdb/ci.py @@ -485,7 +485,7 @@ class CIRelationManager(object): return numfound, len(first_ci_ids), result @classmethod - def add(cls, first_ci_id, second_ci_id, more=None, relation_type_id=None): + def add(cls, first_ci_id, second_ci_id, more=None, relation_type_id=None, many_to_one=False): first_ci = CIManager.confirm_ci_existed(first_ci_id) second_ci = CIManager.confirm_ci_existed(second_ci_id) @@ -495,7 +495,7 @@ class CIRelationManager(object): to_dict=False, first=True) if existed is not None: - if existed.relation_type_id != relation_type_id: + if existed.relation_type_id != relation_type_id and relation_type_id is not None: existed.update(relation_type_id=relation_type_id) CIRelationHistoryManager().add(existed, OperateType.UPDATE) @@ -509,6 +509,16 @@ class CIRelationManager(object): relation_type_id or abort(404, "Relation {0} <-> {1} is not found".format( first_ci.ci_type.name, second_ci.ci_type.name)) + if many_to_one: + for item in CIRelation.get_by(second_ci_id=second_ci_id, + relation_type_id=relation_type_id, + to_dict=False): + item.soft_delete() + his_manager = CIRelationHistoryManager() + his_manager.add(item, operate_type=OperateType.DELETE) + + ci_relation_delete.apply_async(args=(item.first_ci_id, item.second_ci_id), queue=CMDB_QUEUE) + existed = CIRelation.create(first_ci_id=first_ci_id, second_ci_id=second_ci_id, relation_type_id=relation_type_id) @@ -544,3 +554,25 @@ class CIRelationManager(object): ci_relation_delete.apply_async(args=(first_ci_id, second_ci_id), queue=CMDB_QUEUE) return cls.delete(cr.id) + + @classmethod + def batch_update(cls, ci_ids, parents): + """ + only for many to one + :param ci_ids: + :param parents: + :return: + """ + from api.lib.cmdb.utils import TableMap + + if parents is not None and isinstance(parents, dict): + for attr_name in parents: + if parents[attr_name]: + attr = AttributeCache.get(attr_name) + value_table = TableMap(attr_name=attr.name).table + parent = value_table.get_by(attr_id=attr.id, value=parents[attr_name], first=True, to_dict=False) + if not parent: + return abort(404, "{0}: {1} is not found".format(attr_name, parents[attr_name])) + parent_id = parent.ci_id + for ci_id in ci_ids: + cls.add(parent_id, ci_id, many_to_one=True) diff --git a/cmdb-api/api/tasks/cmdb.py b/cmdb-api/api/tasks/cmdb.py index 7560b5e..5210567 100644 --- a/cmdb-api/api/tasks/cmdb.py +++ b/cmdb-api/api/tasks/cmdb.py @@ -11,7 +11,7 @@ from api.extensions import celery from api.extensions import db from api.extensions import es from api.extensions import rd -from api.lib.cmdb.cache import CITypeAttributeCache +from api.lib.cmdb.cache import CITypeAttributesCache 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_RELATION @@ -81,7 +81,7 @@ def ci_type_attribute_order_rebuild(type_id): from api.lib.cmdb.ci_type import CITypeAttributeGroupManager - attrs = CITypeAttributeCache.get(type_id) + attrs = CITypeAttributesCache.get(type_id) id2attr = {attr.attr_id: attr for attr in attrs} res = CITypeAttributeGroupManager.get_by_type_id(type_id, True) diff --git a/cmdb-api/api/views/cmdb/ci_relation.py b/cmdb-api/api/views/cmdb/ci_relation.py index 38ed735..e0fa467 100644 --- a/cmdb-api/api/views/cmdb/ci_relation.py +++ b/cmdb-api/api/views/cmdb/ci_relation.py @@ -11,6 +11,7 @@ from api.lib.cmdb.cache import RelationTypeCache from api.lib.cmdb.ci import CIRelationManager from api.lib.cmdb.search import SearchError from api.lib.cmdb.search.ci_relation.search import Search +from api.lib.decorator import args_required from api.lib.perm.auth import auth_abandoned from api.lib.utils import get_page from api.lib.utils import get_page_size @@ -122,11 +123,13 @@ class CIRelationView(APIView): def post(self, first_ci_id, second_ci_id): manager = CIRelationManager() res = manager.add(first_ci_id, second_ci_id) + return self.jsonify(cr_id=res) def delete(self, first_ci_id, second_ci_id): manager = CIRelationManager() manager.delete_2(first_ci_id, second_ci_id) + return self.jsonify(message="CIType Relation is deleted") @@ -136,4 +139,24 @@ class DeleteCIRelationView(APIView): def delete(self, cr_id): manager = CIRelationManager() manager.delete(cr_id) + return self.jsonify(message="CIType Relation is deleted") + + +class BatchCreateOrUpdateCIRelationView(APIView): + url_prefix = "/ci_relations/batch" + + @args_required('ci_ids') + @args_required('parents') + def post(self): + ci_ids = request.values.get('ci_ids') + parents = request.values.get('parents') + + CIRelationManager.batch_update(ci_ids, parents) + + return self.jsonify(code=200) + + @args_required('ci_ids') + @args_required('parents') + def put(self): + return self.post() diff --git a/cmdb-ui/package.json b/cmdb-ui/package.json index 1adca4b..9d0ee54 100644 --- a/cmdb-ui/package.json +++ b/cmdb-ui/package.json @@ -15,7 +15,7 @@ "@antv/data-set": "^0.10.2", "@handsontable-pro/vue": "^3.1.1", "@handsontable/vue": "^4.1.1", - "ant-design-vue": "1.5.0-beta.1", + "ant-design-vue": "1.5.0", "axios": "^0.19.0", "core-js": "^3.1.2", "enquire.js": "^2.1.6", diff --git a/cmdb-ui/src/App.vue b/cmdb-ui/src/App.vue index ff0f9cd..5b48756 100644 --- a/cmdb-ui/src/App.vue +++ b/cmdb-ui/src/App.vue @@ -1,9 +1,9 @@ diff --git a/cmdb-ui/yarn.lock b/cmdb-ui/yarn.lock index 9e0602e..0fce044 100644 --- a/cmdb-ui/yarn.lock +++ b/cmdb-ui/yarn.lock @@ -2017,10 +2017,10 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ant-design-vue@1.5.0-beta.1: - version "1.5.0-beta.1" - resolved "https://registry.yarnpkg.com/ant-design-vue/-/ant-design-vue-1.5.0-beta.1.tgz#9396e1bb4435c9bc5dc224e2bd888a000144a8f9" - integrity sha512-Fv5vxO+qHakbjsswgZ70/bjiZK4FphdFxv31VjBJKfhA5Ud7K6sNqC0BVpYS8nL0BwxGCVG8I30efNdU3VifnA== +ant-design-vue@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/ant-design-vue/-/ant-design-vue-1.5.0.tgz#2e2c5658cf1211be06fbee95a18eee02965e089f" + integrity sha512-12+mTowYNZZhsXFR848BZRWGtZrWGayJx9j8Dv3gpgPBU4Abi86tz0hUSbnp8RXL6wb7xNcE9JoawNeE9Y83+Q== dependencies: "@ant-design/icons" "^2.1.1" "@ant-design/icons-vue" "^2.0.0"