diff --git a/src/bk-user/bkuser/apis/web/organization/serializers/__init__.py b/src/bk-user/bkuser/apis/web/organization/serializers/__init__.py index ad3f95667..7c1df1a32 100644 --- a/src/bk-user/bkuser/apis/web/organization/serializers/__init__.py +++ b/src/bk-user/bkuser/apis/web/organization/serializers/__init__.py @@ -27,8 +27,8 @@ TenantDepartmentUpdateInputSLZ, ) from .tenants import ( + RequiredTenantUserFieldOutputSLZ, TenantListOutputSLZ, - TenantRequiredUserFieldOutputSLZ, TenantRetrieveOutputSLZ, ) from .users import ( @@ -51,7 +51,7 @@ # 租户 "TenantListOutputSLZ", "TenantRetrieveOutputSLZ", - "TenantRequiredUserFieldOutputSLZ", + "RequiredTenantUserFieldOutputSLZ", # 租户部门 "TenantDepartmentListInputSLZ", "TenantDepartmentListOutputSLZ", diff --git a/src/bk-user/bkuser/apis/web/organization/serializers/batch_operations.py b/src/bk-user/bkuser/apis/web/organization/serializers/batch_operations.py index 9b8e08ebe..a718754ac 100644 --- a/src/bk-user/bkuser/apis/web/organization/serializers/batch_operations.py +++ b/src/bk-user/bkuser/apis/web/organization/serializers/batch_operations.py @@ -27,25 +27,24 @@ class TenantUserInfoSLZ(serializers.Serializer): + """批量创建时校验用户信息用,该模式邮箱,手机号等均为必填字段""" + username = serializers.CharField(help_text="用户名", validators=[validate_data_source_user_username]) full_name = serializers.CharField(help_text="姓名") - email = serializers.EmailField(help_text="邮箱", required=False, default="", allow_blank=True) - phone = serializers.CharField(help_text="手机号", required=False, default="", allow_blank=True) - phone_country_code = serializers.CharField( - help_text="手机国际区号", required=False, default=settings.DEFAULT_PHONE_COUNTRY_CODE, allow_blank=True - ) - extras = serializers.JSONField(help_text="自定义字段", default=dict) + email = serializers.EmailField(help_text="邮箱") + phone = serializers.CharField(help_text="手机号") + phone_country_code = serializers.CharField(help_text="手机国际区号") + extras = serializers.JSONField(help_text="自定义字段") def validate_extras(self, extras: Dict[str, Any]) -> Dict[str, Any]: return validate_user_extras(extras, self.context["custom_fields"], self.context["data_source_id"]) def validate(self, attrs: Dict[str, Any]) -> Dict[str, Any]: - # 如果提供了手机号,则校验手机号是否合法 - if attrs["phone"]: - try: - validate_phone_with_country_code(phone=attrs["phone"], country_code=attrs["phone_country_code"]) - except ValueError as e: - raise ValidationError(str(e)) + # 校验手机号是否合法 + try: + validate_phone_with_country_code(phone=attrs["phone"], country_code=attrs["phone_country_code"]) + except ValueError as e: + raise ValidationError(str(e)) return attrs @@ -82,7 +81,7 @@ def _parse_user_infos( field_count = len(required_field_names) user_infos: List[Dict[str, Any]] = [] for idx, raw_info in enumerate(raw_user_infos, start=1): - # raw_info 格式是以空格为分隔符的用户信息字符串 + # 注:raw_info 格式是以空格为分隔符的用户信息字符串 # 形式如:tiga 迪迦 tiga@otm.com +8613612356789 male shenzhen running,swimming # 字段对应:username full_name email phone gender region sport_hobbies data: List[str] = [s for s in raw_info.split(" ") if s] diff --git a/src/bk-user/bkuser/apis/web/organization/serializers/tenants.py b/src/bk-user/bkuser/apis/web/organization/serializers/tenants.py index 1948dfdc1..1a46730c6 100644 --- a/src/bk-user/bkuser/apis/web/organization/serializers/tenants.py +++ b/src/bk-user/bkuser/apis/web/organization/serializers/tenants.py @@ -49,7 +49,7 @@ def get_data_source(self, obj: Tenant) -> Dict[str, Any] | None: return TenantDataSourceSLZ(data_source).data -class TenantRequiredUserFieldOutputSLZ(serializers.Serializer): +class RequiredTenantUserFieldOutputSLZ(serializers.Serializer): name = serializers.CharField(help_text="字段名称") display_name = serializers.CharField(help_text="字段展示名") tips = serializers.CharField(help_text="提示信息") diff --git a/src/bk-user/bkuser/apis/web/organization/serializers/users.py b/src/bk-user/bkuser/apis/web/organization/serializers/users.py index 6b3f9ae26..82f1e4eb3 100644 --- a/src/bk-user/bkuser/apis/web/organization/serializers/users.py +++ b/src/bk-user/bkuser/apis/web/organization/serializers/users.py @@ -75,7 +75,7 @@ def validate_department_id(self, department_id: int) -> int: department_id and not TenantDepartment.objects.filter(tenant_id=self.context["tenant_id"], id=department_id).exists() ): - raise ValidationError("部门不存在") + raise ValidationError(_("部门不存在")) return department_id diff --git a/src/bk-user/bkuser/apis/web/organization/urls.py b/src/bk-user/bkuser/apis/web/organization/urls.py index 223ee05ce..7544c70fd 100644 --- a/src/bk-user/bkuser/apis/web/organization/urls.py +++ b/src/bk-user/bkuser/apis/web/organization/urls.py @@ -28,7 +28,7 @@ # 租户用户 - 快速录入必填字段 path( "tenants/required-user-fields/", - views.TenantRequiredUserFieldListApi.as_view(), + views.RequiredTenantUserFieldListApi.as_view(), name="organization.tenant.required_user_field.list", ), # 租户部门列表 @@ -49,13 +49,13 @@ views.TenantDepartmentSearchApi.as_view(), name="organization.tenant_department.search", ), - # 数据源部门列表 + # 可选租户部门列表(下拉框数据用) path( "tenants/optional-departments/", views.OptionalTenantDepartmentListApi.as_view(), name="organization.optional_department.list", ), - # 数据源用户列表 + # 可选租户用户列表(下拉框数据用) path( "tenants/optional-leaders/", views.OptionalTenantUserListApi.as_view(), diff --git a/src/bk-user/bkuser/apis/web/organization/views/__init__.py b/src/bk-user/bkuser/apis/web/organization/views/__init__.py index 014dcdee7..3b7f76407 100644 --- a/src/bk-user/bkuser/apis/web/organization/views/__init__.py +++ b/src/bk-user/bkuser/apis/web/organization/views/__init__.py @@ -24,7 +24,7 @@ from .tenants import ( CollaborativeTenantListApi, CurrentTenantRetrieveApi, - TenantRequiredUserFieldListApi, + RequiredTenantUserFieldListApi, ) from .users import ( OptionalTenantUserListApi, @@ -40,7 +40,7 @@ # 租户 "CurrentTenantRetrieveApi", "CollaborativeTenantListApi", - "TenantRequiredUserFieldListApi", + "RequiredTenantUserFieldListApi", # 租户部门 "TenantDepartmentListCreateApi", "TenantDepartmentUpdateDestroyApi", diff --git a/src/bk-user/bkuser/apis/web/organization/views/batch_operations.py b/src/bk-user/bkuser/apis/web/organization/views/batch_operations.py index 08020a6b0..2bd3e39c9 100644 --- a/src/bk-user/bkuser/apis/web/organization/views/batch_operations.py +++ b/src/bk-user/bkuser/apis/web/organization/views/batch_operations.py @@ -110,7 +110,7 @@ def post(self, request, *args, **kwargs): ] TenantUser.objects.bulk_create(tenant_users) - return Response(status=status.HTTP_201_CREATED) + return Response(status=status.HTTP_204_NO_CONTENT) class TenantUserBatchCopyApi(CurrentUserTenantMixin, generics.CreateAPIView): diff --git a/src/bk-user/bkuser/apis/web/organization/views/departments.py b/src/bk-user/bkuser/apis/web/organization/views/departments.py index 7a1e3deaf..9ec19a328 100644 --- a/src/bk-user/bkuser/apis/web/organization/views/departments.py +++ b/src/bk-user/bkuser/apis/web/organization/views/departments.py @@ -340,8 +340,9 @@ def get_queryset(self) -> QuerySet[TenantDepartment]: slz.is_valid(raise_exception=True) params = slz.validated_data + cur_tenant_id = self.get_current_tenant_id() queryset = TenantDepartment.objects.filter( - data_source__owner_tenant_id=self.get_current_tenant_id() + tenant_id=cur_tenant_id, data_source__owner_tenant_id=cur_tenant_id ).select_related("data_source_department") if kw := params.get("keyword"): queryset = queryset.filter(data_source_department__name__icontains=kw) diff --git a/src/bk-user/bkuser/apis/web/organization/views/tenants.py b/src/bk-user/bkuser/apis/web/organization/views/tenants.py index de44807bf..5bda245fd 100644 --- a/src/bk-user/bkuser/apis/web/organization/views/tenants.py +++ b/src/bk-user/bkuser/apis/web/organization/views/tenants.py @@ -17,8 +17,8 @@ from bkuser.apis.web.mixins import CurrentUserTenantMixin from bkuser.apis.web.organization.serializers import ( + RequiredTenantUserFieldOutputSLZ, TenantListOutputSLZ, - TenantRequiredUserFieldOutputSLZ, TenantRetrieveOutputSLZ, ) from bkuser.apps.permission.constants import PermAction @@ -79,7 +79,7 @@ def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) -class TenantRequiredUserFieldListApi(CurrentUserTenantMixin, generics.ListAPIView): +class RequiredTenantUserFieldListApi(CurrentUserTenantMixin, generics.ListAPIView): """租户用户必填字段(快速录入用)""" permission_classes = [IsAuthenticated, perm_class(PermAction.MANAGE_TENANT)] @@ -89,7 +89,7 @@ class TenantRequiredUserFieldListApi(CurrentUserTenantMixin, generics.ListAPIVie @swagger_auto_schema( tags=["organization.tenant"], operation_description="快速录入租户用户必填字段", - responses={status.HTTP_200_OK: TenantRequiredUserFieldOutputSLZ(many=True)}, + responses={status.HTTP_200_OK: RequiredTenantUserFieldOutputSLZ(many=True)}, ) def get(self, request, *args, **kwargs): cur_tenant_id = self.get_current_tenant_id() @@ -110,4 +110,4 @@ def get(self, request, *args, **kwargs): field_infos.append({"name": f.name, "display_name": f.display_name, "tips": tips}) - return Response(TenantRequiredUserFieldOutputSLZ(field_infos, many=True).data, status=status.HTTP_200_OK) + return Response(RequiredTenantUserFieldOutputSLZ(field_infos, many=True).data, status=status.HTTP_200_OK)