From 02848099332564396b985b9c807027cc4af15832 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 17 Sep 2025 12:15:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20base=20system=E5=92=8Cwf=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E4=BA=8B=E5=8A=A1=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/system/views.py | 77 +++++++++++++++++++++----------------------- apps/wf/views.py | 65 +++++++++++++++++++------------------ 2 files changed, 70 insertions(+), 72 deletions(-) diff --git a/apps/system/views.py b/apps/system/views.py index a3a426bc..3a3aa9c3 100755 --- a/apps/system/views.py +++ b/apps/system/views.py @@ -8,8 +8,7 @@ from django_celery_beat.models import (CrontabSchedule, IntervalSchedule, from django_celery_results.models import TaskResult from rest_framework.decorators import action from rest_framework.exceptions import ParseError, ValidationError, PermissionDenied -from rest_framework.mixins import (CreateModelMixin, DestroyModelMixin, - ListModelMixin, RetrieveModelMixin) +from rest_framework.mixins import RetrieveModelMixin from rest_framework.parsers import (JSONParser, MultiPartParser) from rest_framework.serializers import Serializer @@ -20,7 +19,7 @@ from apps.hrm.models import Employee from apps.system.errors import OLD_PASSWORD_WRONG, PASSWORD_NOT_SAME, SCHEDULE_WRONG from apps.system.filters import DeptFilterSet, UserFilterSet # from django_q.models import Task as QTask, Schedule as QSchedule -from apps.utils.mixins import (CustomCreateModelMixin, MyLoggingMixin) +from apps.utils.mixins import (MyLoggingMixin, BulkCreateModelMixin, BulkDestroyModelMixin, CustomListModelMixin) from django.conf import settings from apps.utils.permission import ALL_PERMS from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet @@ -229,7 +228,7 @@ class PTaskViewSet(CustomModelViewSet): return Response() -class PTaskResultViewSet(ListModelMixin, RetrieveModelMixin, CustomGenericViewSet): +class PTaskResultViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericViewSet): """ list:任务执行结果列表 @@ -373,7 +372,7 @@ class RoleViewSet(CustomModelViewSet): ordering = ['create_time'] -class PostRoleViewSet(CreateModelMixin, DestroyModelMixin, ListModelMixin, CustomGenericViewSet): +class PostRoleViewSet(BulkCreateModelMixin, BulkDestroyModelMixin, CustomListModelMixin, CustomGenericViewSet): """岗位/角色关系 岗位/角色关系 @@ -385,7 +384,7 @@ class PostRoleViewSet(CreateModelMixin, DestroyModelMixin, ListModelMixin, Custo filterset_fields = ['post', 'role'] -class UserPostViewSet(CreateModelMixin, DestroyModelMixin, ListModelMixin, CustomGenericViewSet): +class UserPostViewSet(BulkCreateModelMixin, BulkDestroyModelMixin, CustomListModelMixin, CustomGenericViewSet): """用户/岗位关系 用户/岗位关系 @@ -398,37 +397,13 @@ class UserPostViewSet(CreateModelMixin, DestroyModelMixin, ListModelMixin, Custo ordering = ['sort', 'create_time'] def perform_create(self, serializer): - with transaction.atomic(): - instance = serializer.save() - user = instance.user - up = UserPost.objects.filter(user=user).order_by( - 'sort', 'create_time').first() - if up: - user.belong_dept = up.dept - user.post = up.post - user.update_by = self.request.user - user.save() - # 更新人员表 - ep = Employee.objects.get_queryset( - all=True).filter(user=user).first() - if ep: - ep.belong_dept = user.belong_dept - ep.post = user.post - ep.is_deleted = False - ep.save() - - def perform_destroy(self, instance): - with transaction.atomic(): - user = instance.user - instance.delete() - up = UserPost.objects.filter(user=user).order_by( - 'sort', 'create_time').first() - if up: - user.belong_dept = up.dept - user.post = up.post - else: - user.belong_dept = None - user.post = None + instance = serializer.save() + user = instance.user + up = UserPost.objects.filter(user=user).order_by( + 'sort', 'create_time').first() + if up: + user.belong_dept = up.dept + user.post = up.post user.update_by = self.request.user user.save() # 更新人员表 @@ -440,6 +415,28 @@ class UserPostViewSet(CreateModelMixin, DestroyModelMixin, ListModelMixin, Custo ep.is_deleted = False ep.save() + def perform_destroy(self, instance): + user = instance.user + instance.delete() + up = UserPost.objects.filter(user=user).order_by( + 'sort', 'create_time').first() + if up: + user.belong_dept = up.dept + user.post = up.post + else: + user.belong_dept = None + user.post = None + user.update_by = self.request.user + user.save() + # 更新人员表 + ep = Employee.objects.get_queryset( + all=True).filter(user=user).first() + if ep: + ep.belong_dept = user.belong_dept + ep.post = user.post + ep.is_deleted = False + ep.save() + class UserViewSet(CustomModelViewSet): queryset = User.objects.get_queryset(all=True) @@ -610,7 +607,7 @@ class UserViewSet(CustomModelViewSet): return Response() -class FileViewSet(CustomCreateModelMixin, RetrieveModelMixin, ListModelMixin, CustomGenericViewSet): +class FileViewSet(BulkCreateModelMixin, RetrieveModelMixin, CustomListModelMixin, CustomGenericViewSet): """文件上传 list: @@ -651,7 +648,7 @@ class FileViewSet(CustomCreateModelMixin, RetrieveModelMixin, ListModelMixin, Cu instance.save() -class ApkViewSet(MyLoggingMixin, ListModelMixin, CreateModelMixin, GenericViewSet): +class ApkViewSet(MyLoggingMixin, CustomListModelMixin, BulkCreateModelMixin, GenericViewSet): perms_map = {'get': '*', 'post': 'apk.upload'} serializer_class = ApkSerializer @@ -692,7 +689,7 @@ class ApkViewSet(MyLoggingMixin, ListModelMixin, CreateModelMixin, GenericViewSe return Response() -class MyScheduleViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, CustomGenericViewSet): +class MyScheduleViewSet(CustomListModelMixin, BulkCreateModelMixin, BulkDestroyModelMixin, CustomGenericViewSet): perms_map = {'get': '*', 'post': '*', 'delete': 'myschedule.delete'} serializer_class = MyScheduleSerializer diff --git a/apps/wf/views.py b/apps/wf/views.py index c819e22d..ad924489 100755 --- a/apps/wf/views.py +++ b/apps/wf/views.py @@ -239,6 +239,7 @@ class TicketViewSet(CreateUpdateCustomMixin, CreateModelMixin, ListModelMixin, R raise ParseError('请指定查询分类') return super().filter_queryset(queryset) + @transaction.atomic def create(self, request, *args, **kwargs): """ 新建工单 @@ -263,25 +264,25 @@ class TicketViewSet(CreateUpdateCustomMixin, CreateModelMixin, ListModelMixin, R save_ticket_data[key] = ticket_data[key] else: save_ticket_data = ticket_data - with transaction.atomic(): - ticket = serializer.save(state=start_state, - create_by=request.user, - create_time=timezone.now(), - act_state=Ticket.TICKET_ACT_STATE_DRAFT, - belong_dept=request.user.belong_dept, - ticket_data=save_ticket_data) # 先创建出来 - # 更新title和sn - title = vdata.get('title', '') - title_template = ticket.workflow.title_template - if title_template: - all_ticket_data = {**rdata, **ticket_data} - title = title_template.format(**all_ticket_data) - sn = WfService.get_ticket_sn(ticket.workflow) # 流水号 - ticket.sn = sn - ticket.title = title - ticket.save() - ticket = WfService.handle_ticket(ticket=ticket, transition=transition, new_ticket_data=ticket_data, - handler=request.user, created=True) + + ticket = serializer.save(state=start_state, + create_by=request.user, + create_time=timezone.now(), + act_state=Ticket.TICKET_ACT_STATE_DRAFT, + belong_dept=request.user.belong_dept, + ticket_data=save_ticket_data) # 先创建出来 + # 更新title和sn + title = vdata.get('title', '') + title_template = ticket.workflow.title_template + if title_template: + all_ticket_data = {**rdata, **ticket_data} + title = title_template.format(**all_ticket_data) + sn = WfService.get_ticket_sn(ticket.workflow) # 流水号 + ticket.sn = sn + ticket.title = title + ticket.save() + ticket = WfService.handle_ticket(ticket=ticket, transition=transition, new_ticket_data=ticket_data, + handler=request.user, created=True) return Response(TicketSerializer(instance=ticket).data) @action(methods=['get'], detail=False, perms_map={'get': '*'}) @@ -297,6 +298,7 @@ class TicketViewSet(CreateUpdateCustomMixin, CreateModelMixin, ListModelMixin, R return Response(ret) @action(methods=['post'], detail=True, perms_map={'post': '*'}) + @transaction.atomic def handle(self, request, pk=None): """ 处理工单 @@ -307,13 +309,13 @@ class TicketViewSet(CreateUpdateCustomMixin, CreateModelMixin, ListModelMixin, R vdata = serializer.validated_data new_ticket_data = ticket.ticket_data new_ticket_data.update(**vdata['ticket_data']) - with transaction.atomic(): - ticket = WfService.handle_ticket(ticket=ticket, transition=vdata['transition'], - new_ticket_data=new_ticket_data, handler=request.user, - suggestion=vdata.get('suggestion', '')) + ticket = WfService.handle_ticket(ticket=ticket, transition=vdata['transition'], + new_ticket_data=new_ticket_data, handler=request.user, + suggestion=vdata.get('suggestion', '')) return Response(TicketSerializer(instance=ticket).data) @action(methods=['post'], detail=True, perms_map={'post': '*'}) + @transaction.atomic def deliver(self, request, pk=None): """ 转交工单 @@ -325,15 +327,14 @@ class TicketViewSet(CreateUpdateCustomMixin, CreateModelMixin, ListModelMixin, R vdata = serializer.validated_data # 校验之后的数据 if not ticket.state.enable_deliver: raise ParseError('不允许转交') - with transaction.atomic(): - ticket.participant_type = State.PARTICIPANT_TYPE_PERSONAL - ticket.participant = vdata['target_user'] - ticket.save() - TicketFlow.objects.create(ticket=ticket, state=ticket.state, - ticket_data=WfService.get_ticket_all_field_value(ticket), - suggestion=vdata.get('suggestion', ''), participant_type=State.PARTICIPANT_TYPE_PERSONAL, - intervene_type=Transition.TRANSITION_INTERVENE_TYPE_DELIVER, - participant=request.user, transition=None) + ticket.participant_type = State.PARTICIPANT_TYPE_PERSONAL + ticket.participant = vdata['target_user'] + ticket.save() + TicketFlow.objects.create(ticket=ticket, state=ticket.state, + ticket_data=WfService.get_ticket_all_field_value(ticket), + suggestion=vdata.get('suggestion', ''), participant_type=State.PARTICIPANT_TYPE_PERSONAL, + intervene_type=Transition.TRANSITION_INTERVENE_TYPE_DELIVER, + participant=request.user, transition=None) return Response() @action(methods=['get'], detail=True, perms_map={'get': '*'})