feat: wpm优化事务和悲观锁

This commit is contained in:
caoqianming 2025-09-15 09:41:20 +08:00
parent aa80c1b00a
commit 00d0b1ea00
1 changed files with 23 additions and 23 deletions

View File

@ -3,7 +3,6 @@ import math
from django.db import transaction
from rest_framework.decorators import action
from rest_framework.exceptions import ParseError
from rest_framework.mixins import DestroyModelMixin, ListModelMixin, UpdateModelMixin, CreateModelMixin
from rest_framework.response import Response
from rest_framework.serializers import Serializer
from django.db.models import Sum
@ -12,7 +11,7 @@ from apps.system.models import User
from apps.mtm.models import Material, Process, Route, Mgroup, RoutePack, RouteMat
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
from apps.utils.mixins import CustomListModelMixin, BulkCreateModelMixin, ComplexQueryMixin
from apps.utils.mixins import CustomListModelMixin, BulkCreateModelMixin, ComplexQueryMixin, BulkDestroyModelMixin, BulkUpdateModelMixin
from .filters import StLogFilter, SfLogFilter, WMaterialFilter, MlogFilter, HandoverFilter, MlogbFilter, BatchStFilter, MlogbwFilter
from .models import (SfLog, SfLogExp, StLog, WMaterial, Mlog, Handover, Mlogb,
@ -41,6 +40,7 @@ from apps.em.models import Equipment
from django.db.models import Prefetch
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from django.db import connection
# Create your views here.
@ -68,7 +68,7 @@ class StLogViewSet(CustomModelViewSet):
return super().destroy(request, *args, **kwargs)
class SfLogViewSet(UpdateModelMixin, CustomListModelMixin, DestroyModelMixin, CustomGenericViewSet):
class SfLogViewSet(BulkUpdateModelMixin, CustomListModelMixin, BulkDestroyModelMixin, CustomGenericViewSet):
"""
list:值班记录
@ -118,7 +118,7 @@ class SfLogViewSet(UpdateModelMixin, CustomListModelMixin, DestroyModelMixin, Cu
return Response(sr.data)
class SfLogExpViewSet(ListModelMixin, UpdateModelMixin, CustomGenericViewSet):
class SfLogExpViewSet(CustomListModelMixin, BulkUpdateModelMixin, CustomGenericViewSet):
"""
list:异常值班处理
@ -131,7 +131,7 @@ class SfLogExpViewSet(ListModelMixin, UpdateModelMixin, CustomGenericViewSet):
filterset_fields = ['sflog', 'stlog']
class WMaterialViewSet(ListModelMixin, CustomGenericViewSet):
class WMaterialViewSet(CustomListModelMixin, CustomGenericViewSet):
"""
list: 车间库存
@ -208,9 +208,12 @@ class MlogViewSet(CustomModelViewSet):
@classmethod
def lock_and_check_can_update(cls, mlog:Mlog):
# mlog_lock:Mlog = Mlog.objects.select_for_update().get(id=mlog.id)
if not connection.in_atomic_block:
raise ParseError("请在事务中调用该方法")
mlog_lock:Mlog = Mlog.objects.select_for_update().get(id=mlog.id)
if mlog.submit_time is not None:
raise ParseError("该记录已提交无法更改")
return mlog_lock
def get_serializer_class(self):
@ -688,7 +691,7 @@ class MlogbViewSet(CustomListModelMixin, CustomGenericViewSet):
ordering = ["create_time"]
class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, CustomGenericViewSet):
class MlogbInViewSet(BulkCreateModelMixin, BulkUpdateModelMixin, BulkDestroyModelMixin, CustomGenericViewSet):
perms_map = {'post': 'mlog.update', 'delete': 'mlog.update', 'put': 'mlog.update'}
queryset = Mlogb.objects.filter(material_in__isnull=False)
serializer_class = MlogbInSerializer
@ -696,15 +699,15 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
def perform_destroy(self, instance):
ins: Mlogb = instance
MlogViewSet.lock_and_check_can_update(ins.mlog)
mlog = MlogViewSet.lock_and_check_can_update(ins.mlog)
ins.delete()
ins.mlog.cal_mlog_count_from_mlogb()
mlog.cal_mlog_count_from_mlogb()
def perform_update(self, serializer):
ins:Mlogb = serializer.instance
MlogViewSet.lock_and_check_can_update(ins.mlog)
mlog = MlogViewSet.lock_and_check_can_update(ins.mlog)
ins:Mlogb = serializer.save()
ins.mlog.cal_mlog_count_from_mlogb()
mlog.cal_mlog_count_from_mlogb()
@classmethod
def p_create_after(cls, mlogbin:Mlogb):
@ -906,19 +909,19 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
except Exception as e:
raise ParseError(f"个号生成错误: {e}")
class MlogbOutViewSet(UpdateModelMixin, CustomGenericViewSet):
class MlogbOutViewSet(BulkUpdateModelMixin, CustomGenericViewSet):
perms_map = {"put": "mlog.update"}
queryset = Mlogb.objects.filter(material_out__isnull=False)
serializer_class = MlogbOutUpdateSerializer
def perform_update(self, serializer):
ins:Mlogb = serializer.instance
MlogViewSet.lock_and_check_can_update(ins.mlog)
mlog = MlogViewSet.lock_and_check_can_update(ins.mlog)
material_out = serializer.validated_data.get('material_out')
if material_out and material_out.tracking == Material.MA_TRACKING_SINGLE:
raise ParseError("单件产品不支持直接修改")
ins:Mlogb = serializer.save()
ins.mlog.cal_mlog_count_from_mlogb()
mlog.cal_mlog_count_from_mlogb()
class FmlogViewSet(CustomModelViewSet):
@ -943,7 +946,7 @@ class FmlogViewSet(CustomModelViewSet):
ins.save()
return Response()
class BatchStViewSet(ListModelMixin, ComplexQueryMixin, CustomGenericViewSet):
class BatchStViewSet(CustomListModelMixin, ComplexQueryMixin, CustomGenericViewSet):
"""
list: 批次统计数据
@ -1057,7 +1060,7 @@ class MlogbwViewSet(CustomModelViewSet):
pass
else:
mlog = mlogbw.mlogb.mlog
MlogViewSet.lock_and_check_can_update(mlog)
mlog = MlogViewSet.lock_and_check_can_update(mlog)
Mlogbw.cal_count_notok(mlogbw.mlogb)
mlog.cal_mlog_count_from_mlogb()
@ -1066,15 +1069,13 @@ class MlogbwViewSet(CustomModelViewSet):
mlogbIds = list(set([obj["mlogb"] for obj in objs]))
for mlogbId in mlogbIds:
mlogb = Mlogb.objects.get(id=mlogbId)
mlog = mlogb.mlog
MlogViewSet.lock_and_check_can_update(mlog)
mlog = MlogViewSet.lock_and_check_can_update(mlogb.mlog)
Mlogbw.cal_count_notok(mlogb)
mlog.cal_mlog_count_from_mlogb()
def perform_destroy(self, instance:Mlogbw):
mlogb:Mlogb = instance.mlogb
MlogViewSet.lock_and_check_can_update(mlogb.mlog)
mlog = MlogViewSet.lock_and_check_can_update(mlogb.mlog)
if mlogb.material_out is not None and instance.wpr is not None:
raise ParseError("不能删除该产出明细")
@ -1099,7 +1100,6 @@ class MlogbwViewSet(CustomModelViewSet):
for mlogb in mlogb_qs:
Mlogbw.cal_count_notok(mlogb)
mlog = mlogb.mlog
mlog.cal_mlog_count_from_mlogb()
@action(methods=['post'], detail=False, perms_map={'post': 'mlog.update'}, serializer_class=MlogbwStartTestSerializer)
@ -1110,7 +1110,7 @@ class MlogbwViewSet(CustomModelViewSet):
sr.save()
return Response()
class MlogUserViewSet(BulkCreateModelMixin, ListModelMixin, DestroyModelMixin, CustomGenericViewSet):
class MlogUserViewSet(BulkCreateModelMixin, CustomListModelMixin, BulkDestroyModelMixin, CustomGenericViewSet):
perms_map = {"get": "*", "post": "mlog.update", "delete": "mlog.update"}
queryset = MlogUser.objects.all()
serializer_class = MlogUserSerializer
@ -1129,7 +1129,7 @@ class MlogUserViewSet(BulkCreateModelMixin, ListModelMixin, DestroyModelMixin, C
return super().perform_destroy(instance)
class BatchLogViewSet(ListModelMixin, CustomGenericViewSet):
class BatchLogViewSet(CustomListModelMixin, CustomGenericViewSet):
perms_map = {"get": "*"}
queryset = BatchLog.objects.all()
serializer_class = BatchLogSerializer