Skip to content

Commit

Permalink
code review 调整
Browse files Browse the repository at this point in the history
  • Loading branch information
neronkl committed Aug 18, 2023
1 parent 3aa77de commit 325cfce
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 180 deletions.
40 changes: 40 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,40 @@
# -*- 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 django.conf import settings
from drf_yasg.utils import swagger_serializer_method
from rest_framework import serializers

from bkuser.apps.tenant.models import Tenant

logger = logging.getLogger(__name__)


class TenantDepartmentOutputSLZ(serializers.Serializer):
id = serializers.IntegerField(help_text="租户部门ID")
name = serializers.CharField(help_text="部门名称")
has_children = serializers.BooleanField(help_text="是否有子部门")


class TenantListOutputSLZ(serializers.Serializer):
id = serializers.CharField(help_text="租户组织节点ID")
name = serializers.CharField(help_text="租户组织节点名称名")
logo = serializers.SerializerMethodField(help_text="租户 Logo")
departments = serializers.SerializerMethodField(help_text="租户下每个数据源的根组织")

def get_logo(self, instance: Tenant) -> str:
return instance.logo or settings.DEFAULT_TENANT_LOGO

@swagger_serializer_method(serializer_or_field=TenantDepartmentOutputSLZ(many=True))
def get_departments(self, instance: Tenant):
departments = self.context["tenant_root_department_map"].get(instance.id)
return [item.model_dump() for item in departments.values()]
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@

urlpatterns = [
# 租户
path("tenants/", views.TenantsListApi.as_view(), name="tenant_departments.retrieve_tenant"),
path("tenants/<str:id>/", views.TenantRetrieveUpdateApi.as_view(), name="tenant_departments.retrieve_tenant"),
path("tenants/", views.TenantListApi.as_view(), name="organization.tenant.list"),
path("tenants/<str:id>/", views.TenantRetrieveUpdateApi.as_view(), name="organization.tenant.retrieve_update"),
]
Original file line number Diff line number Diff line change
Expand Up @@ -14,56 +14,71 @@
from rest_framework import generics, status
from rest_framework.response import Response

from bkuser.apis.web.tenant_organization.serializers import (
TenantsListOutputSLZ,
TenantsRetrieveOutputSLZ,
TenantUpdateInputSLZ,
)
from bkuser.apis.web.organization.serializers import TenantListOutputSLZ
from bkuser.apis.web.tenant.serializers import TenantRetrieveOutputSLZ, TenantUpdateInputSLZ
from bkuser.apps.data_source.models import DataSourceDepartmentRelation
from bkuser.apps.tenant.models import Tenant
from bkuser.biz.data_source import DataSourceDepartmentHandler, DataSourceHandler
from bkuser.biz.tenant import (
TenantDepartmentHandler,
TenantEditableBaseInfo,
TenantFeatureFlag,
TenantHandler,
)
from bkuser.common.error_codes import error_codes
from bkuser.common.views import ExcludePatchAPIViewMixin

logger = logging.getLogger(__name__)


class TenantsListApi(generics.ListAPIView):
class TenantListApi(generics.ListAPIView):
pagination_class = None
queryset = Tenant.objects.all()
serializer_class = TenantsListOutputSLZ
serializer_class = TenantListOutputSLZ

def _get_tenant_id(self) -> str:
# TODO 根据登录用户获取租户
return self.queryset.first().id
return self.request.user.get_property("tenant_id")

def get_serializer_context(self):
return {"current_tenant_id": self._get_tenant_id()}

def get_queryset(self):
tenant_id = self._get_tenant_id()
# TODO 协同数据源, 以租户的形式展示, 如何获取?
return Tenant.objects.filter(id__in=[tenant_id])
current_tenant_id = self._get_tenant_id()
tenant_root_department_map = {}
# 获取旗下根部门的各个数据源
# TODO 协同数据源,是以租户的形式展示,考虑怎么获取授权的数据源?
tenant_data_sources = DataSourceHandler.get_data_source_map_by_owner([current_tenant_id])
for tenant_id, data_sources in tenant_data_sources.items():
data_sources_ids = [i.id for i in data_sources]
# 通过获取数据源的根节点
root_departments = (
DataSourceDepartmentRelation.objects.root_nodes()
.filter(data_source_id__in=data_sources_ids)
.values_list("department_id", flat=True)
)
# 获取部门基础信息
departments_infos = DataSourceDepartmentHandler.list_departments_info(root_departments)
tenant_root_department_map[
tenant_id
] = TenantDepartmentHandler.convert_data_source_department_to_tenant_department(
tenant_id=current_tenant_id, data_source_departments=departments_infos
)
return {"tenant_root_department_map": tenant_root_department_map}

@swagger_auto_schema(
operation_description="租户列表",
responses={status.HTTP_200_OK: TenantsListOutputSLZ(many=True)},
responses={status.HTTP_200_OK: TenantListOutputSLZ(many=True)},
)
def get(self, request, *args, **kwargs):
# TODO 协同数据源, 以租户的形式展示, 如何获取?
return self.list(request, *args, **kwargs)


class TenantRetrieveUpdateApi(ExcludePatchAPIViewMixin, generics.RetrieveUpdateAPIView):
queryset = Tenant.objects.all()
pagination_class = None
serializer_class = TenantsRetrieveOutputSLZ
serializer_class = TenantRetrieveOutputSLZ
lookup_url_kwarg = "id"

def _get_tenant_id(self) -> str:
# TODO 根据当前租户获取租户ID
return self.queryset.first().id
return self.request.user.get_property("tenant_id")

def get_serializer_context(self):
# 根据当前登录的租户用户,获取租户ID
Expand All @@ -75,7 +90,7 @@ def get_serializer_context(self):

@swagger_auto_schema(
operation_description="单个租户详情",
responses={status.HTTP_200_OK: TenantsRetrieveOutputSLZ()},
responses={status.HTTP_200_OK: TenantRetrieveOutputSLZ()},
)
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
Expand All @@ -93,12 +108,11 @@ def put(self, request, *args, **kwargs):
instance = self.get_object()
# NOTE 因协同数据源,而展示的租户,不返回管理员
if self._get_tenant_id() != instance.id:
return Response
raise error_codes.NO_PERMISSION

should_updated_info = TenantEditableBaseInfo(
name=data["name"], logo=data.get("logo") or "", feature_flags=TenantFeatureFlag(**data["feature_flags"])
name=data["name"], logo=data["logo"] or "", feature_flags=TenantFeatureFlag(**data["feature_flags"])
)

TenantHandler.update_with_managers(instance.id, should_updated_info, data["manager_ids"])

return Response()
2 changes: 1 addition & 1 deletion src/bk-user/bkuser/apis/web/tenant/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def get_data_sources(self, obj: Tenant) -> List[Dict]:

class TenantUpdateInputSLZ(serializers.Serializer):
name = serializers.CharField(help_text="租户名称")
logo = serializers.CharField(help_text="租户 Logo", required=False)
logo = serializers.CharField(help_text="租户 Logo", required=False, default=settings.DEFAULT_TENANT_LOGO)
manager_ids = serializers.ListField(child=serializers.CharField(), help_text="租户用户 ID 列表", allow_empty=False)
feature_flags = TenantFeatureFlagSLZ(help_text="租户特性集")

Expand Down
106 changes: 0 additions & 106 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-tree/", include("bkuser.apis.web.organization.urls")),
]
40 changes: 12 additions & 28 deletions src/bk-user/bkuser/biz/data_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,12 @@
from pydantic import BaseModel

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


class DataSourceDepartmentInfo(BaseModel):
id: int
name: str
data_source_id: int
children: list
full_name: str
children: List[int]


class DataSourceSimpleInfo(BaseModel):
Expand Down Expand Up @@ -51,30 +48,17 @@ def get_data_source_map_by_owner(

class DataSourceDepartmentHandler:
@staticmethod
def retrieve_department(department_id: int) -> DataSourceDepartmentInfo:
def list_departments_info(department_ids: List[int]) -> Dict[int, DataSourceDepartmentInfo]:
"""
获取单个部门信息
获取部门基础信息
"""
try:
# 生成组织架构路径
parent_ids = (
DataSourceDepartmentRelation.objects.get(id=department_id)
.get_ancestors(include_self=True)
.values_list("id", flat=True)
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] = DataSourceDepartmentInfo(
id=item.id,
name=item.name,
children=list(children.values_list("department_id", flat=True)),
)
parents = DataSourceDepartment.objects.filter(id__in=parent_ids).values_list("name", flat=True)
full_name = "/".join(list(parents))
# 构建基础信息
department = DataSourceDepartment.objects.get(id=department_id)
base_info = {
"id": department.id,
"name": department.name,
"full_name": full_name,
"data_source_id": department.data_source_id,
"children": DataSourceDepartmentRelation.objects.filter(parent_id=department.id).values(
"id", flat=True
),
}
return DataSourceDepartmentInfo(**base_info)
except DataSourceDepartment.DoesNotExist:
raise error_codes.OBJECT_NOT_FOUND
return departments_map
Loading

0 comments on commit 325cfce

Please sign in to comment.