From edb4fdf9c1f40dbf0dca054cf5c4e5d3a030a7e6 Mon Sep 17 00:00:00 2001 From: crayon <873217631@qq.com> Date: Wed, 29 Jun 2022 11:26:30 +0800 Subject: [PATCH] =?UTF-8?q?optimization:=20=E9=83=A8=E7=BD=B2=E7=AD=96?= =?UTF-8?q?=E7=95=A5=E5=B1=95=E7=A4=BA=E9=A1=BA=E5=BA=8F=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20(closed=20#856=20closed=20#857)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/backend/subscription/serializers.py | 14 ++------ apps/backend/subscription/views.py | 32 ++++++++++++------- apps/node_man/constants.py | 2 +- apps/node_man/serializers/policy.py | 30 +++++++++++++++-- dev_log/2.2.18/daoqing_202206291110.yaml | 3 ++ frontend/src/types/plugin/plugin-type.ts | 3 +- .../views/plugin/plugin-rule/plugin-rule.vue | 1 + 7 files changed, 58 insertions(+), 27 deletions(-) create mode 100644 dev_log/2.2.18/daoqing_202206291110.yaml diff --git a/apps/backend/subscription/serializers.py b/apps/backend/subscription/serializers.py index afe259ef7..8ecddb4d3 100644 --- a/apps/backend/subscription/serializers.py +++ b/apps/backend/subscription/serializers.py @@ -16,6 +16,7 @@ from apps.exceptions import ValidationError from apps.node_man import constants, models, tools from apps.node_man.models import ProcessStatus +from apps.node_man.serializers import policy class GatewaySerializer(serializers.Serializer): @@ -212,17 +213,8 @@ def validate(self, attrs): return attrs -class SearchDeployPolicySerializer(GatewaySerializer): - class SortSerializer(serializers.Serializer): - head = serializers.ChoiceField(choices=list(constants.POLICY_HEAD_TUPLE)) - sort_type = serializers.ChoiceField(choices=list(constants.SORT_TUPLE)) - - bk_biz_ids = serializers.ListField(child=serializers.IntegerField(min_value=0), min_length=1, required=False) - conditions = serializers.ListField(required=False) - page = serializers.IntegerField(required=False, min_value=1, default=1) - pagesize = serializers.IntegerField(required=False, default=10) - sort = SortSerializer(required=False) - only_root = serializers.BooleanField(label="仅搜索父策略", required=False, default=True) +class SearchDeployPolicySerializer(GatewaySerializer, policy.SearchDeployPolicySerializer): + pass class QueryHostPolicySerializer(serializers.Serializer): diff --git a/apps/backend/subscription/views.py b/apps/backend/subscription/views.py index 212dff01f..571a896ac 100644 --- a/apps/backend/subscription/views.py +++ b/apps/backend/subscription/views.py @@ -829,18 +829,26 @@ def search_deploy_policy(self, *args, **kwargs): begin = (params["page"] - 1) * params["pagesize"] end = (params["page"]) * params["pagesize"] - and_query = Q(category=models.Subscription.CategoryType.POLICY) or_query = Q() + root_query = Q() + and_query = Q(category=models.Subscription.CategoryType.POLICY) # 构造查询条件 for condition in params.get("conditions", []): # 1. 精确查找 - if condition["key"] in ["plugin_name", "id", "enable"]: + if condition["key"] in ["plugin_name", "id"]: if isinstance(condition["value"], list): and_query = and_query & Q(**{condition["key"] + "__in": condition["value"]}) else: and_query = and_query & Q(**{condition["key"]: condition["value"]}) - # 2. 多字段模糊查询 + # 2. 仅在父策略生效的查询条件 + elif condition["key"] in ["enable"]: + if isinstance(condition["value"], list): + root_query = root_query & Q(**{condition["key"] + "__in": condition["value"]}) + else: + root_query = root_query & Q(**{condition["key"]: condition["value"]}) + + # 3. 多字段模糊查询 elif condition["key"] == "query": support_filter_fields = ["name", "plugin_name"] values = condition["value"] if isinstance(condition["value"], list) else [condition["value"]] @@ -859,21 +867,21 @@ def search_deploy_policy(self, *args, **kwargs): ).values_list("pid", flat=True) ) ids_need_expend = ids_need_expend | pids - subscription_qs = models.Subscription.filter_parent_qs().filter((and_query & or_query) | Q(id__in=pids)) + subscription_qs = ( + models.Subscription.filter_parent_qs() + .filter((and_query & or_query) | Q(id__in=pids)) + .filter(root_query) + ) else: subscription_qs = models.Subscription.filter_parent_qs().filter(and_query & or_query) else: subscription_qs = models.Subscription.objects.all().filter(and_query & or_query) # 增加部署节点数量字段 subscription_qs = subscription_qs.extra(select={"bk_biz_scope_len": "JSON_LENGTH(bk_biz_scope)"}) - if params.get("sort"): - sort_head = ( - params["sort"]["head"] if params["sort"]["head"] != "bk_biz_scope" else f"{params['sort']['head']}_len" - ) - if params["sort"]["sort_type"] == constants.SortType.DEC: - subscription_qs = subscription_qs.order_by(f"-{sort_head}") - else: - subscription_qs = subscription_qs.order_by(sort_head) + + ordering: str = params.get("ordering") + if ordering: + subscription_qs = subscription_qs.order_by(*ordering.split(",")) all_subscription = list( subscription_qs.values("id", "name", "plugin_name", "bk_biz_scope", "update_time", "creator", "enable") diff --git a/apps/node_man/constants.py b/apps/node_man/constants.py index b27074d6b..1ee2b6b46 100644 --- a/apps/node_man/constants.py +++ b/apps/node_man/constants.py @@ -158,7 +158,7 @@ def get_optional_items(cls) -> List[str]: HEAD_CHOICES = tuple_choices(HEAD_TUPLE) HeadType = choices_to_namedtuple(HEAD_CHOICES) -POLICY_HEAD_TUPLE = ("name", "plugin_name", "creator", "update_time", "nodes_scope", "bk_biz_scope") +POLICY_HEAD_TUPLE = ("name", "plugin_name", "creator", "update_time", "nodes_scope", "bk_biz_scope", "enable") POLICY_HEAD_CHOICES = tuple_choices(POLICY_HEAD_TUPLE) PolicyHeadType = choices_to_namedtuple(POLICY_HEAD_CHOICES) diff --git a/apps/node_man/serializers/policy.py b/apps/node_man/serializers/policy.py index 7b2186457..51401b3a0 100644 --- a/apps/node_man/serializers/policy.py +++ b/apps/node_man/serializers/policy.py @@ -8,6 +8,8 @@ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ +import typing + from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers @@ -23,11 +25,35 @@ class SortSerializer(serializers.Serializer): sort_type = serializers.ChoiceField(label=_("排序类型"), choices=list(constants.SORT_TUPLE)) bk_biz_ids = serializers.ListField(child=serializers.IntegerField(min_value=0), min_length=1, required=False) - only_root = serializers.BooleanField(label="仅搜索父策略", required=False, default=True) + only_root = serializers.BooleanField(label=_("仅搜索父策略"), required=False, default=True) conditions = serializers.ListField(required=False) page = serializers.IntegerField(required=False, min_value=1, default=1) pagesize = serializers.IntegerField(required=False, default=10) - sort = SortSerializer(label=_("排序"), required=False) + ordering = serializers.CharField(label=_("排序方式"), required=False) + + def validate(self, data): + ordering: str = data.get("ordering") + if not ordering: + return data + order_by_fields: typing.List[str] = ordering.split(",") + preprocessed_order_by_fields: typing.List[str] = [] + for order_by_field in order_by_fields: + order_by_field = order_by_field.strip() + if order_by_field not in constants.POLICY_HEAD_TUPLE and ( + order_by_field.startswith("-") and order_by_field[1:] not in constants.POLICY_HEAD_TUPLE + ): + raise ValidationError( + _("不支持的排序字段 -> {order_by_field}, 全部可排序字段 -> {policy_head_tuple}").format( + order_by_field=order_by_field, policy_head_tuple=constants.POLICY_HEAD_TUPLE + ) + ) + if order_by_field == constants.PolicyHeadType.bk_biz_scope or ( + order_by_field.startswith("-") and order_by_field[1:] == constants.PolicyHeadType.bk_biz_scope + ): + order_by_field = f"{order_by_field}_len" + preprocessed_order_by_fields.append(order_by_field) + data["ordering"] = ",".join(preprocessed_order_by_fields) + return data class FetchPolicyTopoSerializer(serializers.Serializer): diff --git a/dev_log/2.2.18/daoqing_202206291110.yaml b/dev_log/2.2.18/daoqing_202206291110.yaml new file mode 100644 index 000000000..11bfc7ce1 --- /dev/null +++ b/dev_log/2.2.18/daoqing_202206291110.yaml @@ -0,0 +1,3 @@ +--- +optimization: + - "部署策略展示顺序优化 (closed #856 closed #857)" diff --git a/frontend/src/types/plugin/plugin-type.ts b/frontend/src/types/plugin/plugin-type.ts index b6dab4b34..18fede50a 100644 --- a/frontend/src/types/plugin/plugin-type.ts +++ b/frontend/src/types/plugin/plugin-type.ts @@ -272,7 +272,8 @@ export interface IPluginRuleParams { pagesize: number bk_biz_ids?: number[] conditions?: any[] - only_root?: boolean + only_root?: boolean, + ordering?: string } // 升级版本 - 待定 diff --git a/frontend/src/views/plugin/plugin-rule/plugin-rule.vue b/frontend/src/views/plugin/plugin-rule/plugin-rule.vue index 39480ebe4..9b35d57ab 100644 --- a/frontend/src/views/plugin/plugin-rule/plugin-rule.vue +++ b/frontend/src/views/plugin/plugin-rule/plugin-rule.vue @@ -257,6 +257,7 @@ export default class PluginRule extends Mixins(authorityMixin(), pollMixin) { const params: IPluginRuleParams = { page: current, pagesize: limit, + ordering: '-enable,-update_time', }; if (this.searchSelectValue) { params.conditions = [{ key: 'query', value: this.searchSelectValue }];