From 7d654eb21beb3e0fba34215957061a237b5f39a7 Mon Sep 17 00:00:00 2001 From: raja <1647193241@qq.com> Date: Mon, 12 Aug 2024 20:16:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=A3=8E=E9=99=A9=E5=8D=95=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E5=B1=95=E7=A4=BA=E4=BA=8C=E6=9C=9F=20--story=3D11818?= =?UTF-8?q?8959?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 修复风险生成标题的异常 --- .../services/web/risk/handlers/risk.py | 50 ++++++++++--------- .../services/web/risk/resources/risk.py | 4 ++ src/backend/services/web/risk/serializers.py | 3 ++ .../services/web/strategy_v2/resources.py | 21 ++++++-- .../services/web/strategy_v2/serializers.py | 22 ++++++-- src/backend/services/web/strategy_v2/views.py | 1 + 6 files changed, 70 insertions(+), 31 deletions(-) diff --git a/src/backend/services/web/risk/handlers/risk.py b/src/backend/services/web/risk/handlers/risk.py index e3a592c8..bf9ff7b5 100644 --- a/src/backend/services/web/risk/handlers/risk.py +++ b/src/backend/services/web/risk/handlers/risk.py @@ -28,7 +28,7 @@ from django.db.models import Q, QuerySet from django.utils import timezone from django.utils.translation import gettext -from jinja2.exceptions import UndefinedError +from jinja2 import UndefinedError from rest_framework.settings import api_settings from apps.meta.models import GlobalMetaConfig @@ -46,7 +46,7 @@ from services.web.risk.handlers import EventHandler from services.web.risk.models import Risk from services.web.risk.render import RiskTitleUndefined -from services.web.risk.serializers import CreateRiskSerializer, RiskInfoSerializer +from services.web.risk.serializers import CreateRiskSerializer from services.web.strategy_v2.models import Strategy, StrategyTag @@ -103,33 +103,50 @@ def load_events(self, start_time: datetime.datetime, end_time: datetime.datetime return data - def render_risk_title(self, risk: Risk) -> Optional[str]: + @classmethod + def render_risk_title(cls, create_params: dict) -> Optional[str]: """ 生成风险标题 """ - strategy: Strategy = Strategy.objects.filter(strategy_id=risk.strategy_id).first() + strategy: Strategy = Strategy.objects.filter(strategy_id=create_params["strategy_id"]).first() if not strategy or not strategy.risk_title: return - risk_content = RiskInfoSerializer(risk).data # 事件证据为字符串需要转换成列表,并取第一条字典数据 try: - event_evidence = json.loads(risk.event_evidence)[0] + event_evidence = json.loads(create_params["event_evidence"])[0] except (json.JSONDecodeError, IndexError, KeyError): event_evidence = {} - risk_content["event_evidence"] = event_evidence + create_params["event_evidence"] = event_evidence try: - risk_title = Jinja2Renderer(undefined=RiskTitleUndefined).jinja_render(strategy.risk_title, risk_content) + risk_title = Jinja2Renderer(undefined=RiskTitleUndefined).jinja_render(strategy.risk_title, create_params) return risk_title except UndefinedError as err: logger.exception( "[RenderRiskTitleFailed] risk_title: %s; risk_content: %s; err: %s", strategy.risk_title, - risk_content, + create_params, err, ) return strategy.risk_title + def gen_risk_create_params(self, event: dict) -> dict: + create_params = { + "event_content": event.get("event_content"), + "raw_event_id": event["raw_event_id"], + "strategy_id": event["strategy_id"], + "event_evidence": event.get("event_evidence"), + "event_type": self.parse_event_type(event.get("event_type")), + "event_data": event.get("event_data"), + "event_time": datetime.datetime.fromtimestamp(event["event_time"] / 1000), + "event_end_time": datetime.datetime.fromtimestamp(event["event_time"] / 1000), + "event_source": event.get("event_source"), + "operator": self.parse_operator(event.get("operator")), + "tags": list(StrategyTag.objects.filter(strategy_id=event["strategy_id"]).values_list("tag_id", flat=True)), + } + create_params["title"] = self.render_risk_title(create_params) + return create_params + def create_risk(self, event: dict) -> (bool, Risk): """ 创建或更新风险 @@ -174,20 +191,7 @@ def create_risk(self, event: dict) -> (bool, Risk): return False, None # 不存在则创建 - return True, Risk.objects.create( - event_content=event.get("event_content"), - raw_event_id=event["raw_event_id"], - strategy_id=event["strategy_id"], - event_evidence=event.get("event_evidence"), - event_type=self.parse_event_type(event.get("event_type")), - event_data=event.get("event_data"), - event_time=datetime.datetime.fromtimestamp(event["event_time"] / 1000), - event_end_time=datetime.datetime.fromtimestamp(event["event_time"] / 1000), - event_source=event.get("event_source"), - operator=self.parse_operator(event.get("operator")), - tags=list(StrategyTag.objects.filter(strategy_id=event["strategy_id"]).values_list("tag_id", flat=True)), - title=self.render_risk_title(risk), - ) + return True, Risk.objects.create(**self.gen_risk_create_params(event)) def parse_operator(self, operator: str) -> List[str]: operator = operator or "" diff --git a/src/backend/services/web/risk/resources/risk.py b/src/backend/services/web/risk/resources/risk.py index 643b0047..e3d8c024 100644 --- a/src/backend/services/web/risk/resources/risk.py +++ b/src/backend/services/web/risk/resources/risk.py @@ -155,6 +155,10 @@ def perform_request(self, validated_request_data): def load_risks(self, validated_request_data: dict) -> QuerySet: # 构造表达式 q = Q() + # 风险等级 + risk_level = validated_request_data.pop("risk_level", None) + if risk_level: + q &= Q(strategy_id__in=Strategy.objects.filter(risk_level__in=risk_level).values("strategy_id")) for key, val in validated_request_data.items(): if not val: continue diff --git a/src/backend/services/web/risk/serializers.py b/src/backend/services/web/risk/serializers.py index 63e52d02..efe90a57 100644 --- a/src/backend/services/web/risk/serializers.py +++ b/src/backend/services/web/risk/serializers.py @@ -196,6 +196,9 @@ class ListRiskRequestSerializer(serializers.Serializer): order_type = serializers.ChoiceField( label=gettext_lazy("排序方式"), required=False, allow_null=True, allow_blank=True, choices=OrderTypeChoices.choices ) + risk_level = serializers.CharField( + label=gettext_lazy("Risk Level"), required=False, allow_blank=True, allow_null=True + ) def validate(self, attrs: dict) -> dict: # 校验 diff --git a/src/backend/services/web/strategy_v2/resources.py b/src/backend/services/web/strategy_v2/resources.py index ffd2d3f4..e0153126 100644 --- a/src/backend/services/web/strategy_v2/resources.py +++ b/src/backend/services/web/strategy_v2/resources.py @@ -28,7 +28,7 @@ from blueapps.utils.request_provider import get_local_request, get_request_username from django.conf import settings from django.db import transaction -from django.db.models import Count, Q +from django.db.models import Count, Q, QuerySet from django.shortcuts import get_object_or_404 from django.utils.translation import gettext, gettext_lazy from pypinyin import lazy_pinyin @@ -87,6 +87,7 @@ GetRTFieldsRequestSerializer, GetRTFieldsResponseSerializer, GetStrategyCommonResponseSerializer, + GetStrategyDisplayInfoRequestSerializer, GetStrategyFieldValueRequestSerializer, GetStrategyFieldValueResponseSerializer, GetStrategyStatusRequestSerializer, @@ -611,8 +612,8 @@ def get_event_basic_field_configs(self, risk: Optional[Risk], has_permission: bo return [ EventInfoField( field_name=field.field_name, - display_name=field.alias_name, - description=str(field.description), + display_name=str(field.description), + description="", example=getattr(risk, field.field_name, "") if risk and has_permission else "", ) for field in EventMappingFields().fields @@ -667,3 +668,17 @@ def perform_request(self, validated_request_data): "event_data_field_configs": self.get_event_data_field_configs(risk, has_permission), "event_evidence_field_configs": self.get_event_evidence_field_configs(risk, has_permission), } + + +class GetStrategyDisplayInfo(StrategyV2Base): + """ + 获取策略展示信息 + """ + + name = gettext_lazy("获取策略展示信息") + RequestSerializer = GetStrategyDisplayInfoRequestSerializer + + def perform_request(self, validated_request_data): + strategy_ids = validated_request_data["strategy_ids"] + strategies: QuerySet[Strategy] = Strategy.objects.filter(strategy_id__in=strategy_ids).only("risk_level") + return {strategy.strategy_id: {"risk_level": strategy.risk_level} for strategy in strategies} diff --git a/src/backend/services/web/strategy_v2/serializers.py b/src/backend/services/web/strategy_v2/serializers.py index a7f6b41c..c24196ea 100644 --- a/src/backend/services/web/strategy_v2/serializers.py +++ b/src/backend/services/web/strategy_v2/serializers.py @@ -46,7 +46,7 @@ class EventFieldSerializer(serializers.Serializer): field_name = serializers.CharField(label=gettext_lazy("Field Name")) display_name = serializers.CharField(label=gettext_lazy("Field Display Name")) is_priority = serializers.BooleanField(label=gettext_lazy("Is Priority")) - description = serializers.CharField(label=gettext_lazy("Field Description")) + description = serializers.CharField(label=gettext_lazy("Field Description"), default="", allow_blank=True) class CreateStrategyRequestSerializer(serializers.ModelSerializer): @@ -525,11 +525,13 @@ class EventInfoFieldSerializer(serializers.Serializer): def to_internal_value(self, data): # example 可能是 list 或 bool,均转换为字符串进行展示 example = data["example"] - if isinstance(example, (bool, list, dict)): - try: + try: + if isinstance(example, (list, dict)): data["example"] = json.dumps(example) - except Exception: # NOCC:broad-except(需要处理所有错误) - data["example"] = str(example) + except Exception: # NOCC:broad-except(需要处理所有错误) + pass + finally: + data["example"] = str(example) return super().to_internal_value(data) @@ -547,3 +549,13 @@ class GetEventInfoFieldsResponseSerializer(serializers.Serializer): event_evidence_field_configs = serializers.ListField( label=gettext_lazy("Event Evidence Field Configs"), child=EventInfoFieldSerializer(), required=False ) + + +class GetStrategyDisplayInfoRequestSerializer(serializers.Serializer): + strategy_ids = serializers.CharField(label=gettext_lazy("Strategy IDs")) + + def validate_strategy_ids(self, strategy_ids: str) -> List[int]: + try: + return [int(s) for s in strategy_ids.split(",") if s] + except ValueError: + raise serializers.ValidationError(gettext("Strategy ID Invalid")) diff --git a/src/backend/services/web/strategy_v2/views.py b/src/backend/services/web/strategy_v2/views.py index 2854e965..8e8dc57e 100644 --- a/src/backend/services/web/strategy_v2/views.py +++ b/src/backend/services/web/strategy_v2/views.py @@ -61,6 +61,7 @@ def get_permissions(self): ResourceRoute("GET", resource.strategy_v2.get_strategy_common, endpoint="common"), ResourceRoute("GET", resource.strategy_v2.get_strategy_status, endpoint="status"), ResourceRoute("PUT", resource.strategy_v2.retry_strategy, pk_field="strategy_id", endpoint="retry"), + ResourceRoute("GET", resource.strategy_v2.get_strategy_display_info, endpoint="display_info"), ]