Skip to content

Commit

Permalink
code review 调整
Browse files Browse the repository at this point in the history
  • Loading branch information
neronkl committed Aug 22, 2023
1 parent 4718b26 commit 7755b3e
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 92 deletions.
21 changes: 21 additions & 0 deletions src/bk-user/bkuser/apis/web/organization/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
"""
TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-用户管理(Bk-User) available.
Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
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 logging

from rest_framework import serializers

logger = logging.getLogger(__name__)


class TenantDepartmentChildrenListOutputSLZ(serializers.Serializer):
id = serializers.IntegerField(help_text="租户部门ID")
name = serializers.CharField(help_text="部门名称")
has_children = serializers.BooleanField(help_text="是否有子部门")
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,9 @@
from . import views

urlpatterns = [
path("departments/<str:id>/children/", views.TenantDepartmentChildrenListApi.as_view()),
path(
"departments/<int:id>/children/",
views.TenantDepartmentChildrenListApi.as_view(),
name="organization.children.list",
),
]
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,25 @@

from drf_yasg.utils import swagger_auto_schema
from rest_framework import generics, status
from rest_framework.response import Response

from bkuser.apis.web.tenant_organization.serializers import TenantDepartmentChildrenListOutputSLZ
from bkuser.apps.tenant.models import TenantDepartment
from bkuser.apis.web.organization.serializers import TenantDepartmentChildrenListOutputSLZ
from bkuser.biz.tenant import TenantDepartmentHandler

logger = logging.getLogger(__name__)


class TenantDepartmentChildrenListApi(generics.RetrieveAPIView):
lookup_url_kwarg = "id"
queryset = TenantDepartment.objects.all()
class TenantDepartmentChildrenListApi(generics.ListAPIView):
pagination_class = None
serializer_class = TenantDepartmentChildrenListOutputSLZ

@swagger_auto_schema(
operation_description="租户部门的二级子部门",
responses={status.HTTP_200_OK: TenantDepartmentChildrenListOutputSLZ()},
operation_description="租户部门的二级子部门列表",
responses={status.HTTP_200_OK: TenantDepartmentChildrenListOutputSLZ(many=True)},
)
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
tenant_department_id = self.kwargs["id"]
# 拉取子部门信息列表
tenant_department_children = TenantDepartmentHandler.get_tenant_department_children_by_id(tenant_department_id)
data = [item.model_dump(include={"id", "name", "has_children"}) for item in tenant_department_children]
return Response(self.get_serializer(data, many=True).data)
54 changes: 0 additions & 54 deletions src/bk-user/bkuser/apis/web/tenant_organization/serializers.py

This file was deleted.

2 changes: 1 addition & 1 deletion src/bk-user/bkuser/apis/web/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
path("basic/", include("bkuser.apis.web.basic.urls")),
# 租户
path("tenants/", include("bkuser.apis.web.tenant.urls")),
path("tenant-organization-tree/", include("bkuser.apis.web.tenant_organization.urls")),
path("tenant-organization/", include("bkuser.apis.web.organization.urls")),
]
42 changes: 40 additions & 2 deletions src/bk-user/bkuser/biz/data_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@

from pydantic import BaseModel

from bkuser.apps.data_source.models import DataSource
from bkuser.apps.data_source.models import DataSource, DataSourceDepartment, DataSourceDepartmentRelation


class DataSourceDepartmentInfoWithChildren(BaseModel):
id: int
name: str
children: List[int]


class DataSourceSimpleInfo(BaseModel):
Expand All @@ -27,7 +33,7 @@ def get_data_source_map_by_owner(
owner_tenant_ids: Optional[List[str]] = None,
) -> Dict[str, List[DataSourceSimpleInfo]]:
"""
查询租户下数据源
查询数据源
"""
data_sources = DataSource.objects.all()
if owner_tenant_ids is not None:
Expand All @@ -38,3 +44,35 @@ def get_data_source_map_by_owner(
data[i.owner_tenant_id].append(DataSourceSimpleInfo(id=i.id, name=i.name))

return data

@staticmethod
def get_data_sources_by_tenant(tenant_ids: List[str]) -> Dict[str, List[int]]:
# 当前属于租户的数据源
tenant_data_source_map: Dict = {}
data_sources = DataSource.objects.filter(owner_tenant_id__in=tenant_ids).values("id", "owner_tenant_id")
for item in data_sources:
tenant_id = item["owner_tenant_id"]
if tenant_id in tenant_data_source_map:
tenant_data_source_map[tenant_id].append(item["id"])
else:
tenant_data_source_map[tenant_id] = [item["id"]]
# TODO 协同数据源获取
return tenant_data_source_map


class DataSourceDepartmentHandler:
@staticmethod
def get_department_info_by_id(department_ids: List[int]) -> Dict[int, DataSourceDepartmentInfoWithChildren]:
"""
获取部门基础信息
"""
departments = DataSourceDepartment.objects.filter(id__in=department_ids)
departments_map: Dict = {}
for item in departments:
children = DataSourceDepartmentRelation.objects.get(department=item).get_children()
departments_map[item.id] = DataSourceDepartmentInfoWithChildren(
id=item.id,
name=item.name,
children=list(children.values_list("department_id", flat=True)),
)
return departments_map
110 changes: 84 additions & 26 deletions src/bk-user/bkuser/biz/tenant.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

from bkuser.apps.data_source.models import DataSource, DataSourceDepartmentRelation, DataSourcePlugin, DataSourceUser
from bkuser.apps.tenant.models import Tenant, TenantDepartment, TenantManager, TenantUser
from bkuser.biz.data_source import DataSourceDepartmentHandler, DataSourceHandler
from bkuser.utils.uuid import generate_uuid


Expand Down Expand Up @@ -68,11 +69,7 @@ class TenantManagerWithoutID(BaseModel):


class TenantDepartmentBaseInfo(BaseModel):
"""
部门基础信息
"""

tenant_department_id: int
id: int
name: str
has_children: bool

Expand Down Expand Up @@ -133,6 +130,16 @@ def get_tenant_manager_map(tenant_ids: Optional[List[str]] = None) -> Dict[str,

return data

@staticmethod
def retrieve_tenant_managers(tenant_id: str) -> List[TenantUserWithInheritedInfo]:
"""
查询单个租户的租户管理员
"""
tenant_managers = TenantManager.objects.filter(tenant_id=tenant_id)
# 查询管理员对应的信息
tenant_user_ids = [i.tenant_user_id for i in tenant_managers]
return TenantUserHandler.list_tenant_user_by_id(tenant_user_ids)

@staticmethod
def create_with_managers(tenant_info: TenantBaseInfo, managers: List[TenantManagerWithoutID]) -> str:
"""
Expand Down Expand Up @@ -200,29 +207,80 @@ def update_with_managers(tenant_id: str, tenant_info: TenantEditableBaseInfo, ma

class TenantDepartmentHandler:
@staticmethod
def get_tenant_departments_info_map(
tenant_id: str, data_source_departments: Optional[List[int]] = None
) -> Dict[int, TenantDepartmentBaseInfo]:
def convert_data_source_department_to_tenant_department(
tenant_id: str, data_source_department_ids: List[int]
) -> List[TenantDepartmentBaseInfo]:
"""
获取租户的部门映射
转换为租户部门
"""
# tenant_id 租户下部门关系映射
tenant_departments = TenantDepartment.objects.filter(tenant_id=tenant_id)
if data_source_departments:
tenant_departments = tenant_departments.filter(data_source_department_id__in=data_source_departments)
# 构建映射关系数据
departments_map: dict = {}
for item in tenant_departments:
# NOTE: 协同数据源,可能存在未授权全部子部门
children_ids = DataSourceDepartmentRelation.objects.filter(
parent_id=item.data_source_department.id
).values_list("department_id", flat=True)
has_children = TenantDepartment.objects.filter(data_source_department_id__in=children_ids).exists()
departments_map[item.data_source_department.id] = TenantDepartmentBaseInfo(
**{
"tenant_department_id": item.id,
"name": item.data_source_department.name,
"has_children": has_children,
}

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

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

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

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

# 构建返回数据
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_ids:
continue
# 部门基础信息
data_source_department_info = data_source_departments[data_source_department_id]
# 只要一个子部门被授权,都是存在子部门
children_flag = [True for child in data_source_department_info.children if child in bound_departments_ids]
data.append(
TenantDepartmentBaseInfo(
id=tenant_department.id,
name=data_source_department_info.name,
has_children=any(children_flag),
)
)
return departments_map
return data

@staticmethod
def get_tenant_root_departments_by_id(
tenant_ids: List[str], convert_tenant_id: str
) -> Dict[str, List[TenantDepartmentBaseInfo]]:
data_source_map = DataSourceHandler.get_data_sources_by_tenant(tenant_ids)

# 通过获取数据源的根节点
tenant_root_department_map: Dict = {}
for tenant_id, data_source_ids in data_source_map.items():
root_department_ids = (
DataSourceDepartmentRelation.objects.root_nodes()
.filter(data_source_id__in=data_source_ids)
.values_list("department_id", flat=True)
)
# 转换数据源部门为当前为 convert_tenant_id租户的租户部门
tenant_root_department = TenantDepartmentHandler.convert_data_source_department_to_tenant_department(
tenant_id=convert_tenant_id, data_source_department_ids=list(root_department_ids)
)
tenant_root_department_map[tenant_id] = tenant_root_department
return tenant_root_department_map

@staticmethod
def get_tenant_department_children_by_id(tenant_department_id: int) -> List[TenantDepartmentBaseInfo]:
tenant_department = TenantDepartment.objects.get(id=tenant_department_id)
# 获取二级组织
children = DataSourceDepartmentRelation.objects.get(
department=tenant_department.data_source_department
).get_children()
return TenantDepartmentHandler.convert_data_source_department_to_tenant_department(
tenant_department.tenant_id, children.values_list("department_id", flat=True)
)

0 comments on commit 7755b3e

Please sign in to comment.