🐛 修复道路运输证OCR恒失败:上游不得替它补默认正反面
OcrTypeMapping.normalizeSide 对空值恒返回 front,控制器把这个 front 传给下游, 而道路运输证没有正副面参数(supportsSide 为 false),下游于是判 「传了 side 但该证件不支持」并直接抛错——小程序不传 side、传 front、 传空串三种方式实测全部失败,该证件 OCR 从来没能用过。 改为未指定时返回 null,把「默认取正面」交给知晓证件类型的一侧决定, 并补测试钉住这条契约。
This commit is contained in:
+3
@@ -143,6 +143,9 @@ public class DriverAuthController extends BladeController {
|
||||
public R<BaiduOcrResultVO> 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()));
|
||||
}
|
||||
|
||||
+13
-4
@@ -110,14 +110,23 @@ public final class OcrTypeMapping {
|
||||
/**
|
||||
* 规范化正反面参数
|
||||
* <p>
|
||||
* 小程序目前不传该参数,按正面处理(身份证、行驶证、驾驶证的正页是常用场景)。
|
||||
* 小程序不传该参数,按正面处理(身份证、行驶证、驾驶证的正页是常用场景)。
|
||||
* <p>
|
||||
* ⚠️ 调用方**必须原样把返回值交给下游,不要在传参前自行补默认值**:
|
||||
* 这里的「默认正面」只对**支持正副面**的证件成立。道路运输证没有正副面参数,
|
||||
* 若在调用方先把空值填成 {@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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+21
-4
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user