from rest_framework.viewsets import GenericViewSet from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin, RetrieveModelMixin from rest_framework.decorators import action from apps.ability.models import QAction, QActionItem, QOrg, QTask, Quali, QualiLib from apps.ability.serializers_qtask import QActionACreateSerializer, QActionDetailSerializer, QActionListSerializer, QActionNoChangeSerializer, QActionQualiCreateSerializer, QActionQualiUpdateSerializer, QActionServiceSerializer, QOrgListSerializer, QTaskCreateUpdateSerializer, QTaskListSerializer, QualiCreateSerializer, QualiLibListSerializer, QualiListSerializer, QualiSerializer, QualiUpdateSerializer from django.db import transaction from rest_framework.response import Response from rest_framework import status from apps.system.mixins import CreateUpdateCustomMixin from apps.system.models import City from utils.pagination import PageOrNot from rest_framework.exceptions import ParseError from rest_framework import serializers from rest_framework.exceptions import ParseError from utils.queryset import get_child_queryset2 from apps.system.permission_data import RbacFilterSet class QualiLibViewSet(PageOrNot, ListModelMixin, GenericViewSet): perms_map = {'get': '*'} queryset = QualiLib.objects.all() serializer_class = QualiLibListSerializer search_fields = ['name'] ordering = ['-create_time'] class QualiViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): perms_map = {'get': '*'} queryset = Quali.objects.select_related( 'org', 'province', 'city', 'file').prefetch_related('citys') serializer_class = QualiListSerializer search_fields = ['name', 'type', 'grade', 'scope', 'level', 'description'] ordering = ['org', 'org__sort', 'create_time'] filterset_fields = ['org', 'type', 'grade', 'province', 'city', 'citys'] @action(methods=['get'], detail=False, perms_map={'get': '*'}) def my(self, request, *args, **kwargs): """ 我的资质 """ user = self.request.user queryset = self.filter_queryset( self.get_queryset().filter(org=user.dept)) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data) class QTaskViewSet(CreateUpdateCustomMixin, CreateModelMixin, ListModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet): perms_map = {'get': 'qtask_view', 'post': 'qtask_create', 'put': 'qtask_update'} queryset = QTask.objects.all() serializer_class = QTaskListSerializer ordering = ['-create_time'] def get_serializer_class(self): if self.action in ['create', 'update']: return QTaskCreateUpdateSerializer return super().get_serializer_class() @action(methods=['put'], detail=True, perms_map={'put': 'qtask_start'}, serializer_class=serializers.Serializer) @transaction.atomic def start(self, request, *args, **kwargs): """ 发布任务 """ obj = self.get_object() if obj.state == '待发布': obj.state = '进行中' obj.save() return Response() return Response('任务状态错误', status=status.HTTP_400_BAD_REQUEST) class QOrgViewSet(ListModelMixin, GenericViewSet): perms_map = {'get': 'qtask_view'} queryset = QOrg.objects.select_related('qtask', 'org') filterset_fields = ['qtask', 'org', 'qtask__state'] serializer_class = QOrgListSerializer ordering = ['-create_time'] @action(methods=['get'], detail=False, perms_map={'get': 'qtask_my'}) def my(self, request, *args, **kwargs): """ 我的报送任务 """ user = self.request.user queryset = self.filter_queryset(self.get_queryset().filter(qtask__is_deleted=False).exclude(qtask__state='待发布')) mydept = user.dept belong_depts = get_child_queryset2(mydept) queryset = queryset.filter(org__in = belong_depts) deptId = self.request.query_params.get('org', mydept.id) if deptId: queryset = queryset.filter(org__id=deptId) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data) def cal_count(qtask, org): qs = QAction.objects.filter(qtask=qtask, belong_dept=org) qorg = QOrg.objects.get(qtask=qtask, org=org) qorg.count = qs.count() qorg.count_confirmed = qs.filter(confirmed=True).count() qorg.save() class QActionViewSet(RbacFilterSet, PageOrNot, ListModelMixin, DestroyModelMixin, RetrieveModelMixin, GenericViewSet): perms_map = {'get': '*', 'delete': 'qaction_delete'} queryset = QAction.objects.select_related( 'file', 'atype', 'afield', 'qtask', 'belong_dept', 'create_by') filterset_fields = ['qtask', 'belong_dept', 'atype', 'afield'] serializer_class = QActionListSerializer def get_serializer_class(self): if self.action == 'list': return QActionListSerializer elif self.action == 'retrieve': return QActionDetailSerializer return super().get_serializer_class() # @action(methods=['get'], detail=False, perms_map={'get': '*'}) # def my(self, request, *args, **kwargs): # """ # 我的报送操作 # """ # user = self.request.user # queryset = self.filter_queryset( # self.get_queryset().filter(belong_dept=user.dept)) # page = self.paginate_queryset(queryset) # if page is not None: # serializer = self.get_serializer(page, many=True) # return self.get_paginated_response(serializer.data) # serializer = self.get_serializer(queryset, many=True) # return Response(serializer.data) def perform_destroy(self, instance): user = self.request.user if not instance.confirmed: instance.delete(soft=False) cal_count(instance.qtask, user.dept) else: raise ParseError('报送已确认, 不可删除') @action(methods=['post'], detail=False, perms_map={'post': 'qaction_create'}, serializer_class=QActionServiceSerializer) @transaction.atomic def service_update(self, request, *args, **kwargs): """ 更新提供服务 """ user = request.user serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save(create_by=user, belong_dept=user.dept) vdata = serializer.validated_data cal_count(vdata['qtask'], user.dept) return Response() @action(methods=['post'], detail=False, perms_map={'post': 'qaction_create'}, serializer_class=QActionQualiCreateSerializer) @transaction.atomic def quali_create(self, request, *args, **kwargs): """ 新增资质 """ user = request.user serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save(create_by=user, belong_dept=user.dept) vdata = serializer.validated_data cal_count(vdata['qtask'], user.dept) return Response() @action(methods=['post'], detail=False, perms_map={'post': 'qaction_create'}, serializer_class=QActionQualiUpdateSerializer) @transaction.atomic def quali_update(self, request, *args, **kwargs): """ 修改资质 """ user = request.user serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) obj = serializer.save(create_by=user, belong_dept=user.dept) vdata = serializer.validated_data value2 = request.data.get('value2', {}) # 比较差别 quali = Quali.objects.get(id=value2.get('id')) old_data = QualiListSerializer(instance=quali).data obj.value1 = old_data obj.save() for k, v in value2.items(): if v != old_data[k]: QActionItem.objects.create( action='update', field=k, value1=old_data[k], value2=v, qaction=obj) if k == 'citys': old_citys = set(old_data['citys']) new_citys = set(v) removes = old_citys.difference(new_citys) adds = new_citys.difference(old_citys) for i in removes: QActionItem.objects.create( action='city:remove', field='citys', city=City.objects.get(id=i), qaction=obj) for i in adds: QActionItem.objects.create( action='city:add', field='citys', city=City.objects.get(id=i), qaction=obj) cal_count(vdata['qtask'], user.dept) return Response() @action(methods=['post'], detail=False, perms_map={'post': 'qaction_create'}, serializer_class=QActionACreateSerializer) @transaction.atomic def ability_create(self, request, *args, **kwargs): """ 新增能力 """ user = request.user serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save(create_by=user, belong_dept=user.dept) vdata = serializer.validated_data cal_count(vdata['qtask'], user.dept) return Response() @action(methods=['post'], detail=False, perms_map={'post': 'qaction_create'}, serializer_class=QActionNoChangeSerializer) @transaction.atomic def ability_nochange(self, request, *args, **kwargs): """ 能力无变化 """ user = request.user serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save(create_by=user, belong_dept=user.dept, action='ability:nochange') vdata = serializer.validated_data cal_count(vdata['qtask'], user.dept) return Response() @action(methods=['post'], detail=False, perms_map={'post': 'qaction_create'}, serializer_class=QActionNoChangeSerializer) @transaction.atomic def quali_nochange(self, request, *args, **kwargs): """ 资质无变化 """ user = request.user serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save(create_by=user, belong_dept=user.dept, action='quali:nochange') vdata = serializer.validated_data cal_count(vdata['qtask'], user.dept) return Response() @action(methods=['put'], detail=True, perms_map={'put': 'qaction_confirm'}, serializer_class=serializers.Serializer) @transaction.atomic def confirm(self, request, *args, **kwargs): """ 确认 """ obj = self.get_object() if obj.confirmed: raise ParseError('该动作已确认') if obj.action == 'service:update': org = obj.belong_dept org.service = obj.value2 org.save() elif obj.action == 'quali:create': serializer = QualiCreateSerializer(data=obj.value2) serializer.is_valid(raise_exception=True) instance = serializer.save( org=obj.belong_dept, create_by=obj.create_by) if instance.type == 'OTHER': qualiLib, _ = QualiLib.objects.get_or_create( name=instance.name) levels = qualiLib.levels levels.append(instance.level) le = list(set(levels)) qualiLib.levels = le qualiLib.save() instance.qualilib = qualiLib instance.save() elif obj.action == 'quali:update': quali = Quali.objects.get(id=obj.value2.get('id')) s = QualiUpdateSerializer(instance=quali, data=obj.value2) s.is_valid(raise_exception=True) s.save(update_by=obj.create_by) elif obj.action == 'ability:create': pass obj.confirmed = True obj.save() cal_count(obj.qtask, obj.belong_dept) return Response(status=status.HTTP_200_OK)