This commit is contained in:
xie7654
2025-06-29 21:45:27 +08:00
commit f6e68e37c8
1539 changed files with 129319 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
__all__ = [
'DeptViewSet',
'MenuViewSet',
'MenuMetaViewSet',
'RoleViewSet',
'DictDataViewSet',
'DictTypeViewSet',
]
from system.views.dict_data import DictDataViewSet
from system.views.dict_type import DictTypeViewSet
from system.views.menu import MenuViewSet, MenuMetaViewSet
from system.views.role import RoleViewSet
from system.views.dept import DeptViewSet
from system.views.user import *

View File

@@ -0,0 +1,84 @@
from datetime import timezone, datetime
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import status, serializers
from rest_framework.decorators import action
from rest_framework.filters import SearchFilter, OrderingFilter
from rest_framework.response import Response
from system.models import Dept
from utils.custom_model_viewSet import CustomModelViewSet
class DeptSerializer(serializers.ModelSerializer):
"""部门序列化器"""
children = serializers.SerializerMethodField()
status_text = serializers.SerializerMethodField()
class Meta:
model = Dept
fields = '__all__'
read_only_fields = ['id', 'create_time']
def get_children(self, obj):
"""获取子部门"""
children = obj.children.all().order_by('id')
if children:
return DeptSerializer(children, many=True).data
return []
def get_status_text(self, obj):
"""获取状态文本"""
return obj.get_status_display()
class DeptViewSet(CustomModelViewSet):
"""部门管理视图集"""
queryset = Dept.objects.filter(pid__isnull=True).order_by('id', 'status')
serializer_class = DeptSerializer
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['status', 'pid']
search_fields = ['name']
ordering_fields = ['create_time', 'name']
def perform_create(self, serializer):
# 自动设置创建时间
if 'create_time' not in serializer.validated_data:
serializer.validated_data['create_time'] = datetime.now()
serializer.save()
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
pk = kwargs['pk']
instance = Dept.objects.get(pk=pk)
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
if getattr(instance, '_prefetched_objects_cache', None):
# If 'prefetch_related' has been applied to a queryset, we need to
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}
headers = self.get_success_headers(serializer.data)
return self._build_response(
data=serializer.data,
message="ok",
status=status.HTTP_200_OK,
)
def destroy(self, request, *args, **kwargs):
pk = kwargs['pk']
instance = Dept.objects.get(pk=pk)
self.perform_destroy(instance)
return self._build_response(
message="ok",
status=status.HTTP_200_OK,
)
@action(detail=False, methods=['get'])
def tree(self, request):
"""获取部门树形结构"""
queryset = self.get_queryset().filter(pid__isnull=True)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)

View File

@@ -0,0 +1,16 @@
from rest_framework import serializers, viewsets
from system.models import DictData
from utils.custom_model_viewSet import CustomModelViewSet
class DictDataSerializer(serializers.ModelSerializer):
class Meta:
model = DictData
fields = '__all__'
class DictDataViewSet(CustomModelViewSet):
queryset = DictData.objects.filter(is_deleted=False)
serializer_class = DictDataSerializer
filterset_fields = ['dict_type']

View File

@@ -0,0 +1,15 @@
from rest_framework import serializers, viewsets
from system.models import DictType
from utils.custom_model_viewSet import CustomModelViewSet
class DictTypeSerializer(serializers.ModelSerializer):
class Meta:
model = DictType
fields = '__all__'
class DictTypeViewSet(CustomModelViewSet):
queryset = DictType.objects.filter(is_deleted=False)
serializer_class = DictTypeSerializer

View File

@@ -0,0 +1,131 @@
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import viewsets, serializers, status
from rest_framework.decorators import action
from rest_framework.filters import SearchFilter, OrderingFilter
from rest_framework.response import Response
from system.models import Menu, MenuMeta
from utils.custom_model_viewSet import CustomModelViewSet
class MenuMetaSerializer(serializers.ModelSerializer):
"""菜单元数据序列化器"""
class Meta:
model = MenuMeta
fields = '__all__'
class MenuSerializer(serializers.ModelSerializer):
"""菜单序列化器"""
parent = serializers.CharField(source='pid.name', read_only=True)
meta = MenuMetaSerializer()
children = serializers.SerializerMethodField()
status_text = serializers.SerializerMethodField()
type_text = serializers.SerializerMethodField()
class Meta:
model = Menu
fields = '__all__'
read_only_fields = ['id', 'create_time', 'update_time']
def get_children(self, obj):
"""获取子菜单"""
children = obj.children.all()
if children:
return MenuSerializer(children, many=True).data
return []
def get_status_text(self, obj):
"""获取状态文本"""
return obj.get_status_display()
def get_type_text(self, obj):
"""获取菜单类型文本"""
return obj.get_type_display()
def create(self, validated_data):
"""创建菜单及关联的元数据"""
meta_data = validated_data.pop('meta')
meta = MenuMeta.objects.create(**meta_data)
menu = Menu.objects.create(meta=meta, **validated_data)
return menu
def update(self, instance, validated_data):
"""更新菜单及关联的元数据"""
meta_data = validated_data.pop('meta', {})
meta_serializer = self.fields['meta']
meta_serializer.update(instance.meta, meta_data)
return super().update(instance, validated_data)
class MenuMetaViewSet(viewsets.ModelViewSet):
"""菜单元数据视图集"""
queryset = MenuMeta.objects.all()
serializer_class = MenuMetaSerializer
class MenuViewSet(CustomModelViewSet):
"""菜单管理视图集"""
queryset = Menu.objects.filter(pid__isnull=True).order_by('id', 'status')
serializer_class = MenuSerializer
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['status', 'type', 'pid', 'name']
search_fields = ['name', 'path', 'auth_code']
ordering_fields = ['meta__order', 'create_time']
@action(detail=False, methods=['get'])
def tree(self, request):
"""获取菜单树形结构"""
queryset = self.get_queryset().filter(pid__isnull=True)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
@action(detail=False, methods=['get'], url_path='name-exists')
def name_exists(self, request):
return self._build_response()
@action(detail=False, methods=['get'], url_path='name-search')
def name_search(self, request):
name = request.GET.get('name')
pk = request.GET.get('id', None)
queryset = Menu.objects.all()
if pk:
queryset = queryset.exclude(pk=pk)
if name:
queryset = queryset.filter(name=name)
has_menu_name = queryset.exists()
print(has_menu_name, 'has_menu_name')
return self._build_response(data=has_menu_name)
@action(detail=False, methods=['get'], url_path='path-exists')
def path_exists(self, request):
return self._build_response()
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
pk = kwargs['pk']
instance = Menu.objects.get(pk=pk)
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
if getattr(instance, '_prefetched_objects_cache', None):
# If 'prefetch_related' has been applied to a queryset, we need to
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}
headers = self.get_success_headers(serializer.data)
return self._build_response(
data=serializer.data,
message="ok",
status=status.HTTP_200_OK,
)
def destroy(self, request, *args, **kwargs):
pk = kwargs['pk']
instance = Menu.objects.get(pk=pk)
self.perform_destroy(instance)
return self._build_response(
message="ok",
status=status.HTTP_200_OK,
)

View File

@@ -0,0 +1,92 @@
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import status, serializers
from rest_framework.decorators import action
from rest_framework.filters import SearchFilter, OrderingFilter
from rest_framework.generics import get_object_or_404
from rest_framework.response import Response
from system.models import RolePermission, Menu, Role
from utils.custom_model_viewSet import CustomModelViewSet
class RoleSerializer(serializers.ModelSerializer):
"""角色序列化器"""
permissions = serializers.PrimaryKeyRelatedField(
queryset=Menu.objects.all(),
many=True,
required=False
)
status_text = serializers.SerializerMethodField()
class Meta:
model = Role
fields = '__all__'
read_only_fields = ['id', 'create_time']
def get_status_text(self, obj):
"""获取状态文本"""
return obj.get_status_display()
class RoleViewSet(CustomModelViewSet):
"""角色管理视图集"""
queryset = Role.objects.all()
serializer_class = RoleSerializer
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['status']
search_fields = ['name']
ordering_fields = ['create_time']
@action(detail=True, methods=['post'])
def assign_permissions(self, request, pk=None):
"""分配角色权限"""
role = self.get_object()
menu_ids = request.data.get('menu_ids', [])
# 清除原有权限
role.permissions.clear()
# 添加新权限
for menu_id in menu_ids:
menu = get_object_or_404(Menu, id=menu_id)
RolePermission.objects.create(role=role, menu=menu)
serializer = self.get_serializer(role)
return Response(serializer.data)
def create(self, request, *args, **kwargs):
# 获取请求数据
data = request.data.copy()
permissions = data.pop('permissions', []) # 提取权限列表
# 创建角色(不包含权限)
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
role = serializer.save()
# 处理权限关联(可根据需求自定义)
if permissions:
try:
# 验证权限ID是否存在
valid_permissions = Menu.objects.filter(id__in=permissions)
# 创建中间表记录(如果需要保存额外字段)
for menu in valid_permissions:
RolePermission.objects.create(
role=role,
menu=menu,
)
except Exception as e:
# 如果关联失败,删除已创建的角色
role.delete()
return Response(
{'error': f'权限关联失败: {str(e)}'},
status=status.HTTP_400_BAD_REQUEST
)
return self._build_response(
data=serializer.data,
message="ok",
status=status.HTTP_200_OK,
)

View File

@@ -0,0 +1,79 @@
from rest_framework.authtoken.models import Token
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from system.models import User
from utils.custom_model_viewSet import CustomModelViewSet
class UserSerializer(CustomModelViewSet):
class Meta:
model = User
exclude = ('password',)
class UserLogin(ObtainAuthToken):
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data,
context={'request': request})
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
return Response({
"code": 0,
"data": {
"id": user.id,
"password": user.password,
"realName": user.nickname,
"roles": [
"super"
],
"username": user.username,
"accessToken": token.key
},
"error": None,
"message": "ok"
})
class UserInfo(APIView):
def get(self, request, *args, **kwargs):
user = self.request.user
return Response({
"code": 0,
"data": {
"id": user.id,
"realName": user.username,
"roles": [
"super"
],
"username": user.username,
},
"error": None,
"message": "ok"
})
class Codes(APIView):
def get(self, request, *args, **kwargs):
return Response({
"code": 0,
"data": [
"AC_100100",
"AC_100110",
"AC_100120",
"AC_100010"
],
"error": None,
"message": "ok"
})
class UserViewSet(ModelViewSet):
queryset = User.objects.all().order_by('id')
serializer_class = UserSerializer