From 7c4e246be68b301702461cf043b5d8a86396a042 Mon Sep 17 00:00:00 2001 From: JetDrag Date: Thu, 3 Jul 2025 21:19:09 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E5=AE=A1=E8=AE=A1=E9=A3=8E?= =?UTF-8?q?=E9=99=A9=E6=9D=83=E9=99=90=E6=A8=A1=E5=9E=8B=E8=B0=83=E6=95=B4?= =?UTF-8?q?-=E9=A3=8E=E9=99=A9=E5=88=97=E8=A1=A8&=E9=A3=8E=E9=99=A9?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E5=A2=9E=E5=8A=A0=E5=85=B3=E6=B3=A8=E4=BA=BA?= =?UTF-8?q?=E6=9D=83=E9=99=90=20=20--story=3D125525460?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/services/web/risk/admin.py | 4 +- .../services/web/risk/handlers/ticket.py | 25 ++++++++++- ...cketpermission_unique_together_and_more.py | 45 +++++++++++++++++++ src/backend/services/web/risk/models.py | 23 +++++++--- src/backend/services/web/risk/permissions.py | 13 +++--- 5 files changed, 94 insertions(+), 16 deletions(-) create mode 100644 src/backend/services/web/risk/migrations/0027_alter_ticketpermission_unique_together_and_more.py diff --git a/src/backend/services/web/risk/admin.py b/src/backend/services/web/risk/admin.py index 64e137c5a..f6a2b0c78 100644 --- a/src/backend/services/web/risk/admin.py +++ b/src/backend/services/web/risk/admin.py @@ -75,6 +75,6 @@ class TicketNodeAdmin(admin.ModelAdmin): @admin.register(TicketPermission) class TicketPermissionAdmin(admin.ModelAdmin): - list_display = ["id", "risk_id", "action", "operator"] - search_fields = ["risk_id", "operator"] + list_display = ["id", "risk_id", "action", "user"] + search_fields = ["risk_id", "user"] list_filter = ["action"] diff --git a/src/backend/services/web/risk/handlers/ticket.py b/src/backend/services/web/risk/handlers/ticket.py index eaa370ebb..2467a1220 100644 --- a/src/backend/services/web/risk/handlers/ticket.py +++ b/src/backend/services/web/risk/handlers/ticket.py @@ -46,7 +46,13 @@ ) from services.web.risk.handlers.risk import RiskHandler from services.web.risk.handlers.rule import RiskRuleHandler -from services.web.risk.models import ProcessApplication, Risk, RiskRule, TicketNode +from services.web.risk.models import ( + ProcessApplication, + Risk, + RiskRule, + TicketNode, + UserType, +) from services.web.strategy_v2.models import Strategy @@ -132,6 +138,7 @@ def run(self, *args, **kwargs) -> None: self.record_history(process_result=process_result, *args, **kwargs) self.auth_current_operator() self.notice_current_operator() + self.auth_notice_user() self.post_process(process_result=process_result, *args, **kwargs) def pre_check(self, *args, **kwargs) -> None: @@ -208,7 +215,21 @@ def auth_current_operator(self) -> None: if not self.risk.current_operator or not isinstance(self.risk.current_operator, list): return - self.risk.auth_operators(action=ActionEnum.LIST_RISK.id, operators=self.risk.current_operator) + self.risk.auth_users( + action=ActionEnum.LIST_RISK.id, users=self.risk.current_operator, user_type=UserType.OPERATOR + ) + + def auth_notice_user(self) -> None: + """ + 向关注人授权 + """ + + if not self.risk.notice_users or not isinstance(self.risk.notice_users, list): + return + + self.risk.auth_users( + action=ActionEnum.LIST_RISK.id, users=self.risk.notice_users, user_type=UserType.NOTICE_USER + ) def notice_current_operator(self) -> None: """ diff --git a/src/backend/services/web/risk/migrations/0027_alter_ticketpermission_unique_together_and_more.py b/src/backend/services/web/risk/migrations/0027_alter_ticketpermission_unique_together_and_more.py new file mode 100644 index 000000000..3d279f5be --- /dev/null +++ b/src/backend/services/web/risk/migrations/0027_alter_ticketpermission_unique_together_and_more.py @@ -0,0 +1,45 @@ +# Generated by Django 4.2.19 on 2025-07-04 06:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('risk', '0026_risk_created_at_risk_created_by_risk_updated_at_and_more'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='ticketpermission', + unique_together=set(), + ), + migrations.AddField( + model_name='ticketpermission', + name='user', + field=models.CharField(db_index=True, max_length=255, verbose_name='User'), + ), + migrations.AddField( + model_name='ticketpermission', + name='user_type', + field=models.CharField( + choices=[('operator', 'Operator'), ('notice_user', 'Notice User')], + db_index=True, + max_length=32, + verbose_name='User Type', + ), + ), + migrations.RunPython( + code=lambda apps, schema_editor: apps.get_model('risk', 'TicketPermission') + .objects.all() + .update(user=models.F('operator'), user_type='operator'), + reverse_code=lambda apps, schema_editor: None, + ), + migrations.AlterUniqueTogether( + name='ticketpermission', + unique_together={('risk_id', 'action', 'user', 'user_type')}, + ), + migrations.RemoveField( + model_name='ticketpermission', + name='operator', + ), + ] diff --git a/src/backend/services/web/risk/models.py b/src/backend/services/web/risk/models.py index d60ce5d83..ba004daf3 100644 --- a/src/backend/services/web/risk/models.py +++ b/src/backend/services/web/risk/models.py @@ -54,6 +54,11 @@ def generate_risk_id() -> str: return risk_id +class UserType(models.TextChoices): + OPERATOR = "operator" + NOTICE_USER = "notice_user" + + class Risk(OperateRecordModel): """ Risk @@ -120,7 +125,9 @@ def load_authed_risks(cls, action: Union[ActionMeta, str]) -> QuerySet: q = Q( risk_id__in=TicketPermission.objects.filter( - operator=get_request_username(), action=ActionEnum.LIST_RISK.id + user_type__in=[UserType.NOTICE_USER, UserType.OPERATOR], + user=get_request_username(), + action=ActionEnum.LIST_RISK.id, ).values("risk_id") ) @@ -154,13 +161,14 @@ def last_history(self) -> Union["TicketNode", None]: return node return TicketNode() - def auth_operators(self, action: str, operators: List[str]) -> None: + def auth_users(self, action: str, users: List[str], user_type: str = UserType.OPERATOR) -> None: """ - 授权处理人查看权限 + 授权相关用户查询权限 """ - TicketPermission.objects.bulk_create( - objs=[TicketPermission(risk_id=self.risk_id, action=action, operator=operator) for operator in operators], + objs=[ + TicketPermission(risk_id=self.risk_id, action=action, user_type=user_type, user=user) for user in users + ], ignore_conflicts=True, ) @@ -346,11 +354,12 @@ class TicketPermission(models.Model): risk_id = models.CharField(gettext_lazy("Risk ID"), max_length=255, db_index=True) action = models.CharField(gettext_lazy("Action"), max_length=32, db_index=True) - operator = models.CharField(gettext_lazy("Operator"), max_length=255, db_index=True) + user = models.CharField(gettext_lazy("User"), max_length=255, db_index=True) authorized_at = models.DateTimeField(gettext_lazy("Authorized Time"), auto_now_add=True) + user_type = models.CharField(gettext_lazy("User Type"), choices=UserType.choices, max_length=32, db_index=True) class Meta: verbose_name = gettext_lazy("Ticket Permission") verbose_name_plural = verbose_name ordering = ["-id"] - unique_together = [["risk_id", "action", "operator"]] + unique_together = [["risk_id", "action", "user", "user_type"]] diff --git a/src/backend/services/web/risk/permissions.py b/src/backend/services/web/risk/permissions.py index 21b4cc565..c95eb3a3d 100644 --- a/src/backend/services/web/risk/permissions.py +++ b/src/backend/services/web/risk/permissions.py @@ -15,13 +15,12 @@ We undertake not to change the open source license (MIT license) applicable to the current version of the project delivered to anyone in the future. """ - from django.shortcuts import get_object_or_404 from apps.permission.handlers.actions import ActionEnum from apps.permission.handlers.drf import IAMPermission, InstanceActionPermission from apps.permission.handlers.resource_types import ResourceEnum -from services.web.risk.models import Risk, TicketPermission +from services.web.risk.models import Risk, TicketPermission, UserType class RiskViewPermission(InstanceActionPermission): @@ -42,12 +41,16 @@ def has_risk_permission(self, risk_id: str, operator: str) -> bool: def has_risk_local_permission(self, risk_id: str, operator: str) -> bool: """ - 校验本地风险权限 + 校验本地风险权限。 """ - return all( [ - TicketPermission.objects.filter(risk_id=risk_id, action=action.id, operator=operator).exists() + TicketPermission.objects.filter( + user_type__in=[UserType.NOTICE_USER, UserType.OPERATOR], + risk_id=risk_id, + action=action.id, + user=operator, + ).exists() for action in self.actions ] ) From 43d6f034684bf63178a672d0bebf9324046947b0 Mon Sep 17 00:00:00 2001 From: Wang Date: Tue, 12 Aug 2025 11:05:55 +0800 Subject: [PATCH 2/2] fix: update operator description --- src/backend/services/web/risk/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/services/web/risk/constants.py b/src/backend/services/web/risk/constants.py index 355f6f5b2..a854bdee0 100644 --- a/src/backend/services/web/risk/constants.py +++ b/src/backend/services/web/risk/constants.py @@ -217,7 +217,7 @@ def fields(self): OPERATOR = Field( field_name="operator", alias_name="operator", - description=gettext_lazy("负责人"), + description=gettext_lazy("责任人"), field_type=FIELD_TYPE_TEXT, is_text=True, is_analyzed=True,