feat: 生产日志子表全部加mlog锁

This commit is contained in:
caoqianming 2025-09-12 16:48:33 +08:00
parent 6b08200016
commit cdcb02d4d5
2 changed files with 28 additions and 6 deletions

View File

@ -1107,6 +1107,9 @@ class MlogbOutUpdateSerializer(CustomModelSerializer):
return ins return ins
def validate(self, attrs): def validate(self, attrs):
mlog: Mlog = attrs.get("mlog")
if mlog.submit_time is not None:
raise ParseError('生产日志已提交不可编辑')
mlogbdefect = attrs.get("mlogbdefect", []) mlogbdefect = attrs.get("mlogbdefect", [])
if mlogbdefect: if mlogbdefect:
attrs.pop("count_notok_json", None) attrs.pop("count_notok_json", None)

View File

@ -206,6 +206,13 @@ class MlogViewSet(CustomModelViewSet):
data["oinfo_json_"] = {czx_dict.get(k, k): v for k, v in data.get("oinfo_json", {}).items()} data["oinfo_json_"] = {czx_dict.get(k, k): v for k, v in data.get("oinfo_json", {}).items()}
return data return data
@classmethod
def lock_and_check_can_update(cls, mlog:Mlog):
mlog_lock:Mlog = Mlog.objects.select_for_update(id=mlog.id)
if mlog_lock.submit_time is not None:
raise ParseError("该记录已提交无法更改")
def get_serializer_class(self): def get_serializer_class(self):
if self.request.query_params.get('with_mlogb', False): if self.request.query_params.get('with_mlogb', False):
return MlogSerializer return MlogSerializer
@ -689,12 +696,13 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
def perform_destroy(self, instance): def perform_destroy(self, instance):
ins: Mlogb = instance ins: Mlogb = instance
if ins.mlog.submit_time is not None: MlogViewSet.lock_and_check_can_update(ins.mlog)
raise ParseError('生产日志已提交不可编辑')
ins.delete() ins.delete()
ins.mlog.cal_mlog_count_from_mlogb() ins.mlog.cal_mlog_count_from_mlogb()
def perform_update(self, serializer): def perform_update(self, serializer):
ins:Mlogb = serializer.instance
MlogViewSet.lock_and_check_can_update(ins.mlog)
ins:Mlogb = serializer.save() ins:Mlogb = serializer.save()
ins.mlog.cal_mlog_count_from_mlogb() ins.mlog.cal_mlog_count_from_mlogb()
@ -863,6 +871,7 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
def perform_create(self, serializer): def perform_create(self, serializer):
mlogbin: Mlogb = serializer.save() mlogbin: Mlogb = serializer.save()
MlogViewSet.lock_and_check_can_update(mlogbin.mlog)
MlogbInViewSet.p_create_after(mlogbin) MlogbInViewSet.p_create_after(mlogbin)
@classmethod @classmethod
@ -903,6 +912,8 @@ class MlogbOutViewSet(UpdateModelMixin, CustomGenericViewSet):
serializer_class = MlogbOutUpdateSerializer serializer_class = MlogbOutUpdateSerializer
def perform_update(self, serializer): def perform_update(self, serializer):
ins:Mlogb = serializer.instance
MlogViewSet.lock_and_check_can_update(ins.mlog)
material_out = serializer.validated_data.get('material_out') material_out = serializer.validated_data.get('material_out')
if material_out and material_out.tracking == Material.MA_TRACKING_SINGLE: if material_out and material_out.tracking == Material.MA_TRACKING_SINGLE:
raise ParseError("单件产品不支持直接修改") raise ParseError("单件产品不支持直接修改")
@ -968,12 +979,16 @@ class MlogbwViewSet(CustomModelViewSet):
insx = ins insx = ins
else: else:
insx = [ins] insx = [ins]
checked = False
for ins in insx: for ins in insx:
if mlog is None: if mlog is None:
mlog = ins.mlogb.mlog mlog = ins.mlogb.mlog
else: else:
if mlog != ins.mlogb.mlog: if mlog != ins.mlogb.mlog:
raise ParseError("所有记录必须属于同一张日志") raise ParseError("所有记录必须属于同一张日志")
if not checked:
MlogViewSet.lock_and_check_can_update(mlog)
checked = True
wpr:Wpr = ins.wpr wpr:Wpr = ins.wpr
mlogb:Mlogb = ins.mlogb mlogb:Mlogb = ins.mlogb
if wpr.wm != mlogb.wm_in: if wpr.wm != mlogb.wm_in:
@ -1041,20 +1056,25 @@ class MlogbwViewSet(CustomModelViewSet):
if isinstance(mlogbw, list): if isinstance(mlogbw, list):
pass pass
else: else:
Mlogbw.cal_count_notok(mlogbw.mlogb)
mlog = mlogbw.mlogb.mlog mlog = mlogbw.mlogb.mlog
MlogViewSet.lock_and_check_can_update(mlog)
Mlogbw.cal_count_notok(mlogbw.mlogb)
mlog.cal_mlog_count_from_mlogb() mlog.cal_mlog_count_from_mlogb()
def after_bulk_update(self, objs): def after_bulk_update(self, objs):
mlogbIds = list(set([obj["mlogb"] for obj in objs])) mlogbIds = list(set([obj["mlogb"] for obj in objs]))
for mlogbId in mlogbIds: for mlogbId in mlogbIds:
mlogb = Mlogb.objects.get(id=mlogbId) mlogb = Mlogb.objects.get(id=mlogbId)
Mlogbw.cal_count_notok(mlogb)
mlog = mlogb.mlog mlog = mlogb.mlog
MlogViewSet.lock_and_check_can_update(mlog)
Mlogbw.cal_count_notok(mlogb)
mlog.cal_mlog_count_from_mlogb() mlog.cal_mlog_count_from_mlogb()
def perform_destroy(self, instance:Mlogbw): def perform_destroy(self, instance:Mlogbw):
mlogb:Mlogb = instance.mlogb mlogb:Mlogb = instance.mlogb
MlogViewSet.lock_and_check_can_update(mlogb.mlog)
if mlogb.material_out is not None and instance.wpr is not None: if mlogb.material_out is not None and instance.wpr is not None:
raise ParseError("不能删除该产出明细") raise ParseError("不能删除该产出明细")
@ -1105,8 +1125,7 @@ class MlogUserViewSet(BulkCreateModelMixin, ListModelMixin, DestroyModelMixin, C
def perform_destroy(self, instance): def perform_destroy(self, instance):
mlog:Mlog = instance.mlog mlog:Mlog = instance.mlog
if mlog.submit_time is not None: MlogViewSet.lock_and_check_can_update(mlog)
raise ParseError("不能删除该记录")
return super().perform_destroy(instance) return super().perform_destroy(instance)