1
0
forked from erp-dev/erp
This commit is contained in:
2026-07-05 13:53:17 +08:00
parent 4538e51ad5
commit e1cc6df122
24 changed files with 3030 additions and 495 deletions

171
api_core/serializers.py Normal file
View File

@@ -0,0 +1,171 @@
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group, Permission
from django.db import transaction
from rest_framework import serializers
from drf_spectacular.utils import extend_schema_field
from basic_info.models import UserProfile
User = get_user_model()
class CorePermissionSerializer(serializers.ModelSerializer):
app_label = serializers.CharField(source="content_type.app_label", read_only=True)
model = serializers.CharField(source="content_type.model", read_only=True)
full_code = serializers.SerializerMethodField()
class Meta:
model = Permission
fields = [
"id",
"name",
"codename",
"content_type",
"app_label",
"model",
"full_code",
]
read_only_fields = fields
def get_full_code(self, obj) -> str:
return f"{obj.content_type.app_label}.{obj.codename}"
class CoreGroupSerializer(serializers.ModelSerializer):
permissions = serializers.PrimaryKeyRelatedField(
many=True,
queryset=Permission.objects.select_related("content_type").all(),
required=False,
)
permission_details = CorePermissionSerializer(
source="permissions",
many=True,
read_only=True,
)
class Meta:
model = Group
fields = ["id", "name", "permissions", "permission_details"]
class CoreUserSerializer(serializers.ModelSerializer):
groups = serializers.PrimaryKeyRelatedField(
many=True,
queryset=Group.objects.all(),
required=False,
)
user_permissions = serializers.PrimaryKeyRelatedField(
many=True,
queryset=Permission.objects.select_related("content_type").all(),
required=False,
)
password = serializers.CharField(write_only=True, required=False, min_length=6)
merchant_id = serializers.IntegerField(source="profile.merchant_id", read_only=True)
employee_id = serializers.IntegerField(source="employee.id", read_only=True)
employee_name = serializers.CharField(source="employee.name", read_only=True)
group_details = serializers.SerializerMethodField()
permission_details = serializers.SerializerMethodField()
class Meta:
model = User
fields = [
"id",
"username",
"email",
"first_name",
"last_name",
"is_active",
"is_staff",
"is_superuser",
"last_login",
"date_joined",
"merchant_id",
"employee_id",
"employee_name",
"groups",
"group_details",
"user_permissions",
"permission_details",
"password",
]
read_only_fields = [
"id",
"last_login",
"date_joined",
"merchant_id",
"employee_id",
"employee_name",
"group_details",
"permission_details",
]
@extend_schema_field(serializers.ListField(child=serializers.DictField()))
def get_group_details(self, obj) -> list[dict[str, object]]:
return [{"id": group.id, "name": group.name} for group in obj.groups.all()]
@extend_schema_field(CorePermissionSerializer(many=True))
def get_permission_details(self, obj) -> list[dict[str, object]]:
permissions = obj.user_permissions.select_related("content_type").all()
return CorePermissionSerializer(permissions, many=True).data
def validate_username(self, value):
queryset = User.objects.filter(username=value)
if self.instance is not None:
queryset = queryset.exclude(pk=self.instance.pk)
if queryset.exists():
raise serializers.ValidationError("用户名已存在")
return value
def validate(self, attrs):
request = self.context.get("request")
current_user = getattr(request, "user", None)
target_user = self.instance
if current_user is not None and target_user is not None and current_user.pk == target_user.pk:
if attrs.get("is_active") is False:
raise serializers.ValidationError({"is_active": "不能停用当前登录用户"})
if attrs.get("is_superuser") is False:
raise serializers.ValidationError({"is_superuser": "不能取消当前登录用户的 superuser 权限"})
return attrs
def create(self, validated_data):
groups = validated_data.pop("groups", [])
user_permissions = validated_data.pop("user_permissions", [])
password = validated_data.pop("password", None)
merchant = self.context["merchant"]
with transaction.atomic():
user = User(**validated_data)
if password:
user.set_password(password)
else:
user.set_unusable_password()
user.save()
if groups:
user.groups.set(groups)
if user_permissions:
user.user_permissions.set(user_permissions)
UserProfile.objects.create(user=user, merchant=merchant)
return user
def update(self, instance, validated_data):
groups = validated_data.pop("groups", None)
user_permissions = validated_data.pop("user_permissions", None)
password = validated_data.pop("password", None)
with transaction.atomic():
for attr, value in validated_data.items():
setattr(instance, attr, value)
if password:
instance.set_password(password)
instance.save()
if groups is not None:
instance.groups.set(groups)
if user_permissions is not None:
instance.user_permissions.set(user_permissions)
return instance