diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverWaybillServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverWaybillServiceImpl.java index d616bc17..83987141 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverWaybillServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverWaybillServiceImpl.java @@ -403,12 +403,17 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService { LambdaQueryWrapper plateQuery = Wrappers.lambdaQuery(); VehiclePlateSupport.applyPlateMatch(plateQuery, currentBoundPlates(driver)); List boundVehicles = transportVehicleService.list(plateQuery); - boolean anyCertified = boundVehicles.stream().anyMatch(vehicle -> - certificationGate.isVehicleAvailable( + // 逐车取不可用原因:停用与未认证要分开报,否则「车已认证但被停用」 + // 会被报成「认证没通过」,把人引去做无用的重新认证 + String unavailableReason = boundVehicles.stream() + .map(vehicle -> certificationGate.vehicleUnavailableReason( vehicle.getStatus() != null && vehicle.getStatus() == BladeConstant.DB_STATUS_NORMAL, - vehicle.getEffectiveCertRecordId())); - if (!anyCertified) { - throw new ServiceException(certificationGate.vehicleUnavailableReason()); + vehicle.getEffectiveCertRecordId())) + .filter(Objects::nonNull) + .findFirst() + .orElse(null); + if (unavailableReason != null) { + throw new ServiceException(unavailableReason); } } diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/CertificationGate.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/CertificationGate.java index 2af6ae62..5a4ed782 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/CertificationGate.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/CertificationGate.java @@ -76,13 +76,30 @@ public class CertificationGate { * @return 是否可用 */ public boolean isVehicleAvailable(Boolean enabledState, Long effectiveRecordId) { + return vehicleUnavailableReason(enabledState, effectiveRecordId) == null; + } + + /** + * 车辆不可用的原因 + *

+ * 停用与未认证是两件事,处置方式也不同:一个要找调度启用车辆,一个要去提交认证。 + * 合并成同一句话,会把「车已认证、只是被停用」误导成「认证没通过」, + * 让人白做一轮重新认证。 + * + * @param enabledState 运营状态:TRUE 启用 + * @param effectiveRecordId 生效快照指针 + * @return 不可用原因;可用时返回 null + */ + public String vehicleUnavailableReason(Boolean enabledState, Long effectiveRecordId) { if (!Boolean.TRUE.equals(enabledState)) { - return false; + return "该车辆已停用,暂不可接单,请联系调度启用"; } if (!vehicleGateEnabled) { - return true; + return null; } - return CertificationRuleSupport.isCertified(effectiveRecordId); + return CertificationRuleSupport.isCertified(effectiveRecordId) + ? null + : "该车辆尚未通过认证审核,暂不可接单,请先提交认证"; } /** @@ -98,15 +115,6 @@ public class CertificationGate { return CertificationRuleSupport.isCertified(effectiveRecordId); } - /** - * 车辆不可用的提示文案 - * - * @return 面向司机的中文提示 - */ - public String vehicleUnavailableReason() { - return "该车辆尚未通过认证审核,暂不可接单,请先提交认证"; - } - /** * 司机不可用的提示文案 * diff --git a/blade-service/blade-transport/src/test/java/org/springblade/transport/support/CertificationGateTest.java b/blade-service/blade-transport/src/test/java/org/springblade/transport/support/CertificationGateTest.java index afa32c0f..8a9bbb0f 100644 --- a/blade-service/blade-transport/src/test/java/org/springblade/transport/support/CertificationGateTest.java +++ b/blade-service/blade-transport/src/test/java/org/springblade/transport/support/CertificationGateTest.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -96,10 +97,23 @@ class CertificationGateTest { // ------------------------------------------------------------ 提示文案 @Test - @DisplayName("拒绝原因可读,且不泄露内部字段名") - void rejectReasonIsReadable() { - assertTrue(gate.vehicleUnavailableReason().contains("认证")); - assertFalse(gate.vehicleUnavailableReason().contains("effective_cert_record_id")); + @DisplayName("停用与未认证分开报:前者让人去启用车辆,后者才让人去认证") + void unavailableReasonsDistinguishDisabledFromUncertified() { + String disabled = gate.vehicleUnavailableReason(Boolean.FALSE, 7001L); + assertTrue(disabled.contains("停用"), disabled); + assertFalse(disabled.contains("认证审核"), "已认证的车被停用,不该报成认证没通过"); + + String uncertified = gate.vehicleUnavailableReason(Boolean.TRUE, null); + assertTrue(uncertified.contains("认证"), uncertified); + assertFalse(uncertified.contains("停用"), uncertified); + } + + @Test + @DisplayName("可用时没有原因;两种不可用文案都不泄露内部字段名") + void availableHasNoReasonAndTextIsReadable() { + assertNull(gate.vehicleUnavailableReason(Boolean.TRUE, 7001L)); + assertFalse(gate.vehicleUnavailableReason(Boolean.TRUE, null).contains("effective_cert_record_id")); + assertFalse(gate.vehicleUnavailableReason(Boolean.FALSE, null).contains("effective_cert_record_id")); assertTrue(gate.driverUnavailableReason().contains("认证")); }