From 6de80d2bb233dd41c7dfc6377ce36b4ed0eb7d4a Mon Sep 17 00:00:00 2001 From: weicw1996 Date: Thu, 22 Oct 2026 13:44:06 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20=E5=BE=85=E5=9B=9E=E5=8D=95=E7=A1=AE?= =?UTF-8?q?=E8=AE=A4=E4=B8=8B=E6=8B=92=E7=BB=9D=E8=A1=A5=E5=BD=95=E6=89=93?= =?UTF-8?q?=E5=8D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/WaybillServiceImpl.java | 6 +++ .../impl/WaybillPunchRecordSaveTest.java | 54 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/WaybillServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/WaybillServiceImpl.java index 9f40356f..1f54276c 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/WaybillServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/WaybillServiceImpl.java @@ -531,6 +531,12 @@ public class WaybillServiceImpl extends BaseServiceImpl } // 只有显式传 false 才是取消打卡,未传按已打卡处理 boolean punched = !Boolean.FALSE.equals(request.getPunched()); + // 待回单确认的运单司机已无待打卡节点,再补一条打卡流水与状态含义矛盾; + // 漏打的出路是先取消该节点的打卡退回进行中(punched=false),再重新补录。 + if (punched && WaybillProcessSupport.STATUS_PENDING_RETURN_CONFIRM + .equalsIgnoreCase(waybill.getBusinessStatus())) { + throw new ServiceException("运单待业务员确认回单,不能补录打卡"); + } if (ENROUTE_PUNCH_TYPE.equalsIgnoreCase(TransportBusinessSupport.trimToEmpty(request.getType()))) { return saveEnroutePunchRecord(waybill, request, punched); } diff --git a/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/WaybillPunchRecordSaveTest.java b/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/WaybillPunchRecordSaveTest.java index 6b41a1ef..1778a850 100644 --- a/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/WaybillPunchRecordSaveTest.java +++ b/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/WaybillPunchRecordSaveTest.java @@ -18,6 +18,7 @@ import org.springblade.transport.pojo.dto.WaybillPunchRecordSaveRequest; import org.springblade.transport.pojo.entity.Waybill; import org.springblade.transport.pojo.entity.WaybillEnroutePunch; import org.springblade.transport.pojo.entity.WaybillNodePunch; +import org.springblade.transport.support.WaybillProcessSupport; import java.lang.reflect.Field; import java.util.ArrayList; @@ -165,6 +166,59 @@ class WaybillPunchRecordSaveTest { verify(nodePunchMapper, never()).updateById(any(WaybillNodePunch.class)); } + @Test + @DisplayName("待回单确认:补录打卡被拒——司机已无待打卡,漏打应先取消打卡退回进行中") + void rejectBackfillOnPendingReturnConfirm() { + Waybill waybill = waybill(); + waybill.setBusinessStatus(WaybillProcessSupport.STATUS_PENDING_RETURN_CONFIRM); + when(waybillMapper.selectById(WAYBILL_ID)).thenReturn(waybill); + when(nodePunchMapper.selectList(any())).thenReturn(List.of()); + + WaybillPunchRecordSaveRequest request = request("node", "load", "装货"); + request.setPunched(true); + + ServiceException exception = assertThrows(ServiceException.class, + () -> service.savePunchRecord(request)); + + assertEquals("运单待业务员确认回单,不能补录打卡", exception.getMessage()); + verify(nodePunchMapper, never()).insert(any(WaybillNodePunch.class)); + } + + @Test + @DisplayName("待回单确认:取消打卡仍放行——那是退回进行中的唯一路径") + void keepCancelPunchOnPendingReturnConfirm() { + Waybill waybill = waybill(); + waybill.setBusinessStatus(WaybillProcessSupport.STATUS_PENDING_RETURN_CONFIRM); + when(waybillMapper.selectById(WAYBILL_ID)).thenReturn(waybill); + when(nodePunchMapper.selectList(any())).thenReturn(List.of(nodePunch(7001L, "load", "装货"))); + + WaybillPunchRecordSaveRequest request = request("node", "load", "装货"); + request.setPunched(false); + + assertTrue(service.savePunchRecord(request)); + + ArgumentCaptor> captor = ArgumentCaptor.forClass(Collection.class); + verify(nodePunchMapper).deleteBatchIds(captor.capture()); + assertEquals(Set.of(7001L), new HashSet<>(captor.getValue())); + } + + @Test + @DisplayName("已完成运单仍可补录——门禁只对待回单确认生效") + void keepBackfillOnCompletedWaybill() { + Waybill waybill = waybill(); + waybill.setBusinessStatus("completed"); + when(waybillMapper.selectById(WAYBILL_ID)).thenReturn(waybill); + when(nodePunchMapper.selectList(any())).thenReturn(List.of()); + + WaybillPunchRecordSaveRequest request = request("node", "load", "装货"); + request.setPunched(true); + request.setPunchTime("2026-10-06 09:30:00"); + + assertTrue(service.savePunchRecord(request)); + + verify(nodePunchMapper).insert(any(WaybillNodePunch.class)); + } + @Test @DisplayName("接单节点:补录与取消打卡都拒绝——它的完成由运单的接单事实决定") void rejectAcceptNodePunchEdit() {