🐛 修复道路运输证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) {
|
public R<BaiduOcrResultVO> ocr(@RequestBody OcrRecognizeRequest request) {
|
||||||
// 两侧对「驾驶证 / 行驶证」的用词正好相反,故必须经显式映射,不能把入参直接透传下游
|
// 两侧对「驾驶证 / 行驶证」的用词正好相反,故必须经显式映射,不能把入参直接透传下游
|
||||||
BaiduOcrType ocrType = OcrTypeMapping.toBaiduType(request.getType());
|
BaiduOcrType ocrType = OcrTypeMapping.toBaiduType(request.getType());
|
||||||
|
// 未指定时传 null,不要在这里补 front:道路运输证没有正副面参数,
|
||||||
|
// 补了会变成「传了 side 但该证件不支持」,让这条链路恒失败。
|
||||||
|
// 「默认取正面」由知晓证件类型的一侧(OCR 服务)决定。
|
||||||
String side = OcrTypeMapping.normalizeSide(request.getSide());
|
String side = OcrTypeMapping.normalizeSide(request.getSide());
|
||||||
return R.data(baiduOcrService.recognizeUrl(ocrType, side, request.getImageUrl()));
|
return R.data(baiduOcrService.recognizeUrl(ocrType, side, request.getImageUrl()));
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-4
@@ -110,14 +110,23 @@ public final class OcrTypeMapping {
|
|||||||
/**
|
/**
|
||||||
* 规范化正反面参数
|
* 规范化正反面参数
|
||||||
* <p>
|
* <p>
|
||||||
* 小程序目前不传该参数,按正面处理(身份证、行驶证、驾驶证的正页是常用场景)。
|
* 小程序不传该参数,按正面处理(身份证、行驶证、驾驶证的正页是常用场景)。
|
||||||
|
* <p>
|
||||||
|
* ⚠️ 调用方**必须原样把返回值交给下游,不要在传参前自行补默认值**:
|
||||||
|
* 这里的「默认正面」只对**支持正副面**的证件成立。道路运输证没有正副面参数,
|
||||||
|
* 若在调用方先把空值填成 {@code front} 再传下去,下游会看到「传了 side 但该证件
|
||||||
|
* 不支持」而直接报错——本方法返回 null 才是「调用方没指定」,下游据此才分得清
|
||||||
|
* 「默认取正面」和「这个证件根本不该带这个参数」。
|
||||||
*
|
*
|
||||||
* @param side 正反面:front / back
|
* @param side 正反面:front / back
|
||||||
* @return 规范化结果,恒为 front 或 back
|
* @return 规范化结果 front / back;调用方未指定时返回 null
|
||||||
*/
|
*/
|
||||||
public static String normalizeSide(String side) {
|
public static String normalizeSide(String side) {
|
||||||
// 归一化结果是大写,故此处比对 "BACK"
|
String normalized = normalize(side);
|
||||||
return "BACK".equals(normalize(side)) ? SIDE_BACK : SIDE_FRONT;
|
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 org.springblade.transport.ocr.constant.BaiduOcrType;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
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.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
@@ -93,13 +95,28 @@ class OcrTypeMappingTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("正反面:小程序不传 side 时按正面处理")
|
@DisplayName("正反面:小程序不传 side 时返回 null,交由知晓证件类型的一侧决定默认值")
|
||||||
void defaultSide() {
|
void unsetSideStaysNull() {
|
||||||
assertEquals("front", OcrTypeMapping.normalizeSide(null));
|
// 这里恒返回 front 会让道路运输证恒失败:它没有正副面参数,
|
||||||
assertEquals("front", OcrTypeMapping.normalizeSide(""));
|
// 上游先填成 front,下游就变成「传了 side 但该证件不支持」——
|
||||||
|
// 小程序不传 side 也会中招(实测三种传法全部报错)。
|
||||||
|
assertNull(OcrTypeMapping.normalizeSide(null));
|
||||||
|
assertNull(OcrTypeMapping.normalizeSide(""));
|
||||||
|
assertNull(OcrTypeMapping.normalizeSide(" "));
|
||||||
assertEquals("front", OcrTypeMapping.normalizeSide("front"));
|
assertEquals("front", OcrTypeMapping.normalizeSide("front"));
|
||||||
assertEquals("back", OcrTypeMapping.normalizeSide("back"));
|
assertEquals("back", OcrTypeMapping.normalizeSide("back"));
|
||||||
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