Skip to content

Commit

Permalink
revert: rollback organization
Browse files Browse the repository at this point in the history
  • Loading branch information
neronkl committed Dec 12, 2023
1 parent 7610322 commit 435a78d
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 103 deletions.
13 changes: 5 additions & 8 deletions src/bk-user/bkuser/apis/web/organization/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ class TenantDepartmentOutputSLZ(serializers.Serializer):
class TenantUserDepartmentOutputSLZ(serializers.Serializer):
id = serializers.IntegerField(help_text="租户用户ID")
name = serializers.CharField(help_text="租户部门名称")
organization_path = serializers.CharField(help_text="部门路径")


class TenantUserLeaderOutputSLZ(serializers.Serializer):
Expand Down Expand Up @@ -64,12 +63,12 @@ def get_account_expired_at(self, instance: TenantUser) -> str:
class TenantUserListOutputSLZ(TenantUserInfoOutputSLZ):
@swagger_serializer_method(serializer_or_field=TenantUserDepartmentOutputSLZ(many=True))
def get_departments(self, instance: TenantUser) -> List[Dict]:
departments = self.context["tenant_user_departments_map"].get(instance.id) or []
return [{"id": i.id, "name": i.name, "organization_path": i.organization_path} for i in departments]
departments = self.context["tenant_user_departments"].get(instance.id) or []
return [{"id": i.id, "name": i.name} for i in departments]

def to_representation(self, instance: TenantUser) -> Dict:
data = super().to_representation(instance)
user_info = self.context["tenant_user_info_map"].get(instance.id)
user_info = self.context["tenant_users_info"].get(instance.id)
if user_info is not None:
user = user_info.data_source_user
data.update(
Expand All @@ -91,11 +90,9 @@ class TenantUserRetrieveOutputSLZ(TenantUserInfoOutputSLZ):

@swagger_serializer_method(serializer_or_field=TenantUserDepartmentOutputSLZ(many=True))
def get_departments(self, instance: TenantUser) -> List[Dict]:
tenant_user_departments = TenantUserHandler.get_tenant_user_departments_map_by_id(
instance.tenant_id, [instance.id]
)
tenant_user_departments = TenantUserHandler.get_tenant_user_departments_map_by_id([instance.id])
departments = tenant_user_departments.get(instance.id) or []
return [{"id": i.id, "name": i.name, "organization_path": i.organization_path} for i in departments]
return [{"id": i.id, "name": i.name} for i in departments]

@swagger_serializer_method(serializer_or_field=TenantUserLeaderOutputSLZ(many=True))
def get_leaders(self, instance: TenantUser) -> List[Dict]:
Expand Down
79 changes: 41 additions & 38 deletions src/bk-user/bkuser/apis/web/organization/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
from bkuser.apps.permission.constants import PermAction
from bkuser.apps.permission.permissions import perm_class
from bkuser.apps.tenant.models import Tenant, TenantDepartment, TenantUser
from bkuser.biz.data_source import DataSourceDepartmentHandler
from bkuser.biz.tenant import (
TenantDepartmentHandler,
TenantEditableBaseInfo,
Expand Down Expand Up @@ -60,31 +59,31 @@ def get(self, request, *args, **kwargs):
slz.is_valid(raise_exception=True)
data = slz.validated_data

tenant_id = self.get_current_tenant_id()
# 过滤出该租户部门的租户用户
current_department_tenant_user_ids = TenantUserHandler.get_tenant_user_ids_by_tenant_department(
tenant_id=tenant_id, tenant_department_id=self.kwargs["id"], recursive=data["recursive"]
tenant_user_ids = TenantUserHandler.get_tenant_user_ids_by_tenant_department(
tenant_id=self.get_current_tenant_id(), tenant_department_id=self.kwargs["id"], recursive=data["recursive"]
)

# build response
queryset = self.filter_queryset(self.get_queryset().filter(id__in=current_department_tenant_user_ids))
queryset = self.filter_queryset(self.get_queryset().filter(id__in=tenant_user_ids))
if keyword := data.get("keyword"):
queryset = queryset.select_related("data_source_user").filter(
Q(data_source_user__username__icontains=keyword) | Q(data_source_user__full_name__icontains=keyword)
)

tenant_users = self.paginate_queryset(queryset)

tenant_user_ids = [user.id for user in tenant_users]
tenant_user_info_map = {user.id: user for user in TenantUserHandler.list_tenant_user_by_id(tenant_user_ids)}
context = {
"tenant_user_info_map": tenant_user_info_map,
"tenant_user_departments_map": TenantUserHandler.get_tenant_user_departments_map_by_id(
tenant_id, tenant_user_ids
),
slz_context = {
# 租户用户基础信息
"tenant_users_info": {i.id: i for i in TenantUserHandler.list_tenant_user_by_id(tenant_user_ids)},
# 租户用户所属租户组织
"tenant_user_departments": TenantUserHandler.get_tenant_user_departments_map_by_id(tenant_user_ids),
}
serializer = TenantUserListOutputSLZ(tenant_users, many=True, context=context)
return self.get_paginated_response(serializer.data)
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True, context=slz_context)
return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(queryset, many=True, context=slz_context)
return Response(serializer.data)


class TenantUserRetrieveApi(generics.RetrieveAPIView):
Expand Down Expand Up @@ -194,16 +193,10 @@ def get(self, request, *args, **kwargs):
department=tenant_department.data_source_department
).get_children()

# 获取数据源部门基础信息
data_source_department_info_map = DataSourceDepartmentHandler.get_department_info_map_by_ids(
children.values_list("department_id", flat=True)
)
tenant_department_children = TenantDepartmentHandler.convert_data_source_department_to_tenant_department(
tenant_department.tenant_id, data_source_department_info_map
tenant_department.tenant_id, children.values_list("department_id", flat=True)
)
data = [
item.model_dump(include={"id", "name", "has_children"}) for item in tenant_department_children.values()
]
data = [item.model_dump(include={"id", "name", "has_children"}) for item in tenant_department_children]
return Response(TenantDepartmentChildrenListOutputSLZ(data, many=True).data)


Expand All @@ -222,6 +215,22 @@ def get_tenant_user_ids(self, tenant_id):

return TenantUserHandler.get_tenant_user_ids_by_tenant(tenant_id=current_tenant_id)

def get_serializer_context(self):
# 过滤出该租户租户用户
tenant_user_ids = self.get_tenant_user_ids(tenant_id=self.kwargs["id"])

# 租户用户基础信息
tenant_users = TenantUserHandler.list_tenant_user_by_id(tenant_user_ids)
tenant_users_info_map = {i.id: i for i in tenant_users}

# 租户用户所属租户组织
tenant_user_departments_map = TenantUserHandler.get_tenant_user_departments_map_by_id(tenant_user_ids)

return {
"tenant_users_info": tenant_users_info_map,
"tenant_user_departments": tenant_user_departments_map,
}

@swagger_auto_schema(
tags=["tenant-organization"],
operation_description="租户下用户列表",
Expand All @@ -234,24 +243,18 @@ def get(self, request, *args, **kwargs):
data = slz.validated_data

# 租户用户列表ids
tenant_id = self.kwargs["id"]
tenant_user_ids = self.get_tenant_user_ids(self.kwargs["id"])

# build response
queryset = self.filter_queryset(self.get_queryset().filter(id__in=self.get_tenant_user_ids(tenant_id)))
queryset = self.filter_queryset(self.get_queryset().filter(id__in=tenant_user_ids))
if keyword := data.get("keyword"):
queryset = queryset.select_related("data_source_user").filter(
Q(data_source_user__username__icontains=keyword) | Q(data_source_user__full_name__icontains=keyword)
)
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)

tenant_users = self.paginate_queryset(queryset)

tenant_user_ids = [user.id for user in tenant_users]
tenant_user_info_map = {user.id: user for user in TenantUserHandler.list_tenant_user_by_id(tenant_user_ids)}
context = {
"tenant_user_info_map": tenant_user_info_map,
"tenant_user_departments_map": TenantUserHandler.get_tenant_user_departments_map_by_id(
tenant_id, tenant_user_ids
),
}
serializer = TenantUserListOutputSLZ(tenant_users, many=True, context=context)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
4 changes: 1 addition & 3 deletions src/bk-user/bkuser/apis/web/personal_center/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,7 @@ class PersonalCenterTenantUserRetrieveOutputSLZ(serializers.Serializer):

@swagger_serializer_method(serializer_or_field=TenantUserDepartmentOutputSLZ(many=True))
def get_departments(self, instance: TenantUser) -> List[Dict]:
tenant_user_departments = TenantUserHandler.get_tenant_user_departments_map_by_id(
instance.tenant_id, [instance.id]
)
tenant_user_departments = TenantUserHandler.get_tenant_user_departments_map_by_id([instance.id])
departments = tenant_user_departments.get(instance.id) or []
return [{"id": i.id, "name": i.name} for i in departments]

Expand Down
86 changes: 32 additions & 54 deletions src/bk-user/bkuser/biz/tenant.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
)
from bkuser.biz.data_source import (
DataSourceDepartmentHandler,
DataSourceDepartmentInfoWithChildren,
DataSourceHandler,
DataSourceSimpleInfo,
DataSourceUserHandler,
Expand Down Expand Up @@ -91,7 +90,6 @@ class TenantManagerWithoutID(BaseModel):
class TenantDepartmentBaseInfo(BaseModel):
id: int
name: str
organization_path: str
has_children: bool


Expand Down Expand Up @@ -197,40 +195,23 @@ def get_tenant_user_leaders_map_by_id(tenant_user_ids: List[str]) -> Dict[str, L
return tenant_user_leaders_map

@staticmethod
def get_tenant_user_departments_map_by_id(
tenant_id: str, tenant_user_ids: List[str]
) -> Dict[str, List[TenantDepartmentBaseInfo]]:
def get_tenant_user_departments_map_by_id(tenant_user_ids: List[str]) -> Dict[str, List[TenantDepartmentBaseInfo]]:
tenant_users = TenantUser.objects.filter(id__in=tenant_user_ids)

# 获取数据源用户所属部门: 数据源用户ID-所属数据源部门ID列表
# 数据源用户-部门关系映射
data_source_user_department_ids_map = DataSourceDepartmentHandler.get_user_department_ids_map(
user_ids=tenant_users.values_list("data_source_user_id", flat=True)
)
data_source_department_ids = []
for department_id_list in data_source_user_department_ids_map.values():
data_source_department_ids += department_id_list

# 获取数据源部门基础信息
data_source_department_info_map = DataSourceDepartmentHandler.get_department_info_map_by_ids(
data_source_department_ids
)
# 转换为租户部门, 返回数据源部门ID-租户部门数据映射
tenant_department_info_map = TenantDepartmentHandler.convert_data_source_department_to_tenant_department(
tenant_id=tenant_id, data_source_department_info_map=data_source_department_info_map
)
# 构建租户用户-租户部门数据关系
# 租户用户-租户部门数据关系
data: Dict = {}
for tenant_user in tenant_users:
data_source_user_id = tenant_user.data_source_user_id
# 用户所属部门
department_ids = data_source_user_department_ids_map.get(data_source_user_id)
department_ids = data_source_user_department_ids_map.get(tenant_user.data_source_user_id)
if not department_ids:
continue
tenant_department_infos = [
tenant_department_info_map[dept_id]
for dept_id in department_ids
if dept_id in tenant_department_info_map
]

tenant_department_infos = TenantDepartmentHandler.convert_data_source_department_to_tenant_department(
tenant_id=tenant_user.tenant_id, data_source_department_ids=department_ids
)

data[tenant_user.id] = tenant_department_infos
return data

Expand Down Expand Up @@ -396,50 +377,53 @@ def get_data_source_ids_map_by_ids(tenant_ids: List[str]) -> Dict[str, List[int]
class TenantDepartmentHandler:
@staticmethod
def convert_data_source_department_to_tenant_department(
tenant_id: str, data_source_department_info_map: Dict[int, DataSourceDepartmentInfoWithChildren]
) -> Dict[int, TenantDepartmentBaseInfo]:
tenant_id: str, data_source_department_ids: List[int]
) -> List[TenantDepartmentBaseInfo]:
"""
转换为租户部门,返回数据源部门ID-租户部门数据 映射
tenant_id: 租户ID
data_source_department_info_map: 数据源部门ID-数据源部门数据 映射
转换为租户部门
"""
# tenant_id 租户下部门关系映射
tenant_departments = TenantDepartment.objects.filter(tenant_id=tenant_id)

# 获取数据源部门基础信息
data_source_departments = DataSourceDepartmentHandler.get_department_info_map_by_ids(
data_source_department_ids
)

# data_source_departments中包含了父子部门的ID,协同数据源需要查询绑定了该租户
department_ids = list(data_source_department_info_map.keys())
for department in data_source_department_info_map.values():
department_ids = list(data_source_departments.keys())
for department in data_source_departments.values():
department_ids += department.children_ids

# NOTE: 协同数据源,可能存在未授权全部子部门
# 提前拉取所有映射, 过滤绑定的租户部门
tenant_departments = tenant_departments.filter(data_source_department_id__in=department_ids)
if not tenant_departments.exists():
return {}
return []

# 已绑定该租户的数据源部门id
bound_departments_ids = tenant_departments.values_list("data_source_department_id", flat=True)

# 构建返回数据
data: Dict[int, TenantDepartmentBaseInfo] = {}
data: List[TenantDepartmentBaseInfo] = []
for tenant_department in tenant_departments:
# tenant_departments 包含了父子部门的租户映射关系,但是子部门非本次查询的入参,跳过
data_source_department_id = tenant_department.data_source_department_id
if data_source_department_id not in data_source_department_info_map:
if data_source_department_id not in data_source_department_ids:
continue
# 部门基础信息
data_source_department_info = data_source_department_info_map[data_source_department_id]
data_source_department_info = data_source_departments[data_source_department_id]
# 只要一个子部门被授权,都是存在子部门
children_flag = [
True for child in data_source_department_info.children_ids if child in bound_departments_ids
]
data[data_source_department_id] = TenantDepartmentBaseInfo(
id=tenant_department.id,
name=data_source_department_info.name,
organization_path=data_source_department_info.organization_path,
has_children=any(children_flag),
data.append(
TenantDepartmentBaseInfo(
id=tenant_department.id,
name=data_source_department_info.name,
has_children=any(children_flag),
)
)

return data

@staticmethod
Expand All @@ -456,15 +440,9 @@ def get_tenant_root_department_map_by_tenant_id(
.filter(data_source_id__in=data_source_ids)
.values_list("department_id", flat=True)
)
# 获取数据源部门基础信息
data_source_department_info_map = DataSourceDepartmentHandler.get_department_info_map_by_ids(
list(root_department_ids)
)
# 转换数据源部门为当前为 current_tenant_id 租户的租户部门
tenant_root_department_info_map = (
TenantDepartmentHandler.convert_data_source_department_to_tenant_department(
tenant_id=current_tenant_id, data_source_department_info_map=data_source_department_info_map
)
tenant_root_department = TenantDepartmentHandler.convert_data_source_department_to_tenant_department(
tenant_id=current_tenant_id, data_source_department_ids=list(root_department_ids)
)
tenant_root_department_map[tenant_id] = list(tenant_root_department_info_map.values())
tenant_root_department_map[tenant_id] = tenant_root_department
return tenant_root_department_map

0 comments on commit 435a78d

Please sign in to comment.