From 05554eb821558fbcfb445affa841804ed7e7baac Mon Sep 17 00:00:00 2001 From: xie7654 <765462425@qq.com> Date: Mon, 30 Jun 2025 22:26:00 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=86=99AuditUserFieldsMixin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/system/views/menu.py | 5 +++- backend/system/views/role.py | 5 ++-- backend/utils/serializers.py | 30 ++++++++++++------- web/apps/web-antd/src/api/system/role.ts | 2 ++ .../web-antd/src/views/system/role/data.ts | 11 ------- .../src/views/system/role/modules/form.vue | 6 ++-- 6 files changed, 30 insertions(+), 29 deletions(-) diff --git a/backend/system/views/menu.py b/backend/system/views/menu.py index e87441e..8240be2 100644 --- a/backend/system/views/menu.py +++ b/backend/system/views/menu.py @@ -6,6 +6,7 @@ from rest_framework.response import Response from system.models import Menu, MenuMeta from utils.custom_model_viewSet import CustomModelViewSet +from utils.serializers import CustomModelSerializer class MenuMetaSerializer(serializers.ModelSerializer): @@ -14,7 +15,7 @@ class MenuMetaSerializer(serializers.ModelSerializer): model = MenuMeta fields = '__all__' -class MenuSerializer(serializers.ModelSerializer): +class MenuSerializer(CustomModelSerializer): """菜单序列化器""" parent = serializers.CharField(source='pid.name', read_only=True) meta = MenuMetaSerializer() @@ -46,11 +47,13 @@ class MenuSerializer(serializers.ModelSerializer): """创建菜单及关联的元数据""" meta_data = validated_data.pop('meta') meta = MenuMeta.objects.create(**meta_data) + self.set_audit_user_fields(validated_data, is_create=True) menu = Menu.objects.create(meta=meta, **validated_data) return menu def update(self, instance, validated_data): """更新菜单及关联的元数据""" + self.set_audit_user_fields(validated_data, is_create=False) meta_data = validated_data.pop('meta', {}) meta_serializer = self.fields['meta'] meta_serializer.update(instance.meta, meta_data) diff --git a/backend/system/views/role.py b/backend/system/views/role.py index 64bd4cc..e8a3671 100644 --- a/backend/system/views/role.py +++ b/backend/system/views/role.py @@ -7,9 +7,10 @@ from rest_framework.response import Response from system.models import RolePermission, Menu, Role from utils.custom_model_viewSet import CustomModelViewSet +from utils.serializers import CustomModelSerializer -class RoleSerializer(serializers.ModelSerializer): +class RoleSerializer(CustomModelSerializer): """角色序列化器""" permissions = serializers.PrimaryKeyRelatedField( queryset=Menu.objects.all(), @@ -34,7 +35,7 @@ class RoleViewSet(CustomModelViewSet): queryset = Role.objects.all() serializer_class = RoleSerializer filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] - filterset_fields = ['status'] + filterset_fields = ['status', 'name'] search_fields = ['name'] ordering_fields = ['create_time'] diff --git a/backend/utils/serializers.py b/backend/utils/serializers.py index 14c0510..ec64d69 100644 --- a/backend/utils/serializers.py +++ b/backend/utils/serializers.py @@ -9,15 +9,29 @@ from django.utils.functional import cached_property from rest_framework.utils.serializer_helpers import BindingDict -class CustomModelSerializer(ModelSerializer): +class AuditUserFieldsMixin: """ - 增强DRF的ModelSerializer,可自动更新模型的审计字段记录 - (1)self.request能获取到rest_framework.request.Request对象 + 用于自动赋值 creator 和 modifier 字段的 Mixin """ # 修改人的审计字段名称, 默认modifier, 继承使用时可自定义覆盖 modifier_field_id = 'modifier' # 创建人的审计字段名称, 默认creator, 继承使用时可自定义覆盖 creator_field_id = 'creator' + + def set_audit_user_fields(self, validated_data, is_create=True): + username = self.get_request_username() if hasattr(self, 'get_request_username') else None + if getattr(self, 'request', None): + if self.modifier_field_id in self.fields: + validated_data[self.modifier_field_id] = username + if is_create and self.creator_field_id in self.fields: + validated_data[self.creator_field_id] = username + + +class CustomModelSerializer(AuditUserFieldsMixin, ModelSerializer): + """ + 增强DRF的ModelSerializer,可自动更新模型的审计字段记录 + (1)self.request能获取到rest_framework.request.Request对象 + """ # 添加默认时间返回格式 create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True) update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False) @@ -30,17 +44,11 @@ class CustomModelSerializer(ModelSerializer): return super().save(**kwargs) def create(self, validated_data): - if self.request: - if self.modifier_field_id in self.fields: - validated_data[self.modifier_field_id] = self.get_request_username() - if self.creator_field_id in self.fields: - validated_data[self.creator_field_id] = self.get_request_username() + self.set_audit_user_fields(validated_data, is_create=True) return super().create(validated_data) def update(self, instance, validated_data): - if self.request: - if hasattr(self.instance, self.modifier_field_id): - validated_data[self.modifier_field_id] = self.get_request_username() + self.set_audit_user_fields(validated_data, is_create=False) return super().update(instance, validated_data) def get_request_username(self): diff --git a/web/apps/web-antd/src/api/system/role.ts b/web/apps/web-antd/src/api/system/role.ts index a0da3ec..1b273f9 100644 --- a/web/apps/web-antd/src/api/system/role.ts +++ b/web/apps/web-antd/src/api/system/role.ts @@ -7,8 +7,10 @@ export namespace SystemRoleApi { [key: string]: any; id: string; name: string; + permissions: []; profile: { create_time: string; + permissions: []; remark?: string; status: 0 | 1; }; diff --git a/web/apps/web-antd/src/views/system/role/data.ts b/web/apps/web-antd/src/views/system/role/data.ts index a9a5e8f..c596b86 100644 --- a/web/apps/web-antd/src/views/system/role/data.ts +++ b/web/apps/web-antd/src/views/system/role/data.ts @@ -49,7 +49,6 @@ export function useGridFormSchema(): VbenFormSchema[] { fieldName: 'name', label: $t('system.role.roleName'), }, - { component: 'Input', fieldName: 'id', label: $t('system.role.id') }, { component: 'Select', componentProps: { @@ -62,16 +61,6 @@ export function useGridFormSchema(): VbenFormSchema[] { fieldName: 'status', label: $t('system.role.status'), }, - { - component: 'Input', - fieldName: 'remark', - label: $t('system.role.remark'), - }, - { - component: 'RangePicker', - fieldName: 'createTime', - label: $t('system.role.createTime'), - }, ]; } diff --git a/web/apps/web-antd/src/views/system/role/modules/form.vue b/web/apps/web-antd/src/views/system/role/modules/form.vue index 0581a29..0253cef 100644 --- a/web/apps/web-antd/src/views/system/role/modules/form.vue +++ b/web/apps/web-antd/src/views/system/role/modules/form.vue @@ -58,7 +58,6 @@ const [Drawer, drawerApi] = useVbenDrawer({ } else { id.value = undefined; } - if (permissions.value.length === 0) { loadPermissions(); } @@ -70,8 +69,7 @@ async function loadPermissions() { loadingPermissions.value = true; try { const res = await getMenuList(); - console.log(res, 'res') - permissions.value = res.items as unknown as DataNode[]; + permissions.value = res as unknown as DataNode[]; } finally { loadingPermissions.value = false; } @@ -99,7 +97,7 @@ function getNodeClass(node: Recordable) {