-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(organization): 查询租户部门下租户用户列表/租户用户详情
- Loading branch information
Showing
7 changed files
with
475 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# -*- 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. | ||
""" |
118 changes: 118 additions & 0 deletions
118
src/bk-user/bkuser/apis/web/organization/serializers.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
# -*- 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. | ||
""" | ||
from typing import Dict, List | ||
|
||
from django.conf import settings | ||
from drf_yasg.utils import swagger_serializer_method | ||
from rest_framework import serializers | ||
|
||
from bkuser.apps.tenant.models import TenantUser | ||
from bkuser.biz.tenant import TenantUserHandler | ||
|
||
|
||
class TenantUserDepartmentOutputSLZ(serializers.Serializer): | ||
id = serializers.IntegerField(help_text="租户用户ID") | ||
name = serializers.CharField(help_text="租户部门名称") | ||
|
||
|
||
class TenantUserLeaderOutputSLZ(serializers.Serializer): | ||
id = serializers.IntegerField(help_text="租户用户ID") | ||
username = serializers.CharField(help_text="上级用户名") | ||
full_name = serializers.BooleanField(help_text="上级名称") | ||
|
||
|
||
class TenantDepartmentUserSearchInputSLZ(serializers.Serializer): | ||
page = serializers.IntegerField(required=False, default=1) | ||
page_size = serializers.IntegerField(required=False, default=10) | ||
recursive = serializers.BooleanField(help_text="仅仅展示该部门下人员", default=True) | ||
keyword = serializers.CharField(help_text="搜索关键字", required=False) | ||
|
||
|
||
class TenantDepartmentUserOutputSLZ(serializers.Serializer): | ||
id = serializers.CharField(help_text="租户用户ID") | ||
username = serializers.CharField(help_text="租户用户名", required=False) | ||
full_name = serializers.CharField(help_text="用户姓名", required=False) | ||
email = serializers.EmailField(help_text="用户邮箱", required=False) | ||
phone = serializers.CharField(help_text="用户手机号", required=False) | ||
phone_country_code = serializers.CharField( | ||
help_text="手机号国际区号", required=False, default=settings.DEFAULT_PHONE_COUNTRY_CODE | ||
) | ||
account_expired_at = serializers.DateTimeField(help_text="账号过期时间") | ||
departments = serializers.SerializerMethodField(help_text="用户所属部门") | ||
leaders = serializers.SerializerMethodField(help_text="用户上级") | ||
|
||
@swagger_serializer_method(serializer_or_field=TenantUserDepartmentOutputSLZ(many=True)) | ||
def get_departments(self, instance: TenantUser) -> List[Dict]: | ||
departments = self.context["tenant_user_departments"].get(instance.id, []) | ||
if not departments: | ||
return [] | ||
return [i.model_dump(include={"id", "name"}) for i in departments] | ||
|
||
@swagger_serializer_method(serializer_or_field=TenantUserLeaderOutputSLZ(many=True)) | ||
def get_leaders(self, instance: TenantUser) -> List[Dict]: | ||
leader_infos = self.context["tenant_user_leaders"].get(instance.id) | ||
if not leader_infos: | ||
return [] | ||
return [ | ||
{ | ||
"id": i.id, | ||
**i.data_source_user.model_dump(include={"username", "full_name"}), | ||
} | ||
for i in leader_infos | ||
] | ||
|
||
def to_representation(self, instance: TenantUser) -> Dict: | ||
data = super().to_representation(instance) | ||
|
||
user = instance.data_source_user | ||
if user: | ||
data["full_name"] = user.full_name | ||
data["username"] = user.username | ||
data["email"] = user.email | ||
data["phone"] = user.phone | ||
data["phone_country_code"] = user.phone_country_code | ||
data["logo"] = user.logo or settings.DEFAULT_DATA_SOURCE_USER_LOGO | ||
return data | ||
|
||
|
||
class TenantUserRetrieveOutputSLZ(TenantDepartmentUserOutputSLZ): | ||
@swagger_serializer_method(serializer_or_field=TenantUserDepartmentOutputSLZ(many=True)) | ||
def get_departments(self, instance: TenantUser) -> List[Dict]: | ||
tenant_user_departments = TenantUserHandler.get_tenant_user_department_by_id([instance.id]) | ||
if not tenant_user_departments: | ||
return [] | ||
departments = tenant_user_departments[0].departments | ||
return [i.model_dump(include={"id", "name"}) for i in departments] | ||
|
||
@swagger_serializer_method(serializer_or_field=TenantUserLeaderOutputSLZ(many=True)) | ||
def get_leaders(self, instance: TenantUser) -> List[Dict]: | ||
tenant_user_leaders = TenantUserHandler.get_tenant_user_leaders_by_id([instance.id]) | ||
if not tenant_user_leaders: | ||
return [] | ||
leader_infos = tenant_user_leaders[0].leaders | ||
return [ | ||
{ | ||
"id": i.id, | ||
**i.data_source_user.model_dump(include={"username", "full_name"}), | ||
} | ||
for i in leader_infos | ||
] | ||
|
||
def to_representation(self, instance: TenantUser) -> Dict: | ||
data = super().to_representation(instance) | ||
user = instance.data_source_user | ||
data["full_name"] = user.full_name | ||
data["username"] = user.username | ||
data["email"] = user.email | ||
data["phone"] = user.phone | ||
data["phone_country_code"] = user.phone_country_code | ||
data["logo"] = user.logo or settings.DEFAULT_DATA_SOURCE_USER_LOGO | ||
return data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# -*- 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. | ||
""" | ||
from django.urls import path | ||
|
||
from . import views | ||
|
||
urlpatterns = [ | ||
# 租户用户 | ||
path("departments/<int:id>/users/", views.TenantDepartmentUserListApi.as_view(), name="departments.users.list"), | ||
path("users/<str:id>/", views.TenantUsersRetrieveApi.as_view(), name="department.users.retrieve"), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# -*- 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.db.models import Q | ||
from drf_yasg.utils import swagger_auto_schema | ||
from rest_framework import generics, status | ||
from rest_framework.response import Response | ||
|
||
from bkuser.apis.web.organization.serializers import ( | ||
TenantDepartmentUserOutputSLZ, | ||
TenantDepartmentUserSearchInputSLZ, | ||
TenantUserRetrieveOutputSLZ, | ||
) | ||
from bkuser.apps.tenant.models import TenantDepartment, TenantUser | ||
from bkuser.biz.tenant import TenantUserHandler | ||
from bkuser.common.pagination import CustomPageNumberPagination | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class TenantDepartmentUserListApi(generics.ListAPIView): | ||
queryset = TenantUser.objects.all() | ||
lookup_url_kwarg = "id" | ||
pagination_class = CustomPageNumberPagination | ||
serializer_class = TenantDepartmentUserOutputSLZ | ||
|
||
def get_serializer_context(self): | ||
tenant_department = TenantDepartment.objects.get(id=self.kwargs[self.lookup_url_kwarg]) | ||
tenant_user_ids = TenantUser.objects.filter(tenant_id=tenant_department.tenant_id).values_list("id", flat=True) | ||
|
||
# 租户用户基础信息 | ||
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_leaders = TenantUserHandler.get_tenant_user_leaders_by_id(tenant_user_ids) | ||
tenant_user_leader_map = {i.id: i.leaders for i in tenant_user_leaders} | ||
|
||
# 租户用户所属租户组织 | ||
tenant_user_departments = TenantUserHandler.get_tenant_user_department_by_id(tenant_user_ids) | ||
tenant_user_department_map = {i.id: i.departments for i in tenant_user_departments} | ||
|
||
return { | ||
"tenant_users_info": tenant_users_info_map, | ||
"tenant_user_leaders": tenant_user_leader_map, | ||
"tenant_user_departments": tenant_user_department_map, | ||
} | ||
|
||
@swagger_auto_schema( | ||
operation_description="租户部门下用户详情列表", | ||
responses={status.HTTP_200_OK: TenantDepartmentUserOutputSLZ(many=True)}, | ||
) | ||
def get(self, request, *args, **kwargs): | ||
slz = TenantDepartmentUserSearchInputSLZ(data=self.request.query_params) | ||
slz.is_valid(raise_exception=True) | ||
data = slz.validated_data | ||
recursive = data.get("recursive") | ||
keyword = data.get("keyword") | ||
# 过滤该租户部门下的用户 | ||
tenant_user_ids = TenantUserHandler.get_tenant_users_by_tenant_department( | ||
tenant_department_id=self.kwargs["id"], recursive=recursive | ||
) | ||
|
||
# build response | ||
queryset = self.filter_queryset(self.get_queryset().filter(id__in=tenant_user_ids)) | ||
if keyword: | ||
queryset = queryset.prefetch_related("data_source_user").filter( | ||
Q(data_source_user__username__icontains=keyword) | ||
| Q(data_source_user__email__icontains=keyword) | ||
| Q(data_source_user__phone__icontains=keyword), | ||
id__in=tenant_user_ids, | ||
) | ||
page = self.paginate_queryset(queryset) | ||
if page is not None: | ||
serializer = self.get_serializer(page, many=True) | ||
return self.get_paginated_response(serializer.data) | ||
|
||
serializer = self.get_serializer(queryset, many=True) | ||
return Response(serializer.data) | ||
|
||
|
||
class TenantUsersRetrieveApi(generics.RetrieveAPIView): | ||
queryset = TenantUser.objects.all() | ||
lookup_url_kwarg = "id" | ||
serializer_class = TenantUserRetrieveOutputSLZ | ||
|
||
@swagger_auto_schema( | ||
operation_description="租户部门下单个用户详情", | ||
responses={status.HTTP_200_OK: TenantUserRetrieveOutputSLZ()}, | ||
) | ||
def get(self, request, *args, **kwargs): | ||
return self.retrieve(request, *args, **kwargs) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.