From 214ff38ef80451bee3cce7e7035dc19cd6e90b1c Mon Sep 17 00:00:00 2001 From: "weicw1996@qq.com" Date: Sat, 3 Oct 2026 15:35:22 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20=E4=BF=AE=E5=A4=8D=E9=81=93=E8=B7=AF?= =?UTF-8?q?=E8=BF=90=E8=BE=93=E8=AF=81OCR=E6=81=92=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=EF=BC=9A=E4=B8=8A=E6=B8=B8=E4=B8=8D=E5=BE=97=E6=9B=BF=E5=AE=83?= =?UTF-8?q?=E8=A1=A5=E9=BB=98=E8=AE=A4=E6=AD=A3=E5=8F=8D=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OcrTypeMapping.normalizeSide 对空值恒返回 front,控制器把这个 front 传给下游, 而道路运输证没有正副面参数(supportsSide 为 false),下游于是判 「传了 side 但该证件不支持」并直接抛错——小程序不传 side、传 front、 传空串三种方式实测全部失败,该证件 OCR 从来没能用过。 改为未指定时返回 null,把「默认取正面」交给知晓证件类型的一侧决定, 并补测试钉住这条契约。 --- .../controller/DriverAuthController.java | 3 +++ .../transport/support/OcrTypeMapping.java | 17 ++++++++++--- .../transport/support/OcrTypeMappingTest.java | 25 ++++++++++++++++--- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/DriverAuthController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/DriverAuthController.java index 6f7e7876..d759344b 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/DriverAuthController.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/DriverAuthController.java @@ -143,6 +143,9 @@ public class DriverAuthController extends BladeController { public R ocr(@RequestBody OcrRecognizeRequest request) { // 两侧对「驾驶证 / 行驶证」的用词正好相反,故必须经显式映射,不能把入参直接透传下游 BaiduOcrType ocrType = OcrTypeMapping.toBaiduType(request.getType()); + // 未指定时传 null,不要在这里补 front:道路运输证没有正副面参数, + // 补了会变成「传了 side 但该证件不支持」,让这条链路恒失败。 + // 「默认取正面」由知晓证件类型的一侧(OCR 服务)决定。 String side = OcrTypeMapping.normalizeSide(request.getSide()); return R.data(baiduOcrService.recognizeUrl(ocrType, side, request.getImageUrl())); } diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/OcrTypeMapping.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/OcrTypeMapping.java index 61bf18f3..83afbf81 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/OcrTypeMapping.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/OcrTypeMapping.java @@ -110,14 +110,23 @@ public final class OcrTypeMapping { /** * 规范化正反面参数 *

- * 小程序目前不传该参数,按正面处理(身份证、行驶证、驾驶证的正页是常用场景)。 + * 小程序不传该参数,按正面处理(身份证、行驶证、驾驶证的正页是常用场景)。 + *

+ * ⚠️ 调用方**必须原样把返回值交给下游,不要在传参前自行补默认值**: + * 这里的「默认正面」只对**支持正副面**的证件成立。道路运输证没有正副面参数, + * 若在调用方先把空值填成 {@code front} 再传下去,下游会看到「传了 side 但该证件 + * 不支持」而直接报错——本方法返回 null 才是「调用方没指定」,下游据此才分得清 + * 「默认取正面」和「这个证件根本不该带这个参数」。 * * @param side 正反面:front / back - * @return 规范化结果,恒为 front 或 back + * @return 规范化结果 front / back;调用方未指定时返回 null */ public static String normalizeSide(String side) { - // 归一化结果是大写,故此处比对 "BACK" - return "BACK".equals(normalize(side)) ? SIDE_BACK : SIDE_FRONT; + String normalized = normalize(side); + if (normalized.isEmpty()) { + return null; + } + return SIDE_BACK.equals(normalized.toLowerCase(Locale.ROOT)) ? SIDE_BACK : SIDE_FRONT; } /** diff --git a/blade-service/blade-transport/src/test/java/org/springblade/transport/support/OcrTypeMappingTest.java b/blade-service/blade-transport/src/test/java/org/springblade/transport/support/OcrTypeMappingTest.java index c88a8057..698d21df 100644 --- a/blade-service/blade-transport/src/test/java/org/springblade/transport/support/OcrTypeMappingTest.java +++ b/blade-service/blade-transport/src/test/java/org/springblade/transport/support/OcrTypeMappingTest.java @@ -5,6 +5,8 @@ import org.junit.jupiter.api.Test; import org.springblade.transport.ocr.constant.BaiduOcrType; 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.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -93,13 +95,28 @@ class OcrTypeMappingTest { } @Test - @DisplayName("正反面:小程序不传 side 时按正面处理") - void defaultSide() { - assertEquals("front", OcrTypeMapping.normalizeSide(null)); - assertEquals("front", OcrTypeMapping.normalizeSide("")); + @DisplayName("正反面:小程序不传 side 时返回 null,交由知晓证件类型的一侧决定默认值") + void unsetSideStaysNull() { + // 这里恒返回 front 会让道路运输证恒失败:它没有正副面参数, + // 上游先填成 front,下游就变成「传了 side 但该证件不支持」—— + // 小程序不传 side 也会中招(实测三种传法全部报错)。 + assertNull(OcrTypeMapping.normalizeSide(null)); + assertNull(OcrTypeMapping.normalizeSide("")); + assertNull(OcrTypeMapping.normalizeSide(" ")); assertEquals("front", OcrTypeMapping.normalizeSide("front")); assertEquals("back", OcrTypeMapping.normalizeSide("back")); assertEquals("back", OcrTypeMapping.normalizeSide("BACK")); } + @Test + @DisplayName("正反面:道路运输证不带正副面参数,其余证件默认正面") + void roadTransportHasNoSide() { + // 下游据此区分「默认取正面」与「该证件不该带这个参数」,故这条契约必须有测试守 + assertFalse(OcrTypeMapping.toBaiduType("road_transport").supportsSide(), + "道路运输证没有正副面参数,上游不得替它补 front"); + assertTrue(OcrTypeMapping.toBaiduType("vehicle").supportsSide()); + assertTrue(OcrTypeMapping.toBaiduType("driver").supportsSide()); + assertTrue(OcrTypeMapping.toBaiduType("idcard").supportsSide()); + } + }