feat: base system和wf优化事务处理

This commit is contained in:
caoqianming 2025-09-17 12:15:26 +08:00
parent f60250bb21
commit 0284809933
2 changed files with 70 additions and 72 deletions

View File

@ -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

View File

@ -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': '*'})