From 7c4c887d74fd139582e3a5353239e5fe9bd2f2f7 Mon Sep 17 00:00:00 2001 From: "weicw1996@qq.com" Date: Sun, 4 Oct 2026 23:24:22 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20=E4=BF=AE=E8=AE=A4=E8=AF=81=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=E6=B8=85=E7=A9=BA=E5=8F=B8=E6=9C=BA=E8=BD=A6=E8=BE=86?= =?UTF-8?q?=E7=BB=91=E5=AE=9A=EF=BC=8C=E5=AF=BC=E8=87=B4=E8=BD=A6=E8=BE=86?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=B6=88=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Driver.drivingVehicle 标了 @TableField(updateStrategy = FieldStrategy.ALWAYS), 该策略忽略 null 直接写:任何一次 updateById 只要 patch 里没带这个字段, 就会把库里的 driving_vehicle 写成 NULL。而司机端的车辆列表正是按这一列 的车牌匹配出来的(DriverAppServiceImpl.myVehicles 开头就判空返回空列表), 清空即页面显示「暂无绑定车辆」,且司机在界面上无法自行恢复。 两条链路都会触发: - 提交认证:updateDriverDisplayCache 只 patch id/状态/驳回原因; - 审核通过:本次改动新增的快照写回,同样只 patch 证件字段。 已在两处 updateById 前把该车的原值搬进 patch,并补回归测试: 先确认去掉修复后测试确实失败(expected 桂A12345,桂B67890 but was null)。 保留 ALWAYS 策略不动——它保证了「能显式清空车辆绑定」这一能力, 问题在于 patch 式更新必须自己带上原值,而不是删掉策略。 --- .../service/impl/CertAuditServiceImpl.java | 22 +++++++++++++++++++ .../service/impl/DriverCertServiceImpl.java | 7 ++++++ .../impl/CertAuditServiceImplTest.java | 19 ++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CertAuditServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CertAuditServiceImpl.java index 89d0b0e6..d1bedbb3 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CertAuditServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CertAuditServiceImpl.java @@ -213,6 +213,10 @@ public class CertAuditServiceImpl implements ICertAuditService { driver.setId(record.getBizId()); driver.setCertificationStatus(status); driver.setCertificationRejectReason(reason); + // 必须带上 driving_vehicle 原值:该列是 FieldStrategy.ALWAYS, + // 更新时忽略 null 直接写,patch 里不带它就会把司机的车辆绑定清成 NULL, + // 而车辆列表正是按这一列匹配的(清空即「暂无绑定车辆」)。 + copyDrivingVehicle(record.getBizId(), driver); if (pass) { driver.setEffectiveCertRecordId(newEffectiveId); // 通过即生效:与车辆侧同理,把这次快照的证件内容一并写回司机档案。 @@ -224,6 +228,24 @@ public class CertAuditServiceImpl implements ICertAuditService { driverService.updateById(driver); } + /** + * 把司机当前的车辆绑定原值搬进 patch,避免被 ALWAYS 更新策略清空 + *

+ * {@code driving_vehicle} 上标了 {@code FieldStrategy.ALWAYS},任何一次 + * {@code updateById} 都会把该列写成 patch 里的值(null 也照写)。 + * 而司机端的车辆列表是按这一列的车牌匹配出来的,一旦被清空, + * 页面就变成「暂无绑定车辆」,且无法从界面上恢复。 + * + * @param driverId 司机主键 + * @param patch 待更新的司机 patch(就地写入原值) + */ + private void copyDrivingVehicle(Long driverId, Driver patch) { + Driver current = driverService.getById(driverId); + if (current != null) { + patch.setDrivingVehicle(current.getDrivingVehicle()); + } + } + /** * 把生效快照里的司机证件字段搬进司机档案(就地写入同一个 patch 对象) *

diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverCertServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverCertServiceImpl.java index 524e81d4..7246529d 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverCertServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverCertServiceImpl.java @@ -368,6 +368,13 @@ public class DriverCertServiceImpl implements IDriverCertService { patch.setId(driverId); patch.setCertificationStatus(status); patch.setCertificationRejectReason(rejectReason); + // 必须带上 driving_vehicle 原值:该列标了 FieldStrategy.ALWAYS, + // 更新时忽略 null 直接写,patch 里不带它就会把司机的车辆绑定清成 NULL, + // 而司机端的车辆列表正是按这一列的车牌匹配出来的(清空即「暂无绑定车辆」)。 + Driver current = driverService.getById(driverId); + if (current != null) { + patch.setDrivingVehicle(current.getDrivingVehicle()); + } driverService.updateById(patch); } diff --git a/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/CertAuditServiceImplTest.java b/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/CertAuditServiceImplTest.java index 352aef64..ae268991 100644 --- a/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/CertAuditServiceImplTest.java +++ b/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/CertAuditServiceImplTest.java @@ -155,6 +155,25 @@ class CertAuditServiceImplTest { assertEquals(RECORD_ID, captor.getValue().getEffectiveCertRecordId()); } + @Test + @DisplayName("通过司机认证:patch 必须带上车辆绑定,不得把 driving_vehicle 清空") + void approveDriverKeepsDrivingVehicle() { + TransportCertRecord record = driverRecord(TransportCertRecord.STATUS_PENDING); + when(certRecordService.getById(RECORD_ID)).thenReturn(record); + Driver existing = driver(null); + existing.setDrivingVehicle("桂A12345,桂B67890"); + when(driverService.getById(DRIVER_ID)).thenReturn(existing); + + service.audit(RECORD_ID, true, null); + + ArgumentCaptor captor = ArgumentCaptor.forClass(Driver.class); + verify(driverService).updateById(captor.capture()); + // driving_vehicle 标了 FieldStrategy.ALWAYS,patch 里为 null 就会把该列写成 NULL; + // 而司机端车辆列表正是按这一列匹配的,清空即「暂无绑定车辆」且界面上无法恢复 + assertEquals("桂A12345,桂B67890", captor.getValue().getDrivingVehicle(), + "审核通过不得把司机的车辆绑定清空"); + } + // ------------------------------------------------------------ 驳回 @Test