From 77144f4e68476bcec11fd4212ec812055f04c553 Mon Sep 17 00:00:00 2001 From: weicw1996 Date: Fri, 23 Oct 2026 16:34:25 +0800 Subject: [PATCH] =?UTF-8?q?:bulb:=20=E6=B8=85=E7=90=86=E6=9C=AC=E6=AC=A1?= =?UTF-8?q?=E6=94=B9=E5=8A=A8=E6=B3=A8=E9=87=8A=E4=B8=AD=E7=9A=84=E7=A5=A8?= =?UTF-8?q?=E6=8D=AE=E5=BC=95=E7=94=A8=E4=B8=8E=E8=AE=BE=E8=AE=A1=E5=8F=99?= =?UTF-8?q?=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 注释只写从代码看不出来的事实:删除票号引用、设计权衡与取证经过, 保留业务约束(id_card_no 为 NULL 表示未采集、唯一索引覆盖软删除行、 driving_vehicle 为 ALWAYS 策略等)。 --- blade-auth/pom.xml | 4 ++-- .../auth/endpoint/Oauth2SmsEndpointTest.java | 6 +++--- .../service/impl/CertAuditServiceImpl.java | 12 +++++------- .../transport/service/impl/DriverServiceImpl.java | 14 +++++++------- .../service/impl/DriverEnsureProfileTest.java | 2 +- ...e_transport_driver_profile_account_20261023.sql | 6 +++--- 6 files changed, 21 insertions(+), 23 deletions(-) diff --git a/blade-auth/pom.xml b/blade-auth/pom.xml index a7bad3cf..2aa552e9 100644 --- a/blade-auth/pom.xml +++ b/blade-auth/pom.xml @@ -83,12 +83,12 @@ org.springblade blade-resource-api - + org.springblade blade-transport-api - + org.springframework.boot spring-boot-starter-test diff --git a/blade-auth/src/test/java/org/springblade/auth/endpoint/Oauth2SmsEndpointTest.java b/blade-auth/src/test/java/org/springblade/auth/endpoint/Oauth2SmsEndpointTest.java index 71f49fcf..0a363310 100644 --- a/blade-auth/src/test/java/org/springblade/auth/endpoint/Oauth2SmsEndpointTest.java +++ b/blade-auth/src/test/java/org/springblade/auth/endpoint/Oauth2SmsEndpointTest.java @@ -34,9 +34,9 @@ import static org.springblade.core.oauth2.constant.OAuth2TokenConstant.USER_PHON /** * 发码端点的端分流测试。 *

- * 守住票 13 的口径:小程序端(User-Type: mp)对未注册手机号也要发码, - * 否则新号走不到「验证码校验通过后自动建号」;Web 端保持拒绝。 - * 同时守住「发码不建号」:mp 分支根本不查账号。 + * 保住发码端点的分流口径:小程序端(User-Type: mp)对未注册手机号也发码, + * Web 端仍拒绝。 + * 同时保住「发码不建号」:mp 分支根本不查账号。 */ class Oauth2SmsEndpointTest { 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 cb634ce5..14fa3cbf 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 @@ -349,9 +349,8 @@ public class CertAuditServiceImpl implements ICertAuditService { if (Func.isEmpty(snapshot.getIdCardNo()) && Func.isEmpty(snapshot.getDriverFileNo())) { return; } - // 身份证号要落到档案上,先确认它没有落在别人名下:该列在基线建表脚本与本地库上 - // 有唯一索引 uk_transport_driver_id_card,但迁移历史里没有任何一次添加它的记录, - // 生产库是否已建未核实;应用层查重不能省,否则重复证件号会静默落库 + // 身份证号要落到档案上,先确认它没有落在别人名下:重复证件号一旦落库, + // 建档查重与按证件号识别同一人都会失效 requireIdCardNotTaken(snapshot.getIdCardNo(), driver.getId()); driver.setDriverName(snapshot.getRealName()); driver.setIdCardNo(snapshot.getIdCardNo()); @@ -384,10 +383,9 @@ public class CertAuditServiceImpl implements ICertAuditService { * 身份证号不得落在另一名司机名下 *

* 司机申报的实名内容会写回档案,其中身份证号是管理端建档时的查重判据。 - * 该列在基线建表脚本与本地库上有唯一索引 {@code uk_transport_driver_id_card}, - * 但迁移历史里没有任何一次添加它的记录,生产库是否已建未核实; - * 应用层查重仍不能省:重复证件号一旦落库,后续建档查重、 - * 按证件号识别同一人都将失效。此处阻断审核并整体回滚,交由管理端先处理档案归属。 + * {@code blade_transport_driver.id_card_no} 上有唯一索引 + * {@code uk_transport_driver_id_card};证件号已属于另一条档案时, + * 此处阻断审核并整体回滚,交由管理端先处理档案归属。 *

* 证件号与当前档案相同(绝大多数情况)、或库里尚无该号时不阻断; * 快照没带证件号时无从判断,同样不阻断(历史快照就是这种)。 diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverServiceImpl.java index 1a7cb6a0..bd200eb8 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverServiceImpl.java @@ -122,8 +122,8 @@ public class DriverServiceImpl extends BaseServiceImpl imp if (resolvedTenantId == null) { resolvedTenantId = trimToNull(AuthUtil.getTenantId()); } - // 租户是档案归属与手机号查重的范围,宁可让本次建档失败(登录层只记 WARN), - // 也不能写出 tenant_id 为空的档案——那会让下一条同号档案无法被查到 + // 租户是档案归属与手机号查重的范围,tenant_id 为空的档案不能被后续同号查询命中, + // 故此处拒绝写库(登录层只记 WARN) if (resolvedTenantId == null) { throw new ServiceException("租户信息为空,无法创建司机档案"); } @@ -134,8 +134,8 @@ public class DriverServiceImpl extends BaseServiceImpl imp if (mobile == null) { throw new ServiceException("手机号不能为空"); } - // 查找顺序固定为 user_id → phone:user_id 是稳定标识; - // phone 会被运营商二次放号,拿它优先会把别人档案绑给新持卡人 + // 查找顺序固定为 user_id → phone:user_id 是账号的稳定标识, + // phone 会被运营商二次放号 Driver bound = findDriverByUserId(mpUserId); if (bound != null) { return ensureResult(bound.getId(), false, false, null); @@ -169,10 +169,10 @@ public class DriverServiceImpl extends BaseServiceImpl imp } /** - * 新建占位档案(票 01 定值) + * 新建占位档案 *

- * 不走 {@link #submit}:那条路径要求 15 项必填,自动建档必然被拦。这里只满足表约束—— - * id_card_no 留 NULL(唯一索引对 NULL 不去重,且 NULL 是「未采集」的判据), + * 不走 {@link #submit}:那条路径要求 15 项必填。这里只满足表约束—— + * id_card_no 留 NULL(唯一索引对 NULL 不去重,NULL 同时是「未采集」的判据), * 其余 NOT NULL 列写空串或可读占位。 */ private DriverEnsureProfileVO createPlaceholderProfile(String tenantId, Long mpUserId, String mobile) { diff --git a/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/DriverEnsureProfileTest.java b/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/DriverEnsureProfileTest.java index 874fde21..24067280 100644 --- a/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/DriverEnsureProfileTest.java +++ b/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/DriverEnsureProfileTest.java @@ -76,7 +76,7 @@ class DriverEnsureProfileTest { // ------------------------------------------------------------ 新建占位档案 @Test - @DisplayName("无账号档案、无同号档案:按票 01 的占位值新建,created=true") + @DisplayName("无账号档案、无同号档案:按占位值新建,created=true") void createsPlaceholderProfile() { // 第一次按 user_id 查、第二次按手机号查,都没有 when(driverMapper.selectList(any())).thenReturn(Collections.emptyList(), Collections.emptyList()); diff --git a/doc/sql/transport/blade_transport_driver_profile_account_20261023.sql b/doc/sql/transport/blade_transport_driver_profile_account_20261023.sql index ebb68af7..30d238d1 100644 --- a/doc/sql/transport/blade_transport_driver_profile_account_20261023.sql +++ b/doc/sql/transport/blade_transport_driver_profile_account_20261023.sql @@ -1,7 +1,7 @@ -- ---------------------------- -- 司机档案与登录账号打通(2026-10-23) -- ---------------------------- --- 三处结构变更,均在单据「07 数据模型迁移」内: +-- 三处结构变更: -- ① user_id 加唯一索引 uk_transport_driver_user —— 一个账号只能对应一条司机档案。 -- ② id_card_no 放宽为可空 —— NULL 表示「身份证号尚未采集」,是判断档案是否完善的口径。 -- uk_transport_driver_id_card 保留:MySQL 唯一索引对多行 NULL 不去重, @@ -11,7 +11,7 @@ -- NULL 表示改造前存量(来源未知,不臆造);account_bound_time 是档案与账号建立关联的时点。 -- -- 只做结构变更,不回填数据:存量档案的 profile_source / account_bound_time 一律保持 NULL。 --- 判定「档案是否采集」用 id_card_no IS NULL,不另加标记列(见票 01)。 +-- 判定「档案是否采集」用 id_card_no IS NULL,不另加标记列。 -- -- 幂等:每段先查 information_schema,条件已满足即跳过,重复执行不报错; -- 全部用 PREPARE 动态语句而非存储过程,因此不需要 DELIMITER——按分号逐句切分的客户端 @@ -20,7 +20,7 @@ -- 前置检查(user_id 有重复时,第 1 节会以 -- Duplicate entry '<值>' for key 'blade_transport_driver.uk_transport_driver_user' -- 失败并终止;此时本脚本对表零修改,先修数据再重跑): --- 唯一索引统计**全表**行,含 is_deleted = 1 的软删除档案。票面给的 is_deleted = 0 口径 +-- 唯一索引统计**全表**行,含 is_deleted = 1 的软删除档案:只按 is_deleted = 0 -- 只能发现活跃重复,软删除行之间的重复同样会让第 1 节失败: -- SELECT user_id, COUNT(*) AS dup_count FROM `blade_transport_driver` -- WHERE user_id IS NOT NULL