from rest_framework import generics, status from rest_framework.decorators import api_view, action from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.viewsets import ModelViewSet from rest_framework.exceptions import PermissionDenied from .models import Material, MaterialCategory, MaterialSubcategory from .serializers import MaterialSerializer, MaterialListSerializer, MaterialCategorySerializer, MaterialSubcategorySerializer class MaterialViewSet(ModelViewSet): """ 材料视图集 """ permission_classes = [IsAuthenticated] def get_queryset(self): """ 根据用户角色过滤材料 """ queryset = Material.objects.all() # 普通用户只能看到自己工厂的材料 if self.request.user.role != 'admin': queryset = queryset.filter(factory=self.request.user.factory) # 支持按状态过滤 status_filter = self.request.query_params.get('status') if status_filter: queryset = queryset.filter(status=status_filter) # 支持按名称搜索 name = self.request.query_params.get('name') if name: queryset = queryset.filter(name__icontains=name) # 支持按工厂过滤 factory_id = self.request.query_params.get('factory_id') if factory_id: queryset = queryset.filter(factory_id=factory_id) # 支持按专业类别过滤 major_category = self.request.query_params.get('major_category') if major_category: queryset = queryset.filter(major_category=major_category) # 支持按材料分类过滤 material_category = self.request.query_params.get('material_category') if material_category: queryset = queryset.filter(material_category=material_category) # 支持按材料子类过滤 material_subcategory = self.request.query_params.get('material_subcategory') if material_subcategory: queryset = queryset.filter(material_subcategory=material_subcategory) # 支持按应用场景过滤 (JSONField contains) application_scene = self.request.query_params.get('application_scene') if application_scene: queryset = queryset.filter(application_scene__contains=[application_scene]) # 支持按竞争优势过滤 (JSONField contains) advantage = self.request.query_params.get('advantage') if advantage: queryset = queryset.filter(advantage__contains=[advantage]) return queryset def get_serializer_class(self): """ 根据操作类型选择序列化器 """ if self.action == 'list': return MaterialListSerializer return MaterialSerializer def perform_create(self, serializer): """ 创建材料时自动设置工厂 """ # 普通用户只能为自己工厂创建材料 if self.request.user.role != 'admin': serializer.save(factory=self.request.user.factory) else: serializer.save() def perform_update(self, serializer): """ 更新材料时的权限控制 """ # 普通用户只能更新自己工厂的材料 if (self.request.user.role != 'admin' and self.request.user.factory_id != self.get_object().factory_id): raise PermissionDenied("无权修改其他工厂的材料") serializer.save() def perform_destroy(self, instance): """ 删除材料时的权限控制 """ # 普通用户只能删除自己工厂的材料 if (self.request.user.role != 'admin' and self.request.user.factory_id != instance.factory_id): raise PermissionDenied("无权删除其他工厂的材料") instance.delete() @action(detail=True, methods=['post']) def submit(self, request, pk=None): """ 提交审核 """ material = self.get_object() # 普通用户只能提交自己工厂的材料 if (request.user.role != 'admin' and request.user.factory_id != material.factory_id): return Response( {"detail": "无权提交其他工厂的材料"}, status=status.HTTP_403_FORBIDDEN ) if material.status != 'draft': return Response( {"detail": "只有创建中的材料才能提交审核"}, status=status.HTTP_400_BAD_REQUEST ) material.status = 'pending' material.save() return Response({"status": "已提交审核"}) @action(detail=True, methods=['post']) def approve(self, request, pk=None): """ 审核通过 """ # 只有管理员可以审核 if request.user.role != 'admin': return Response( {"detail": "只有管理员可以审核材料"}, status=status.HTTP_403_FORBIDDEN ) material = self.get_object() if material.status != 'pending': return Response( {"detail": "只有待审核的材料才能审核"}, status=status.HTTP_400_BAD_REQUEST ) material.status = 'approved' material.save() return Response({"status": "审核通过"}) @action(detail=True, methods=['post']) def reject(self, request, pk=None): """ 审核拒绝 """ # 只有管理员可以审核 if request.user.role != 'admin': return Response( {"detail": "只有管理员可以审核材料"}, status=status.HTTP_403_FORBIDDEN ) material = self.get_object() if material.status != 'pending': return Response( {"detail": "只有待审核的材料才能审核"}, status=status.HTTP_400_BAD_REQUEST ) material.status = 'draft' material.save() return Response({"status": "审核拒绝"}) @action(detail=False, methods=['get']) def choices(self, request): """ 材料字段枚举 """ return Response({ 'major_category': Material.MAJOR_CATEGORY_CHOICES, 'replace_type': Material.REPLACE_TYPE_CHOICES, 'advantage': Material.ADVANTAGE_CHOICES, 'application_scene': Material.APPLICATION_SCENE_CHOICES, 'star_level': Material.STAR_LEVEL_CHOICES, 'status': Material.STATUS_CHOICES, }) class MaterialCategoryViewSet(ModelViewSet): """ 材料分类视图集 """ queryset = MaterialCategory.objects.all().order_by('id') serializer_class = MaterialCategorySerializer permission_classes = [IsAuthenticated] def perform_create(self, serializer): if self.request.user.role != 'admin': raise PermissionDenied("只有管理员可以创建材料分类") serializer.save() def perform_update(self, serializer): if self.request.user.role != 'admin': raise PermissionDenied("只有管理员可以更新材料分类") serializer.save() def perform_destroy(self, instance): if self.request.user.role != 'admin': raise PermissionDenied("只有管理员可以删除材料分类") instance.delete() class MaterialSubcategoryViewSet(ModelViewSet): """ 材料子分类视图集 """ queryset = MaterialSubcategory.objects.select_related('category').all().order_by('id') serializer_class = MaterialSubcategorySerializer permission_classes = [IsAuthenticated] def get_queryset(self): queryset = super().get_queryset() category_id = self.request.query_params.get('category_id') if category_id: queryset = queryset.filter(category_id=category_id) return queryset def perform_create(self, serializer): if self.request.user.role != 'admin': raise PermissionDenied("只有管理员可以创建材料子分类") serializer.save() def perform_update(self, serializer): if self.request.user.role != 'admin': raise PermissionDenied("只有管理员可以更新材料子分类") serializer.save() def perform_destroy(self, instance): if self.request.user.role != 'admin': raise PermissionDenied("只有管理员可以删除材料子分类") instance.delete()