mat/backend/apps/material/views.py

246 lines
8.4 KiB
Python

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()