From 8d50307218859728de5dda2c7fdeb25b009b933f Mon Sep 17 00:00:00 2001 From: Timmy Date: Fri, 14 Jul 2023 12:41:36 +0800 Subject: [PATCH] Feat role switch (#2092) * feat: grademanager user can switch to subsetmanger * feat: add super manager switch --- saas/backend/apps/role/filters.py | 4 +++ saas/backend/apps/role/serializers.py | 1 + saas/backend/apps/role/views/role.py | 4 ++- saas/backend/biz/role.py | 36 ++++++++++++++++++++------- 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/saas/backend/apps/role/filters.py b/saas/backend/apps/role/filters.py index 796079082..a649e87d4 100644 --- a/saas/backend/apps/role/filters.py +++ b/saas/backend/apps/role/filters.py @@ -17,6 +17,7 @@ class GradeMangerFilter(InitialFilterSet): name = filters.CharFilter(lookup_expr="icontains", label="名称") hidden = filters.BooleanFilter(method="hidden_filter", initial=True) + with_super = filters.BooleanFilter(method="with_super_filter", initial=False) class Meta: model = Role @@ -27,6 +28,9 @@ def hidden_filter(self, queryset, name, value): return queryset.filter(hidden=False) return queryset + def with_super_filter(self, queryset, name, value): + return queryset + class RoleCommonActionFilter(filters.FilterSet): system_id = filters.CharFilter(label="系统id") diff --git a/saas/backend/apps/role/serializers.py b/saas/backend/apps/role/serializers.py index 9df235375..3e6b5b93d 100644 --- a/saas/backend/apps/role/serializers.py +++ b/saas/backend/apps/role/serializers.py @@ -222,6 +222,7 @@ class Meta: model = Role fields = ( "id", + "type", "name", "description", "creator", diff --git a/saas/backend/apps/role/views/role.py b/saas/backend/apps/role/views/role.py index 80253b245..a9cb31c08 100644 --- a/saas/backend/apps/role/views/role.py +++ b/saas/backend/apps/role/views/role.py @@ -114,7 +114,9 @@ class GradeManagerViewSet(mixins.ListModelMixin, GenericViewSet): def get_queryset(self): request = self.request - return RoleListQuery(request.role, request.user).query_grade_manager() + return RoleListQuery(request.role, request.user).query_grade_manager( + with_super=bool(request.query_params.get("with_super", False)) + ) @swagger_auto_schema( operation_description="创建分级管理员", diff --git a/saas/backend/biz/role.py b/saas/backend/biz/role.py index b841e66a7..7d47030ef 100644 --- a/saas/backend/biz/role.py +++ b/saas/backend/biz/role.py @@ -16,7 +16,7 @@ from blue_krill.web.std_error import APIError from django.conf import settings from django.db import connection -from django.db.models import Q +from django.db.models import Case, Q, Value, When from django.utils.functional import cached_property from django.utils.translation import gettext as _ from pydantic import BaseModel, parse_obj_as @@ -781,13 +781,28 @@ def list_role_scope_include_user(self): mgr_ids = self._list_authorization_scope_include_user_role_ids() return self.role_svc.list_by_ids(mgr_ids, with_hidden=False) - def query_grade_manager(self): + def query_grade_manager(self, with_super: bool = False): """ 查询分级管理员列表 """ + queryset = Role.objects.filter(type=RoleType.GRADE_MANAGER.value).order_by("-updated_time") + if with_super: + type_order = Case( + When(type=RoleType.SUPER_MANAGER.value, then=Value(1)), + When(type=RoleType.SYSTEM_MANAGER.value, then=Value(2)), + When(type=RoleType.GRADE_MANAGER.value, then=Value(3)), + ) + queryset = ( + Role.objects.filter( + type__in=[RoleType.SUPER_MANAGER, RoleType.SYSTEM_MANAGER, RoleType.GRADE_MANAGER.value] + ) + .alias(type_order=type_order) + .order_by("type_order", "-updated_time") + ) + # 作为超级管理员时,可以管理所有分级管理员 if self.role.type == RoleType.SUPER_MANAGER.value: - return Role.objects.filter(type=RoleType.GRADE_MANAGER.value).order_by("-updated_time") + return queryset # 作为个人时,只能管理加入的的分级管理员 assert self.user @@ -799,7 +814,7 @@ def query_grade_manager(self): grade_manager_ids = list(RoleRelation.objects.filter(role_id__in=role_ids).values_list("parent_id", flat=True)) role_ids.extend(grade_manager_ids) - return Role.objects.filter(type=RoleType.GRADE_MANAGER.value, id__in=role_ids).order_by("-updated_time") + return queryset.filter(id__in=role_ids) def query_subset_manager(self): """ @@ -1231,11 +1246,14 @@ def _diff_conditions( def can_user_manage_role(username: str, role_id: int) -> bool: """是否用户能管理角色""" - if RoleUser.objects.user_role_exists(username, role_id): - return True + role_ids = [role_id] relation = RoleRelation.objects.filter(role_id=role_id).first() - if not relation: - return False + if relation: + role_ids.append(relation.parent_id) + + super_manager = Role.objects.filter(type=RoleType.SUPER_MANAGER.value).first() + if super_manager: + role_ids.append(super_manager.id) - return RoleUser.objects.user_role_exists(username, relation.parent_id) + return RoleUser.objects.filter(role_id__in=role_ids, username=username).exists()