diff --git a/api-web/api-interface/src/main/java/com/heyu/api/controller/car/RecognizeDriverLicenseController.java b/api-web/api-interface/src/main/java/com/heyu/api/controller/car/RecognizeDriverLicenseController.java index 313dfd1..fe74153 100644 --- a/api-web/api-interface/src/main/java/com/heyu/api/controller/car/RecognizeDriverLicenseController.java +++ b/api-web/api-interface/src/main/java/com/heyu/api/controller/car/RecognizeDriverLicenseController.java @@ -70,8 +70,7 @@ public class RecognizeDriverLicenseController extends BaseController { try { String validateError = validateRequest(request); if (validateError != null) { - log.info("[驾驶证识别] 阶段=入参校验 结论=拦截 说明=请求未进入识别链路(不计费) " - + "入参摘要={} 对外提示摘要={}", + log.info("驾驶证识别:参数检查没通过,直接返回错误(还没调识别、不扣费)。{} 返回给客户:{}", buildInputLogContext(request), abbreviate(validateError, 120)); return R.error(validateError); } @@ -82,9 +81,8 @@ public class RecognizeDriverLicenseController extends BaseController { String content = buildRequestContent(request, drivingLicenseSide); if (isBlank(content)) { - log.error("[驾驶证识别] 阶段=报文组装 结论=失败 目标页面={} 页面标签={} 影像模式={} " - + "请求体字节长度=0 入参摘要={} 原因=未写入有效image或url节点", - drivingLicenseSide, sideLabel(drivingLicenseSide), imageMode, inputContext); + log.error("驾驶证识别:组装请求失败,请求里没带有效图片。识别{},{}。{}", + sideDesc(drivingLicenseSide), imageModeDesc(imageMode), inputContext); return okResult(drivingLicenseSide, formatHint( "报文组装异常", "识别请求体在序列化后未包含任何影像载荷,平台侧无法受理本次识别", @@ -95,14 +93,13 @@ public class RecognizeDriverLicenseController extends BaseController { } int requestBodyLength = content.length(); - log.info("[驾驶证识别] 阶段=平台调用 开始 目标页面={} 页面标签={} 影像模式={} " - + "请求体字节长度={} 入参摘要={}", - drivingLicenseSide, sideLabel(drivingLicenseSide), imageMode, requestBodyLength, inputContext); + log.info("驾驶证识别:开始调用平台识别。识别{},{},请求大小约 {} 字节。{}", + sideDesc(drivingLicenseSide), imageModeDesc(imageMode), requestBodyLength, inputContext); Map platformResult = requestBaidu(DRIVING_LICENSE_URI, content); if (platformResult == null) { - log.error("[驾驶证识别] 阶段=平台调用 结论=无回执 目标页面={} 页面标签={} 影像模式={} " - + "请求体字节长度={} 入参摘要={} 可能原因=链路超时/鉴权失败/响应不可解析", - drivingLicenseSide, sideLabel(drivingLicenseSide), imageMode, requestBodyLength, inputContext); + log.error("驾驶证识别:平台没有返回结果(可能网络超时、鉴权失败或响应无法解析)。识别{},{}," + + "请求约 {} 字节。{}", + sideDesc(drivingLicenseSide), imageModeDesc(imageMode), requestBodyLength, inputContext); return okResult(drivingLicenseSide, formatHint( "服务无回执", "识别指令已下发,但在约定时间内未收到平台可解析的 JSON 回执", @@ -117,9 +114,9 @@ public class RecognizeDriverLicenseController extends BaseController { : buildFaceResp(platformResult); if (hint == null && isRecognizeDataEmpty(data)) { - log.info("[驾驶证识别] 阶段=字段映射 结论=全空 目标页面={} 页面标签={} 影像模式={} " - + "入参摘要={} 平台回执摘要={} 已映射字段数=0 说明=回执结构正常但未抽取到任何业务字段", - drivingLicenseSide, sideLabel(drivingLicenseSide), imageMode, + log.info("驾驶证识别:平台有返回,但证号、姓名等字段一个都没识别出来(可能传错正/副页或图片不清晰)。" + + "识别{},{}。客户传的:{}。平台回执:{}", + sideDesc(drivingLicenseSide), imageModeDesc(imageMode), inputContext, buildPlatformReceiptSummary(platformResult)); hint = formatHint( "字段映射为空", @@ -134,14 +131,13 @@ public class RecognizeDriverLicenseController extends BaseController { long cost = System.currentTimeMillis() - start; int mappedFieldCount = countMappedFields(data); if (StringUtils.isNotBlank(hint)) { - log.info("[驾驶证识别] 阶段=请求结束 结论=成功(含业务提示) 目标页面={} 页面标签={} 影像模式={} " - + "耗时={}ms 已映射字段数={} 入参摘要={} 平台回执摘要={} 对外提示摘要={}", - drivingLicenseSide, sideLabel(drivingLicenseSide), imageMode, cost, mappedFieldCount, + log.info("驾驶证识别:处理结束(接口仍返回成功,但带了提示信息)。耗时 {} ms,识别出 {} 个字段。" + + "识别{},{}。客户传的:{}。平台回执:{}。给客户的提示:{}", + cost, mappedFieldCount, sideDesc(drivingLicenseSide), imageModeDesc(imageMode), inputContext, buildPlatformReceiptSummary(platformResult), abbreviate(hint, 120)); } else { - log.info("[驾驶证识别] 阶段=请求结束 结论=成功 目标页面={} 页面标签={} 影像模式={} " - + "耗时={}ms 已映射字段数={} 入参摘要={} 平台回执摘要={}", - drivingLicenseSide, sideLabel(drivingLicenseSide), imageMode, cost, mappedFieldCount, + log.info("驾驶证识别:识别成功。耗时 {} ms,共识别出 {} 个字段。识别{},{}。客户传的:{}。平台回执:{}", + cost, mappedFieldCount, sideDesc(drivingLicenseSide), imageModeDesc(imageMode), inputContext, buildPlatformReceiptSummary(platformResult)); } return okResult(drivingLicenseSide, hint, data); @@ -149,13 +145,12 @@ public class RecognizeDriverLicenseController extends BaseController { } catch (Exception e) { long cost = System.currentTimeMillis() - start; String side = request != null ? resolveDrivingLicenseSide(request) : ApiConstants.front; - log.error("[驾驶证识别] 阶段=运行时 结论=未捕获异常 耗时={}ms 目标页面={} 页面标签={} 影像模式={} " - + "入参摘要={} 异常类型={} 异常信息={}", - cost, side, sideLabel(side), - request != null ? resolveImageMode(request) : "未知", + log.error("驾驶证识别:程序运行出错,耗时 {} ms。识别{},{}。客户传的:{}。异常:{} - {}", + cost, sideDesc(side), + request != null ? imageModeDesc(resolveImageMode(request)) : "未知", buildInputLogContext(request), - e.getClass().getName(), - e.getMessage() != null ? e.getMessage() : "无", e); + e.getClass().getSimpleName(), + e.getMessage() != null ? e.getMessage() : "无具体说明", e); return okResult(side, formatHint( "运行时故障", "服务端在处理识别流程时抛出未预期异常,识别结果不可用", @@ -168,8 +163,7 @@ public class RecognizeDriverLicenseController extends BaseController { private String validateRequest(DriverLicenseRecognizeRequest request) { if (request == null) { - log.info("[驾驶证识别] 阶段=入参校验 结论=拒绝 原因=Spring未绑定到请求Bean " - + "入参摘要=request=null 计费标记=未调用平台"); + log.info("驾驶证识别:没收到任何请求参数(表单未绑定成功),直接拒绝,未调用识别、不扣费"); return formatHint( "入参绑定失败", "控制器未接收到可绑定的表单对象,所有业务字段均为空", @@ -179,7 +173,7 @@ public class RecognizeDriverLicenseController extends BaseController { ); } if (isBlank(request.getImageBase64()) && isBlank(request.getImageUrl())) { - log.info("[驾驶证识别] 阶段=入参校验 结论=拒绝 原因=影像双字段皆空 入参摘要={} 计费标记=未调用平台", + log.info("驾驶证识别:没传图片(imageBase64 和 imageUrl 都为空),直接拒绝,未调用识别、不扣费。{}", buildInputLogContext(request)); return formatHint( "影像源缺失", @@ -190,11 +184,11 @@ public class RecognizeDriverLicenseController extends BaseController { ); } if (StringUtils.isNotBlank(request.getImageBase64()) && StringUtils.isNotBlank(request.getImageUrl())) { - log.info("[驾驶证识别] 阶段=入参兼容 说明=Base64与URL同时存在,按规范丢弃URL仅保留Base64流 入参摘要={}", + log.info("驾驶证识别:客户同时传了 Base64 和图片链接,按规则只用 Base64,忽略链接。{}", buildInputLogContext(request)); } if (resolveDrivingLicenseSide(request) == null) { - log.info("[驾驶证识别] 阶段=入参校验 结论=拒绝 原因=side非法 入参摘要={} 计费标记=未调用平台", + log.info("驾驶证识别:side 参数写错了(只支持 face/front 正页、back 副页),直接拒绝,未调用识别、不扣费。{}", buildInputLogContext(request)); return formatHint( "页面标识无效", @@ -238,6 +232,28 @@ public class RecognizeDriverLicenseController extends BaseController { return ApiConstants.back.equals(drivingLicenseSide) ? "副页(back)" : "正页(front/face)"; } + /** 日志用:正页/副页中文说明 */ + private String sideDesc(String drivingLicenseSide) { + return ApiConstants.back.equals(drivingLicenseSide) ? "驾驶证副页" : "驾驶证正页"; + } + + /** 日志用:图片提交方式中文说明 */ + private String imageModeDesc(String imageMode) { + if ("Base64".equals(imageMode)) { + return "使用 Base64 编码图片"; + } + if ("URL".equals(imageMode)) { + return "使用图片链接"; + } + if (imageMode != null && imageMode.contains("Base64")) { + return "同时传了 Base64 和链接,实际使用 Base64"; + } + if ("无".equals(imageMode)) { + return "未传图片"; + } + return "图片提交方式未知"; + } + private String buildRequestContent(DriverLicenseRecognizeRequest request, String drivingLicenseSide) { StringBuilder sb = new StringBuilder(); if (StringUtils.isNotBlank(request.getImageBase64())) { @@ -272,11 +288,9 @@ public class RecognizeDriverLicenseController extends BaseController { String errorMsg = errorMsgObj != null ? errorMsgObj.toString() : "平台未返回文字描述"; String knownHint = PLATFORM_ERROR_HINTS.get(errorCode); String category = resolveErrorCategory(errorCode); - log.error("[驾驶证识别] 阶段=平台回执 结论=业务拒绝 目标页面={} 页面标签={} 影像模式={} " - + "错误分类={} 错误码={} 错误描述={} 是否命中本地错误码说明={} " - + "入参摘要={} 平台回执摘要={}", - drivingLicenseSide, sideLabel(drivingLicenseSide), imageMode, - category, errorCode, errorMsg, knownHint != null, + log.error("驾驶证识别:平台拒绝了本次识别。[{}] 错误码 {},原因:{}。识别{},{}。客户传的:{}。{}", + category, errorCode, errorMsg, + sideDesc(drivingLicenseSide), imageModeDesc(imageMode), inputContext, buildPlatformReceiptSummary(platformResult)); return formatHint( category, @@ -286,9 +300,8 @@ public class RecognizeDriverLicenseController extends BaseController { ); } if (isWordsResultEmpty(platformResult)) { - log.info("[驾驶证识别] 阶段=结果解析 结论=空集 目标页面={} 页面标签={} 影像模式={} " - + "入参摘要={} 平台回执摘要={} 说明=回执中不存在可遍历的结构化结果节点", - drivingLicenseSide, sideLabel(drivingLicenseSide), imageMode, + log.info("驾驶证识别:平台返回了,但没有识别结果数据(可能不是驾驶证或 side 传错)。识别{},{}。客户传的:{}。{}", + sideDesc(drivingLicenseSide), imageModeDesc(imageMode), inputContext, buildPlatformReceiptSummary(platformResult)); return formatHint( "结构化结果缺失", @@ -408,43 +421,48 @@ public class RecognizeDriverLicenseController extends BaseController { } /** - * 入参日志摘要(不打印 base64 正文,仅长度与 url 长度) + * 入参日志说明(不打印 base64 正文,只说长度) */ private String buildInputLogContext(DriverLicenseRecognizeRequest request) { if (request == null) { - return "request=null"; + return "未收到请求体"; } - String sideParam = isBlank(request.getSide()) ? "未传" : request.getSide().trim(); + String sideParam = isBlank(request.getSide()) ? "未传(默认按正页)" : request.getSide().trim(); String resolvedSide = resolveDrivingLicenseSide(request); - String targetPage = resolvedSide == null ? "无法解析" : sideLabel(resolvedSide); - return "side入参=" + sideParam - + ",目标页面=" + targetPage - + ",影像模式=" + resolveImageMode(request) - + ",base64长度=" + textLength(request.getImageBase64()) - + ",url长度=" + textLength(request.getImageUrl()) - + ",url是否为空=" + isBlank(request.getImageUrl()); + String targetPage = resolvedSide == null ? "side 无法识别" : sideDesc(resolvedSide); + String imageMode = resolveImageMode(request); + int base64Len = textLength(request.getImageBase64()); + int urlLen = textLength(request.getImageUrl()); + return String.format("识别%s,side 参数=%s,%s,Base64 长度 %d 字符,图片链接长度 %d 字符", + targetPage, sideParam, imageModeDesc(imageMode), base64Len, urlLen); } /** - * 平台回执日志摘要(便于失败排查) + * 平台回执日志说明(便于失败排查) */ private String buildPlatformReceiptSummary(Map platformResult) { if (platformResult == null) { - return "platformResult=null"; + return "平台无任何回执"; } - StringBuilder sb = new StringBuilder(); - sb.append("error_code=").append(platformResult.get("error_code")); - sb.append(",error_msg=").append(platformResult.get("error_msg")); - sb.append(",log_id=").append(platformResult.get("log_id")); - sb.append(",words_result_num=").append(platformResult.get("words_result_num")); - sb.append(",direction=").append(platformResult.get("direction")); + Object errorCode = platformResult.get("error_code"); + Object errorMsg = platformResult.get("error_msg"); + Object logId = platformResult.get("log_id"); + if (errorCode != null) { + return String.format("平台返回失败,错误码 %s,说明:%s,流水号 %s", + errorCode, + errorMsg != null ? errorMsg : "无", + logId != null ? logId : "无"); + } + Object wordsResultNum = platformResult.get("words_result_num"); Object wordsResult = platformResult.get("words_result"); + int fieldCount = 0; if (wordsResult instanceof Map) { - sb.append(",结果字段数=").append(((Map) wordsResult).size()); - } else { - sb.append(",结果字段数=不可解析"); + fieldCount = ((Map) wordsResult).size(); } - return sb.toString(); + return String.format("平台返回成功,识别结果约 %s 项、结构化字段 %d 个,流水号 %s", + wordsResultNum != null ? wordsResultNum : "未知", + fieldCount, + logId != null ? logId : "无"); } private int textLength(String value) {