🐛 回退配载准入对进行中运单的放行,恢复只放行待执行

This commit is contained in:
2026-10-27 16:15:00 +08:00
parent c82657ca56
commit cd9c7f4357
7 changed files with 30 additions and 32 deletions
@@ -872,8 +872,8 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
String prefix = "运单" + waybill.getWaybillNo();
return prefix + switch (reason) {
case NOT_ROAD -> "运输方式不是公路,不可配载";
case NOT_LOADABLE_STATUS -> "当前状态不是待执行或进行中,不可配载";
case ON_OTHER_MANIFEST -> "已关联其他有效配载单";
case NOT_PENDING -> "当前状态不是待执行,不可配载";
case ON_OTHER_MANIFEST -> "已关联其他配载单";
};
}
@@ -29,7 +29,7 @@ import java.util.List;
import java.util.Locale;
/**
* 可配载准入判据:公路 + 待执行/进行中 + 未关联其它配载单。
* 可配载准入判据:公路 + 待执行 + 未关联其它配载单。
* <p>
* 接单状态不进判据:拒单票照样可配载。配载提交会把它的接单事实清成待接单,
* 否则新司机看不到这张票——司机端入口一律排除已拒绝的运单。
@@ -38,11 +38,8 @@ import java.util.Locale;
*/
public final class LoadableAdmissionSupport {
/** 可配载业务状态:待执行、进行中;已完成、已取消、草稿与调度中间态一律不可配载 */
public static final List<String> LOADABLE_BUSINESS_STATUSES = List.of(
WaybillProcessSupport.STATUS_PENDING,
WaybillProcessSupport.STATUS_RUNNING
);
/** 可配载只放行待执行:已完成、已取消、草稿与调度中间态一律不可配载 */
public static final String LOADABLE_BUSINESS_STATUS = WaybillProcessSupport.STATUS_PENDING;
/**
* 公路运输方式的同义写法,按「包含」比对,与前端运单管理页的识别口径一致。
@@ -59,7 +56,7 @@ public final class LoadableAdmissionSupport {
}
/**
* 不可配载的原因,按判定顺序排列:公路 → 待执行/进行中 → 未关联其它配载单。
* 不可配载的原因,按判定顺序排列:公路 → 待执行 → 未关联其它配载单。
* <p>
* 判据只产出原因,中文文案由调用方映射——面向用户的措辞不进这一层。
*/
@@ -68,8 +65,8 @@ public final class LoadableAdmissionSupport {
/** 运输方式不是公路 */
NOT_ROAD,
/** 业务状态不是待执行或进行中 */
NOT_LOADABLE_STATUS,
/** 业务状态不是待执行 */
NOT_PENDING,
/** 已关联其它配载单 */
ON_OTHER_MANIFEST
@@ -122,8 +119,8 @@ public final class LoadableAdmissionSupport {
if (waybill == null || !isRoadTransport(waybill.getTransportType())) {
return UnloadableReason.NOT_ROAD;
}
if (!LOADABLE_BUSINESS_STATUSES.contains(text(waybill.getBusinessStatus()))) {
return UnloadableReason.NOT_LOADABLE_STATUS;
if (!LOADABLE_BUSINESS_STATUS.equals(text(waybill.getBusinessStatus()))) {
return UnloadableReason.NOT_PENDING;
}
String loadingNo = text(waybill.getLoadingNo());
if (loadingNo.isEmpty() || loadingNo.equals(text(ownLoadingNo))) {
@@ -151,13 +148,13 @@ public final class LoadableAdmissionSupport {
}
/**
* 把整条可配载判据加到运单查询上:公路 + 待执行/进行中 + 未配载。
* 把整条可配载判据加到运单查询上:公路 + 待执行 + 未配载。
*
* @param wrapper 运单列表查询条件
*/
public static void applyLoadableConditions(LambdaQueryWrapper<Waybill> wrapper) {
applyRoadTransportCondition(wrapper);
wrapper.in(Waybill::getBusinessStatus, LOADABLE_BUSINESS_STATUSES);
wrapper.eq(Waybill::getBusinessStatus, LOADABLE_BUSINESS_STATUS);
wrapper.and(nested -> nested.isNull(Waybill::getLoadingNo).or().eq(Waybill::getLoadingNo, ""));
}
@@ -257,14 +257,14 @@ class DriverTripCardTest {
}
@Test
@DisplayName("首页当前任务取运输中运次,最多一条")
@DisplayName("首页当前任务取运输中与待回单确认运次,最多一条")
void tripCurrentTaskTakesRunningTrip() {
stubTripPage(1, loadingTrip());
DriverWaybillCardVO card = runAsDriver(() -> service.tripCurrentTask());
assertNotNull(card);
assertEquals(1, capturedQuery().getStatus());
assertEquals(List.of(1, 4), capturedQuery().getStatuses(), "只剩待回单确认的司机首页仍有当前任务");
assertEquals(1, capturedQuery().getSize());
Page<TripVO> empty = new Page<>(1, 1, 0);
@@ -369,7 +369,7 @@ class LoadingManageChildStatusWriteTest {
waybill.setProjectId(projectId);
waybill.setProcessJson(processJson);
waybill.setDeptId(DEPT_ID_LONG);
// 可配载放行公路 + 待执行/进行中 + 未配载,夹具默认待执行
// 可配载只放行公路 + 待执行 + 未配载,夹具的票都是这种票
waybill.setTransportType("公路运输");
waybill.setBusinessStatus("pending");
return waybill;
@@ -168,7 +168,7 @@ class ManageTripListDetailTest {
}
@Test
@DisplayName("待处理列表:两档与「未拒单」交给同一次共享取数;待重新派单仍走子单被拒那条路")
@DisplayName("待处理列表:三档(待接单/进行中/待回单确认)与「未拒单」交给同一次共享取数;待重新派单仍走子单被拒那条路")
void pendingListUsesSharedQuery() {
when(tripQueryService.page(any())).thenReturn(pageOf(0));
when(waybillService.page(any(), any())).thenAnswer(invocation -> invocation.getArgument(0));
@@ -177,7 +177,7 @@ class ManageTripListDetailTest {
ArgumentCaptor<TripQueryVO> captor = ArgumentCaptor.forClass(TripQueryVO.class);
verify(tripQueryService, times(1)).page(captor.capture());
assertEquals(List.of(0, 1), captor.getValue().getStatuses(), "待处理只要待接单与进行中两档");
assertEquals(List.of(0, 1, 4), captor.getValue().getStatuses(), "待处理含待接单、进行中、待回单确认三档");
assertTrue(captor.getValue().isExcludeRejectedTrips(), "未拒单也交给共享取数");
service.pendingList(1, 10, null, true);
@@ -68,7 +68,7 @@ class WaybillLoadableQueryTest {
}
@Test
@DisplayName("开关开启:公路词表、待执行/进行中、未配载一次全部进 wrapper,接单状态不参与")
@DisplayName("开关开启:公路词表、待执行、未配载一次全部进 wrapper,接单状态不参与")
void loadableSwitchAppliesWholePredicate() {
LambdaQueryWrapper<Waybill> wrapper = capturedQuery(loadableQuery());
String sql = String.valueOf(wrapper.getTargetSql());
@@ -79,8 +79,10 @@ class WaybillLoadableQueryTest {
assertTrue(params.contains("%" + keyword + "%"),
"公路词表要整份进条件,只写 road 会漏掉中文取值的运单:" + params);
}
assertTrue(sql.contains("business_status") && params.contains("pending") && params.contains("running"),
"放行待执行与进行中:" + sql + " " + params);
assertTrue(sql.contains("business_status =") && params.contains("pending"),
"只放行待执行:" + sql + " " + params);
assertFalse(params.contains("running"),
"进行中一律不可配载,不能沿用「待执行与进行中都可配载」的旧口径:" + params);
assertTrue(sql.contains("loading_no IS NULL") && sql.contains("loading_no ="),
"未配载要同时覆盖 NULL 与空串:" + sql);
assertFalse(sql.contains("driver_accept_status"),
@@ -50,12 +50,10 @@ class LoadableAdmissionSupportTest {
// ------------------------------------------------------------ 单张运单准入
@Test
@DisplayName("公路 + 待执行/进行中 + 未配载才可配载")
@DisplayName("公路 + 待执行 + 未配载才可配载")
void loadableOnlyWhenAllConditionsHold() {
assertTrue(LoadableAdmissionSupport.isLoadable(waybill("road", "pending", null, "pending"), null));
assertTrue(LoadableAdmissionSupport.isLoadable(waybill("公路运输", "pending", "", null), null));
assertTrue(LoadableAdmissionSupport.isLoadable(waybill("road", "running", null, null), null),
"进行中也可配载");
}
@Test
@@ -66,10 +64,12 @@ class LoadableAdmissionSupportTest {
}
@Test
@DisplayName("非公路、非待执行/进行中、已关联配载单各自单独即可拒绝")
@DisplayName("非公路、非待执行、已关联配载单各自单独即可拒绝")
void eachConditionRejectsOnItsOwn() {
assertFalse(LoadableAdmissionSupport.isLoadable(waybill("railway", "pending", null, "pending"), null),
"非公路不可配载");
assertFalse(LoadableAdmissionSupport.isLoadable(waybill("road", "running", null, null), null),
"进行中不可配载:不需要接单的项目保存后即为进行中,那是过程配置的产物,不代表可配载");
assertFalse(LoadableAdmissionSupport.isLoadable(waybill("road", "draft", null, null), null));
assertFalse(LoadableAdmissionSupport.isLoadable(waybill("road", "completed", null, null), null));
assertFalse(LoadableAdmissionSupport.isLoadable(waybill("road", "cancelled", null, null), null));
@@ -79,19 +79,18 @@ class LoadableAdmissionSupportTest {
}
@Test
@DisplayName("不可配载原因按 公路 → 待执行/进行中 → 未关联其它配载单 取第一条")
@DisplayName("不可配载原因按 公路 → 待执行 → 未关联其它配载单 取第一条")
void unloadableReasonFollowsPredicateOrder() {
assertEquals(LoadableAdmissionSupport.UnloadableReason.NOT_ROAD,
LoadableAdmissionSupport.unloadableReason(
waybill("railway", "completed", "PZ20260101-002", null), "PZ20260101-001"));
assertEquals(LoadableAdmissionSupport.UnloadableReason.NOT_LOADABLE_STATUS,
waybill("railway", "running", "PZ20260101-002", null), "PZ20260101-001"));
assertEquals(LoadableAdmissionSupport.UnloadableReason.NOT_PENDING,
LoadableAdmissionSupport.unloadableReason(
waybill("road", "completed", "PZ20260101-002", null), "PZ20260101-001"));
waybill("road", "running", "PZ20260101-002", null), "PZ20260101-001"));
assertEquals(LoadableAdmissionSupport.UnloadableReason.ON_OTHER_MANIFEST,
LoadableAdmissionSupport.unloadableReason(
waybill("road", "pending", "PZ20260101-002", null), "PZ20260101-001"));
assertNull(LoadableAdmissionSupport.unloadableReason(waybill("road", "pending", null, null), null));
assertNull(LoadableAdmissionSupport.unloadableReason(waybill("road", "running", null, null), null));
assertNull(LoadableAdmissionSupport.unloadableReason(
waybill("road", "pending", "PZ20260101-001", null), "PZ20260101-001"));
}