From a0fcbd220e6ebdcfe9fa0233a277b9dcf2e702d8 Mon Sep 17 00:00:00 2001 From: pycook Date: Mon, 21 Oct 2019 21:53:46 +0800 Subject: [PATCH] attributes paginate and fix update value --- api/lib/cmdb/attribute.py | 29 +++++--- api/lib/cmdb/ci.py | 2 - api/lib/cmdb/search.py | 16 +++-- api/lib/cmdb/value.py | 15 ++++- api/views/cmdb/attribute.py | 18 +++-- ui/src/views/cmdb/attributes/index.vue | 66 ++++++++++++------- .../cmdb/attributes/module/attributeForm.vue | 1 - 7 files changed, 98 insertions(+), 49 deletions(-) diff --git a/api/lib/cmdb/attribute.py b/api/lib/cmdb/attribute.py index f36de13..1d2fe3f 100644 --- a/api/lib/cmdb/attribute.py +++ b/api/lib/cmdb/attribute.py @@ -38,17 +38,30 @@ class AttributeManager(object): db.session.add(table) db.session.flush() - def get_attributes(self, name=None): + @classmethod + def search_attributes(cls, name=None, alias=None, page=1, page_size=None): """ :param name: + :param alias: + :param page: + :param page_size: :return: attribute, if name is None, then return all attributes """ - attrs = Attribute.get_by_like(name=name) if name is not None else Attribute.get_by() + if name is not None: + attrs = Attribute.get_by_like(name=name) + elif alias is not None: + attrs = Attribute.get_by_like(alias=alias) + else: + attrs = Attribute.get_by() + + numfound = len(attrs) + attrs = attrs[(page - 1) * page_size:][:page_size] res = list() for attr in attrs: - attr["is_choice"] and attr.update(dict(choice_value=self.get_choice_values(attr["id"], attr["value_type"]))) + attr["is_choice"] and attr.update(dict(choice_value=cls.get_choice_values(attr["id"], attr["value_type"]))) res.append(attr) - return res + + return numfound, res def get_attribute_by_name(self, name): attr = Attribute.get_by(name=name, first=True) @@ -112,19 +125,19 @@ class AttributeManager(object): is_choice = True if choice_value else False attr.update(flush=True, **kwargs) - + if is_choice: self._add_choice_values(attr.id, attr.value_type, choice_value) - + try: db.session.commit() except Exception as e: db.session.rollback() current_app.logger.error("update attribute error, {0}".format(str(e))) return abort(400, "update attribute <{0}> failed".format(_id)) - + AttributeCache.clean(attr) - + return attr.id @staticmethod diff --git a/api/lib/cmdb/ci.py b/api/lib/cmdb/ci.py index 74c5619..e62e675 100644 --- a/api/lib/cmdb/ci.py +++ b/api/lib/cmdb/ci.py @@ -34,8 +34,6 @@ from api.models.cmdb import CITypeAttribute from api.tasks.cmdb import ci_cache from api.tasks.cmdb import ci_delete -__author__ = 'pycook' - class CIManager(object): """ manage CI interface diff --git a/api/lib/cmdb/search.py b/api/lib/cmdb/search.py index 95de15d..df46d9f 100644 --- a/api/lib/cmdb/search.py +++ b/api/lib/cmdb/search.py @@ -1,6 +1,8 @@ # -*- coding:utf-8 -*- +from __future__ import unicode_literals + import time from flask import current_app @@ -39,7 +41,7 @@ class Search(object): self.query_sql = "" self.type_id_list = [] self.only_type_query = False - + @staticmethod def _operator_proc(key): operator = "&" @@ -127,7 +129,7 @@ class Search(object): if self.only_type_query: return ret_sql.format(query_sql, "ORDER BY B.ci_id {1} LIMIT {0:d}, {2};".format( - (self.page - 1) * self.count, sort_type, self.count)) + (self.page - 1) * self.count, sort_type, self.count)) elif self.type_id_list: self.query_sql = "SELECT B.ci_id FROM ({0}) AS B {1}".format( @@ -170,13 +172,13 @@ class Search(object): elif self.type_id_list: self.query_sql = """SELECT C.ci_id FROM ({0}) AS C - INNER JOIN cis on c_cis.id=C.ci_id - WHERE cis.type_id in ({1})""".format(new_table, ",".join(self.type_id_list)) + INNER JOIN c_cis on c_cis.id=C.ci_id + WHERE c_cis.type_id in ({1})""".format(new_table, ",".join(self.type_id_list)) return """SELECT SQL_CALC_FOUND_ROWS DISTINCT C.ci_id, C.value FROM ({0}) AS C - INNER JOIN cis on c_cis.id=C.ci_id - WHERE cis.type_id in ({4}) + INNER JOIN c_cis on c_cis.id=C.ci_id + WHERE c_cis.type_id in ({4}) ORDER BY C.value {2} LIMIT {1:d}, {3};""".format(new_table, (self.page - 1) * self.count, @@ -299,7 +301,7 @@ class Search(object): self.query_sql = query_sql current_app.logger.debug(query_sql) numfound, res = self._execute_sql(query_sql) - current_app.logger.info("query ci ids is: {0}".format(time.time() - s)) + current_app.logger.debug("query ci ids is: {0}".format(time.time() - s)) return numfound, [_res[0] for _res in res] return 0, [] diff --git a/api/lib/cmdb/value.py b/api/lib/cmdb/value.py index 951b29e..e4ef9b3 100644 --- a/api/lib/cmdb/value.py +++ b/api/lib/cmdb/value.py @@ -14,6 +14,7 @@ from api.lib.cmdb.const import TableMap from api.lib.cmdb.const import ExistPolicy from api.lib.cmdb.const import OperateType from api.lib.cmdb.history import AttributeHistoryManger +from api.models.cmdb import Attribute class AttributeValueManager(object): @@ -47,6 +48,7 @@ class AttributeValueManager(object): attr = self._get_attr(field) if not attr: continue + value_table = TableMap(attr_name=attr.name).table rs = value_table.get_by(ci_id=ci_id, attr_id=attr.id, @@ -130,9 +132,16 @@ class AttributeValueManager(object): for v in value_list: v = self._validate(attr, v, value_table, ci_id) + if not v and attr.value_type != Attribute.TEXT: + v = None + if operate_type == OperateType.ADD: - value_table.create(ci_id=ci_id, attr_id=attr.id, value=v) - self._write_change(ci_id, attr.id, operate_type, None, v) + if v is not None: + value_table.create(ci_id=ci_id, attr_id=attr.id, value=v) + self._write_change(ci_id, attr.id, operate_type, None, v) elif existed_attr.value != v: - existed_attr.update(value=v) + if v is not None: + existed_attr.update(value=v) + else: + existed_attr.delete() self._write_change(ci_id, attr.id, operate_type, existed_value, v) diff --git a/api/views/cmdb/attribute.py b/api/views/cmdb/attribute.py index 0ce947b..b09e3df 100644 --- a/api/views/cmdb/attribute.py +++ b/api/views/cmdb/attribute.py @@ -11,16 +11,26 @@ from api.lib.cmdb.const import RoleEnum from api.lib.cmdb.attribute import AttributeManager from api.lib.decorator import args_required from api.lib.utils import handle_arg_list +from api.lib.utils import get_page +from api.lib.utils import get_page_size + class AttributeSearchView(APIView): url_prefix = ("/attributes/s", "/attributes/search") def get(self): - q = request.values.get("q") - attrs = AttributeManager().get_attributes(name=q) - count = len(attrs) - return self.jsonify(numfound=count, attributes=attrs) + name = request.values.get("name") + alias = request.values.get("alias") + page = get_page(request.values.get("page", 1)) + page_size = get_page_size(request.values.get("page_size")) + numfound, res = AttributeManager.search_attributes(name=name, alias=alias, page=page, page_size=page_size) + + return self.jsonify(page=page, + page_size=page_size, + numfound=numfound, + total=len(res), + attributes=res) class AttributeView(APIView): diff --git a/ui/src/views/cmdb/attributes/index.vue b/ui/src/views/cmdb/attributes/index.vue index b3d97fb..9fac323 100644 --- a/ui/src/views/cmdb/attributes/index.vue +++ b/ui/src/views/cmdb/attributes/index.vue @@ -12,7 +12,9 @@ :rowKey="record=>record.id" :rowSelection="options.rowSelection" :scroll="scroll" - :showPagination="showPagination" + :pagination="{ showTotal: (total, range) => `${range[0]}-${range[1]} 共 ${total} 条记录`, pageSizeOptions: pageSizeOptions}" + showPagination="auto" + :pageSize="25" ref="table" size="middle" @@ -20,7 +22,7 @@
Search + >搜索 Reset + >重置
@@ -69,7 +71,16 @@ @@ -93,7 +104,7 @@ export default { }, data () { return { - scroll: { x: 1400, y: 500 }, + scroll: { x: 1000, y: 500 }, btnName: '新增属性', CITypeName: this.$route.params.CITypeName, @@ -107,11 +118,8 @@ export default { transferTargetKeys: [], transferSelectedKeys: [], originTargetKeys: [], + pageSizeOptions: ['10', '25', '50', '100'], - pagination: { - defaultPageSize: 20 - }, - showPagination: false, columnSearchText: { alias: '', name: '' @@ -121,7 +129,7 @@ export default { title: '名称', dataIndex: 'alias', sorter: false, - width: 200, + width: 250, scopedSlots: { customRender: 'aliasSearchRender', filterDropdown: 'filterDropdown', @@ -140,7 +148,7 @@ export default { title: '英文名', dataIndex: 'name', sorter: false, - width: 200, + width: 250, scopedSlots: { customRender: 'nameSearchRender', filterDropdown: 'filterDropdown', @@ -159,7 +167,7 @@ export default { title: '类型', dataIndex: 'value_type', sorter: false, - width: 100, + width: 80, scopedSlots: { customRender: 'value_type' }, customRender: (text) => valueTypeMap[text] @@ -167,7 +175,7 @@ export default { { title: '唯一', dataIndex: 'is_unique', - width: 80, + width: 50, sorter: false, scopedSlots: { customRender: 'is_check' } @@ -176,7 +184,7 @@ export default { title: '索引', dataIndex: 'is_index', sorter: false, - width: 80, + width: 50, scopedSlots: { customRender: 'is_check' } }, @@ -184,7 +192,7 @@ export default { title: '排序', dataIndex: 'is_sortable', sorter: false, - width: 80, + width: 50, scopedSlots: { customRender: 'is_check' } }, @@ -192,7 +200,7 @@ export default { title: '链接', dataIndex: 'is_link', sorter: false, - width: 80, + width: 50, scopedSlots: { customRender: 'is_check' } }, @@ -200,7 +208,7 @@ export default { title: '密码', dataIndex: 'is_password', sorter: false, - width: 100, + width: 50, scopedSlots: { customRender: 'is_check' } }, @@ -221,15 +229,22 @@ export default { } ], loadData: parameter => { + parameter['page_size'] = parameter['pageSize'] + parameter['page'] = parameter['pageNo'] + Object.assign(parameter, this.queryParam) console.log('loadData.parameter', parameter) - return searchAttributes() + return searchAttributes(parameter) .then(res => { - this.allAttributes = res.attributes - return { - data: res.attributes + res.pageNo = res.page + res.pageSize = res.total + res.totalCount = res.numfound + res.totalPage = Math.ceil(res.numfound / parameter.pageSize) + res.data = res.attributes - } + console.log('loadData.res', res) + this.allAttributes = res.attributes + return res }) }, @@ -285,17 +300,20 @@ export default { this.getAttributes() this.setScrollY() }, + inject: ['reload'], + methods: { handleSearch (selectedKeys, confirm, column) { confirm() this.columnSearchText[column.dataIndex] = selectedKeys[0] + this.queryParam[column.dataIndex] = selectedKeys[0] }, handleReset (clearFilters, column) { clearFilters() this.columnSearchText[column.dataIndex] = '' + this.queryParam[column.dataIndex] = '' }, - getAttributes () { searchAttributes().then(res => { this.allAttributes = res.attributes diff --git a/ui/src/views/cmdb/attributes/module/attributeForm.vue b/ui/src/views/cmdb/attributes/module/attributeForm.vue index 9959925..7c41f40 100644 --- a/ui/src/views/cmdb/attributes/module/attributeForm.vue +++ b/ui/src/views/cmdb/attributes/module/attributeForm.vue @@ -255,7 +255,6 @@ export default { e.preventDefault() this.form.validateFields((err, values) => { if (!err) { - // eslint-disable-next-line no-console console.log('Received values of form: ', values) if (values.choice_value) { values.choice_value = values.choice_value.split('\n')