🐛 派单与导入解析不到司机档案时留脱敏 WARN
改派、主单派单、Excel 导入三条写路径在解析不到档案时只落空不阻断,补 log.warn(号码用 DesensitizedUtil.mobilePhone 脱敏)。同时去掉解析结果上多余的 id > 0 归一:解析入口只返回 null 或唯一命中的档案 ID。
This commit is contained in:
+10
-3
@@ -4,8 +4,10 @@
|
||||
*/
|
||||
package org.springblade.transport.service.impl;
|
||||
|
||||
import cn.hutool.core.util.DesensitizedUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.log.exception.ServiceException;
|
||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||
import org.springblade.core.tool.jackson.JsonUtil;
|
||||
@@ -51,6 +53,7 @@ import java.util.Objects;
|
||||
* @author Chill
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, MasterOrder> implements IMasterOrderService {
|
||||
|
||||
private static final String CARRIER_SELF = "自运";
|
||||
@@ -266,11 +269,15 @@ public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, M
|
||||
waybill.setTransportType(string(dispatch, "transportType")); waybill.setCarrierType(string(dispatch, "carrierType"));
|
||||
waybill.setCarrierContractId(longValue(dispatch, "carrierContractId")); waybill.setCarrierName(string(dispatch, "carrierName")); waybill.setDriverName(string(dispatch, "driverName"));
|
||||
waybill.setDriverPhone(string(dispatch, "driverPhone")); waybill.setVehicleNo(string(dispatch, "vehicleNo")); waybill.setTrailerVehicleNo(string(dispatch, "trailerVehicleNo"));
|
||||
// 归属主键是档案 ID:调度带了就用它,否则按手机号解析;承运商司机解析为空也照常派单
|
||||
// 归属主键是档案 ID:调度带了就用它,否则按手机号解析;解析入口只返回 null 或唯一命中的
|
||||
// 档案 ID,承运商司机解析为空也照常派单,落空时留 WARN
|
||||
Long driverId = longValue(dispatch, "driverId");
|
||||
if (driverId == null || driverId <= 0) {
|
||||
Long resolvedDriverId = driverService.resolveDriverIdByMobile(waybill.getTenantId(), waybill.getDriverPhone());
|
||||
driverId = resolvedDriverId != null && resolvedDriverId > 0 ? resolvedDriverId : null;
|
||||
driverId = driverService.resolveDriverIdByMobile(waybill.getTenantId(), waybill.getDriverPhone());
|
||||
if (driverId == null) {
|
||||
log.warn("总单 {} 派单的司机手机号未唯一匹配司机档案,driver_id 落空(不阻断派单)。租户={} 手机号={}",
|
||||
masterOrder.getMasterNo(), waybill.getTenantId(), DesensitizedUtil.mobilePhone(waybill.getDriverPhone()));
|
||||
}
|
||||
}
|
||||
waybill.setDriverId(driverId);
|
||||
waybill.setCaptainName(string(dispatch, "captainName")); waybill.setCabinNo(string(dispatch, "cabinNo")); waybill.setContainerNo(string(dispatch, "containerNo"));
|
||||
|
||||
+2
-2
@@ -500,12 +500,12 @@ public class WaybillImportBatchServiceImpl extends BaseServiceImpl<WaybillImport
|
||||
if (driverId != null && driverId > 0) {
|
||||
return;
|
||||
}
|
||||
// 解析入口只返回 null 或唯一命中的档案 ID,不需要再按哨兵归一
|
||||
Long resolvedDriverId = driverService.resolveDriverIdByMobile(waybill.getTenantId(), waybill.getDriverPhone());
|
||||
if (resolvedDriverId != null && resolvedDriverId > 0) {
|
||||
if (resolvedDriverId != null) {
|
||||
waybill.setDriverId(resolvedDriverId);
|
||||
return;
|
||||
}
|
||||
// driver_id 只有 >0 才算有主,0 / -1 都按无主落空
|
||||
waybill.setDriverId(null);
|
||||
log.warn("第{}行 运单 {} 的司机手机号未唯一匹配司机档案,driver_id 留空(不阻断导入)",
|
||||
rowNo, waybill.getWaybillNo());
|
||||
|
||||
+8
-4
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
package org.springblade.transport.service.impl;
|
||||
|
||||
import cn.hutool.core.util.DesensitizedUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
@@ -1615,12 +1616,15 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
|
||||
TransportBusinessSupport.validateRequired(vehicleNo, "车牌号不能为空");
|
||||
|
||||
// 归属主键是档案 ID,手机号只是派单时的号码快照:调用方带了档案 ID 就用它,
|
||||
// 否则按手机号解析;承运商司机、未建档司机解析为空,派单照旧成功,只留 WARN
|
||||
// 否则按手机号解析;解析入口只返回 null 或唯一命中的档案 ID,承运商司机、未建档司机
|
||||
// 解析为空,派单照旧成功,落空时留 WARN
|
||||
Long driverId = request.getDriverId();
|
||||
if (driverId == null || driverId <= 0) {
|
||||
Long resolvedDriverId = driverService.resolveDriverIdByMobile(waybill.getTenantId(), driverPhone);
|
||||
// driver_id 只有 >0 才算有主,0 / -1 都是「无主」的哨兵写法,落库统一为 NULL
|
||||
driverId = resolvedDriverId != null && resolvedDriverId > 0 ? resolvedDriverId : null;
|
||||
driverId = driverService.resolveDriverIdByMobile(waybill.getTenantId(), driverPhone);
|
||||
if (driverId == null) {
|
||||
log.warn("运单 {} 的司机手机号未唯一匹配司机档案,driver_id 落空(不阻断派单)。租户={} 手机号={}",
|
||||
waybill.getWaybillNo(), waybill.getTenantId(), DesensitizedUtil.mobilePhone(driverPhone));
|
||||
}
|
||||
}
|
||||
waybill.setDriverId(driverId);
|
||||
waybill.setDriverName(driverName);
|
||||
|
||||
+23
@@ -1,5 +1,7 @@
|
||||
package org.springblade.transport.service.impl;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -11,6 +13,7 @@ import org.springblade.transport.service.IDriverService;
|
||||
import org.springblade.transport.service.IProjectApplyService;
|
||||
import org.springblade.transport.service.ITransportPlanService;
|
||||
import org.springblade.transport.service.IWaybillService;
|
||||
import org.springblade.transport.support.LogCapture;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -18,6 +21,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -84,6 +88,25 @@ class MasterOrderDriverIdTest {
|
||||
verify(waybillService).submit(any(Waybill.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("解析不到档案:落空时留一条脱敏 WARN,派单照常成功")
|
||||
void unresolvedProfileLogsMaskedWarning() throws Exception {
|
||||
when(driverService.resolveDriverIdByMobile(any(), eq(DRIVER_PHONE))).thenReturn(null);
|
||||
try (LogCapture logs = LogCapture.open(MasterOrderServiceImpl.class)) {
|
||||
assertTrue(createWaybill(dispatch()));
|
||||
|
||||
String warning = logs.events().stream()
|
||||
.filter(event -> event.getLevel() == Level.WARN)
|
||||
.map(ILoggingEvent::getFormattedMessage)
|
||||
.filter(message -> message.contains("司机档案"))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new AssertionError("解析失败必须留 WARN,实际日志:" + logs.messages()));
|
||||
assertTrue(warning.contains("138****8000"), "WARN 里的号码必须脱敏,实际:" + warning);
|
||||
assertFalse(warning.contains(DRIVER_PHONE), "WARN 里不能出现完整号码,实际:" + warning);
|
||||
assertTrue(warning.contains("ZD-20261027-001"), "WARN 要带业务标识(总单号),实际:" + warning);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------ 夹具
|
||||
|
||||
private boolean createWaybill(Map<String, Object> dispatch) throws Exception {
|
||||
|
||||
-11
@@ -86,17 +86,6 @@ class WaybillImportDriverIdTest {
|
||||
assertNull(waybill.getDriverId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("解析器返回 0(无主哨兵):按无主落空,不把 0 写进库")
|
||||
void normalizesSentinelToNull() throws Exception {
|
||||
when(driverService.resolveDriverIdByMobile(any(), eq(DRIVER_PHONE))).thenReturn(0L);
|
||||
|
||||
Waybill waybill = importedWaybill(0L);
|
||||
fillDriverOwnership(waybill, 3);
|
||||
|
||||
assertNull(waybill.getDriverId());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------ 夹具
|
||||
|
||||
private void fillDriverOwnership(Waybill waybill, int rowNo) throws Exception {
|
||||
|
||||
+24
@@ -1,5 +1,7 @@
|
||||
package org.springblade.transport.service.impl;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
@@ -12,11 +14,13 @@ import org.springblade.transport.mapper.WaybillMapper;
|
||||
import org.springblade.transport.pojo.entity.Waybill;
|
||||
import org.springblade.transport.service.IDriverService;
|
||||
import org.springblade.transport.service.IProcessConfigService;
|
||||
import org.springblade.transport.support.LogCapture;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -108,6 +112,25 @@ class WaybillReassignDriverIdTest {
|
||||
assertNull(capturedWaybill().getDriverId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("解析不到档案:落空时留一条脱敏 WARN,派单照常成功")
|
||||
void unresolvedProfileLogsMaskedWarning() {
|
||||
when(driverService.resolveDriverIdByMobile(TENANT_ID, DRIVER_PHONE)).thenReturn(null);
|
||||
try (LogCapture logs = LogCapture.open(WaybillServiceImpl.class)) {
|
||||
assertTrue(service.reassignWithoutDeptCheck(reassignRequest(null)));
|
||||
|
||||
String warning = logs.events().stream()
|
||||
.filter(event -> event.getLevel() == Level.WARN)
|
||||
.map(ILoggingEvent::getFormattedMessage)
|
||||
.filter(message -> message.contains("司机档案"))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new AssertionError("解析失败必须留 WARN,实际日志:" + logs.messages()));
|
||||
assertTrue(warning.contains("138****8000"), "WARN 里的号码必须脱敏,实际:" + warning);
|
||||
assertFalse(warning.contains(DRIVER_PHONE), "WARN 里不能出现完整号码,实际:" + warning);
|
||||
assertTrue(warning.contains("YD-20261027-001"), "WARN 要带业务标识(运单号),实际:" + warning);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------ 夹具
|
||||
|
||||
private void setUpAgain() throws Exception {
|
||||
@@ -131,6 +154,7 @@ class WaybillReassignDriverIdTest {
|
||||
waybill.setId(WAYBILL_ID);
|
||||
waybill.setIsDeleted(0);
|
||||
waybill.setTenantId(TENANT_ID);
|
||||
waybill.setWaybillNo("YD-20261027-001");
|
||||
waybill.setBusinessStatus("pending");
|
||||
waybill.setTransportType("road");
|
||||
waybill.setDriverName("张三");
|
||||
|
||||
Reference in New Issue
Block a user